less.js 490 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618
  1. /**
  2. * Less - Leaner CSS v4.2.2
  3. * http://lesscss.org
  4. *
  5. * Copyright (c) 2009-2025, Alexis Sellier <self@cloudhead.net>
  6. * Licensed under the Apache-2.0 License.
  7. *
  8. * @license Apache-2.0
  9. */
  10. (function (global, factory) {
  11. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  12. typeof define === 'function' && define.amd ? define(factory) :
  13. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.less = factory());
  14. })(this, (function () { 'use strict';
  15. // Export a new default each time
  16. function defaultOptions () {
  17. return {
  18. /* Inline Javascript - @plugin still allowed */
  19. javascriptEnabled: false,
  20. /* Outputs a makefile import dependency list to stdout. */
  21. depends: false,
  22. /* (DEPRECATED) Compress using less built-in compression.
  23. * This does an okay job but does not utilise all the tricks of
  24. * dedicated css compression. */
  25. compress: false,
  26. /* Runs the less parser and just reports errors without any output. */
  27. lint: false,
  28. /* Sets available include paths.
  29. * If the file in an @import rule does not exist at that exact location,
  30. * less will look for it at the location(s) passed to this option.
  31. * You might use this for instance to specify a path to a library which
  32. * you want to be referenced simply and relatively in the less files. */
  33. paths: [],
  34. /* color output in the terminal */
  35. color: true,
  36. /* The strictImports controls whether the compiler will allow an @import inside of either
  37. * @media blocks or (a later addition) other selector blocks.
  38. * See: https://github.com/less/less.js/issues/656 */
  39. strictImports: false,
  40. /* Allow Imports from Insecure HTTPS Hosts */
  41. insecure: false,
  42. /* Allows you to add a path to every generated import and url in your css.
  43. * This does not affect less import statements that are processed, just ones
  44. * that are left in the output css. */
  45. rootpath: '',
  46. /* By default URLs are kept as-is, so if you import a file in a sub-directory
  47. * that references an image, exactly the same URL will be output in the css.
  48. * This option allows you to re-write URL's in imported files so that the
  49. * URL is always relative to the base imported file */
  50. rewriteUrls: false,
  51. /* How to process math
  52. * 0 always - eagerly try to solve all operations
  53. * 1 parens-division - require parens for division "/"
  54. * 2 parens | strict - require parens for all operations
  55. * 3 strict-legacy - legacy strict behavior (super-strict)
  56. */
  57. math: 1,
  58. /* Without this option, less attempts to guess at the output unit when it does maths. */
  59. strictUnits: false,
  60. /* Effectively the declaration is put at the top of your base Less file,
  61. * meaning it can be used but it also can be overridden if this variable
  62. * is defined in the file. */
  63. globalVars: null,
  64. /* As opposed to the global variable option, this puts the declaration at the
  65. * end of your base file, meaning it will override anything defined in your Less file. */
  66. modifyVars: null,
  67. /* This option allows you to specify a argument to go on to every URL. */
  68. urlArgs: ''
  69. };
  70. }
  71. function extractId(href) {
  72. return href.replace(/^[a-z-]+:\/+?[^/]+/, '') // Remove protocol & domain
  73. .replace(/[?&]livereload=\w+/, '') // Remove LiveReload cachebuster
  74. .replace(/^\//, '') // Remove root /
  75. .replace(/\.[a-zA-Z]+$/, '') // Remove simple extension
  76. .replace(/[^.\w-]+/g, '-') // Replace illegal characters
  77. .replace(/\./g, ':'); // Replace dots with colons(for valid id)
  78. }
  79. function addDataAttr(options, tag) {
  80. if (!tag) {
  81. return;
  82. } // in case of tag is null or undefined
  83. for (var opt in tag.dataset) {
  84. if (Object.prototype.hasOwnProperty.call(tag.dataset, opt)) {
  85. if (opt === 'env' || opt === 'dumpLineNumbers' || opt === 'rootpath' || opt === 'errorReporting') {
  86. options[opt] = tag.dataset[opt];
  87. }
  88. else {
  89. try {
  90. options[opt] = JSON.parse(tag.dataset[opt]);
  91. }
  92. catch (_) { }
  93. }
  94. }
  95. }
  96. }
  97. var browser = {
  98. createCSS: function (document, styles, sheet) {
  99. // Strip the query-string
  100. var href = sheet.href || '';
  101. // If there is no title set, use the filename, minus the extension
  102. var id = "less:".concat(sheet.title || extractId(href));
  103. // If this has already been inserted into the DOM, we may need to replace it
  104. var oldStyleNode = document.getElementById(id);
  105. var keepOldStyleNode = false;
  106. // Create a new stylesheet node for insertion or (if necessary) replacement
  107. var styleNode = document.createElement('style');
  108. styleNode.setAttribute('type', 'text/css');
  109. if (sheet.media) {
  110. styleNode.setAttribute('media', sheet.media);
  111. }
  112. styleNode.id = id;
  113. if (!styleNode.styleSheet) {
  114. styleNode.appendChild(document.createTextNode(styles));
  115. // If new contents match contents of oldStyleNode, don't replace oldStyleNode
  116. keepOldStyleNode = (oldStyleNode !== null && oldStyleNode.childNodes.length > 0 && styleNode.childNodes.length > 0 &&
  117. oldStyleNode.firstChild.nodeValue === styleNode.firstChild.nodeValue);
  118. }
  119. var head = document.getElementsByTagName('head')[0];
  120. // If there is no oldStyleNode, just append; otherwise, only append if we need
  121. // to replace oldStyleNode with an updated stylesheet
  122. if (oldStyleNode === null || keepOldStyleNode === false) {
  123. var nextEl = sheet && sheet.nextSibling || null;
  124. if (nextEl) {
  125. nextEl.parentNode.insertBefore(styleNode, nextEl);
  126. }
  127. else {
  128. head.appendChild(styleNode);
  129. }
  130. }
  131. if (oldStyleNode && keepOldStyleNode === false) {
  132. oldStyleNode.parentNode.removeChild(oldStyleNode);
  133. }
  134. // For IE.
  135. // This needs to happen *after* the style element is added to the DOM, otherwise IE 7 and 8 may crash.
  136. // See http://social.msdn.microsoft.com/Forums/en-US/7e081b65-878a-4c22-8e68-c10d39c2ed32/internet-explorer-crashes-appending-style-element-to-head
  137. if (styleNode.styleSheet) {
  138. try {
  139. styleNode.styleSheet.cssText = styles;
  140. }
  141. catch (e) {
  142. throw new Error('Couldn\'t reassign styleSheet.cssText.');
  143. }
  144. }
  145. },
  146. currentScript: function (window) {
  147. var document = window.document;
  148. return document.currentScript || (function () {
  149. var scripts = document.getElementsByTagName('script');
  150. return scripts[scripts.length - 1];
  151. })();
  152. }
  153. };
  154. var addDefaultOptions = (function (window, options) {
  155. // use options from the current script tag data attribues
  156. addDataAttr(options, browser.currentScript(window));
  157. if (options.isFileProtocol === undefined) {
  158. options.isFileProtocol = /^(file|(chrome|safari)(-extension)?|resource|qrc|app):/.test(window.location.protocol);
  159. }
  160. // Load styles asynchronously (default: false)
  161. //
  162. // This is set to `false` by default, so that the body
  163. // doesn't start loading before the stylesheets are parsed.
  164. // Setting this to `true` can result in flickering.
  165. //
  166. options.async = options.async || false;
  167. options.fileAsync = options.fileAsync || false;
  168. // Interval between watch polls
  169. options.poll = options.poll || (options.isFileProtocol ? 1000 : 1500);
  170. options.env = options.env || (window.location.hostname == '127.0.0.1' ||
  171. window.location.hostname == '0.0.0.0' ||
  172. window.location.hostname == 'localhost' ||
  173. (window.location.port &&
  174. window.location.port.length > 0) ||
  175. options.isFileProtocol ? 'development'
  176. : 'production');
  177. var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(window.location.hash);
  178. if (dumpLineNumbers) {
  179. options.dumpLineNumbers = dumpLineNumbers[1];
  180. }
  181. if (options.useFileCache === undefined) {
  182. options.useFileCache = true;
  183. }
  184. if (options.onReady === undefined) {
  185. options.onReady = true;
  186. }
  187. if (options.relativeUrls) {
  188. options.rewriteUrls = 'all';
  189. }
  190. });
  191. var logger$1 = {
  192. error: function (msg) {
  193. this._fireEvent('error', msg);
  194. },
  195. warn: function (msg) {
  196. this._fireEvent('warn', msg);
  197. },
  198. info: function (msg) {
  199. this._fireEvent('info', msg);
  200. },
  201. debug: function (msg) {
  202. this._fireEvent('debug', msg);
  203. },
  204. addListener: function (listener) {
  205. this._listeners.push(listener);
  206. },
  207. removeListener: function (listener) {
  208. for (var i_1 = 0; i_1 < this._listeners.length; i_1++) {
  209. if (this._listeners[i_1] === listener) {
  210. this._listeners.splice(i_1, 1);
  211. return;
  212. }
  213. }
  214. },
  215. _fireEvent: function (type, msg) {
  216. for (var i_2 = 0; i_2 < this._listeners.length; i_2++) {
  217. var logFunction = this._listeners[i_2][type];
  218. if (logFunction) {
  219. logFunction(msg);
  220. }
  221. }
  222. },
  223. _listeners: []
  224. };
  225. /**
  226. * @todo Document why this abstraction exists, and the relationship between
  227. * environment, file managers, and plugin manager
  228. */
  229. var Environment = /** @class */ (function () {
  230. function Environment(externalEnvironment, fileManagers) {
  231. this.fileManagers = fileManagers || [];
  232. externalEnvironment = externalEnvironment || {};
  233. var optionalFunctions = ['encodeBase64', 'mimeLookup', 'charsetLookup', 'getSourceMapGenerator'];
  234. var requiredFunctions = [];
  235. var functions = requiredFunctions.concat(optionalFunctions);
  236. for (var i_1 = 0; i_1 < functions.length; i_1++) {
  237. var propName = functions[i_1];
  238. var environmentFunc = externalEnvironment[propName];
  239. if (environmentFunc) {
  240. this[propName] = environmentFunc.bind(externalEnvironment);
  241. }
  242. else if (i_1 < requiredFunctions.length) {
  243. this.warn("missing required function in environment - ".concat(propName));
  244. }
  245. }
  246. }
  247. Environment.prototype.getFileManager = function (filename, currentDirectory, options, environment, isSync) {
  248. if (!filename) {
  249. logger$1.warn('getFileManager called with no filename.. Please report this issue. continuing.');
  250. }
  251. if (currentDirectory === undefined) {
  252. logger$1.warn('getFileManager called with null directory.. Please report this issue. continuing.');
  253. }
  254. var fileManagers = this.fileManagers;
  255. if (options.pluginManager) {
  256. fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers());
  257. }
  258. for (var i_2 = fileManagers.length - 1; i_2 >= 0; i_2--) {
  259. var fileManager = fileManagers[i_2];
  260. if (fileManager[isSync ? 'supportsSync' : 'supports'](filename, currentDirectory, options, environment)) {
  261. return fileManager;
  262. }
  263. }
  264. return null;
  265. };
  266. Environment.prototype.addFileManager = function (fileManager) {
  267. this.fileManagers.push(fileManager);
  268. };
  269. Environment.prototype.clearFileManagers = function () {
  270. this.fileManagers = [];
  271. };
  272. return Environment;
  273. }());
  274. var colors = {
  275. 'aliceblue': '#f0f8ff',
  276. 'antiquewhite': '#faebd7',
  277. 'aqua': '#00ffff',
  278. 'aquamarine': '#7fffd4',
  279. 'azure': '#f0ffff',
  280. 'beige': '#f5f5dc',
  281. 'bisque': '#ffe4c4',
  282. 'black': '#000000',
  283. 'blanchedalmond': '#ffebcd',
  284. 'blue': '#0000ff',
  285. 'blueviolet': '#8a2be2',
  286. 'brown': '#a52a2a',
  287. 'burlywood': '#deb887',
  288. 'cadetblue': '#5f9ea0',
  289. 'chartreuse': '#7fff00',
  290. 'chocolate': '#d2691e',
  291. 'coral': '#ff7f50',
  292. 'cornflowerblue': '#6495ed',
  293. 'cornsilk': '#fff8dc',
  294. 'crimson': '#dc143c',
  295. 'cyan': '#00ffff',
  296. 'darkblue': '#00008b',
  297. 'darkcyan': '#008b8b',
  298. 'darkgoldenrod': '#b8860b',
  299. 'darkgray': '#a9a9a9',
  300. 'darkgrey': '#a9a9a9',
  301. 'darkgreen': '#006400',
  302. 'darkkhaki': '#bdb76b',
  303. 'darkmagenta': '#8b008b',
  304. 'darkolivegreen': '#556b2f',
  305. 'darkorange': '#ff8c00',
  306. 'darkorchid': '#9932cc',
  307. 'darkred': '#8b0000',
  308. 'darksalmon': '#e9967a',
  309. 'darkseagreen': '#8fbc8f',
  310. 'darkslateblue': '#483d8b',
  311. 'darkslategray': '#2f4f4f',
  312. 'darkslategrey': '#2f4f4f',
  313. 'darkturquoise': '#00ced1',
  314. 'darkviolet': '#9400d3',
  315. 'deeppink': '#ff1493',
  316. 'deepskyblue': '#00bfff',
  317. 'dimgray': '#696969',
  318. 'dimgrey': '#696969',
  319. 'dodgerblue': '#1e90ff',
  320. 'firebrick': '#b22222',
  321. 'floralwhite': '#fffaf0',
  322. 'forestgreen': '#228b22',
  323. 'fuchsia': '#ff00ff',
  324. 'gainsboro': '#dcdcdc',
  325. 'ghostwhite': '#f8f8ff',
  326. 'gold': '#ffd700',
  327. 'goldenrod': '#daa520',
  328. 'gray': '#808080',
  329. 'grey': '#808080',
  330. 'green': '#008000',
  331. 'greenyellow': '#adff2f',
  332. 'honeydew': '#f0fff0',
  333. 'hotpink': '#ff69b4',
  334. 'indianred': '#cd5c5c',
  335. 'indigo': '#4b0082',
  336. 'ivory': '#fffff0',
  337. 'khaki': '#f0e68c',
  338. 'lavender': '#e6e6fa',
  339. 'lavenderblush': '#fff0f5',
  340. 'lawngreen': '#7cfc00',
  341. 'lemonchiffon': '#fffacd',
  342. 'lightblue': '#add8e6',
  343. 'lightcoral': '#f08080',
  344. 'lightcyan': '#e0ffff',
  345. 'lightgoldenrodyellow': '#fafad2',
  346. 'lightgray': '#d3d3d3',
  347. 'lightgrey': '#d3d3d3',
  348. 'lightgreen': '#90ee90',
  349. 'lightpink': '#ffb6c1',
  350. 'lightsalmon': '#ffa07a',
  351. 'lightseagreen': '#20b2aa',
  352. 'lightskyblue': '#87cefa',
  353. 'lightslategray': '#778899',
  354. 'lightslategrey': '#778899',
  355. 'lightsteelblue': '#b0c4de',
  356. 'lightyellow': '#ffffe0',
  357. 'lime': '#00ff00',
  358. 'limegreen': '#32cd32',
  359. 'linen': '#faf0e6',
  360. 'magenta': '#ff00ff',
  361. 'maroon': '#800000',
  362. 'mediumaquamarine': '#66cdaa',
  363. 'mediumblue': '#0000cd',
  364. 'mediumorchid': '#ba55d3',
  365. 'mediumpurple': '#9370d8',
  366. 'mediumseagreen': '#3cb371',
  367. 'mediumslateblue': '#7b68ee',
  368. 'mediumspringgreen': '#00fa9a',
  369. 'mediumturquoise': '#48d1cc',
  370. 'mediumvioletred': '#c71585',
  371. 'midnightblue': '#191970',
  372. 'mintcream': '#f5fffa',
  373. 'mistyrose': '#ffe4e1',
  374. 'moccasin': '#ffe4b5',
  375. 'navajowhite': '#ffdead',
  376. 'navy': '#000080',
  377. 'oldlace': '#fdf5e6',
  378. 'olive': '#808000',
  379. 'olivedrab': '#6b8e23',
  380. 'orange': '#ffa500',
  381. 'orangered': '#ff4500',
  382. 'orchid': '#da70d6',
  383. 'palegoldenrod': '#eee8aa',
  384. 'palegreen': '#98fb98',
  385. 'paleturquoise': '#afeeee',
  386. 'palevioletred': '#d87093',
  387. 'papayawhip': '#ffefd5',
  388. 'peachpuff': '#ffdab9',
  389. 'peru': '#cd853f',
  390. 'pink': '#ffc0cb',
  391. 'plum': '#dda0dd',
  392. 'powderblue': '#b0e0e6',
  393. 'purple': '#800080',
  394. 'rebeccapurple': '#663399',
  395. 'red': '#ff0000',
  396. 'rosybrown': '#bc8f8f',
  397. 'royalblue': '#4169e1',
  398. 'saddlebrown': '#8b4513',
  399. 'salmon': '#fa8072',
  400. 'sandybrown': '#f4a460',
  401. 'seagreen': '#2e8b57',
  402. 'seashell': '#fff5ee',
  403. 'sienna': '#a0522d',
  404. 'silver': '#c0c0c0',
  405. 'skyblue': '#87ceeb',
  406. 'slateblue': '#6a5acd',
  407. 'slategray': '#708090',
  408. 'slategrey': '#708090',
  409. 'snow': '#fffafa',
  410. 'springgreen': '#00ff7f',
  411. 'steelblue': '#4682b4',
  412. 'tan': '#d2b48c',
  413. 'teal': '#008080',
  414. 'thistle': '#d8bfd8',
  415. 'tomato': '#ff6347',
  416. 'turquoise': '#40e0d0',
  417. 'violet': '#ee82ee',
  418. 'wheat': '#f5deb3',
  419. 'white': '#ffffff',
  420. 'whitesmoke': '#f5f5f5',
  421. 'yellow': '#ffff00',
  422. 'yellowgreen': '#9acd32'
  423. };
  424. var unitConversions = {
  425. length: {
  426. 'm': 1,
  427. 'cm': 0.01,
  428. 'mm': 0.001,
  429. 'in': 0.0254,
  430. 'px': 0.0254 / 96,
  431. 'pt': 0.0254 / 72,
  432. 'pc': 0.0254 / 72 * 12
  433. },
  434. duration: {
  435. 's': 1,
  436. 'ms': 0.001
  437. },
  438. angle: {
  439. 'rad': 1 / (2 * Math.PI),
  440. 'deg': 1 / 360,
  441. 'grad': 1 / 400,
  442. 'turn': 1
  443. }
  444. };
  445. var data = { colors: colors, unitConversions: unitConversions };
  446. /**
  447. * The reason why Node is a class and other nodes simply do not extend
  448. * from Node (since we're transpiling) is due to this issue:
  449. *
  450. * @see https://github.com/less/less.js/issues/3434
  451. */
  452. var Node = /** @class */ (function () {
  453. function Node() {
  454. this.parent = null;
  455. this.visibilityBlocks = undefined;
  456. this.nodeVisible = undefined;
  457. this.rootNode = null;
  458. this.parsed = null;
  459. }
  460. Object.defineProperty(Node.prototype, "currentFileInfo", {
  461. get: function () {
  462. return this.fileInfo();
  463. },
  464. enumerable: false,
  465. configurable: true
  466. });
  467. Object.defineProperty(Node.prototype, "index", {
  468. get: function () {
  469. return this.getIndex();
  470. },
  471. enumerable: false,
  472. configurable: true
  473. });
  474. Node.prototype.setParent = function (nodes, parent) {
  475. function set(node) {
  476. if (node && node instanceof Node) {
  477. node.parent = parent;
  478. }
  479. }
  480. if (Array.isArray(nodes)) {
  481. nodes.forEach(set);
  482. }
  483. else {
  484. set(nodes);
  485. }
  486. };
  487. Node.prototype.getIndex = function () {
  488. return this._index || (this.parent && this.parent.getIndex()) || 0;
  489. };
  490. Node.prototype.fileInfo = function () {
  491. return this._fileInfo || (this.parent && this.parent.fileInfo()) || {};
  492. };
  493. Node.prototype.isRulesetLike = function () { return false; };
  494. Node.prototype.toCSS = function (context) {
  495. var strs = [];
  496. this.genCSS(context, {
  497. // remove when genCSS has JSDoc types
  498. // eslint-disable-next-line no-unused-vars
  499. add: function (chunk, fileInfo, index) {
  500. strs.push(chunk);
  501. },
  502. isEmpty: function () {
  503. return strs.length === 0;
  504. }
  505. });
  506. return strs.join('');
  507. };
  508. Node.prototype.genCSS = function (context, output) {
  509. output.add(this.value);
  510. };
  511. Node.prototype.accept = function (visitor) {
  512. this.value = visitor.visit(this.value);
  513. };
  514. Node.prototype.eval = function () { return this; };
  515. Node.prototype._operate = function (context, op, a, b) {
  516. switch (op) {
  517. case '+': return a + b;
  518. case '-': return a - b;
  519. case '*': return a * b;
  520. case '/': return a / b;
  521. }
  522. };
  523. Node.prototype.fround = function (context, value) {
  524. var precision = context && context.numPrecision;
  525. // add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999...) are properly rounded:
  526. return (precision) ? Number((value + 2e-16).toFixed(precision)) : value;
  527. };
  528. Node.compare = function (a, b) {
  529. /* returns:
  530. -1: a < b
  531. 0: a = b
  532. 1: a > b
  533. and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */
  534. if ((a.compare) &&
  535. // for "symmetric results" force toCSS-based comparison
  536. // of Quoted or Anonymous if either value is one of those
  537. !(b.type === 'Quoted' || b.type === 'Anonymous')) {
  538. return a.compare(b);
  539. }
  540. else if (b.compare) {
  541. return -b.compare(a);
  542. }
  543. else if (a.type !== b.type) {
  544. return undefined;
  545. }
  546. a = a.value;
  547. b = b.value;
  548. if (!Array.isArray(a)) {
  549. return a === b ? 0 : undefined;
  550. }
  551. if (a.length !== b.length) {
  552. return undefined;
  553. }
  554. for (var i_1 = 0; i_1 < a.length; i_1++) {
  555. if (Node.compare(a[i_1], b[i_1]) !== 0) {
  556. return undefined;
  557. }
  558. }
  559. return 0;
  560. };
  561. Node.numericCompare = function (a, b) {
  562. return a < b ? -1
  563. : a === b ? 0
  564. : a > b ? 1 : undefined;
  565. };
  566. // Returns true if this node represents root of ast imported by reference
  567. Node.prototype.blocksVisibility = function () {
  568. if (this.visibilityBlocks === undefined) {
  569. this.visibilityBlocks = 0;
  570. }
  571. return this.visibilityBlocks !== 0;
  572. };
  573. Node.prototype.addVisibilityBlock = function () {
  574. if (this.visibilityBlocks === undefined) {
  575. this.visibilityBlocks = 0;
  576. }
  577. this.visibilityBlocks = this.visibilityBlocks + 1;
  578. };
  579. Node.prototype.removeVisibilityBlock = function () {
  580. if (this.visibilityBlocks === undefined) {
  581. this.visibilityBlocks = 0;
  582. }
  583. this.visibilityBlocks = this.visibilityBlocks - 1;
  584. };
  585. // Turns on node visibility - if called node will be shown in output regardless
  586. // of whether it comes from import by reference or not
  587. Node.prototype.ensureVisibility = function () {
  588. this.nodeVisible = true;
  589. };
  590. // Turns off node visibility - if called node will NOT be shown in output regardless
  591. // of whether it comes from import by reference or not
  592. Node.prototype.ensureInvisibility = function () {
  593. this.nodeVisible = false;
  594. };
  595. // return values:
  596. // false - the node must not be visible
  597. // true - the node must be visible
  598. // undefined or null - the node has the same visibility as its parent
  599. Node.prototype.isVisible = function () {
  600. return this.nodeVisible;
  601. };
  602. Node.prototype.visibilityInfo = function () {
  603. return {
  604. visibilityBlocks: this.visibilityBlocks,
  605. nodeVisible: this.nodeVisible
  606. };
  607. };
  608. Node.prototype.copyVisibilityInfo = function (info) {
  609. if (!info) {
  610. return;
  611. }
  612. this.visibilityBlocks = info.visibilityBlocks;
  613. this.nodeVisible = info.nodeVisible;
  614. };
  615. return Node;
  616. }());
  617. //
  618. // RGB Colors - #ff0014, #eee
  619. //
  620. var Color = function (rgb, a, originalForm) {
  621. var self = this;
  622. //
  623. // The end goal here, is to parse the arguments
  624. // into an integer triplet, such as `128, 255, 0`
  625. //
  626. // This facilitates operations and conversions.
  627. //
  628. if (Array.isArray(rgb)) {
  629. this.rgb = rgb;
  630. }
  631. else if (rgb.length >= 6) {
  632. this.rgb = [];
  633. rgb.match(/.{2}/g).map(function (c, i) {
  634. if (i < 3) {
  635. self.rgb.push(parseInt(c, 16));
  636. }
  637. else {
  638. self.alpha = (parseInt(c, 16)) / 255;
  639. }
  640. });
  641. }
  642. else {
  643. this.rgb = [];
  644. rgb.split('').map(function (c, i) {
  645. if (i < 3) {
  646. self.rgb.push(parseInt(c + c, 16));
  647. }
  648. else {
  649. self.alpha = (parseInt(c + c, 16)) / 255;
  650. }
  651. });
  652. }
  653. this.alpha = this.alpha || (typeof a === 'number' ? a : 1);
  654. if (typeof originalForm !== 'undefined') {
  655. this.value = originalForm;
  656. }
  657. };
  658. Color.prototype = Object.assign(new Node(), {
  659. type: 'Color',
  660. luma: function () {
  661. var r = this.rgb[0] / 255, g = this.rgb[1] / 255, b = this.rgb[2] / 255;
  662. r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4);
  663. g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4);
  664. b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4);
  665. return 0.2126 * r + 0.7152 * g + 0.0722 * b;
  666. },
  667. genCSS: function (context, output) {
  668. output.add(this.toCSS(context));
  669. },
  670. toCSS: function (context, doNotCompress) {
  671. var compress = context && context.compress && !doNotCompress;
  672. var color;
  673. var alpha;
  674. var colorFunction;
  675. var args = [];
  676. // `value` is set if this color was originally
  677. // converted from a named color string so we need
  678. // to respect this and try to output named color too.
  679. alpha = this.fround(context, this.alpha);
  680. if (this.value) {
  681. if (this.value.indexOf('rgb') === 0) {
  682. if (alpha < 1) {
  683. colorFunction = 'rgba';
  684. }
  685. }
  686. else if (this.value.indexOf('hsl') === 0) {
  687. if (alpha < 1) {
  688. colorFunction = 'hsla';
  689. }
  690. else {
  691. colorFunction = 'hsl';
  692. }
  693. }
  694. else {
  695. return this.value;
  696. }
  697. }
  698. else {
  699. if (alpha < 1) {
  700. colorFunction = 'rgba';
  701. }
  702. }
  703. switch (colorFunction) {
  704. case 'rgba':
  705. args = this.rgb.map(function (c) {
  706. return clamp$1(Math.round(c), 255);
  707. }).concat(clamp$1(alpha, 1));
  708. break;
  709. case 'hsla':
  710. args.push(clamp$1(alpha, 1));
  711. // eslint-disable-next-line no-fallthrough
  712. case 'hsl':
  713. color = this.toHSL();
  714. args = [
  715. this.fround(context, color.h),
  716. "".concat(this.fround(context, color.s * 100), "%"),
  717. "".concat(this.fround(context, color.l * 100), "%")
  718. ].concat(args);
  719. }
  720. if (colorFunction) {
  721. // Values are capped between `0` and `255`, rounded and zero-padded.
  722. return "".concat(colorFunction, "(").concat(args.join(",".concat(compress ? '' : ' ')), ")");
  723. }
  724. color = this.toRGB();
  725. if (compress) {
  726. var splitcolor = color.split('');
  727. // Convert color to short format
  728. if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) {
  729. color = "#".concat(splitcolor[1]).concat(splitcolor[3]).concat(splitcolor[5]);
  730. }
  731. }
  732. return color;
  733. },
  734. //
  735. // Operations have to be done per-channel, if not,
  736. // channels will spill onto each other. Once we have
  737. // our result, in the form of an integer triplet,
  738. // we create a new Color node to hold the result.
  739. //
  740. operate: function (context, op, other) {
  741. var rgb = new Array(3);
  742. var alpha = this.alpha * (1 - other.alpha) + other.alpha;
  743. for (var c = 0; c < 3; c++) {
  744. rgb[c] = this._operate(context, op, this.rgb[c], other.rgb[c]);
  745. }
  746. return new Color(rgb, alpha);
  747. },
  748. toRGB: function () {
  749. return toHex(this.rgb);
  750. },
  751. toHSL: function () {
  752. var r = this.rgb[0] / 255, g = this.rgb[1] / 255, b = this.rgb[2] / 255, a = this.alpha;
  753. var max = Math.max(r, g, b), min = Math.min(r, g, b);
  754. var h;
  755. var s;
  756. var l = (max + min) / 2;
  757. var d = max - min;
  758. if (max === min) {
  759. h = s = 0;
  760. }
  761. else {
  762. s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
  763. switch (max) {
  764. case r:
  765. h = (g - b) / d + (g < b ? 6 : 0);
  766. break;
  767. case g:
  768. h = (b - r) / d + 2;
  769. break;
  770. case b:
  771. h = (r - g) / d + 4;
  772. break;
  773. }
  774. h /= 6;
  775. }
  776. return { h: h * 360, s: s, l: l, a: a };
  777. },
  778. // Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
  779. toHSV: function () {
  780. var r = this.rgb[0] / 255, g = this.rgb[1] / 255, b = this.rgb[2] / 255, a = this.alpha;
  781. var max = Math.max(r, g, b), min = Math.min(r, g, b);
  782. var h;
  783. var s;
  784. var v = max;
  785. var d = max - min;
  786. if (max === 0) {
  787. s = 0;
  788. }
  789. else {
  790. s = d / max;
  791. }
  792. if (max === min) {
  793. h = 0;
  794. }
  795. else {
  796. switch (max) {
  797. case r:
  798. h = (g - b) / d + (g < b ? 6 : 0);
  799. break;
  800. case g:
  801. h = (b - r) / d + 2;
  802. break;
  803. case b:
  804. h = (r - g) / d + 4;
  805. break;
  806. }
  807. h /= 6;
  808. }
  809. return { h: h * 360, s: s, v: v, a: a };
  810. },
  811. toARGB: function () {
  812. return toHex([this.alpha * 255].concat(this.rgb));
  813. },
  814. compare: function (x) {
  815. return (x.rgb &&
  816. x.rgb[0] === this.rgb[0] &&
  817. x.rgb[1] === this.rgb[1] &&
  818. x.rgb[2] === this.rgb[2] &&
  819. x.alpha === this.alpha) ? 0 : undefined;
  820. }
  821. });
  822. Color.fromKeyword = function (keyword) {
  823. var c;
  824. var key = keyword.toLowerCase();
  825. // eslint-disable-next-line no-prototype-builtins
  826. if (colors.hasOwnProperty(key)) {
  827. c = new Color(colors[key].slice(1));
  828. }
  829. else if (key === 'transparent') {
  830. c = new Color([0, 0, 0], 0);
  831. }
  832. if (c) {
  833. c.value = keyword;
  834. return c;
  835. }
  836. };
  837. function clamp$1(v, max) {
  838. return Math.min(Math.max(v, 0), max);
  839. }
  840. function toHex(v) {
  841. return "#".concat(v.map(function (c) {
  842. c = clamp$1(Math.round(c), 255);
  843. return (c < 16 ? '0' : '') + c.toString(16);
  844. }).join(''));
  845. }
  846. var Paren = function (node) {
  847. this.value = node;
  848. };
  849. Paren.prototype = Object.assign(new Node(), {
  850. type: 'Paren',
  851. genCSS: function (context, output) {
  852. output.add('(');
  853. this.value.genCSS(context, output);
  854. output.add(')');
  855. },
  856. eval: function (context) {
  857. return new Paren(this.value.eval(context));
  858. }
  859. });
  860. var _noSpaceCombinators = {
  861. '': true,
  862. ' ': true,
  863. '|': true
  864. };
  865. var Combinator = function (value) {
  866. if (value === ' ') {
  867. this.value = ' ';
  868. this.emptyOrWhitespace = true;
  869. }
  870. else {
  871. this.value = value ? value.trim() : '';
  872. this.emptyOrWhitespace = this.value === '';
  873. }
  874. };
  875. Combinator.prototype = Object.assign(new Node(), {
  876. type: 'Combinator',
  877. genCSS: function (context, output) {
  878. var spaceOrEmpty = (context.compress || _noSpaceCombinators[this.value]) ? '' : ' ';
  879. output.add(spaceOrEmpty + this.value + spaceOrEmpty);
  880. }
  881. });
  882. var Element = function (combinator, value, isVariable, index, currentFileInfo, visibilityInfo) {
  883. this.combinator = combinator instanceof Combinator ?
  884. combinator : new Combinator(combinator);
  885. if (typeof value === 'string') {
  886. this.value = value.trim();
  887. }
  888. else if (value) {
  889. this.value = value;
  890. }
  891. else {
  892. this.value = '';
  893. }
  894. this.isVariable = isVariable;
  895. this._index = index;
  896. this._fileInfo = currentFileInfo;
  897. this.copyVisibilityInfo(visibilityInfo);
  898. this.setParent(this.combinator, this);
  899. };
  900. Element.prototype = Object.assign(new Node(), {
  901. type: 'Element',
  902. accept: function (visitor) {
  903. var value = this.value;
  904. this.combinator = visitor.visit(this.combinator);
  905. if (typeof value === 'object') {
  906. this.value = visitor.visit(value);
  907. }
  908. },
  909. eval: function (context) {
  910. return new Element(this.combinator, this.value.eval ? this.value.eval(context) : this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo());
  911. },
  912. clone: function () {
  913. return new Element(this.combinator, this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo());
  914. },
  915. genCSS: function (context, output) {
  916. output.add(this.toCSS(context), this.fileInfo(), this.getIndex());
  917. },
  918. toCSS: function (context) {
  919. context = context || {};
  920. var value = this.value;
  921. var firstSelector = context.firstSelector;
  922. if (value instanceof Paren) {
  923. // selector in parens should not be affected by outer selector
  924. // flags (breaks only interpolated selectors - see #1973)
  925. context.firstSelector = true;
  926. }
  927. value = value.toCSS ? value.toCSS(context) : value;
  928. context.firstSelector = firstSelector;
  929. if (value === '' && this.combinator.value.charAt(0) === '&') {
  930. return '';
  931. }
  932. else {
  933. return this.combinator.toCSS(context) + value;
  934. }
  935. }
  936. });
  937. var Math$1 = {
  938. ALWAYS: 0,
  939. PARENS_DIVISION: 1,
  940. PARENS: 2
  941. // removed - STRICT_LEGACY: 3
  942. };
  943. var RewriteUrls = {
  944. OFF: 0,
  945. LOCAL: 1,
  946. ALL: 2
  947. };
  948. /******************************************************************************
  949. Copyright (c) Microsoft Corporation.
  950. Permission to use, copy, modify, and/or distribute this software for any
  951. purpose with or without fee is hereby granted.
  952. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  953. REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  954. AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  955. INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  956. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  957. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  958. PERFORMANCE OF THIS SOFTWARE.
  959. ***************************************************************************** */
  960. var __assign = function() {
  961. __assign = Object.assign || function __assign(t) {
  962. for (var s, i = 1, n = arguments.length; i < n; i++) {
  963. s = arguments[i];
  964. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
  965. }
  966. return t;
  967. };
  968. return __assign.apply(this, arguments);
  969. };
  970. function __spreadArray(to, from, pack) {
  971. if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
  972. if (ar || !(i in from)) {
  973. if (!ar) ar = Array.prototype.slice.call(from, 0, i);
  974. ar[i] = from[i];
  975. }
  976. }
  977. return to.concat(ar || Array.prototype.slice.call(from));
  978. }
  979. typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
  980. var e = new Error(message);
  981. return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
  982. };
  983. /**
  984. * Returns the object type of the given payload
  985. *
  986. * @param {*} payload
  987. * @returns {string}
  988. */
  989. function getType(payload) {
  990. return Object.prototype.toString.call(payload).slice(8, -1);
  991. }
  992. /**
  993. * Returns whether the payload is a plain JavaScript object (excluding special classes or objects with other prototypes)
  994. *
  995. * @param {*} payload
  996. * @returns {payload is PlainObject}
  997. */
  998. function isPlainObject(payload) {
  999. if (getType(payload) !== 'Object')
  1000. return false;
  1001. return payload.constructor === Object && Object.getPrototypeOf(payload) === Object.prototype;
  1002. }
  1003. /**
  1004. * Returns whether the payload is an array
  1005. *
  1006. * @param {any} payload
  1007. * @returns {payload is any[]}
  1008. */
  1009. function isArray(payload) {
  1010. return getType(payload) === 'Array';
  1011. }
  1012. function assignProp(carry, key, newVal, originalObject, includeNonenumerable) {
  1013. var propType = {}.propertyIsEnumerable.call(originalObject, key)
  1014. ? 'enumerable'
  1015. : 'nonenumerable';
  1016. if (propType === 'enumerable')
  1017. carry[key] = newVal;
  1018. if (includeNonenumerable && propType === 'nonenumerable') {
  1019. Object.defineProperty(carry, key, {
  1020. value: newVal,
  1021. enumerable: false,
  1022. writable: true,
  1023. configurable: true,
  1024. });
  1025. }
  1026. }
  1027. /**
  1028. * Copy (clone) an object and all its props recursively to get rid of any prop referenced of the original object. Arrays are also cloned, however objects inside arrays are still linked.
  1029. *
  1030. * @export
  1031. * @template T
  1032. * @param {T} target Target can be anything
  1033. * @param {Options} [options = {}] Options can be `props` or `nonenumerable`
  1034. * @returns {T} the target with replaced values
  1035. * @export
  1036. */
  1037. function copy(target, options) {
  1038. if (options === void 0) { options = {}; }
  1039. if (isArray(target)) {
  1040. return target.map(function (item) { return copy(item, options); });
  1041. }
  1042. if (!isPlainObject(target)) {
  1043. return target;
  1044. }
  1045. var props = Object.getOwnPropertyNames(target);
  1046. var symbols = Object.getOwnPropertySymbols(target);
  1047. return __spreadArray(__spreadArray([], props, true), symbols, true).reduce(function (carry, key) {
  1048. if (isArray(options.props) && !options.props.includes(key)) {
  1049. return carry;
  1050. }
  1051. var val = target[key];
  1052. var newVal = copy(val, options);
  1053. assignProp(carry, key, newVal, target, options.nonenumerable);
  1054. return carry;
  1055. }, {});
  1056. }
  1057. /* jshint proto: true */
  1058. function getLocation(index, inputStream) {
  1059. var n = index + 1;
  1060. var line = null;
  1061. var column = -1;
  1062. while (--n >= 0 && inputStream.charAt(n) !== '\n') {
  1063. column++;
  1064. }
  1065. if (typeof index === 'number') {
  1066. line = (inputStream.slice(0, index).match(/\n/g) || '').length;
  1067. }
  1068. return {
  1069. line: line,
  1070. column: column
  1071. };
  1072. }
  1073. function copyArray(arr) {
  1074. var i;
  1075. var length = arr.length;
  1076. var copy = new Array(length);
  1077. for (i = 0; i < length; i++) {
  1078. copy[i] = arr[i];
  1079. }
  1080. return copy;
  1081. }
  1082. function clone(obj) {
  1083. var cloned = {};
  1084. for (var prop in obj) {
  1085. if (Object.prototype.hasOwnProperty.call(obj, prop)) {
  1086. cloned[prop] = obj[prop];
  1087. }
  1088. }
  1089. return cloned;
  1090. }
  1091. function defaults(obj1, obj2) {
  1092. var newObj = obj2 || {};
  1093. if (!obj2._defaults) {
  1094. newObj = {};
  1095. var defaults_1 = copy(obj1);
  1096. newObj._defaults = defaults_1;
  1097. var cloned = obj2 ? copy(obj2) : {};
  1098. Object.assign(newObj, defaults_1, cloned);
  1099. }
  1100. return newObj;
  1101. }
  1102. function copyOptions(obj1, obj2) {
  1103. if (obj2 && obj2._defaults) {
  1104. return obj2;
  1105. }
  1106. var opts = defaults(obj1, obj2);
  1107. if (opts.strictMath) {
  1108. opts.math = Math$1.PARENS;
  1109. }
  1110. // Back compat with changed relativeUrls option
  1111. if (opts.relativeUrls) {
  1112. opts.rewriteUrls = RewriteUrls.ALL;
  1113. }
  1114. if (typeof opts.math === 'string') {
  1115. switch (opts.math.toLowerCase()) {
  1116. case 'always':
  1117. opts.math = Math$1.ALWAYS;
  1118. break;
  1119. case 'parens-division':
  1120. opts.math = Math$1.PARENS_DIVISION;
  1121. break;
  1122. case 'strict':
  1123. case 'parens':
  1124. opts.math = Math$1.PARENS;
  1125. break;
  1126. default:
  1127. opts.math = Math$1.PARENS;
  1128. }
  1129. }
  1130. if (typeof opts.rewriteUrls === 'string') {
  1131. switch (opts.rewriteUrls.toLowerCase()) {
  1132. case 'off':
  1133. opts.rewriteUrls = RewriteUrls.OFF;
  1134. break;
  1135. case 'local':
  1136. opts.rewriteUrls = RewriteUrls.LOCAL;
  1137. break;
  1138. case 'all':
  1139. opts.rewriteUrls = RewriteUrls.ALL;
  1140. break;
  1141. }
  1142. }
  1143. return opts;
  1144. }
  1145. function merge(obj1, obj2) {
  1146. for (var prop in obj2) {
  1147. if (Object.prototype.hasOwnProperty.call(obj2, prop)) {
  1148. obj1[prop] = obj2[prop];
  1149. }
  1150. }
  1151. return obj1;
  1152. }
  1153. function flattenArray(arr, result) {
  1154. if (result === void 0) { result = []; }
  1155. for (var i_1 = 0, length_1 = arr.length; i_1 < length_1; i_1++) {
  1156. var value = arr[i_1];
  1157. if (Array.isArray(value)) {
  1158. flattenArray(value, result);
  1159. }
  1160. else {
  1161. if (value !== undefined) {
  1162. result.push(value);
  1163. }
  1164. }
  1165. }
  1166. return result;
  1167. }
  1168. function isNullOrUndefined(val) {
  1169. return val === null || val === undefined;
  1170. }
  1171. var utils = /*#__PURE__*/Object.freeze({
  1172. __proto__: null,
  1173. getLocation: getLocation,
  1174. copyArray: copyArray,
  1175. clone: clone,
  1176. defaults: defaults,
  1177. copyOptions: copyOptions,
  1178. merge: merge,
  1179. flattenArray: flattenArray,
  1180. isNullOrUndefined: isNullOrUndefined
  1181. });
  1182. var anonymousFunc = /(<anonymous>|Function):(\d+):(\d+)/;
  1183. /**
  1184. * This is a centralized class of any error that could be thrown internally (mostly by the parser).
  1185. * Besides standard .message it keeps some additional data like a path to the file where the error
  1186. * occurred along with line and column numbers.
  1187. *
  1188. * @class
  1189. * @extends Error
  1190. * @type {module.LessError}
  1191. *
  1192. * @prop {string} type
  1193. * @prop {string} filename
  1194. * @prop {number} index
  1195. * @prop {number} line
  1196. * @prop {number} column
  1197. * @prop {number} callLine
  1198. * @prop {number} callExtract
  1199. * @prop {string[]} extract
  1200. *
  1201. * @param {Object} e - An error object to wrap around or just a descriptive object
  1202. * @param {Object} fileContentMap - An object with file contents in 'contents' property (like importManager) @todo - move to fileManager?
  1203. * @param {string} [currentFilename]
  1204. */
  1205. var LessError = function (e, fileContentMap, currentFilename) {
  1206. Error.call(this);
  1207. var filename = e.filename || currentFilename;
  1208. this.message = e.message;
  1209. this.stack = e.stack;
  1210. if (fileContentMap && filename) {
  1211. var input = fileContentMap.contents[filename];
  1212. var loc = getLocation(e.index, input);
  1213. var line = loc.line;
  1214. var col = loc.column;
  1215. var callLine = e.call && getLocation(e.call, input).line;
  1216. var lines = input ? input.split('\n') : '';
  1217. this.type = e.type || 'Syntax';
  1218. this.filename = filename;
  1219. this.index = e.index;
  1220. this.line = typeof line === 'number' ? line + 1 : null;
  1221. this.column = col;
  1222. if (!this.line && this.stack) {
  1223. var found = this.stack.match(anonymousFunc);
  1224. /**
  1225. * We have to figure out how this environment stringifies anonymous functions
  1226. * so we can correctly map plugin errors.
  1227. *
  1228. * Note, in Node 8, the output of anonymous funcs varied based on parameters
  1229. * being present or not, so we inject dummy params.
  1230. */
  1231. var func = new Function('a', 'throw new Error()');
  1232. var lineAdjust = 0;
  1233. try {
  1234. func();
  1235. }
  1236. catch (e) {
  1237. var match = e.stack.match(anonymousFunc);
  1238. lineAdjust = 1 - parseInt(match[2]);
  1239. }
  1240. if (found) {
  1241. if (found[2]) {
  1242. this.line = parseInt(found[2]) + lineAdjust;
  1243. }
  1244. if (found[3]) {
  1245. this.column = parseInt(found[3]);
  1246. }
  1247. }
  1248. }
  1249. this.callLine = callLine + 1;
  1250. this.callExtract = lines[callLine];
  1251. this.extract = [
  1252. lines[this.line - 2],
  1253. lines[this.line - 1],
  1254. lines[this.line]
  1255. ];
  1256. }
  1257. };
  1258. if (typeof Object.create === 'undefined') {
  1259. var F = function () { };
  1260. F.prototype = Error.prototype;
  1261. LessError.prototype = new F();
  1262. }
  1263. else {
  1264. LessError.prototype = Object.create(Error.prototype);
  1265. }
  1266. LessError.prototype.constructor = LessError;
  1267. /**
  1268. * An overridden version of the default Object.prototype.toString
  1269. * which uses additional information to create a helpful message.
  1270. *
  1271. * @param {Object} options
  1272. * @returns {string}
  1273. */
  1274. LessError.prototype.toString = function (options) {
  1275. options = options || {};
  1276. var message = '';
  1277. var extract = this.extract || [];
  1278. var error = [];
  1279. var stylize = function (str) { return str; };
  1280. if (options.stylize) {
  1281. var type = typeof options.stylize;
  1282. if (type !== 'function') {
  1283. throw Error("options.stylize should be a function, got a ".concat(type, "!"));
  1284. }
  1285. stylize = options.stylize;
  1286. }
  1287. if (this.line !== null) {
  1288. if (typeof extract[0] === 'string') {
  1289. error.push(stylize("".concat(this.line - 1, " ").concat(extract[0]), 'grey'));
  1290. }
  1291. if (typeof extract[1] === 'string') {
  1292. var errorTxt = "".concat(this.line, " ");
  1293. if (extract[1]) {
  1294. errorTxt += extract[1].slice(0, this.column) +
  1295. stylize(stylize(stylize(extract[1].substr(this.column, 1), 'bold') +
  1296. extract[1].slice(this.column + 1), 'red'), 'inverse');
  1297. }
  1298. error.push(errorTxt);
  1299. }
  1300. if (typeof extract[2] === 'string') {
  1301. error.push(stylize("".concat(this.line + 1, " ").concat(extract[2]), 'grey'));
  1302. }
  1303. error = "".concat(error.join('\n') + stylize('', 'reset'), "\n");
  1304. }
  1305. message += stylize("".concat(this.type, "Error: ").concat(this.message), 'red');
  1306. if (this.filename) {
  1307. message += stylize(' in ', 'red') + this.filename;
  1308. }
  1309. if (this.line) {
  1310. message += stylize(" on line ".concat(this.line, ", column ").concat(this.column + 1, ":"), 'grey');
  1311. }
  1312. message += "\n".concat(error);
  1313. if (this.callLine) {
  1314. message += "".concat(stylize('from ', 'red') + (this.filename || ''), "/n");
  1315. message += "".concat(stylize(this.callLine, 'grey'), " ").concat(this.callExtract, "/n");
  1316. }
  1317. return message;
  1318. };
  1319. var _visitArgs = { visitDeeper: true };
  1320. var _hasIndexed = false;
  1321. function _noop(node) {
  1322. return node;
  1323. }
  1324. function indexNodeTypes(parent, ticker) {
  1325. // add .typeIndex to tree node types for lookup table
  1326. var key, child;
  1327. for (key in parent) {
  1328. /* eslint guard-for-in: 0 */
  1329. child = parent[key];
  1330. switch (typeof child) {
  1331. case 'function':
  1332. // ignore bound functions directly on tree which do not have a prototype
  1333. // or aren't nodes
  1334. if (child.prototype && child.prototype.type) {
  1335. child.prototype.typeIndex = ticker++;
  1336. }
  1337. break;
  1338. case 'object':
  1339. ticker = indexNodeTypes(child, ticker);
  1340. break;
  1341. }
  1342. }
  1343. return ticker;
  1344. }
  1345. var Visitor = /** @class */ (function () {
  1346. function Visitor(implementation) {
  1347. this._implementation = implementation;
  1348. this._visitInCache = {};
  1349. this._visitOutCache = {};
  1350. if (!_hasIndexed) {
  1351. indexNodeTypes(tree, 1);
  1352. _hasIndexed = true;
  1353. }
  1354. }
  1355. Visitor.prototype.visit = function (node) {
  1356. if (!node) {
  1357. return node;
  1358. }
  1359. var nodeTypeIndex = node.typeIndex;
  1360. if (!nodeTypeIndex) {
  1361. // MixinCall args aren't a node type?
  1362. if (node.value && node.value.typeIndex) {
  1363. this.visit(node.value);
  1364. }
  1365. return node;
  1366. }
  1367. var impl = this._implementation;
  1368. var func = this._visitInCache[nodeTypeIndex];
  1369. var funcOut = this._visitOutCache[nodeTypeIndex];
  1370. var visitArgs = _visitArgs;
  1371. var fnName;
  1372. visitArgs.visitDeeper = true;
  1373. if (!func) {
  1374. fnName = "visit".concat(node.type);
  1375. func = impl[fnName] || _noop;
  1376. funcOut = impl["".concat(fnName, "Out")] || _noop;
  1377. this._visitInCache[nodeTypeIndex] = func;
  1378. this._visitOutCache[nodeTypeIndex] = funcOut;
  1379. }
  1380. if (func !== _noop) {
  1381. var newNode = func.call(impl, node, visitArgs);
  1382. if (node && impl.isReplacing) {
  1383. node = newNode;
  1384. }
  1385. }
  1386. if (visitArgs.visitDeeper && node) {
  1387. if (node.length) {
  1388. for (var i_1 = 0, cnt = node.length; i_1 < cnt; i_1++) {
  1389. if (node[i_1].accept) {
  1390. node[i_1].accept(this);
  1391. }
  1392. }
  1393. }
  1394. else if (node.accept) {
  1395. node.accept(this);
  1396. }
  1397. }
  1398. if (funcOut != _noop) {
  1399. funcOut.call(impl, node);
  1400. }
  1401. return node;
  1402. };
  1403. Visitor.prototype.visitArray = function (nodes, nonReplacing) {
  1404. if (!nodes) {
  1405. return nodes;
  1406. }
  1407. var cnt = nodes.length;
  1408. var i;
  1409. // Non-replacing
  1410. if (nonReplacing || !this._implementation.isReplacing) {
  1411. for (i = 0; i < cnt; i++) {
  1412. this.visit(nodes[i]);
  1413. }
  1414. return nodes;
  1415. }
  1416. // Replacing
  1417. var out = [];
  1418. for (i = 0; i < cnt; i++) {
  1419. var evald = this.visit(nodes[i]);
  1420. if (evald === undefined) {
  1421. continue;
  1422. }
  1423. if (!evald.splice) {
  1424. out.push(evald);
  1425. }
  1426. else if (evald.length) {
  1427. this.flatten(evald, out);
  1428. }
  1429. }
  1430. return out;
  1431. };
  1432. Visitor.prototype.flatten = function (arr, out) {
  1433. if (!out) {
  1434. out = [];
  1435. }
  1436. var cnt, i, item, nestedCnt, j, nestedItem;
  1437. for (i = 0, cnt = arr.length; i < cnt; i++) {
  1438. item = arr[i];
  1439. if (item === undefined) {
  1440. continue;
  1441. }
  1442. if (!item.splice) {
  1443. out.push(item);
  1444. continue;
  1445. }
  1446. for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) {
  1447. nestedItem = item[j];
  1448. if (nestedItem === undefined) {
  1449. continue;
  1450. }
  1451. if (!nestedItem.splice) {
  1452. out.push(nestedItem);
  1453. }
  1454. else if (nestedItem.length) {
  1455. this.flatten(nestedItem, out);
  1456. }
  1457. }
  1458. }
  1459. return out;
  1460. };
  1461. return Visitor;
  1462. }());
  1463. var contexts = {};
  1464. var copyFromOriginal = function copyFromOriginal(original, destination, propertiesToCopy) {
  1465. if (!original) {
  1466. return;
  1467. }
  1468. for (var i_1 = 0; i_1 < propertiesToCopy.length; i_1++) {
  1469. if (Object.prototype.hasOwnProperty.call(original, propertiesToCopy[i_1])) {
  1470. destination[propertiesToCopy[i_1]] = original[propertiesToCopy[i_1]];
  1471. }
  1472. }
  1473. };
  1474. /*
  1475. parse is used whilst parsing
  1476. */
  1477. var parseCopyProperties = [
  1478. // options
  1479. 'paths',
  1480. 'rewriteUrls',
  1481. 'rootpath',
  1482. 'strictImports',
  1483. 'insecure',
  1484. 'dumpLineNumbers',
  1485. 'compress',
  1486. 'syncImport',
  1487. 'chunkInput',
  1488. 'mime',
  1489. 'useFileCache',
  1490. // context
  1491. 'processImports',
  1492. // Used by the import manager to stop multiple import visitors being created.
  1493. 'pluginManager' // Used as the plugin manager for the session
  1494. ];
  1495. contexts.Parse = function (options) {
  1496. copyFromOriginal(options, this, parseCopyProperties);
  1497. if (typeof this.paths === 'string') {
  1498. this.paths = [this.paths];
  1499. }
  1500. };
  1501. var evalCopyProperties = [
  1502. 'paths',
  1503. 'compress',
  1504. 'math',
  1505. 'strictUnits',
  1506. 'sourceMap',
  1507. 'importMultiple',
  1508. 'urlArgs',
  1509. 'javascriptEnabled',
  1510. 'pluginManager',
  1511. 'importantScope',
  1512. 'rewriteUrls' // option - whether to adjust URL's to be relative
  1513. ];
  1514. contexts.Eval = function (options, frames) {
  1515. copyFromOriginal(options, this, evalCopyProperties);
  1516. if (typeof this.paths === 'string') {
  1517. this.paths = [this.paths];
  1518. }
  1519. this.frames = frames || [];
  1520. this.importantScope = this.importantScope || [];
  1521. };
  1522. contexts.Eval.prototype.enterCalc = function () {
  1523. if (!this.calcStack) {
  1524. this.calcStack = [];
  1525. }
  1526. this.calcStack.push(true);
  1527. this.inCalc = true;
  1528. };
  1529. contexts.Eval.prototype.exitCalc = function () {
  1530. this.calcStack.pop();
  1531. if (!this.calcStack.length) {
  1532. this.inCalc = false;
  1533. }
  1534. };
  1535. contexts.Eval.prototype.inParenthesis = function () {
  1536. if (!this.parensStack) {
  1537. this.parensStack = [];
  1538. }
  1539. this.parensStack.push(true);
  1540. };
  1541. contexts.Eval.prototype.outOfParenthesis = function () {
  1542. this.parensStack.pop();
  1543. };
  1544. contexts.Eval.prototype.inCalc = false;
  1545. contexts.Eval.prototype.mathOn = true;
  1546. contexts.Eval.prototype.isMathOn = function (op) {
  1547. if (!this.mathOn) {
  1548. return false;
  1549. }
  1550. if (op === '/' && this.math !== Math$1.ALWAYS && (!this.parensStack || !this.parensStack.length)) {
  1551. return false;
  1552. }
  1553. if (this.math > Math$1.PARENS_DIVISION) {
  1554. return this.parensStack && this.parensStack.length;
  1555. }
  1556. return true;
  1557. };
  1558. contexts.Eval.prototype.pathRequiresRewrite = function (path) {
  1559. var isRelative = this.rewriteUrls === RewriteUrls.LOCAL ? isPathLocalRelative : isPathRelative;
  1560. return isRelative(path);
  1561. };
  1562. contexts.Eval.prototype.rewritePath = function (path, rootpath) {
  1563. var newPath;
  1564. rootpath = rootpath || '';
  1565. newPath = this.normalizePath(rootpath + path);
  1566. // If a path was explicit relative and the rootpath was not an absolute path
  1567. // we must ensure that the new path is also explicit relative.
  1568. if (isPathLocalRelative(path) &&
  1569. isPathRelative(rootpath) &&
  1570. isPathLocalRelative(newPath) === false) {
  1571. newPath = "./".concat(newPath);
  1572. }
  1573. return newPath;
  1574. };
  1575. contexts.Eval.prototype.normalizePath = function (path) {
  1576. var segments = path.split('/').reverse();
  1577. var segment;
  1578. path = [];
  1579. while (segments.length !== 0) {
  1580. segment = segments.pop();
  1581. switch (segment) {
  1582. case '.':
  1583. break;
  1584. case '..':
  1585. if ((path.length === 0) || (path[path.length - 1] === '..')) {
  1586. path.push(segment);
  1587. }
  1588. else {
  1589. path.pop();
  1590. }
  1591. break;
  1592. default:
  1593. path.push(segment);
  1594. break;
  1595. }
  1596. }
  1597. return path.join('/');
  1598. };
  1599. function isPathRelative(path) {
  1600. return !/^(?:[a-z-]+:|\/|#)/i.test(path);
  1601. }
  1602. function isPathLocalRelative(path) {
  1603. return path.charAt(0) === '.';
  1604. }
  1605. // todo - do the same for the toCSS ?
  1606. var ImportSequencer = /** @class */ (function () {
  1607. function ImportSequencer(onSequencerEmpty) {
  1608. this.imports = [];
  1609. this.variableImports = [];
  1610. this._onSequencerEmpty = onSequencerEmpty;
  1611. this._currentDepth = 0;
  1612. }
  1613. ImportSequencer.prototype.addImport = function (callback) {
  1614. var importSequencer = this, importItem = {
  1615. callback: callback,
  1616. args: null,
  1617. isReady: false
  1618. };
  1619. this.imports.push(importItem);
  1620. return function () {
  1621. importItem.args = Array.prototype.slice.call(arguments, 0);
  1622. importItem.isReady = true;
  1623. importSequencer.tryRun();
  1624. };
  1625. };
  1626. ImportSequencer.prototype.addVariableImport = function (callback) {
  1627. this.variableImports.push(callback);
  1628. };
  1629. ImportSequencer.prototype.tryRun = function () {
  1630. this._currentDepth++;
  1631. try {
  1632. while (true) {
  1633. while (this.imports.length > 0) {
  1634. var importItem = this.imports[0];
  1635. if (!importItem.isReady) {
  1636. return;
  1637. }
  1638. this.imports = this.imports.slice(1);
  1639. importItem.callback.apply(null, importItem.args);
  1640. }
  1641. if (this.variableImports.length === 0) {
  1642. break;
  1643. }
  1644. var variableImport = this.variableImports[0];
  1645. this.variableImports = this.variableImports.slice(1);
  1646. variableImport();
  1647. }
  1648. }
  1649. finally {
  1650. this._currentDepth--;
  1651. }
  1652. if (this._currentDepth === 0 && this._onSequencerEmpty) {
  1653. this._onSequencerEmpty();
  1654. }
  1655. };
  1656. return ImportSequencer;
  1657. }());
  1658. /* eslint-disable no-unused-vars */
  1659. var ImportVisitor = function (importer, finish) {
  1660. this._visitor = new Visitor(this);
  1661. this._importer = importer;
  1662. this._finish = finish;
  1663. this.context = new contexts.Eval();
  1664. this.importCount = 0;
  1665. this.onceFileDetectionMap = {};
  1666. this.recursionDetector = {};
  1667. this._sequencer = new ImportSequencer(this._onSequencerEmpty.bind(this));
  1668. };
  1669. ImportVisitor.prototype = {
  1670. isReplacing: false,
  1671. run: function (root) {
  1672. try {
  1673. // process the contents
  1674. this._visitor.visit(root);
  1675. }
  1676. catch (e) {
  1677. this.error = e;
  1678. }
  1679. this.isFinished = true;
  1680. this._sequencer.tryRun();
  1681. },
  1682. _onSequencerEmpty: function () {
  1683. if (!this.isFinished) {
  1684. return;
  1685. }
  1686. this._finish(this.error);
  1687. },
  1688. visitImport: function (importNode, visitArgs) {
  1689. var inlineCSS = importNode.options.inline;
  1690. if (!importNode.css || inlineCSS) {
  1691. var context = new contexts.Eval(this.context, copyArray(this.context.frames));
  1692. var importParent = context.frames[0];
  1693. this.importCount++;
  1694. if (importNode.isVariableImport()) {
  1695. this._sequencer.addVariableImport(this.processImportNode.bind(this, importNode, context, importParent));
  1696. }
  1697. else {
  1698. this.processImportNode(importNode, context, importParent);
  1699. }
  1700. }
  1701. visitArgs.visitDeeper = false;
  1702. },
  1703. processImportNode: function (importNode, context, importParent) {
  1704. var evaldImportNode;
  1705. var inlineCSS = importNode.options.inline;
  1706. try {
  1707. evaldImportNode = importNode.evalForImport(context);
  1708. }
  1709. catch (e) {
  1710. if (!e.filename) {
  1711. e.index = importNode.getIndex();
  1712. e.filename = importNode.fileInfo().filename;
  1713. }
  1714. // attempt to eval properly and treat as css
  1715. importNode.css = true;
  1716. // if that fails, this error will be thrown
  1717. importNode.error = e;
  1718. }
  1719. if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) {
  1720. if (evaldImportNode.options.multiple) {
  1721. context.importMultiple = true;
  1722. }
  1723. // try appending if we haven't determined if it is css or not
  1724. var tryAppendLessExtension = evaldImportNode.css === undefined;
  1725. for (var i_1 = 0; i_1 < importParent.rules.length; i_1++) {
  1726. if (importParent.rules[i_1] === importNode) {
  1727. importParent.rules[i_1] = evaldImportNode;
  1728. break;
  1729. }
  1730. }
  1731. var onImported = this.onImported.bind(this, evaldImportNode, context), sequencedOnImported = this._sequencer.addImport(onImported);
  1732. this._importer.push(evaldImportNode.getPath(), tryAppendLessExtension, evaldImportNode.fileInfo(), evaldImportNode.options, sequencedOnImported);
  1733. }
  1734. else {
  1735. this.importCount--;
  1736. if (this.isFinished) {
  1737. this._sequencer.tryRun();
  1738. }
  1739. }
  1740. },
  1741. onImported: function (importNode, context, e, root, importedAtRoot, fullPath) {
  1742. if (e) {
  1743. if (!e.filename) {
  1744. e.index = importNode.getIndex();
  1745. e.filename = importNode.fileInfo().filename;
  1746. }
  1747. this.error = e;
  1748. }
  1749. var importVisitor = this, inlineCSS = importNode.options.inline, isPlugin = importNode.options.isPlugin, isOptional = importNode.options.optional, duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector;
  1750. if (!context.importMultiple) {
  1751. if (duplicateImport) {
  1752. importNode.skip = true;
  1753. }
  1754. else {
  1755. importNode.skip = function () {
  1756. if (fullPath in importVisitor.onceFileDetectionMap) {
  1757. return true;
  1758. }
  1759. importVisitor.onceFileDetectionMap[fullPath] = true;
  1760. return false;
  1761. };
  1762. }
  1763. }
  1764. if (!fullPath && isOptional) {
  1765. importNode.skip = true;
  1766. }
  1767. if (root) {
  1768. importNode.root = root;
  1769. importNode.importedFilename = fullPath;
  1770. if (!inlineCSS && !isPlugin && (context.importMultiple || !duplicateImport)) {
  1771. importVisitor.recursionDetector[fullPath] = true;
  1772. var oldContext = this.context;
  1773. this.context = context;
  1774. try {
  1775. this._visitor.visit(root);
  1776. }
  1777. catch (e) {
  1778. this.error = e;
  1779. }
  1780. this.context = oldContext;
  1781. }
  1782. }
  1783. importVisitor.importCount--;
  1784. if (importVisitor.isFinished) {
  1785. importVisitor._sequencer.tryRun();
  1786. }
  1787. },
  1788. visitDeclaration: function (declNode, visitArgs) {
  1789. if (declNode.value.type === 'DetachedRuleset') {
  1790. this.context.frames.unshift(declNode);
  1791. }
  1792. else {
  1793. visitArgs.visitDeeper = false;
  1794. }
  1795. },
  1796. visitDeclarationOut: function (declNode) {
  1797. if (declNode.value.type === 'DetachedRuleset') {
  1798. this.context.frames.shift();
  1799. }
  1800. },
  1801. visitAtRule: function (atRuleNode, visitArgs) {
  1802. this.context.frames.unshift(atRuleNode);
  1803. },
  1804. visitAtRuleOut: function (atRuleNode) {
  1805. this.context.frames.shift();
  1806. },
  1807. visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {
  1808. this.context.frames.unshift(mixinDefinitionNode);
  1809. },
  1810. visitMixinDefinitionOut: function (mixinDefinitionNode) {
  1811. this.context.frames.shift();
  1812. },
  1813. visitRuleset: function (rulesetNode, visitArgs) {
  1814. this.context.frames.unshift(rulesetNode);
  1815. },
  1816. visitRulesetOut: function (rulesetNode) {
  1817. this.context.frames.shift();
  1818. },
  1819. visitMedia: function (mediaNode, visitArgs) {
  1820. this.context.frames.unshift(mediaNode.rules[0]);
  1821. },
  1822. visitMediaOut: function (mediaNode) {
  1823. this.context.frames.shift();
  1824. }
  1825. };
  1826. var SetTreeVisibilityVisitor = /** @class */ (function () {
  1827. function SetTreeVisibilityVisitor(visible) {
  1828. this.visible = visible;
  1829. }
  1830. SetTreeVisibilityVisitor.prototype.run = function (root) {
  1831. this.visit(root);
  1832. };
  1833. SetTreeVisibilityVisitor.prototype.visitArray = function (nodes) {
  1834. if (!nodes) {
  1835. return nodes;
  1836. }
  1837. var cnt = nodes.length;
  1838. var i;
  1839. for (i = 0; i < cnt; i++) {
  1840. this.visit(nodes[i]);
  1841. }
  1842. return nodes;
  1843. };
  1844. SetTreeVisibilityVisitor.prototype.visit = function (node) {
  1845. if (!node) {
  1846. return node;
  1847. }
  1848. if (node.constructor === Array) {
  1849. return this.visitArray(node);
  1850. }
  1851. if (!node.blocksVisibility || node.blocksVisibility()) {
  1852. return node;
  1853. }
  1854. if (this.visible) {
  1855. node.ensureVisibility();
  1856. }
  1857. else {
  1858. node.ensureInvisibility();
  1859. }
  1860. node.accept(this);
  1861. return node;
  1862. };
  1863. return SetTreeVisibilityVisitor;
  1864. }());
  1865. /* eslint-disable no-unused-vars */
  1866. /* jshint loopfunc:true */
  1867. var ExtendFinderVisitor = /** @class */ (function () {
  1868. function ExtendFinderVisitor() {
  1869. this._visitor = new Visitor(this);
  1870. this.contexts = [];
  1871. this.allExtendsStack = [[]];
  1872. }
  1873. ExtendFinderVisitor.prototype.run = function (root) {
  1874. root = this._visitor.visit(root);
  1875. root.allExtends = this.allExtendsStack[0];
  1876. return root;
  1877. };
  1878. ExtendFinderVisitor.prototype.visitDeclaration = function (declNode, visitArgs) {
  1879. visitArgs.visitDeeper = false;
  1880. };
  1881. ExtendFinderVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) {
  1882. visitArgs.visitDeeper = false;
  1883. };
  1884. ExtendFinderVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) {
  1885. if (rulesetNode.root) {
  1886. return;
  1887. }
  1888. var i;
  1889. var j;
  1890. var extend;
  1891. var allSelectorsExtendList = [];
  1892. var extendList;
  1893. // get &:extend(.a); rules which apply to all selectors in this ruleset
  1894. var rules = rulesetNode.rules, ruleCnt = rules ? rules.length : 0;
  1895. for (i = 0; i < ruleCnt; i++) {
  1896. if (rulesetNode.rules[i] instanceof tree.Extend) {
  1897. allSelectorsExtendList.push(rules[i]);
  1898. rulesetNode.extendOnEveryPath = true;
  1899. }
  1900. }
  1901. // now find every selector and apply the extends that apply to all extends
  1902. // and the ones which apply to an individual extend
  1903. var paths = rulesetNode.paths;
  1904. for (i = 0; i < paths.length; i++) {
  1905. var selectorPath = paths[i], selector = selectorPath[selectorPath.length - 1], selExtendList = selector.extendList;
  1906. extendList = selExtendList ? copyArray(selExtendList).concat(allSelectorsExtendList)
  1907. : allSelectorsExtendList;
  1908. if (extendList) {
  1909. extendList = extendList.map(function (allSelectorsExtend) {
  1910. return allSelectorsExtend.clone();
  1911. });
  1912. }
  1913. for (j = 0; j < extendList.length; j++) {
  1914. this.foundExtends = true;
  1915. extend = extendList[j];
  1916. extend.findSelfSelectors(selectorPath);
  1917. extend.ruleset = rulesetNode;
  1918. if (j === 0) {
  1919. extend.firstExtendOnThisSelectorPath = true;
  1920. }
  1921. this.allExtendsStack[this.allExtendsStack.length - 1].push(extend);
  1922. }
  1923. }
  1924. this.contexts.push(rulesetNode.selectors);
  1925. };
  1926. ExtendFinderVisitor.prototype.visitRulesetOut = function (rulesetNode) {
  1927. if (!rulesetNode.root) {
  1928. this.contexts.length = this.contexts.length - 1;
  1929. }
  1930. };
  1931. ExtendFinderVisitor.prototype.visitMedia = function (mediaNode, visitArgs) {
  1932. mediaNode.allExtends = [];
  1933. this.allExtendsStack.push(mediaNode.allExtends);
  1934. };
  1935. ExtendFinderVisitor.prototype.visitMediaOut = function (mediaNode) {
  1936. this.allExtendsStack.length = this.allExtendsStack.length - 1;
  1937. };
  1938. ExtendFinderVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) {
  1939. atRuleNode.allExtends = [];
  1940. this.allExtendsStack.push(atRuleNode.allExtends);
  1941. };
  1942. ExtendFinderVisitor.prototype.visitAtRuleOut = function (atRuleNode) {
  1943. this.allExtendsStack.length = this.allExtendsStack.length - 1;
  1944. };
  1945. return ExtendFinderVisitor;
  1946. }());
  1947. var ProcessExtendsVisitor = /** @class */ (function () {
  1948. function ProcessExtendsVisitor() {
  1949. this._visitor = new Visitor(this);
  1950. }
  1951. ProcessExtendsVisitor.prototype.run = function (root) {
  1952. var extendFinder = new ExtendFinderVisitor();
  1953. this.extendIndices = {};
  1954. extendFinder.run(root);
  1955. if (!extendFinder.foundExtends) {
  1956. return root;
  1957. }
  1958. root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends));
  1959. this.allExtendsStack = [root.allExtends];
  1960. var newRoot = this._visitor.visit(root);
  1961. this.checkExtendsForNonMatched(root.allExtends);
  1962. return newRoot;
  1963. };
  1964. ProcessExtendsVisitor.prototype.checkExtendsForNonMatched = function (extendList) {
  1965. var indices = this.extendIndices;
  1966. extendList.filter(function (extend) {
  1967. return !extend.hasFoundMatches && extend.parent_ids.length == 1;
  1968. }).forEach(function (extend) {
  1969. var selector = '_unknown_';
  1970. try {
  1971. selector = extend.selector.toCSS({});
  1972. }
  1973. catch (_) { }
  1974. if (!indices["".concat(extend.index, " ").concat(selector)]) {
  1975. indices["".concat(extend.index, " ").concat(selector)] = true;
  1976. logger$1.warn("extend '".concat(selector, "' has no matches"));
  1977. }
  1978. });
  1979. };
  1980. ProcessExtendsVisitor.prototype.doExtendChaining = function (extendsList, extendsListTarget, iterationCount) {
  1981. //
  1982. // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering
  1983. // and pasting the selector we would do normally, but we are also adding an extend with the same target selector
  1984. // this means this new extend can then go and alter other extends
  1985. //
  1986. // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors
  1987. // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already
  1988. // processed if we look at each selector at a time, as is done in visitRuleset
  1989. var extendIndex;
  1990. var targetExtendIndex;
  1991. var matches;
  1992. var extendsToAdd = [];
  1993. var newSelector;
  1994. var extendVisitor = this;
  1995. var selectorPath;
  1996. var extend;
  1997. var targetExtend;
  1998. var newExtend;
  1999. iterationCount = iterationCount || 0;
  2000. // loop through comparing every extend with every target extend.
  2001. // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place
  2002. // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one
  2003. // and the second is the target.
  2004. // the separation into two lists allows us to process a subset of chains with a bigger set, as is the
  2005. // case when processing media queries
  2006. for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) {
  2007. for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) {
  2008. extend = extendsList[extendIndex];
  2009. targetExtend = extendsListTarget[targetExtendIndex];
  2010. // look for circular references
  2011. if (extend.parent_ids.indexOf(targetExtend.object_id) >= 0) {
  2012. continue;
  2013. }
  2014. // find a match in the target extends self selector (the bit before :extend)
  2015. selectorPath = [targetExtend.selfSelectors[0]];
  2016. matches = extendVisitor.findMatch(extend, selectorPath);
  2017. if (matches.length) {
  2018. extend.hasFoundMatches = true;
  2019. // we found a match, so for each self selector..
  2020. extend.selfSelectors.forEach(function (selfSelector) {
  2021. var info = targetExtend.visibilityInfo();
  2022. // process the extend as usual
  2023. newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector, extend.isVisible());
  2024. // but now we create a new extend from it
  2025. newExtend = new (tree.Extend)(targetExtend.selector, targetExtend.option, 0, targetExtend.fileInfo(), info);
  2026. newExtend.selfSelectors = newSelector;
  2027. // add the extend onto the list of extends for that selector
  2028. newSelector[newSelector.length - 1].extendList = [newExtend];
  2029. // record that we need to add it.
  2030. extendsToAdd.push(newExtend);
  2031. newExtend.ruleset = targetExtend.ruleset;
  2032. // remember its parents for circular references
  2033. newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids);
  2034. // only process the selector once.. if we have :extend(.a,.b) then multiple
  2035. // extends will look at the same selector path, so when extending
  2036. // we know that any others will be duplicates in terms of what is added to the css
  2037. if (targetExtend.firstExtendOnThisSelectorPath) {
  2038. newExtend.firstExtendOnThisSelectorPath = true;
  2039. targetExtend.ruleset.paths.push(newSelector);
  2040. }
  2041. });
  2042. }
  2043. }
  2044. }
  2045. if (extendsToAdd.length) {
  2046. // try to detect circular references to stop a stack overflow.
  2047. // may no longer be needed.
  2048. this.extendChainCount++;
  2049. if (iterationCount > 100) {
  2050. var selectorOne = '{unable to calculate}';
  2051. var selectorTwo = '{unable to calculate}';
  2052. try {
  2053. selectorOne = extendsToAdd[0].selfSelectors[0].toCSS();
  2054. selectorTwo = extendsToAdd[0].selector.toCSS();
  2055. }
  2056. catch (e) { }
  2057. throw { message: "extend circular reference detected. One of the circular extends is currently:".concat(selectorOne, ":extend(").concat(selectorTwo, ")") };
  2058. }
  2059. // now process the new extends on the existing rules so that we can handle a extending b extending c extending
  2060. // d extending e...
  2061. return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount + 1));
  2062. }
  2063. else {
  2064. return extendsToAdd;
  2065. }
  2066. };
  2067. ProcessExtendsVisitor.prototype.visitDeclaration = function (ruleNode, visitArgs) {
  2068. visitArgs.visitDeeper = false;
  2069. };
  2070. ProcessExtendsVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) {
  2071. visitArgs.visitDeeper = false;
  2072. };
  2073. ProcessExtendsVisitor.prototype.visitSelector = function (selectorNode, visitArgs) {
  2074. visitArgs.visitDeeper = false;
  2075. };
  2076. ProcessExtendsVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) {
  2077. if (rulesetNode.root) {
  2078. return;
  2079. }
  2080. var matches;
  2081. var pathIndex;
  2082. var extendIndex;
  2083. var allExtends = this.allExtendsStack[this.allExtendsStack.length - 1];
  2084. var selectorsToAdd = [];
  2085. var extendVisitor = this;
  2086. var selectorPath;
  2087. // look at each selector path in the ruleset, find any extend matches and then copy, find and replace
  2088. for (extendIndex = 0; extendIndex < allExtends.length; extendIndex++) {
  2089. for (pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) {
  2090. selectorPath = rulesetNode.paths[pathIndex];
  2091. // extending extends happens initially, before the main pass
  2092. if (rulesetNode.extendOnEveryPath) {
  2093. continue;
  2094. }
  2095. var extendList = selectorPath[selectorPath.length - 1].extendList;
  2096. if (extendList && extendList.length) {
  2097. continue;
  2098. }
  2099. matches = this.findMatch(allExtends[extendIndex], selectorPath);
  2100. if (matches.length) {
  2101. allExtends[extendIndex].hasFoundMatches = true;
  2102. allExtends[extendIndex].selfSelectors.forEach(function (selfSelector) {
  2103. var extendedSelectors;
  2104. extendedSelectors = extendVisitor.extendSelector(matches, selectorPath, selfSelector, allExtends[extendIndex].isVisible());
  2105. selectorsToAdd.push(extendedSelectors);
  2106. });
  2107. }
  2108. }
  2109. }
  2110. rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd);
  2111. };
  2112. ProcessExtendsVisitor.prototype.findMatch = function (extend, haystackSelectorPath) {
  2113. //
  2114. // look through the haystack selector path to try and find the needle - extend.selector
  2115. // returns an array of selector matches that can then be replaced
  2116. //
  2117. var haystackSelectorIndex;
  2118. var hackstackSelector;
  2119. var hackstackElementIndex;
  2120. var haystackElement;
  2121. var targetCombinator;
  2122. var i;
  2123. var extendVisitor = this;
  2124. var needleElements = extend.selector.elements;
  2125. var potentialMatches = [];
  2126. var potentialMatch;
  2127. var matches = [];
  2128. // loop through the haystack elements
  2129. for (haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) {
  2130. hackstackSelector = haystackSelectorPath[haystackSelectorIndex];
  2131. for (hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) {
  2132. haystackElement = hackstackSelector.elements[hackstackElementIndex];
  2133. // if we allow elements before our match we can add a potential match every time. otherwise only at the first element.
  2134. if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) {
  2135. potentialMatches.push({ pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0,
  2136. initialCombinator: haystackElement.combinator });
  2137. }
  2138. for (i = 0; i < potentialMatches.length; i++) {
  2139. potentialMatch = potentialMatches[i];
  2140. // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't
  2141. // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to
  2142. // work out what the resulting combinator will be
  2143. targetCombinator = haystackElement.combinator.value;
  2144. if (targetCombinator === '' && hackstackElementIndex === 0) {
  2145. targetCombinator = ' ';
  2146. }
  2147. // if we don't match, null our match to indicate failure
  2148. if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) ||
  2149. (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) {
  2150. potentialMatch = null;
  2151. }
  2152. else {
  2153. potentialMatch.matched++;
  2154. }
  2155. // if we are still valid and have finished, test whether we have elements after and whether these are allowed
  2156. if (potentialMatch) {
  2157. potentialMatch.finished = potentialMatch.matched === needleElements.length;
  2158. if (potentialMatch.finished &&
  2159. (!extend.allowAfter &&
  2160. (hackstackElementIndex + 1 < hackstackSelector.elements.length || haystackSelectorIndex + 1 < haystackSelectorPath.length))) {
  2161. potentialMatch = null;
  2162. }
  2163. }
  2164. // if null we remove, if not, we are still valid, so either push as a valid match or continue
  2165. if (potentialMatch) {
  2166. if (potentialMatch.finished) {
  2167. potentialMatch.length = needleElements.length;
  2168. potentialMatch.endPathIndex = haystackSelectorIndex;
  2169. potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match
  2170. potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again
  2171. matches.push(potentialMatch);
  2172. }
  2173. }
  2174. else {
  2175. potentialMatches.splice(i, 1);
  2176. i--;
  2177. }
  2178. }
  2179. }
  2180. }
  2181. return matches;
  2182. };
  2183. ProcessExtendsVisitor.prototype.isElementValuesEqual = function (elementValue1, elementValue2) {
  2184. if (typeof elementValue1 === 'string' || typeof elementValue2 === 'string') {
  2185. return elementValue1 === elementValue2;
  2186. }
  2187. if (elementValue1 instanceof tree.Attribute) {
  2188. if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) {
  2189. return false;
  2190. }
  2191. if (!elementValue1.value || !elementValue2.value) {
  2192. if (elementValue1.value || elementValue2.value) {
  2193. return false;
  2194. }
  2195. return true;
  2196. }
  2197. elementValue1 = elementValue1.value.value || elementValue1.value;
  2198. elementValue2 = elementValue2.value.value || elementValue2.value;
  2199. return elementValue1 === elementValue2;
  2200. }
  2201. elementValue1 = elementValue1.value;
  2202. elementValue2 = elementValue2.value;
  2203. if (elementValue1 instanceof tree.Selector) {
  2204. if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) {
  2205. return false;
  2206. }
  2207. for (var i_1 = 0; i_1 < elementValue1.elements.length; i_1++) {
  2208. if (elementValue1.elements[i_1].combinator.value !== elementValue2.elements[i_1].combinator.value) {
  2209. if (i_1 !== 0 || (elementValue1.elements[i_1].combinator.value || ' ') !== (elementValue2.elements[i_1].combinator.value || ' ')) {
  2210. return false;
  2211. }
  2212. }
  2213. if (!this.isElementValuesEqual(elementValue1.elements[i_1].value, elementValue2.elements[i_1].value)) {
  2214. return false;
  2215. }
  2216. }
  2217. return true;
  2218. }
  2219. return false;
  2220. };
  2221. ProcessExtendsVisitor.prototype.extendSelector = function (matches, selectorPath, replacementSelector, isVisible) {
  2222. // for a set of matches, replace each match with the replacement selector
  2223. var currentSelectorPathIndex = 0, currentSelectorPathElementIndex = 0, path = [], matchIndex, selector, firstElement, match, newElements;
  2224. for (matchIndex = 0; matchIndex < matches.length; matchIndex++) {
  2225. match = matches[matchIndex];
  2226. selector = selectorPath[match.pathIndex];
  2227. firstElement = new tree.Element(match.initialCombinator, replacementSelector.elements[0].value, replacementSelector.elements[0].isVariable, replacementSelector.elements[0].getIndex(), replacementSelector.elements[0].fileInfo());
  2228. if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) {
  2229. path[path.length - 1].elements = path[path.length - 1]
  2230. .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));
  2231. currentSelectorPathElementIndex = 0;
  2232. currentSelectorPathIndex++;
  2233. }
  2234. newElements = selector.elements
  2235. .slice(currentSelectorPathElementIndex, match.index)
  2236. .concat([firstElement])
  2237. .concat(replacementSelector.elements.slice(1));
  2238. if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) {
  2239. path[path.length - 1].elements =
  2240. path[path.length - 1].elements.concat(newElements);
  2241. }
  2242. else {
  2243. path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex));
  2244. path.push(new tree.Selector(newElements));
  2245. }
  2246. currentSelectorPathIndex = match.endPathIndex;
  2247. currentSelectorPathElementIndex = match.endPathElementIndex;
  2248. if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) {
  2249. currentSelectorPathElementIndex = 0;
  2250. currentSelectorPathIndex++;
  2251. }
  2252. }
  2253. if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) {
  2254. path[path.length - 1].elements = path[path.length - 1]
  2255. .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));
  2256. currentSelectorPathIndex++;
  2257. }
  2258. path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length));
  2259. path = path.map(function (currentValue) {
  2260. // we can re-use elements here, because the visibility property matters only for selectors
  2261. var derived = currentValue.createDerived(currentValue.elements);
  2262. if (isVisible) {
  2263. derived.ensureVisibility();
  2264. }
  2265. else {
  2266. derived.ensureInvisibility();
  2267. }
  2268. return derived;
  2269. });
  2270. return path;
  2271. };
  2272. ProcessExtendsVisitor.prototype.visitMedia = function (mediaNode, visitArgs) {
  2273. var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]);
  2274. newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends));
  2275. this.allExtendsStack.push(newAllExtends);
  2276. };
  2277. ProcessExtendsVisitor.prototype.visitMediaOut = function (mediaNode) {
  2278. var lastIndex = this.allExtendsStack.length - 1;
  2279. this.allExtendsStack.length = lastIndex;
  2280. };
  2281. ProcessExtendsVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) {
  2282. var newAllExtends = atRuleNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]);
  2283. newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, atRuleNode.allExtends));
  2284. this.allExtendsStack.push(newAllExtends);
  2285. };
  2286. ProcessExtendsVisitor.prototype.visitAtRuleOut = function (atRuleNode) {
  2287. var lastIndex = this.allExtendsStack.length - 1;
  2288. this.allExtendsStack.length = lastIndex;
  2289. };
  2290. return ProcessExtendsVisitor;
  2291. }());
  2292. /* eslint-disable no-unused-vars */
  2293. var JoinSelectorVisitor = /** @class */ (function () {
  2294. function JoinSelectorVisitor() {
  2295. this.contexts = [[]];
  2296. this._visitor = new Visitor(this);
  2297. }
  2298. JoinSelectorVisitor.prototype.run = function (root) {
  2299. return this._visitor.visit(root);
  2300. };
  2301. JoinSelectorVisitor.prototype.visitDeclaration = function (declNode, visitArgs) {
  2302. visitArgs.visitDeeper = false;
  2303. };
  2304. JoinSelectorVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) {
  2305. visitArgs.visitDeeper = false;
  2306. };
  2307. JoinSelectorVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) {
  2308. var context = this.contexts[this.contexts.length - 1];
  2309. var paths = [];
  2310. var selectors;
  2311. this.contexts.push(paths);
  2312. if (!rulesetNode.root) {
  2313. selectors = rulesetNode.selectors;
  2314. if (selectors) {
  2315. selectors = selectors.filter(function (selector) { return selector.getIsOutput(); });
  2316. rulesetNode.selectors = selectors.length ? selectors : (selectors = null);
  2317. if (selectors) {
  2318. rulesetNode.joinSelectors(paths, context, selectors);
  2319. }
  2320. }
  2321. if (!selectors) {
  2322. rulesetNode.rules = null;
  2323. }
  2324. rulesetNode.paths = paths;
  2325. }
  2326. };
  2327. JoinSelectorVisitor.prototype.visitRulesetOut = function (rulesetNode) {
  2328. this.contexts.length = this.contexts.length - 1;
  2329. };
  2330. JoinSelectorVisitor.prototype.visitMedia = function (mediaNode, visitArgs) {
  2331. var context = this.contexts[this.contexts.length - 1];
  2332. mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia);
  2333. };
  2334. JoinSelectorVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) {
  2335. var context = this.contexts[this.contexts.length - 1];
  2336. if (atRuleNode.rules && atRuleNode.rules.length) {
  2337. atRuleNode.rules[0].root = (atRuleNode.isRooted || context.length === 0 || null);
  2338. }
  2339. };
  2340. return JoinSelectorVisitor;
  2341. }());
  2342. /* eslint-disable no-unused-vars */
  2343. var CSSVisitorUtils = /** @class */ (function () {
  2344. function CSSVisitorUtils(context) {
  2345. this._visitor = new Visitor(this);
  2346. this._context = context;
  2347. }
  2348. CSSVisitorUtils.prototype.containsSilentNonBlockedChild = function (bodyRules) {
  2349. var rule;
  2350. if (!bodyRules) {
  2351. return false;
  2352. }
  2353. for (var r = 0; r < bodyRules.length; r++) {
  2354. rule = bodyRules[r];
  2355. if (rule.isSilent && rule.isSilent(this._context) && !rule.blocksVisibility()) {
  2356. // the atrule contains something that was referenced (likely by extend)
  2357. // therefore it needs to be shown in output too
  2358. return true;
  2359. }
  2360. }
  2361. return false;
  2362. };
  2363. CSSVisitorUtils.prototype.keepOnlyVisibleChilds = function (owner) {
  2364. if (owner && owner.rules) {
  2365. owner.rules = owner.rules.filter(function (thing) { return thing.isVisible(); });
  2366. }
  2367. };
  2368. CSSVisitorUtils.prototype.isEmpty = function (owner) {
  2369. return (owner && owner.rules)
  2370. ? (owner.rules.length === 0) : true;
  2371. };
  2372. CSSVisitorUtils.prototype.hasVisibleSelector = function (rulesetNode) {
  2373. return (rulesetNode && rulesetNode.paths)
  2374. ? (rulesetNode.paths.length > 0) : false;
  2375. };
  2376. CSSVisitorUtils.prototype.resolveVisibility = function (node) {
  2377. if (!node.blocksVisibility()) {
  2378. if (this.isEmpty(node)) {
  2379. return;
  2380. }
  2381. return node;
  2382. }
  2383. var compiledRulesBody = node.rules[0];
  2384. this.keepOnlyVisibleChilds(compiledRulesBody);
  2385. if (this.isEmpty(compiledRulesBody)) {
  2386. return;
  2387. }
  2388. node.ensureVisibility();
  2389. node.removeVisibilityBlock();
  2390. return node;
  2391. };
  2392. CSSVisitorUtils.prototype.isVisibleRuleset = function (rulesetNode) {
  2393. if (rulesetNode.firstRoot) {
  2394. return true;
  2395. }
  2396. if (this.isEmpty(rulesetNode)) {
  2397. return false;
  2398. }
  2399. if (!rulesetNode.root && !this.hasVisibleSelector(rulesetNode)) {
  2400. return false;
  2401. }
  2402. return true;
  2403. };
  2404. return CSSVisitorUtils;
  2405. }());
  2406. var ToCSSVisitor = function (context) {
  2407. this._visitor = new Visitor(this);
  2408. this._context = context;
  2409. this.utils = new CSSVisitorUtils(context);
  2410. };
  2411. ToCSSVisitor.prototype = {
  2412. isReplacing: true,
  2413. run: function (root) {
  2414. return this._visitor.visit(root);
  2415. },
  2416. visitDeclaration: function (declNode, visitArgs) {
  2417. if (declNode.blocksVisibility() || declNode.variable) {
  2418. return;
  2419. }
  2420. return declNode;
  2421. },
  2422. visitMixinDefinition: function (mixinNode, visitArgs) {
  2423. // mixin definitions do not get eval'd - this means they keep state
  2424. // so we have to clear that state here so it isn't used if toCSS is called twice
  2425. mixinNode.frames = [];
  2426. },
  2427. visitExtend: function (extendNode, visitArgs) {
  2428. },
  2429. visitComment: function (commentNode, visitArgs) {
  2430. if (commentNode.blocksVisibility() || commentNode.isSilent(this._context)) {
  2431. return;
  2432. }
  2433. return commentNode;
  2434. },
  2435. visitMedia: function (mediaNode, visitArgs) {
  2436. var originalRules = mediaNode.rules[0].rules;
  2437. mediaNode.accept(this._visitor);
  2438. visitArgs.visitDeeper = false;
  2439. return this.utils.resolveVisibility(mediaNode, originalRules);
  2440. },
  2441. visitImport: function (importNode, visitArgs) {
  2442. if (importNode.blocksVisibility()) {
  2443. return;
  2444. }
  2445. return importNode;
  2446. },
  2447. visitAtRule: function (atRuleNode, visitArgs) {
  2448. if (atRuleNode.rules && atRuleNode.rules.length) {
  2449. return this.visitAtRuleWithBody(atRuleNode, visitArgs);
  2450. }
  2451. else {
  2452. return this.visitAtRuleWithoutBody(atRuleNode, visitArgs);
  2453. }
  2454. },
  2455. visitAnonymous: function (anonymousNode, visitArgs) {
  2456. if (!anonymousNode.blocksVisibility()) {
  2457. anonymousNode.accept(this._visitor);
  2458. return anonymousNode;
  2459. }
  2460. },
  2461. visitAtRuleWithBody: function (atRuleNode, visitArgs) {
  2462. // if there is only one nested ruleset and that one has no path, then it is
  2463. // just fake ruleset
  2464. function hasFakeRuleset(atRuleNode) {
  2465. var bodyRules = atRuleNode.rules;
  2466. return bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0);
  2467. }
  2468. function getBodyRules(atRuleNode) {
  2469. var nodeRules = atRuleNode.rules;
  2470. if (hasFakeRuleset(atRuleNode)) {
  2471. return nodeRules[0].rules;
  2472. }
  2473. return nodeRules;
  2474. }
  2475. // it is still true that it is only one ruleset in array
  2476. // this is last such moment
  2477. // process childs
  2478. var originalRules = getBodyRules(atRuleNode);
  2479. atRuleNode.accept(this._visitor);
  2480. visitArgs.visitDeeper = false;
  2481. if (!this.utils.isEmpty(atRuleNode)) {
  2482. this._mergeRules(atRuleNode.rules[0].rules);
  2483. }
  2484. return this.utils.resolveVisibility(atRuleNode, originalRules);
  2485. },
  2486. visitAtRuleWithoutBody: function (atRuleNode, visitArgs) {
  2487. if (atRuleNode.blocksVisibility()) {
  2488. return;
  2489. }
  2490. if (atRuleNode.name === '@charset') {
  2491. // Only output the debug info together with subsequent @charset definitions
  2492. // a comment (or @media statement) before the actual @charset atrule would
  2493. // be considered illegal css as it has to be on the first line
  2494. if (this.charset) {
  2495. if (atRuleNode.debugInfo) {
  2496. var comment = new tree.Comment("/* ".concat(atRuleNode.toCSS(this._context).replace(/\n/g, ''), " */\n"));
  2497. comment.debugInfo = atRuleNode.debugInfo;
  2498. return this._visitor.visit(comment);
  2499. }
  2500. return;
  2501. }
  2502. this.charset = true;
  2503. }
  2504. return atRuleNode;
  2505. },
  2506. checkValidNodes: function (rules, isRoot) {
  2507. if (!rules) {
  2508. return;
  2509. }
  2510. for (var i_1 = 0; i_1 < rules.length; i_1++) {
  2511. var ruleNode = rules[i_1];
  2512. if (isRoot && ruleNode instanceof tree.Declaration && !ruleNode.variable) {
  2513. throw { message: 'Properties must be inside selector blocks. They cannot be in the root',
  2514. index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename };
  2515. }
  2516. if (ruleNode instanceof tree.Call) {
  2517. throw { message: "Function '".concat(ruleNode.name, "' did not return a root node"),
  2518. index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename };
  2519. }
  2520. if (ruleNode.type && !ruleNode.allowRoot) {
  2521. throw { message: "".concat(ruleNode.type, " node returned by a function is not valid here"),
  2522. index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename };
  2523. }
  2524. }
  2525. },
  2526. visitRuleset: function (rulesetNode, visitArgs) {
  2527. // at this point rulesets are nested into each other
  2528. var rule;
  2529. var rulesets = [];
  2530. this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot);
  2531. if (!rulesetNode.root) {
  2532. // remove invisible paths
  2533. this._compileRulesetPaths(rulesetNode);
  2534. // remove rulesets from this ruleset body and compile them separately
  2535. var nodeRules = rulesetNode.rules;
  2536. var nodeRuleCnt = nodeRules ? nodeRules.length : 0;
  2537. for (var i_2 = 0; i_2 < nodeRuleCnt;) {
  2538. rule = nodeRules[i_2];
  2539. if (rule && rule.rules) {
  2540. // visit because we are moving them out from being a child
  2541. rulesets.push(this._visitor.visit(rule));
  2542. nodeRules.splice(i_2, 1);
  2543. nodeRuleCnt--;
  2544. continue;
  2545. }
  2546. i_2++;
  2547. }
  2548. // accept the visitor to remove rules and refactor itself
  2549. // then we can decide nogw whether we want it or not
  2550. // compile body
  2551. if (nodeRuleCnt > 0) {
  2552. rulesetNode.accept(this._visitor);
  2553. }
  2554. else {
  2555. rulesetNode.rules = null;
  2556. }
  2557. visitArgs.visitDeeper = false;
  2558. }
  2559. else { // if (! rulesetNode.root) {
  2560. rulesetNode.accept(this._visitor);
  2561. visitArgs.visitDeeper = false;
  2562. }
  2563. if (rulesetNode.rules) {
  2564. this._mergeRules(rulesetNode.rules);
  2565. this._removeDuplicateRules(rulesetNode.rules);
  2566. }
  2567. // now decide whether we keep the ruleset
  2568. if (this.utils.isVisibleRuleset(rulesetNode)) {
  2569. rulesetNode.ensureVisibility();
  2570. rulesets.splice(0, 0, rulesetNode);
  2571. }
  2572. if (rulesets.length === 1) {
  2573. return rulesets[0];
  2574. }
  2575. return rulesets;
  2576. },
  2577. _compileRulesetPaths: function (rulesetNode) {
  2578. if (rulesetNode.paths) {
  2579. rulesetNode.paths = rulesetNode.paths
  2580. .filter(function (p) {
  2581. var i;
  2582. if (p[0].elements[0].combinator.value === ' ') {
  2583. p[0].elements[0].combinator = new (tree.Combinator)('');
  2584. }
  2585. for (i = 0; i < p.length; i++) {
  2586. if (p[i].isVisible() && p[i].getIsOutput()) {
  2587. return true;
  2588. }
  2589. }
  2590. return false;
  2591. });
  2592. }
  2593. },
  2594. _removeDuplicateRules: function (rules) {
  2595. if (!rules) {
  2596. return;
  2597. }
  2598. // remove duplicates
  2599. var ruleCache = {};
  2600. var ruleList;
  2601. var rule;
  2602. var i;
  2603. for (i = rules.length - 1; i >= 0; i--) {
  2604. rule = rules[i];
  2605. if (rule instanceof tree.Declaration) {
  2606. if (!ruleCache[rule.name]) {
  2607. ruleCache[rule.name] = rule;
  2608. }
  2609. else {
  2610. ruleList = ruleCache[rule.name];
  2611. if (ruleList instanceof tree.Declaration) {
  2612. ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._context)];
  2613. }
  2614. var ruleCSS = rule.toCSS(this._context);
  2615. if (ruleList.indexOf(ruleCSS) !== -1) {
  2616. rules.splice(i, 1);
  2617. }
  2618. else {
  2619. ruleList.push(ruleCSS);
  2620. }
  2621. }
  2622. }
  2623. }
  2624. },
  2625. _mergeRules: function (rules) {
  2626. if (!rules) {
  2627. return;
  2628. }
  2629. var groups = {};
  2630. var groupsArr = [];
  2631. for (var i_3 = 0; i_3 < rules.length; i_3++) {
  2632. var rule = rules[i_3];
  2633. if (rule.merge) {
  2634. var key = rule.name;
  2635. groups[key] ? rules.splice(i_3--, 1) :
  2636. groupsArr.push(groups[key] = []);
  2637. groups[key].push(rule);
  2638. }
  2639. }
  2640. groupsArr.forEach(function (group) {
  2641. if (group.length > 0) {
  2642. var result_1 = group[0];
  2643. var space_1 = [];
  2644. var comma_1 = [new tree.Expression(space_1)];
  2645. group.forEach(function (rule) {
  2646. if ((rule.merge === '+') && (space_1.length > 0)) {
  2647. comma_1.push(new tree.Expression(space_1 = []));
  2648. }
  2649. space_1.push(rule.value);
  2650. result_1.important = result_1.important || rule.important;
  2651. });
  2652. result_1.value = new tree.Value(comma_1);
  2653. }
  2654. });
  2655. }
  2656. };
  2657. var visitors = {
  2658. Visitor: Visitor,
  2659. ImportVisitor: ImportVisitor,
  2660. MarkVisibleSelectorsVisitor: SetTreeVisibilityVisitor,
  2661. ExtendVisitor: ProcessExtendsVisitor,
  2662. JoinSelectorVisitor: JoinSelectorVisitor,
  2663. ToCSSVisitor: ToCSSVisitor
  2664. };
  2665. // Split the input into chunks.
  2666. function chunker (input, fail) {
  2667. var len = input.length;
  2668. var level = 0;
  2669. var parenLevel = 0;
  2670. var lastOpening;
  2671. var lastOpeningParen;
  2672. var lastMultiComment;
  2673. var lastMultiCommentEndBrace;
  2674. var chunks = [];
  2675. var emitFrom = 0;
  2676. var chunkerCurrentIndex;
  2677. var currentChunkStartIndex;
  2678. var cc;
  2679. var cc2;
  2680. var matched;
  2681. function emitChunk(force) {
  2682. var len = chunkerCurrentIndex - emitFrom;
  2683. if (((len < 512) && !force) || !len) {
  2684. return;
  2685. }
  2686. chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1));
  2687. emitFrom = chunkerCurrentIndex + 1;
  2688. }
  2689. for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
  2690. cc = input.charCodeAt(chunkerCurrentIndex);
  2691. if (((cc >= 97) && (cc <= 122)) || (cc < 34)) {
  2692. // a-z or whitespace
  2693. continue;
  2694. }
  2695. switch (cc) {
  2696. case 40: // (
  2697. parenLevel++;
  2698. lastOpeningParen = chunkerCurrentIndex;
  2699. continue;
  2700. case 41: // )
  2701. if (--parenLevel < 0) {
  2702. return fail('missing opening `(`', chunkerCurrentIndex);
  2703. }
  2704. continue;
  2705. case 59: // ;
  2706. if (!parenLevel) {
  2707. emitChunk();
  2708. }
  2709. continue;
  2710. case 123: // {
  2711. level++;
  2712. lastOpening = chunkerCurrentIndex;
  2713. continue;
  2714. case 125: // }
  2715. if (--level < 0) {
  2716. return fail('missing opening `{`', chunkerCurrentIndex);
  2717. }
  2718. if (!level && !parenLevel) {
  2719. emitChunk();
  2720. }
  2721. continue;
  2722. case 92: // \
  2723. if (chunkerCurrentIndex < len - 1) {
  2724. chunkerCurrentIndex++;
  2725. continue;
  2726. }
  2727. return fail('unescaped `\\`', chunkerCurrentIndex);
  2728. case 34:
  2729. case 39:
  2730. case 96: // ", ' and `
  2731. matched = 0;
  2732. currentChunkStartIndex = chunkerCurrentIndex;
  2733. for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
  2734. cc2 = input.charCodeAt(chunkerCurrentIndex);
  2735. if (cc2 > 96) {
  2736. continue;
  2737. }
  2738. if (cc2 == cc) {
  2739. matched = 1;
  2740. break;
  2741. }
  2742. if (cc2 == 92) { // \
  2743. if (chunkerCurrentIndex == len - 1) {
  2744. return fail('unescaped `\\`', chunkerCurrentIndex);
  2745. }
  2746. chunkerCurrentIndex++;
  2747. }
  2748. }
  2749. if (matched) {
  2750. continue;
  2751. }
  2752. return fail("unmatched `".concat(String.fromCharCode(cc), "`"), currentChunkStartIndex);
  2753. case 47: // /, check for comment
  2754. if (parenLevel || (chunkerCurrentIndex == len - 1)) {
  2755. continue;
  2756. }
  2757. cc2 = input.charCodeAt(chunkerCurrentIndex + 1);
  2758. if (cc2 == 47) {
  2759. // //, find lnfeed
  2760. for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
  2761. cc2 = input.charCodeAt(chunkerCurrentIndex);
  2762. if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) {
  2763. break;
  2764. }
  2765. }
  2766. }
  2767. else if (cc2 == 42) {
  2768. // /*, find */
  2769. lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex;
  2770. for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) {
  2771. cc2 = input.charCodeAt(chunkerCurrentIndex);
  2772. if (cc2 == 125) {
  2773. lastMultiCommentEndBrace = chunkerCurrentIndex;
  2774. }
  2775. if (cc2 != 42) {
  2776. continue;
  2777. }
  2778. if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) {
  2779. break;
  2780. }
  2781. }
  2782. if (chunkerCurrentIndex == len - 1) {
  2783. return fail('missing closing `*/`', currentChunkStartIndex);
  2784. }
  2785. chunkerCurrentIndex++;
  2786. }
  2787. continue;
  2788. case 42: // *, check for unmatched */
  2789. if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) {
  2790. return fail('unmatched `/*`', chunkerCurrentIndex);
  2791. }
  2792. continue;
  2793. }
  2794. }
  2795. if (level !== 0) {
  2796. if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) {
  2797. return fail('missing closing `}` or `*/`', lastOpening);
  2798. }
  2799. else {
  2800. return fail('missing closing `}`', lastOpening);
  2801. }
  2802. }
  2803. else if (parenLevel !== 0) {
  2804. return fail('missing closing `)`', lastOpeningParen);
  2805. }
  2806. emitChunk(true);
  2807. return chunks;
  2808. }
  2809. var getParserInput = (function () {
  2810. var // Less input string
  2811. input;
  2812. var // current chunk
  2813. j;
  2814. var // holds state for backtracking
  2815. saveStack = [];
  2816. var // furthest index the parser has gone to
  2817. furthest;
  2818. var // if this is furthest we got to, this is the probably cause
  2819. furthestPossibleErrorMessage;
  2820. var // chunkified input
  2821. chunks;
  2822. var // current chunk
  2823. current;
  2824. var // index of current chunk, in `input`
  2825. currentPos;
  2826. var parserInput = {};
  2827. var CHARCODE_SPACE = 32;
  2828. var CHARCODE_TAB = 9;
  2829. var CHARCODE_LF = 10;
  2830. var CHARCODE_CR = 13;
  2831. var CHARCODE_PLUS = 43;
  2832. var CHARCODE_COMMA = 44;
  2833. var CHARCODE_FORWARD_SLASH = 47;
  2834. var CHARCODE_9 = 57;
  2835. function skipWhitespace(length) {
  2836. var oldi = parserInput.i;
  2837. var oldj = j;
  2838. var curr = parserInput.i - currentPos;
  2839. var endIndex = parserInput.i + current.length - curr;
  2840. var mem = (parserInput.i += length);
  2841. var inp = input;
  2842. var c;
  2843. var nextChar;
  2844. var comment;
  2845. for (; parserInput.i < endIndex; parserInput.i++) {
  2846. c = inp.charCodeAt(parserInput.i);
  2847. if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) {
  2848. nextChar = inp.charAt(parserInput.i + 1);
  2849. if (nextChar === '/') {
  2850. comment = { index: parserInput.i, isLineComment: true };
  2851. var nextNewLine = inp.indexOf('\n', parserInput.i + 2);
  2852. if (nextNewLine < 0) {
  2853. nextNewLine = endIndex;
  2854. }
  2855. parserInput.i = nextNewLine;
  2856. comment.text = inp.substr(comment.index, parserInput.i - comment.index);
  2857. parserInput.commentStore.push(comment);
  2858. continue;
  2859. }
  2860. else if (nextChar === '*') {
  2861. var nextStarSlash = inp.indexOf('*/', parserInput.i + 2);
  2862. if (nextStarSlash >= 0) {
  2863. comment = {
  2864. index: parserInput.i,
  2865. text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i),
  2866. isLineComment: false
  2867. };
  2868. parserInput.i += comment.text.length - 1;
  2869. parserInput.commentStore.push(comment);
  2870. continue;
  2871. }
  2872. }
  2873. break;
  2874. }
  2875. if ((c !== CHARCODE_SPACE) && (c !== CHARCODE_LF) && (c !== CHARCODE_TAB) && (c !== CHARCODE_CR)) {
  2876. break;
  2877. }
  2878. }
  2879. current = current.slice(length + parserInput.i - mem + curr);
  2880. currentPos = parserInput.i;
  2881. if (!current.length) {
  2882. if (j < chunks.length - 1) {
  2883. current = chunks[++j];
  2884. skipWhitespace(0); // skip space at the beginning of a chunk
  2885. return true; // things changed
  2886. }
  2887. parserInput.finished = true;
  2888. }
  2889. return oldi !== parserInput.i || oldj !== j;
  2890. }
  2891. parserInput.save = function () {
  2892. currentPos = parserInput.i;
  2893. saveStack.push({ current: current, i: parserInput.i, j: j });
  2894. };
  2895. parserInput.restore = function (possibleErrorMessage) {
  2896. if (parserInput.i > furthest || (parserInput.i === furthest && possibleErrorMessage && !furthestPossibleErrorMessage)) {
  2897. furthest = parserInput.i;
  2898. furthestPossibleErrorMessage = possibleErrorMessage;
  2899. }
  2900. var state = saveStack.pop();
  2901. current = state.current;
  2902. currentPos = parserInput.i = state.i;
  2903. j = state.j;
  2904. };
  2905. parserInput.forget = function () {
  2906. saveStack.pop();
  2907. };
  2908. parserInput.isWhitespace = function (offset) {
  2909. var pos = parserInput.i + (offset || 0);
  2910. var code = input.charCodeAt(pos);
  2911. return (code === CHARCODE_SPACE || code === CHARCODE_CR || code === CHARCODE_TAB || code === CHARCODE_LF);
  2912. };
  2913. // Specialization of $(tok)
  2914. parserInput.$re = function (tok) {
  2915. if (parserInput.i > currentPos) {
  2916. current = current.slice(parserInput.i - currentPos);
  2917. currentPos = parserInput.i;
  2918. }
  2919. var m = tok.exec(current);
  2920. if (!m) {
  2921. return null;
  2922. }
  2923. skipWhitespace(m[0].length);
  2924. if (typeof m === 'string') {
  2925. return m;
  2926. }
  2927. return m.length === 1 ? m[0] : m;
  2928. };
  2929. parserInput.$char = function (tok) {
  2930. if (input.charAt(parserInput.i) !== tok) {
  2931. return null;
  2932. }
  2933. skipWhitespace(1);
  2934. return tok;
  2935. };
  2936. parserInput.$peekChar = function (tok) {
  2937. if (input.charAt(parserInput.i) !== tok) {
  2938. return null;
  2939. }
  2940. return tok;
  2941. };
  2942. parserInput.$str = function (tok) {
  2943. var tokLength = tok.length;
  2944. // https://jsperf.com/string-startswith/21
  2945. for (var i_1 = 0; i_1 < tokLength; i_1++) {
  2946. if (input.charAt(parserInput.i + i_1) !== tok.charAt(i_1)) {
  2947. return null;
  2948. }
  2949. }
  2950. skipWhitespace(tokLength);
  2951. return tok;
  2952. };
  2953. parserInput.$quoted = function (loc) {
  2954. var pos = loc || parserInput.i;
  2955. var startChar = input.charAt(pos);
  2956. if (startChar !== '\'' && startChar !== '"') {
  2957. return;
  2958. }
  2959. var length = input.length;
  2960. var currentPosition = pos;
  2961. for (var i_2 = 1; i_2 + currentPosition < length; i_2++) {
  2962. var nextChar = input.charAt(i_2 + currentPosition);
  2963. switch (nextChar) {
  2964. case '\\':
  2965. i_2++;
  2966. continue;
  2967. case '\r':
  2968. case '\n':
  2969. break;
  2970. case startChar: {
  2971. var str = input.substr(currentPosition, i_2 + 1);
  2972. if (!loc && loc !== 0) {
  2973. skipWhitespace(i_2 + 1);
  2974. return str;
  2975. }
  2976. return [startChar, str];
  2977. }
  2978. }
  2979. }
  2980. return null;
  2981. };
  2982. /**
  2983. * Permissive parsing. Ignores everything except matching {} [] () and quotes
  2984. * until matching token (outside of blocks)
  2985. */
  2986. parserInput.$parseUntil = function (tok) {
  2987. var quote = '';
  2988. var returnVal = null;
  2989. var inComment = false;
  2990. var blockDepth = 0;
  2991. var blockStack = [];
  2992. var parseGroups = [];
  2993. var length = input.length;
  2994. var startPos = parserInput.i;
  2995. var lastPos = parserInput.i;
  2996. var i = parserInput.i;
  2997. var loop = true;
  2998. var testChar;
  2999. if (typeof tok === 'string') {
  3000. testChar = function (char) { return char === tok; };
  3001. }
  3002. else {
  3003. testChar = function (char) { return tok.test(char); };
  3004. }
  3005. do {
  3006. var nextChar = input.charAt(i);
  3007. if (blockDepth === 0 && testChar(nextChar)) {
  3008. returnVal = input.substr(lastPos, i - lastPos);
  3009. if (returnVal) {
  3010. parseGroups.push(returnVal);
  3011. }
  3012. else {
  3013. parseGroups.push(' ');
  3014. }
  3015. returnVal = parseGroups;
  3016. skipWhitespace(i - startPos);
  3017. loop = false;
  3018. }
  3019. else {
  3020. if (inComment) {
  3021. if (nextChar === '*' &&
  3022. input.charAt(i + 1) === '/') {
  3023. i++;
  3024. blockDepth--;
  3025. inComment = false;
  3026. }
  3027. i++;
  3028. continue;
  3029. }
  3030. switch (nextChar) {
  3031. case '\\':
  3032. i++;
  3033. nextChar = input.charAt(i);
  3034. parseGroups.push(input.substr(lastPos, i - lastPos + 1));
  3035. lastPos = i + 1;
  3036. break;
  3037. case '/':
  3038. if (input.charAt(i + 1) === '*') {
  3039. i++;
  3040. inComment = true;
  3041. blockDepth++;
  3042. }
  3043. break;
  3044. case '\'':
  3045. case '"':
  3046. quote = parserInput.$quoted(i);
  3047. if (quote) {
  3048. parseGroups.push(input.substr(lastPos, i - lastPos), quote);
  3049. i += quote[1].length - 1;
  3050. lastPos = i + 1;
  3051. }
  3052. else {
  3053. skipWhitespace(i - startPos);
  3054. returnVal = nextChar;
  3055. loop = false;
  3056. }
  3057. break;
  3058. case '{':
  3059. blockStack.push('}');
  3060. blockDepth++;
  3061. break;
  3062. case '(':
  3063. blockStack.push(')');
  3064. blockDepth++;
  3065. break;
  3066. case '[':
  3067. blockStack.push(']');
  3068. blockDepth++;
  3069. break;
  3070. case '}':
  3071. case ')':
  3072. case ']': {
  3073. var expected = blockStack.pop();
  3074. if (nextChar === expected) {
  3075. blockDepth--;
  3076. }
  3077. else {
  3078. // move the parser to the error and return expected
  3079. skipWhitespace(i - startPos);
  3080. returnVal = expected;
  3081. loop = false;
  3082. }
  3083. }
  3084. }
  3085. i++;
  3086. if (i > length) {
  3087. loop = false;
  3088. }
  3089. }
  3090. } while (loop);
  3091. return returnVal ? returnVal : null;
  3092. };
  3093. parserInput.autoCommentAbsorb = true;
  3094. parserInput.commentStore = [];
  3095. parserInput.finished = false;
  3096. // Same as $(), but don't change the state of the parser,
  3097. // just return the match.
  3098. parserInput.peek = function (tok) {
  3099. if (typeof tok === 'string') {
  3100. // https://jsperf.com/string-startswith/21
  3101. for (var i_3 = 0; i_3 < tok.length; i_3++) {
  3102. if (input.charAt(parserInput.i + i_3) !== tok.charAt(i_3)) {
  3103. return false;
  3104. }
  3105. }
  3106. return true;
  3107. }
  3108. else {
  3109. return tok.test(current);
  3110. }
  3111. };
  3112. // Specialization of peek()
  3113. // TODO remove or change some currentChar calls to peekChar
  3114. parserInput.peekChar = function (tok) { return input.charAt(parserInput.i) === tok; };
  3115. parserInput.currentChar = function () { return input.charAt(parserInput.i); };
  3116. parserInput.prevChar = function () { return input.charAt(parserInput.i - 1); };
  3117. parserInput.getInput = function () { return input; };
  3118. parserInput.peekNotNumeric = function () {
  3119. var c = input.charCodeAt(parserInput.i);
  3120. // Is the first char of the dimension 0-9, '.', '+' or '-'
  3121. return (c > CHARCODE_9 || c < CHARCODE_PLUS) || c === CHARCODE_FORWARD_SLASH || c === CHARCODE_COMMA;
  3122. };
  3123. parserInput.start = function (str, chunkInput, failFunction) {
  3124. input = str;
  3125. parserInput.i = j = currentPos = furthest = 0;
  3126. // chunking apparently makes things quicker (but my tests indicate
  3127. // it might actually make things slower in node at least)
  3128. // and it is a non-perfect parse - it can't recognise
  3129. // unquoted urls, meaning it can't distinguish comments
  3130. // meaning comments with quotes or {}() in them get 'counted'
  3131. // and then lead to parse errors.
  3132. // In addition if the chunking chunks in the wrong place we might
  3133. // not be able to parse a parser statement in one go
  3134. // this is officially deprecated but can be switched on via an option
  3135. // in the case it causes too much performance issues.
  3136. if (chunkInput) {
  3137. chunks = chunker(str, failFunction);
  3138. }
  3139. else {
  3140. chunks = [str];
  3141. }
  3142. current = chunks[0];
  3143. skipWhitespace(0);
  3144. };
  3145. parserInput.end = function () {
  3146. var message;
  3147. var isFinished = parserInput.i >= input.length;
  3148. if (parserInput.i < furthest) {
  3149. message = furthestPossibleErrorMessage;
  3150. parserInput.i = furthest;
  3151. }
  3152. return {
  3153. isFinished: isFinished,
  3154. furthest: parserInput.i,
  3155. furthestPossibleErrorMessage: message,
  3156. furthestReachedEnd: parserInput.i >= input.length - 1,
  3157. furthestChar: input[parserInput.i]
  3158. };
  3159. };
  3160. return parserInput;
  3161. });
  3162. function makeRegistry(base) {
  3163. return {
  3164. _data: {},
  3165. add: function (name, func) {
  3166. // precautionary case conversion, as later querying of
  3167. // the registry by function-caller uses lower case as well.
  3168. name = name.toLowerCase();
  3169. // eslint-disable-next-line no-prototype-builtins
  3170. if (this._data.hasOwnProperty(name)) ;
  3171. this._data[name] = func;
  3172. },
  3173. addMultiple: function (functions) {
  3174. var _this = this;
  3175. Object.keys(functions).forEach(function (name) {
  3176. _this.add(name, functions[name]);
  3177. });
  3178. },
  3179. get: function (name) {
  3180. return this._data[name] || (base && base.get(name));
  3181. },
  3182. getLocalFunctions: function () {
  3183. return this._data;
  3184. },
  3185. inherit: function () {
  3186. return makeRegistry(this);
  3187. },
  3188. create: function (base) {
  3189. return makeRegistry(base);
  3190. }
  3191. };
  3192. }
  3193. var functionRegistry = makeRegistry(null);
  3194. var MediaSyntaxOptions = {
  3195. queryInParens: true
  3196. };
  3197. var ContainerSyntaxOptions = {
  3198. queryInParens: true
  3199. };
  3200. var Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) {
  3201. this.value = value;
  3202. this._index = index;
  3203. this._fileInfo = currentFileInfo;
  3204. this.mapLines = mapLines;
  3205. this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike;
  3206. this.allowRoot = true;
  3207. this.copyVisibilityInfo(visibilityInfo);
  3208. };
  3209. Anonymous.prototype = Object.assign(new Node(), {
  3210. type: 'Anonymous',
  3211. eval: function () {
  3212. return new Anonymous(this.value, this._index, this._fileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo());
  3213. },
  3214. compare: function (other) {
  3215. return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;
  3216. },
  3217. isRulesetLike: function () {
  3218. return this.rulesetLike;
  3219. },
  3220. genCSS: function (context, output) {
  3221. this.nodeVisible = Boolean(this.value);
  3222. if (this.nodeVisible) {
  3223. output.add(this.value, this._fileInfo, this._index, this.mapLines);
  3224. }
  3225. }
  3226. });
  3227. //
  3228. // less.js - parser
  3229. //
  3230. // A relatively straight-forward predictive parser.
  3231. // There is no tokenization/lexing stage, the input is parsed
  3232. // in one sweep.
  3233. //
  3234. // To make the parser fast enough to run in the browser, several
  3235. // optimization had to be made:
  3236. //
  3237. // - Matching and slicing on a huge input is often cause of slowdowns.
  3238. // The solution is to chunkify the input into smaller strings.
  3239. // The chunks are stored in the `chunks` var,
  3240. // `j` holds the current chunk index, and `currentPos` holds
  3241. // the index of the current chunk in relation to `input`.
  3242. // This gives us an almost 4x speed-up.
  3243. //
  3244. // - In many cases, we don't need to match individual tokens;
  3245. // for example, if a value doesn't hold any variables, operations
  3246. // or dynamic references, the parser can effectively 'skip' it,
  3247. // treating it as a literal.
  3248. // An example would be '1px solid #000' - which evaluates to itself,
  3249. // we don't need to know what the individual components are.
  3250. // The drawback, of course is that you don't get the benefits of
  3251. // syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
  3252. // and a smaller speed-up in the code-gen.
  3253. //
  3254. //
  3255. // Token matching is done with the `$` function, which either takes
  3256. // a terminal string or regexp, or a non-terminal function to call.
  3257. // It also takes care of moving all the indices forwards.
  3258. //
  3259. var Parser = function Parser(context, imports, fileInfo, currentIndex) {
  3260. currentIndex = currentIndex || 0;
  3261. var parsers;
  3262. var parserInput = getParserInput();
  3263. function error(msg, type) {
  3264. throw new LessError({
  3265. index: parserInput.i,
  3266. filename: fileInfo.filename,
  3267. type: type || 'Syntax',
  3268. message: msg
  3269. }, imports);
  3270. }
  3271. function expect(arg, msg) {
  3272. // some older browsers return typeof 'function' for RegExp
  3273. var result = (arg instanceof Function) ? arg.call(parsers) : parserInput.$re(arg);
  3274. if (result) {
  3275. return result;
  3276. }
  3277. error(msg || (typeof arg === 'string'
  3278. ? "expected '".concat(arg, "' got '").concat(parserInput.currentChar(), "'")
  3279. : 'unexpected token'));
  3280. }
  3281. // Specialization of expect()
  3282. function expectChar(arg, msg) {
  3283. if (parserInput.$char(arg)) {
  3284. return arg;
  3285. }
  3286. error(msg || "expected '".concat(arg, "' got '").concat(parserInput.currentChar(), "'"));
  3287. }
  3288. function getDebugInfo(index) {
  3289. var filename = fileInfo.filename;
  3290. return {
  3291. lineNumber: getLocation(index, parserInput.getInput()).line + 1,
  3292. fileName: filename
  3293. };
  3294. }
  3295. /**
  3296. * Used after initial parsing to create nodes on the fly
  3297. *
  3298. * @param {String} str - string to parse
  3299. * @param {Array} parseList - array of parsers to run input through e.g. ["value", "important"]
  3300. * @param {Number} currentIndex - start number to begin indexing
  3301. * @param {Object} fileInfo - fileInfo to attach to created nodes
  3302. */
  3303. function parseNode(str, parseList, callback) {
  3304. var result;
  3305. var returnNodes = [];
  3306. var parser = parserInput;
  3307. try {
  3308. parser.start(str, false, function fail(msg, index) {
  3309. callback({
  3310. message: msg,
  3311. index: index + currentIndex
  3312. });
  3313. });
  3314. for (var x = 0, p = void 0; (p = parseList[x]); x++) {
  3315. result = parsers[p]();
  3316. returnNodes.push(result || null);
  3317. }
  3318. var endInfo = parser.end();
  3319. if (endInfo.isFinished) {
  3320. callback(null, returnNodes);
  3321. }
  3322. else {
  3323. callback(true, null);
  3324. }
  3325. }
  3326. catch (e) {
  3327. throw new LessError({
  3328. index: e.index + currentIndex,
  3329. message: e.message
  3330. }, imports, fileInfo.filename);
  3331. }
  3332. }
  3333. //
  3334. // The Parser
  3335. //
  3336. return {
  3337. parserInput: parserInput,
  3338. imports: imports,
  3339. fileInfo: fileInfo,
  3340. parseNode: parseNode,
  3341. //
  3342. // Parse an input string into an abstract syntax tree,
  3343. // @param str A string containing 'less' markup
  3344. // @param callback call `callback` when done.
  3345. // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply
  3346. //
  3347. parse: function (str, callback, additionalData) {
  3348. var root;
  3349. var err = null;
  3350. var globalVars;
  3351. var modifyVars;
  3352. var ignored;
  3353. var preText = '';
  3354. // Optionally disable @plugin parsing
  3355. if (additionalData && additionalData.disablePluginRule) {
  3356. parsers.plugin = function () {
  3357. var dir = parserInput.$re(/^@plugin?\s+/);
  3358. if (dir) {
  3359. error('@plugin statements are not allowed when disablePluginRule is set to true');
  3360. }
  3361. };
  3362. }
  3363. globalVars = (additionalData && additionalData.globalVars) ? "".concat(Parser.serializeVars(additionalData.globalVars), "\n") : '';
  3364. modifyVars = (additionalData && additionalData.modifyVars) ? "\n".concat(Parser.serializeVars(additionalData.modifyVars)) : '';
  3365. if (context.pluginManager) {
  3366. var preProcessors = context.pluginManager.getPreProcessors();
  3367. for (var i_1 = 0; i_1 < preProcessors.length; i_1++) {
  3368. str = preProcessors[i_1].process(str, { context: context, imports: imports, fileInfo: fileInfo });
  3369. }
  3370. }
  3371. if (globalVars || (additionalData && additionalData.banner)) {
  3372. preText = ((additionalData && additionalData.banner) ? additionalData.banner : '') + globalVars;
  3373. ignored = imports.contentsIgnoredChars;
  3374. ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0;
  3375. ignored[fileInfo.filename] += preText.length;
  3376. }
  3377. str = str.replace(/\r\n?/g, '\n');
  3378. // Remove potential UTF Byte Order Mark
  3379. str = preText + str.replace(/^\uFEFF/, '') + modifyVars;
  3380. imports.contents[fileInfo.filename] = str;
  3381. // Start with the primary rule.
  3382. // The whole syntax tree is held under a Ruleset node,
  3383. // with the `root` property set to true, so no `{}` are
  3384. // output. The callback is called when the input is parsed.
  3385. try {
  3386. parserInput.start(str, context.chunkInput, function fail(msg, index) {
  3387. throw new LessError({
  3388. index: index,
  3389. type: 'Parse',
  3390. message: msg,
  3391. filename: fileInfo.filename
  3392. }, imports);
  3393. });
  3394. tree.Node.prototype.parse = this;
  3395. root = new tree.Ruleset(null, this.parsers.primary());
  3396. tree.Node.prototype.rootNode = root;
  3397. root.root = true;
  3398. root.firstRoot = true;
  3399. root.functionRegistry = functionRegistry.inherit();
  3400. }
  3401. catch (e) {
  3402. return callback(new LessError(e, imports, fileInfo.filename));
  3403. }
  3404. // If `i` is smaller than the `input.length - 1`,
  3405. // it means the parser wasn't able to parse the whole
  3406. // string, so we've got a parsing error.
  3407. //
  3408. // We try to extract a \n delimited string,
  3409. // showing the line where the parse error occurred.
  3410. // We split it up into two parts (the part which parsed,
  3411. // and the part which didn't), so we can color them differently.
  3412. var endInfo = parserInput.end();
  3413. if (!endInfo.isFinished) {
  3414. var message = endInfo.furthestPossibleErrorMessage;
  3415. if (!message) {
  3416. message = 'Unrecognised input';
  3417. if (endInfo.furthestChar === '}') {
  3418. message += '. Possibly missing opening \'{\'';
  3419. }
  3420. else if (endInfo.furthestChar === ')') {
  3421. message += '. Possibly missing opening \'(\'';
  3422. }
  3423. else if (endInfo.furthestReachedEnd) {
  3424. message += '. Possibly missing something';
  3425. }
  3426. }
  3427. err = new LessError({
  3428. type: 'Parse',
  3429. message: message,
  3430. index: endInfo.furthest,
  3431. filename: fileInfo.filename
  3432. }, imports);
  3433. }
  3434. var finish = function (e) {
  3435. e = err || e || imports.error;
  3436. if (e) {
  3437. if (!(e instanceof LessError)) {
  3438. e = new LessError(e, imports, fileInfo.filename);
  3439. }
  3440. return callback(e);
  3441. }
  3442. else {
  3443. return callback(null, root);
  3444. }
  3445. };
  3446. if (context.processImports !== false) {
  3447. new visitors.ImportVisitor(imports, finish)
  3448. .run(root);
  3449. }
  3450. else {
  3451. return finish();
  3452. }
  3453. },
  3454. //
  3455. // Here in, the parsing rules/functions
  3456. //
  3457. // The basic structure of the syntax tree generated is as follows:
  3458. //
  3459. // Ruleset -> Declaration -> Value -> Expression -> Entity
  3460. //
  3461. // Here's some Less code:
  3462. //
  3463. // .class {
  3464. // color: #fff;
  3465. // border: 1px solid #000;
  3466. // width: @w + 4px;
  3467. // > .child {...}
  3468. // }
  3469. //
  3470. // And here's what the parse tree might look like:
  3471. //
  3472. // Ruleset (Selector '.class', [
  3473. // Declaration ("color", Value ([Expression [Color #fff]]))
  3474. // Declaration ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
  3475. // Declaration ("width", Value ([Expression [Operation " + " [Variable "@w"][Dimension 4px]]]))
  3476. // Ruleset (Selector [Element '>', '.child'], [...])
  3477. // ])
  3478. //
  3479. // In general, most rules will try to parse a token with the `$re()` function, and if the return
  3480. // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
  3481. // first, before parsing, that's when we use `peek()`.
  3482. //
  3483. parsers: parsers = {
  3484. //
  3485. // The `primary` rule is the *entry* and *exit* point of the parser.
  3486. // The rules here can appear at any level of the parse tree.
  3487. //
  3488. // The recursive nature of the grammar is an interplay between the `block`
  3489. // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
  3490. // as represented by this simplified grammar:
  3491. //
  3492. // primary → (ruleset | declaration)+
  3493. // ruleset → selector+ block
  3494. // block → '{' primary '}'
  3495. //
  3496. // Only at one point is the primary rule not called from the
  3497. // block rule: at the root level.
  3498. //
  3499. primary: function () {
  3500. var mixin = this.mixin;
  3501. var root = [];
  3502. var node;
  3503. while (true) {
  3504. while (true) {
  3505. node = this.comment();
  3506. if (!node) {
  3507. break;
  3508. }
  3509. root.push(node);
  3510. }
  3511. // always process comments before deciding if finished
  3512. if (parserInput.finished) {
  3513. break;
  3514. }
  3515. if (parserInput.peek('}')) {
  3516. break;
  3517. }
  3518. node = this.extendRule();
  3519. if (node) {
  3520. root = root.concat(node);
  3521. continue;
  3522. }
  3523. node = mixin.definition() || this.declaration() || mixin.call(false, false) ||
  3524. this.ruleset() || this.variableCall() || this.entities.call() || this.atrule();
  3525. if (node) {
  3526. root.push(node);
  3527. }
  3528. else {
  3529. var foundSemiColon = false;
  3530. while (parserInput.$char(';')) {
  3531. foundSemiColon = true;
  3532. }
  3533. if (!foundSemiColon) {
  3534. break;
  3535. }
  3536. }
  3537. }
  3538. return root;
  3539. },
  3540. // comments are collected by the main parsing mechanism and then assigned to nodes
  3541. // where the current structure allows it
  3542. comment: function () {
  3543. if (parserInput.commentStore.length) {
  3544. var comment = parserInput.commentStore.shift();
  3545. return new (tree.Comment)(comment.text, comment.isLineComment, comment.index + currentIndex, fileInfo);
  3546. }
  3547. },
  3548. //
  3549. // Entities are tokens which can be found inside an Expression
  3550. //
  3551. entities: {
  3552. mixinLookup: function () {
  3553. return parsers.mixin.call(true, true);
  3554. },
  3555. //
  3556. // A string, which supports escaping " and '
  3557. //
  3558. // "milky way" 'he\'s the one!'
  3559. //
  3560. quoted: function (forceEscaped) {
  3561. var str;
  3562. var index = parserInput.i;
  3563. var isEscaped = false;
  3564. parserInput.save();
  3565. if (parserInput.$char('~')) {
  3566. isEscaped = true;
  3567. }
  3568. else if (forceEscaped) {
  3569. parserInput.restore();
  3570. return;
  3571. }
  3572. str = parserInput.$quoted();
  3573. if (!str) {
  3574. parserInput.restore();
  3575. return;
  3576. }
  3577. parserInput.forget();
  3578. return new (tree.Quoted)(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index + currentIndex, fileInfo);
  3579. },
  3580. //
  3581. // A catch-all word, such as:
  3582. //
  3583. // black border-collapse
  3584. //
  3585. keyword: function () {
  3586. var k = parserInput.$char('%') || parserInput.$re(/^\[?(?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+\]?/);
  3587. if (k) {
  3588. return tree.Color.fromKeyword(k) || new (tree.Keyword)(k);
  3589. }
  3590. },
  3591. //
  3592. // A function call
  3593. //
  3594. // rgb(255, 0, 255)
  3595. //
  3596. // The arguments are parsed with the `entities.arguments` parser.
  3597. //
  3598. call: function () {
  3599. var name;
  3600. var args;
  3601. var func;
  3602. var index = parserInput.i;
  3603. // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18
  3604. if (parserInput.peek(/^url\(/i)) {
  3605. return;
  3606. }
  3607. parserInput.save();
  3608. name = parserInput.$re(/^([\w-]+|%|~|progid:[\w.]+)\(/);
  3609. if (!name) {
  3610. parserInput.forget();
  3611. return;
  3612. }
  3613. name = name[1];
  3614. func = this.customFuncCall(name);
  3615. if (func) {
  3616. args = func.parse();
  3617. if (args && func.stop) {
  3618. parserInput.forget();
  3619. return args;
  3620. }
  3621. }
  3622. args = this.arguments(args);
  3623. if (!parserInput.$char(')')) {
  3624. parserInput.restore('Could not parse call arguments or missing \')\'');
  3625. return;
  3626. }
  3627. parserInput.forget();
  3628. return new (tree.Call)(name, args, index + currentIndex, fileInfo);
  3629. },
  3630. declarationCall: function () {
  3631. var validCall;
  3632. var args;
  3633. var index = parserInput.i;
  3634. parserInput.save();
  3635. validCall = parserInput.$re(/^[\w]+\(/);
  3636. if (!validCall) {
  3637. parserInput.forget();
  3638. return;
  3639. }
  3640. validCall = validCall.substring(0, validCall.length - 1);
  3641. var rule = this.ruleProperty();
  3642. var value;
  3643. if (rule) {
  3644. value = this.value();
  3645. }
  3646. if (rule && value) {
  3647. args = [new (tree.Declaration)(rule, value, null, null, parserInput.i + currentIndex, fileInfo, true)];
  3648. }
  3649. if (!parserInput.$char(')')) {
  3650. parserInput.restore('Could not parse call arguments or missing \')\'');
  3651. return;
  3652. }
  3653. parserInput.forget();
  3654. return new (tree.Call)(validCall, args, index + currentIndex, fileInfo);
  3655. },
  3656. //
  3657. // Parsing rules for functions with non-standard args, e.g.:
  3658. //
  3659. // boolean(not(2 > 1))
  3660. //
  3661. // This is a quick prototype, to be modified/improved when
  3662. // more custom-parsed funcs come (e.g. `selector(...)`)
  3663. //
  3664. customFuncCall: function (name) {
  3665. /* Ideally the table is to be moved out of here for faster perf.,
  3666. but it's quite tricky since it relies on all these `parsers`
  3667. and `expect` available only here */
  3668. return {
  3669. alpha: f(parsers.ieAlpha, true),
  3670. boolean: f(condition),
  3671. 'if': f(condition)
  3672. }[name.toLowerCase()];
  3673. function f(parse, stop) {
  3674. return {
  3675. parse: parse,
  3676. stop: stop // when true - stop after parse() and return its result,
  3677. // otherwise continue for plain args
  3678. };
  3679. }
  3680. function condition() {
  3681. return [expect(parsers.condition, 'expected condition')];
  3682. }
  3683. },
  3684. arguments: function (prevArgs) {
  3685. var argsComma = prevArgs || [];
  3686. var argsSemiColon = [];
  3687. var isSemiColonSeparated;
  3688. var value;
  3689. parserInput.save();
  3690. while (true) {
  3691. if (prevArgs) {
  3692. prevArgs = false;
  3693. }
  3694. else {
  3695. value = parsers.detachedRuleset() || this.assignment() || parsers.expression();
  3696. if (!value) {
  3697. break;
  3698. }
  3699. if (value.value && value.value.length == 1) {
  3700. value = value.value[0];
  3701. }
  3702. argsComma.push(value);
  3703. }
  3704. if (parserInput.$char(',')) {
  3705. continue;
  3706. }
  3707. if (parserInput.$char(';') || isSemiColonSeparated) {
  3708. isSemiColonSeparated = true;
  3709. value = (argsComma.length < 1) ? argsComma[0]
  3710. : new tree.Value(argsComma);
  3711. argsSemiColon.push(value);
  3712. argsComma = [];
  3713. }
  3714. }
  3715. parserInput.forget();
  3716. return isSemiColonSeparated ? argsSemiColon : argsComma;
  3717. },
  3718. literal: function () {
  3719. return this.dimension() ||
  3720. this.color() ||
  3721. this.quoted() ||
  3722. this.unicodeDescriptor();
  3723. },
  3724. // Assignments are argument entities for calls.
  3725. // They are present in ie filter properties as shown below.
  3726. //
  3727. // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
  3728. //
  3729. assignment: function () {
  3730. var key;
  3731. var value;
  3732. parserInput.save();
  3733. key = parserInput.$re(/^\w+(?=\s?=)/i);
  3734. if (!key) {
  3735. parserInput.restore();
  3736. return;
  3737. }
  3738. if (!parserInput.$char('=')) {
  3739. parserInput.restore();
  3740. return;
  3741. }
  3742. value = parsers.entity();
  3743. if (value) {
  3744. parserInput.forget();
  3745. return new (tree.Assignment)(key, value);
  3746. }
  3747. else {
  3748. parserInput.restore();
  3749. }
  3750. },
  3751. //
  3752. // Parse url() tokens
  3753. //
  3754. // We use a specific rule for urls, because they don't really behave like
  3755. // standard function calls. The difference is that the argument doesn't have
  3756. // to be enclosed within a string, so it can't be parsed as an Expression.
  3757. //
  3758. url: function () {
  3759. var value;
  3760. var index = parserInput.i;
  3761. parserInput.autoCommentAbsorb = false;
  3762. if (!parserInput.$str('url(')) {
  3763. parserInput.autoCommentAbsorb = true;
  3764. return;
  3765. }
  3766. value = this.quoted() || this.variable() || this.property() ||
  3767. parserInput.$re(/^(?:(?:\\[()'"])|[^()'"])+/) || '';
  3768. parserInput.autoCommentAbsorb = true;
  3769. expectChar(')');
  3770. return new (tree.URL)((value.value !== undefined ||
  3771. value instanceof tree.Variable ||
  3772. value instanceof tree.Property) ?
  3773. value : new (tree.Anonymous)(value, index), index + currentIndex, fileInfo);
  3774. },
  3775. //
  3776. // A Variable entity, such as `@fink`, in
  3777. //
  3778. // width: @fink + 2px
  3779. //
  3780. // We use a different parser for variable definitions,
  3781. // see `parsers.variable`.
  3782. //
  3783. variable: function () {
  3784. var ch;
  3785. var name;
  3786. var index = parserInput.i;
  3787. parserInput.save();
  3788. if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^@@?[\w-]+/))) {
  3789. ch = parserInput.currentChar();
  3790. if (ch === '(' || ch === '[' && !parserInput.prevChar().match(/^\s/)) {
  3791. // this may be a VariableCall lookup
  3792. var result = parsers.variableCall(name);
  3793. if (result) {
  3794. parserInput.forget();
  3795. return result;
  3796. }
  3797. }
  3798. parserInput.forget();
  3799. return new (tree.Variable)(name, index + currentIndex, fileInfo);
  3800. }
  3801. parserInput.restore();
  3802. },
  3803. // A variable entity using the protective {} e.g. @{var}
  3804. variableCurly: function () {
  3805. var curly;
  3806. var index = parserInput.i;
  3807. if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\{([\w-]+)\}/))) {
  3808. return new (tree.Variable)("@".concat(curly[1]), index + currentIndex, fileInfo);
  3809. }
  3810. },
  3811. //
  3812. // A Property accessor, such as `$color`, in
  3813. //
  3814. // background-color: $color
  3815. //
  3816. property: function () {
  3817. var name;
  3818. var index = parserInput.i;
  3819. if (parserInput.currentChar() === '$' && (name = parserInput.$re(/^\$[\w-]+/))) {
  3820. return new (tree.Property)(name, index + currentIndex, fileInfo);
  3821. }
  3822. },
  3823. // A property entity useing the protective {} e.g. ${prop}
  3824. propertyCurly: function () {
  3825. var curly;
  3826. var index = parserInput.i;
  3827. if (parserInput.currentChar() === '$' && (curly = parserInput.$re(/^\$\{([\w-]+)\}/))) {
  3828. return new (tree.Property)("$".concat(curly[1]), index + currentIndex, fileInfo);
  3829. }
  3830. },
  3831. //
  3832. // A Hexadecimal color
  3833. //
  3834. // #4F3C2F
  3835. //
  3836. // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
  3837. //
  3838. color: function () {
  3839. var rgb;
  3840. parserInput.save();
  3841. if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\w.#[])?/))) {
  3842. if (!rgb[2]) {
  3843. parserInput.forget();
  3844. return new (tree.Color)(rgb[1], undefined, rgb[0]);
  3845. }
  3846. }
  3847. parserInput.restore();
  3848. },
  3849. colorKeyword: function () {
  3850. parserInput.save();
  3851. var autoCommentAbsorb = parserInput.autoCommentAbsorb;
  3852. parserInput.autoCommentAbsorb = false;
  3853. var k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/);
  3854. parserInput.autoCommentAbsorb = autoCommentAbsorb;
  3855. if (!k) {
  3856. parserInput.forget();
  3857. return;
  3858. }
  3859. parserInput.restore();
  3860. var color = tree.Color.fromKeyword(k);
  3861. if (color) {
  3862. parserInput.$str(k);
  3863. return color;
  3864. }
  3865. },
  3866. //
  3867. // A Dimension, that is, a number and a unit
  3868. //
  3869. // 0.5em 95%
  3870. //
  3871. dimension: function () {
  3872. if (parserInput.peekNotNumeric()) {
  3873. return;
  3874. }
  3875. var value = parserInput.$re(/^([+-]?\d*\.?\d+)(%|[a-z_]+)?/i);
  3876. if (value) {
  3877. return new (tree.Dimension)(value[1], value[2]);
  3878. }
  3879. },
  3880. //
  3881. // A unicode descriptor, as is used in unicode-range
  3882. //
  3883. // U+0?? or U+00A1-00A9
  3884. //
  3885. unicodeDescriptor: function () {
  3886. var ud;
  3887. ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(-[0-9a-fA-F?]+)?/);
  3888. if (ud) {
  3889. return new (tree.UnicodeDescriptor)(ud[0]);
  3890. }
  3891. },
  3892. //
  3893. // JavaScript code to be evaluated
  3894. //
  3895. // `window.location.href`
  3896. //
  3897. javascript: function () {
  3898. var js;
  3899. var index = parserInput.i;
  3900. parserInput.save();
  3901. var escape = parserInput.$char('~');
  3902. var jsQuote = parserInput.$char('`');
  3903. if (!jsQuote) {
  3904. parserInput.restore();
  3905. return;
  3906. }
  3907. js = parserInput.$re(/^[^`]*`/);
  3908. if (js) {
  3909. parserInput.forget();
  3910. return new (tree.JavaScript)(js.substr(0, js.length - 1), Boolean(escape), index + currentIndex, fileInfo);
  3911. }
  3912. parserInput.restore('invalid javascript definition');
  3913. }
  3914. },
  3915. //
  3916. // The variable part of a variable definition. Used in the `rule` parser
  3917. //
  3918. // @fink:
  3919. //
  3920. variable: function () {
  3921. var name;
  3922. if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\s*:/))) {
  3923. return name[1];
  3924. }
  3925. },
  3926. //
  3927. // Call a variable value to retrieve a detached ruleset
  3928. // or a value from a detached ruleset's rules.
  3929. //
  3930. // @fink();
  3931. // @fink;
  3932. // color: @fink[@color];
  3933. //
  3934. variableCall: function (parsedName) {
  3935. var lookups;
  3936. var i = parserInput.i;
  3937. var inValue = !!parsedName;
  3938. var name = parsedName;
  3939. parserInput.save();
  3940. if (name || (parserInput.currentChar() === '@'
  3941. && (name = parserInput.$re(/^(@[\w-]+)(\(\s*\))?/)))) {
  3942. lookups = this.mixin.ruleLookups();
  3943. if (!lookups && ((inValue && parserInput.$str('()') !== '()') || (name[2] !== '()'))) {
  3944. parserInput.restore('Missing \'[...]\' lookup in variable call');
  3945. return;
  3946. }
  3947. if (!inValue) {
  3948. name = name[1];
  3949. }
  3950. var call = new tree.VariableCall(name, i, fileInfo);
  3951. if (!inValue && parsers.end()) {
  3952. parserInput.forget();
  3953. return call;
  3954. }
  3955. else {
  3956. parserInput.forget();
  3957. return new tree.NamespaceValue(call, lookups, i, fileInfo);
  3958. }
  3959. }
  3960. parserInput.restore();
  3961. },
  3962. //
  3963. // extend syntax - used to extend selectors
  3964. //
  3965. extend: function (isRule) {
  3966. var elements;
  3967. var e;
  3968. var index = parserInput.i;
  3969. var option;
  3970. var extendList;
  3971. var extend;
  3972. if (!parserInput.$str(isRule ? '&:extend(' : ':extend(')) {
  3973. return;
  3974. }
  3975. do {
  3976. option = null;
  3977. elements = null;
  3978. while (!(option = parserInput.$re(/^(all)(?=\s*(\)|,))/))) {
  3979. e = this.element();
  3980. if (!e) {
  3981. break;
  3982. }
  3983. if (elements) {
  3984. elements.push(e);
  3985. }
  3986. else {
  3987. elements = [e];
  3988. }
  3989. }
  3990. option = option && option[1];
  3991. if (!elements) {
  3992. error('Missing target selector for :extend().');
  3993. }
  3994. extend = new (tree.Extend)(new (tree.Selector)(elements), option, index + currentIndex, fileInfo);
  3995. if (extendList) {
  3996. extendList.push(extend);
  3997. }
  3998. else {
  3999. extendList = [extend];
  4000. }
  4001. } while (parserInput.$char(','));
  4002. expect(/^\)/);
  4003. if (isRule) {
  4004. expect(/^;/);
  4005. }
  4006. return extendList;
  4007. },
  4008. //
  4009. // extendRule - used in a rule to extend all the parent selectors
  4010. //
  4011. extendRule: function () {
  4012. return this.extend(true);
  4013. },
  4014. //
  4015. // Mixins
  4016. //
  4017. mixin: {
  4018. //
  4019. // A Mixin call, with an optional argument list
  4020. //
  4021. // #mixins > .square(#fff);
  4022. // #mixins.square(#fff);
  4023. // .rounded(4px, black);
  4024. // .button;
  4025. //
  4026. // We can lookup / return a value using the lookup syntax:
  4027. //
  4028. // color: #mixin.square(#fff)[@color];
  4029. //
  4030. // The `while` loop is there because mixins can be
  4031. // namespaced, but we only support the child and descendant
  4032. // selector for now.
  4033. //
  4034. call: function (inValue, getLookup) {
  4035. var s = parserInput.currentChar();
  4036. var important = false;
  4037. var lookups;
  4038. var index = parserInput.i;
  4039. var elements;
  4040. var args;
  4041. var hasParens;
  4042. if (s !== '.' && s !== '#') {
  4043. return;
  4044. }
  4045. parserInput.save(); // stop us absorbing part of an invalid selector
  4046. elements = this.elements();
  4047. if (elements) {
  4048. if (parserInput.$char('(')) {
  4049. args = this.args(true).args;
  4050. expectChar(')');
  4051. hasParens = true;
  4052. }
  4053. if (getLookup !== false) {
  4054. lookups = this.ruleLookups();
  4055. }
  4056. if (getLookup === true && !lookups) {
  4057. parserInput.restore();
  4058. return;
  4059. }
  4060. if (inValue && !lookups && !hasParens) {
  4061. // This isn't a valid in-value mixin call
  4062. parserInput.restore();
  4063. return;
  4064. }
  4065. if (!inValue && parsers.important()) {
  4066. important = true;
  4067. }
  4068. if (inValue || parsers.end()) {
  4069. parserInput.forget();
  4070. var mixin = new (tree.mixin.Call)(elements, args, index + currentIndex, fileInfo, !lookups && important);
  4071. if (lookups) {
  4072. return new tree.NamespaceValue(mixin, lookups);
  4073. }
  4074. else {
  4075. return mixin;
  4076. }
  4077. }
  4078. }
  4079. parserInput.restore();
  4080. },
  4081. /**
  4082. * Matching elements for mixins
  4083. * (Start with . or # and can have > )
  4084. */
  4085. elements: function () {
  4086. var elements;
  4087. var e;
  4088. var c;
  4089. var elem;
  4090. var elemIndex;
  4091. var re = /^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/;
  4092. while (true) {
  4093. elemIndex = parserInput.i;
  4094. e = parserInput.$re(re);
  4095. if (!e) {
  4096. break;
  4097. }
  4098. elem = new (tree.Element)(c, e, false, elemIndex + currentIndex, fileInfo);
  4099. if (elements) {
  4100. elements.push(elem);
  4101. }
  4102. else {
  4103. elements = [elem];
  4104. }
  4105. c = parserInput.$char('>');
  4106. }
  4107. return elements;
  4108. },
  4109. args: function (isCall) {
  4110. var entities = parsers.entities;
  4111. var returner = { args: null, variadic: false };
  4112. var expressions = [];
  4113. var argsSemiColon = [];
  4114. var argsComma = [];
  4115. var isSemiColonSeparated;
  4116. var expressionContainsNamed;
  4117. var name;
  4118. var nameLoop;
  4119. var value;
  4120. var arg;
  4121. var expand;
  4122. var hasSep = true;
  4123. parserInput.save();
  4124. while (true) {
  4125. if (isCall) {
  4126. arg = parsers.detachedRuleset() || parsers.expression();
  4127. }
  4128. else {
  4129. parserInput.commentStore.length = 0;
  4130. if (parserInput.$str('...')) {
  4131. returner.variadic = true;
  4132. if (parserInput.$char(';') && !isSemiColonSeparated) {
  4133. isSemiColonSeparated = true;
  4134. }
  4135. (isSemiColonSeparated ? argsSemiColon : argsComma)
  4136. .push({ variadic: true });
  4137. break;
  4138. }
  4139. arg = entities.variable() || entities.property() || entities.literal() || entities.keyword() || this.call(true);
  4140. }
  4141. if (!arg || !hasSep) {
  4142. break;
  4143. }
  4144. nameLoop = null;
  4145. if (arg.throwAwayComments) {
  4146. arg.throwAwayComments();
  4147. }
  4148. value = arg;
  4149. var val = null;
  4150. if (isCall) {
  4151. // Variable
  4152. if (arg.value && arg.value.length == 1) {
  4153. val = arg.value[0];
  4154. }
  4155. }
  4156. else {
  4157. val = arg;
  4158. }
  4159. if (val && (val instanceof tree.Variable || val instanceof tree.Property)) {
  4160. if (parserInput.$char(':')) {
  4161. if (expressions.length > 0) {
  4162. if (isSemiColonSeparated) {
  4163. error('Cannot mix ; and , as delimiter types');
  4164. }
  4165. expressionContainsNamed = true;
  4166. }
  4167. value = parsers.detachedRuleset() || parsers.expression();
  4168. if (!value) {
  4169. if (isCall) {
  4170. error('could not understand value for named argument');
  4171. }
  4172. else {
  4173. parserInput.restore();
  4174. returner.args = [];
  4175. return returner;
  4176. }
  4177. }
  4178. nameLoop = (name = val.name);
  4179. }
  4180. else if (parserInput.$str('...')) {
  4181. if (!isCall) {
  4182. returner.variadic = true;
  4183. if (parserInput.$char(';') && !isSemiColonSeparated) {
  4184. isSemiColonSeparated = true;
  4185. }
  4186. (isSemiColonSeparated ? argsSemiColon : argsComma)
  4187. .push({ name: arg.name, variadic: true });
  4188. break;
  4189. }
  4190. else {
  4191. expand = true;
  4192. }
  4193. }
  4194. else if (!isCall) {
  4195. name = nameLoop = val.name;
  4196. value = null;
  4197. }
  4198. }
  4199. if (value) {
  4200. expressions.push(value);
  4201. }
  4202. argsComma.push({ name: nameLoop, value: value, expand: expand });
  4203. if (parserInput.$char(',')) {
  4204. hasSep = true;
  4205. continue;
  4206. }
  4207. hasSep = parserInput.$char(';') === ';';
  4208. if (hasSep || isSemiColonSeparated) {
  4209. if (expressionContainsNamed) {
  4210. error('Cannot mix ; and , as delimiter types');
  4211. }
  4212. isSemiColonSeparated = true;
  4213. if (expressions.length > 1) {
  4214. value = new (tree.Value)(expressions);
  4215. }
  4216. argsSemiColon.push({ name: name, value: value, expand: expand });
  4217. name = null;
  4218. expressions = [];
  4219. expressionContainsNamed = false;
  4220. }
  4221. }
  4222. parserInput.forget();
  4223. returner.args = isSemiColonSeparated ? argsSemiColon : argsComma;
  4224. return returner;
  4225. },
  4226. //
  4227. // A Mixin definition, with a list of parameters
  4228. //
  4229. // .rounded (@radius: 2px, @color) {
  4230. // ...
  4231. // }
  4232. //
  4233. // Until we have a finer grained state-machine, we have to
  4234. // do a look-ahead, to make sure we don't have a mixin call.
  4235. // See the `rule` function for more information.
  4236. //
  4237. // We start by matching `.rounded (`, and then proceed on to
  4238. // the argument list, which has optional default values.
  4239. // We store the parameters in `params`, with a `value` key,
  4240. // if there is a value, such as in the case of `@radius`.
  4241. //
  4242. // Once we've got our params list, and a closing `)`, we parse
  4243. // the `{...}` block.
  4244. //
  4245. definition: function () {
  4246. var name;
  4247. var params = [];
  4248. var match;
  4249. var ruleset;
  4250. var cond;
  4251. var variadic = false;
  4252. if ((parserInput.currentChar() !== '.' && parserInput.currentChar() !== '#') ||
  4253. parserInput.peek(/^[^{]*\}/)) {
  4254. return;
  4255. }
  4256. parserInput.save();
  4257. match = parserInput.$re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/);
  4258. if (match) {
  4259. name = match[1];
  4260. var argInfo = this.args(false);
  4261. params = argInfo.args;
  4262. variadic = argInfo.variadic;
  4263. // .mixincall("@{a}");
  4264. // looks a bit like a mixin definition..
  4265. // also
  4266. // .mixincall(@a: {rule: set;});
  4267. // so we have to be nice and restore
  4268. if (!parserInput.$char(')')) {
  4269. parserInput.restore('Missing closing \')\'');
  4270. return;
  4271. }
  4272. parserInput.commentStore.length = 0;
  4273. if (parserInput.$str('when')) { // Guard
  4274. cond = expect(parsers.conditions, 'expected condition');
  4275. }
  4276. ruleset = parsers.block();
  4277. if (ruleset) {
  4278. parserInput.forget();
  4279. return new (tree.mixin.Definition)(name, params, ruleset, cond, variadic);
  4280. }
  4281. else {
  4282. parserInput.restore();
  4283. }
  4284. }
  4285. else {
  4286. parserInput.restore();
  4287. }
  4288. },
  4289. ruleLookups: function () {
  4290. var rule;
  4291. var lookups = [];
  4292. if (parserInput.currentChar() !== '[') {
  4293. return;
  4294. }
  4295. while (true) {
  4296. parserInput.save();
  4297. rule = this.lookupValue();
  4298. if (!rule && rule !== '') {
  4299. parserInput.restore();
  4300. break;
  4301. }
  4302. lookups.push(rule);
  4303. parserInput.forget();
  4304. }
  4305. if (lookups.length > 0) {
  4306. return lookups;
  4307. }
  4308. },
  4309. lookupValue: function () {
  4310. parserInput.save();
  4311. if (!parserInput.$char('[')) {
  4312. parserInput.restore();
  4313. return;
  4314. }
  4315. var name = parserInput.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/);
  4316. if (!parserInput.$char(']')) {
  4317. parserInput.restore();
  4318. return;
  4319. }
  4320. if (name || name === '') {
  4321. parserInput.forget();
  4322. return name;
  4323. }
  4324. parserInput.restore();
  4325. }
  4326. },
  4327. //
  4328. // Entities are the smallest recognized token,
  4329. // and can be found inside a rule's value.
  4330. //
  4331. entity: function () {
  4332. var entities = this.entities;
  4333. return this.comment() || entities.literal() || entities.variable() || entities.url() ||
  4334. entities.property() || entities.call() || entities.keyword() || this.mixin.call(true) ||
  4335. entities.javascript();
  4336. },
  4337. //
  4338. // A Declaration terminator. Note that we use `peek()` to check for '}',
  4339. // because the `block` rule will be expecting it, but we still need to make sure
  4340. // it's there, if ';' was omitted.
  4341. //
  4342. end: function () {
  4343. return parserInput.$char(';') || parserInput.peek('}');
  4344. },
  4345. //
  4346. // IE's alpha function
  4347. //
  4348. // alpha(opacity=88)
  4349. //
  4350. ieAlpha: function () {
  4351. var value;
  4352. // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18
  4353. if (!parserInput.$re(/^opacity=/i)) {
  4354. return;
  4355. }
  4356. value = parserInput.$re(/^\d+/);
  4357. if (!value) {
  4358. value = expect(parsers.entities.variable, 'Could not parse alpha');
  4359. value = "@{".concat(value.name.slice(1), "}");
  4360. }
  4361. expectChar(')');
  4362. return new tree.Quoted('', "alpha(opacity=".concat(value, ")"));
  4363. },
  4364. //
  4365. // A Selector Element
  4366. //
  4367. // div
  4368. // + h1
  4369. // #socks
  4370. // input[type="text"]
  4371. //
  4372. // Elements are the building blocks for Selectors,
  4373. // they are made out of a `Combinator` (see combinator rule),
  4374. // and an element name, such as a tag a class, or `*`.
  4375. //
  4376. element: function () {
  4377. var e;
  4378. var c;
  4379. var v;
  4380. var index = parserInput.i;
  4381. c = this.combinator();
  4382. e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) ||
  4383. // eslint-disable-next-line no-control-regex
  4384. parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
  4385. parserInput.$char('*') || parserInput.$char('&') || this.attribute() ||
  4386. parserInput.$re(/^\([^&()@]+\)/) || parserInput.$re(/^[.#:](?=@)/) ||
  4387. this.entities.variableCurly();
  4388. if (!e) {
  4389. parserInput.save();
  4390. if (parserInput.$char('(')) {
  4391. if ((v = this.selector(false))) {
  4392. var selectors = [];
  4393. while (parserInput.$char(',')) {
  4394. selectors.push(v);
  4395. selectors.push(new Anonymous(','));
  4396. v = this.selector(false);
  4397. }
  4398. selectors.push(v);
  4399. if (parserInput.$char(')')) {
  4400. if (selectors.length > 1) {
  4401. e = new (tree.Paren)(new Selector(selectors));
  4402. }
  4403. else {
  4404. e = new (tree.Paren)(v);
  4405. }
  4406. parserInput.forget();
  4407. }
  4408. else {
  4409. parserInput.restore('Missing closing \')\'');
  4410. }
  4411. }
  4412. else {
  4413. parserInput.restore('Missing closing \')\'');
  4414. }
  4415. }
  4416. else {
  4417. parserInput.forget();
  4418. }
  4419. }
  4420. if (e) {
  4421. return new (tree.Element)(c, e, e instanceof tree.Variable, index + currentIndex, fileInfo);
  4422. }
  4423. },
  4424. //
  4425. // Combinators combine elements together, in a Selector.
  4426. //
  4427. // Because our parser isn't white-space sensitive, special care
  4428. // has to be taken, when parsing the descendant combinator, ` `,
  4429. // as it's an empty space. We have to check the previous character
  4430. // in the input, to see if it's a ` ` character. More info on how
  4431. // we deal with this in *combinator.js*.
  4432. //
  4433. combinator: function () {
  4434. var c = parserInput.currentChar();
  4435. if (c === '/') {
  4436. parserInput.save();
  4437. var slashedCombinator = parserInput.$re(/^\/[a-z]+\//i);
  4438. if (slashedCombinator) {
  4439. parserInput.forget();
  4440. return new (tree.Combinator)(slashedCombinator);
  4441. }
  4442. parserInput.restore();
  4443. }
  4444. if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') {
  4445. parserInput.i++;
  4446. if (c === '^' && parserInput.currentChar() === '^') {
  4447. c = '^^';
  4448. parserInput.i++;
  4449. }
  4450. while (parserInput.isWhitespace()) {
  4451. parserInput.i++;
  4452. }
  4453. return new (tree.Combinator)(c);
  4454. }
  4455. else if (parserInput.isWhitespace(-1)) {
  4456. return new (tree.Combinator)(' ');
  4457. }
  4458. else {
  4459. return new (tree.Combinator)(null);
  4460. }
  4461. },
  4462. //
  4463. // A CSS Selector
  4464. // with less extensions e.g. the ability to extend and guard
  4465. //
  4466. // .class > div + h1
  4467. // li a:hover
  4468. //
  4469. // Selectors are made out of one or more Elements, see above.
  4470. //
  4471. selector: function (isLess) {
  4472. var index = parserInput.i;
  4473. var elements;
  4474. var extendList;
  4475. var c;
  4476. var e;
  4477. var allExtends;
  4478. var when;
  4479. var condition;
  4480. isLess = isLess !== false;
  4481. while ((isLess && (extendList = this.extend())) || (isLess && (when = parserInput.$str('when'))) || (e = this.element())) {
  4482. if (when) {
  4483. condition = expect(this.conditions, 'expected condition');
  4484. }
  4485. else if (condition) {
  4486. error('CSS guard can only be used at the end of selector');
  4487. }
  4488. else if (extendList) {
  4489. if (allExtends) {
  4490. allExtends = allExtends.concat(extendList);
  4491. }
  4492. else {
  4493. allExtends = extendList;
  4494. }
  4495. }
  4496. else {
  4497. if (allExtends) {
  4498. error('Extend can only be used at the end of selector');
  4499. }
  4500. c = parserInput.currentChar();
  4501. if (Array.isArray(e)) {
  4502. e.forEach(function (ele) { return elements.push(ele); });
  4503. }
  4504. if (elements) {
  4505. elements.push(e);
  4506. }
  4507. else {
  4508. elements = [e];
  4509. }
  4510. e = null;
  4511. }
  4512. if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') {
  4513. break;
  4514. }
  4515. }
  4516. if (elements) {
  4517. return new (tree.Selector)(elements, allExtends, condition, index + currentIndex, fileInfo);
  4518. }
  4519. if (allExtends) {
  4520. error('Extend must be used to extend a selector, it cannot be used on its own');
  4521. }
  4522. },
  4523. selectors: function () {
  4524. var s;
  4525. var selectors;
  4526. while (true) {
  4527. s = this.selector();
  4528. if (!s) {
  4529. break;
  4530. }
  4531. if (selectors) {
  4532. selectors.push(s);
  4533. }
  4534. else {
  4535. selectors = [s];
  4536. }
  4537. parserInput.commentStore.length = 0;
  4538. if (s.condition && selectors.length > 1) {
  4539. error('Guards are only currently allowed on a single selector.');
  4540. }
  4541. if (!parserInput.$char(',')) {
  4542. break;
  4543. }
  4544. if (s.condition) {
  4545. error('Guards are only currently allowed on a single selector.');
  4546. }
  4547. parserInput.commentStore.length = 0;
  4548. }
  4549. return selectors;
  4550. },
  4551. attribute: function () {
  4552. if (!parserInput.$char('[')) {
  4553. return;
  4554. }
  4555. var entities = this.entities;
  4556. var key;
  4557. var val;
  4558. var op;
  4559. //
  4560. // case-insensitive flag
  4561. // e.g. [attr operator value i]
  4562. //
  4563. var cif;
  4564. if (!(key = entities.variableCurly())) {
  4565. key = expect(/^(?:[_A-Za-z0-9-*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/);
  4566. }
  4567. op = parserInput.$re(/^[|~*$^]?=/);
  4568. if (op) {
  4569. val = entities.quoted() || parserInput.$re(/^[0-9]+%/) || parserInput.$re(/^[\w-]+/) || entities.variableCurly();
  4570. if (val) {
  4571. cif = parserInput.$re(/^[iIsS]/);
  4572. }
  4573. }
  4574. expectChar(']');
  4575. return new (tree.Attribute)(key, op, val, cif);
  4576. },
  4577. //
  4578. // The `block` rule is used by `ruleset` and `mixin.definition`.
  4579. // It's a wrapper around the `primary` rule, with added `{}`.
  4580. //
  4581. block: function () {
  4582. var content;
  4583. if (parserInput.$char('{') && (content = this.primary()) && parserInput.$char('}')) {
  4584. return content;
  4585. }
  4586. },
  4587. blockRuleset: function () {
  4588. var block = this.block();
  4589. if (block) {
  4590. block = new tree.Ruleset(null, block);
  4591. }
  4592. return block;
  4593. },
  4594. detachedRuleset: function () {
  4595. var argInfo;
  4596. var params;
  4597. var variadic;
  4598. parserInput.save();
  4599. if (parserInput.$re(/^[.#]\(/)) {
  4600. /**
  4601. * DR args currently only implemented for each() function, and not
  4602. * yet settable as `@dr: #(@arg) {}`
  4603. * This should be done when DRs are merged with mixins.
  4604. * See: https://github.com/less/less-meta/issues/16
  4605. */
  4606. argInfo = this.mixin.args(false);
  4607. params = argInfo.args;
  4608. variadic = argInfo.variadic;
  4609. if (!parserInput.$char(')')) {
  4610. parserInput.restore();
  4611. return;
  4612. }
  4613. }
  4614. var blockRuleset = this.blockRuleset();
  4615. if (blockRuleset) {
  4616. parserInput.forget();
  4617. if (params) {
  4618. return new tree.mixin.Definition(null, params, blockRuleset, null, variadic);
  4619. }
  4620. return new tree.DetachedRuleset(blockRuleset);
  4621. }
  4622. parserInput.restore();
  4623. },
  4624. //
  4625. // div, .class, body > p {...}
  4626. //
  4627. ruleset: function () {
  4628. var selectors;
  4629. var rules;
  4630. var debugInfo;
  4631. parserInput.save();
  4632. if (context.dumpLineNumbers) {
  4633. debugInfo = getDebugInfo(parserInput.i);
  4634. }
  4635. selectors = this.selectors();
  4636. if (selectors && (rules = this.block())) {
  4637. parserInput.forget();
  4638. var ruleset = new (tree.Ruleset)(selectors, rules, context.strictImports);
  4639. if (context.dumpLineNumbers) {
  4640. ruleset.debugInfo = debugInfo;
  4641. }
  4642. return ruleset;
  4643. }
  4644. else {
  4645. parserInput.restore();
  4646. }
  4647. },
  4648. declaration: function () {
  4649. var name;
  4650. var value;
  4651. var index = parserInput.i;
  4652. var hasDR;
  4653. var c = parserInput.currentChar();
  4654. var important;
  4655. var merge;
  4656. var isVariable;
  4657. if (c === '.' || c === '#' || c === '&' || c === ':') {
  4658. return;
  4659. }
  4660. parserInput.save();
  4661. name = this.variable() || this.ruleProperty();
  4662. if (name) {
  4663. isVariable = typeof name === 'string';
  4664. if (isVariable) {
  4665. value = this.detachedRuleset();
  4666. if (value) {
  4667. hasDR = true;
  4668. }
  4669. }
  4670. parserInput.commentStore.length = 0;
  4671. if (!value) {
  4672. // a name returned by this.ruleProperty() is always an array of the form:
  4673. // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"]
  4674. // where each item is a tree.Keyword or tree.Variable
  4675. merge = !isVariable && name.length > 1 && name.pop().value;
  4676. // Custom property values get permissive parsing
  4677. if (name[0].value && name[0].value.slice(0, 2) === '--') {
  4678. if (parserInput.$char(';')) {
  4679. value = new Anonymous('');
  4680. }
  4681. else {
  4682. value = this.permissiveValue(/[;}]/);
  4683. }
  4684. }
  4685. // Try to store values as anonymous
  4686. // If we need the value later we'll re-parse it in ruleset.parseValue
  4687. else {
  4688. value = this.anonymousValue();
  4689. }
  4690. if (value) {
  4691. parserInput.forget();
  4692. // anonymous values absorb the end ';' which is required for them to work
  4693. return new (tree.Declaration)(name, value, false, merge, index + currentIndex, fileInfo);
  4694. }
  4695. if (!value) {
  4696. value = this.value();
  4697. }
  4698. if (value) {
  4699. important = this.important();
  4700. }
  4701. else if (isVariable) {
  4702. // As a last resort, try permissiveValue
  4703. value = this.permissiveValue();
  4704. }
  4705. }
  4706. if (value && (this.end() || hasDR)) {
  4707. parserInput.forget();
  4708. return new (tree.Declaration)(name, value, important, merge, index + currentIndex, fileInfo);
  4709. }
  4710. else {
  4711. parserInput.restore();
  4712. }
  4713. }
  4714. else {
  4715. parserInput.restore();
  4716. }
  4717. },
  4718. anonymousValue: function () {
  4719. var index = parserInput.i;
  4720. var match = parserInput.$re(/^([^.#@$+/'"*`(;{}-]*);/);
  4721. if (match) {
  4722. return new (tree.Anonymous)(match[1], index + currentIndex);
  4723. }
  4724. },
  4725. /**
  4726. * Used for custom properties, at-rules, and variables (as fallback)
  4727. * Parses almost anything inside of {} [] () "" blocks
  4728. * until it reaches outer-most tokens.
  4729. *
  4730. * First, it will try to parse comments and entities to reach
  4731. * the end. This is mostly like the Expression parser except no
  4732. * math is allowed.
  4733. */
  4734. permissiveValue: function (untilTokens) {
  4735. var i;
  4736. var e;
  4737. var done;
  4738. var value;
  4739. var tok = untilTokens || ';';
  4740. var index = parserInput.i;
  4741. var result = [];
  4742. function testCurrentChar() {
  4743. var char = parserInput.currentChar();
  4744. if (typeof tok === 'string') {
  4745. return char === tok;
  4746. }
  4747. else {
  4748. return tok.test(char);
  4749. }
  4750. }
  4751. if (testCurrentChar()) {
  4752. return;
  4753. }
  4754. value = [];
  4755. do {
  4756. e = this.comment();
  4757. if (e) {
  4758. value.push(e);
  4759. continue;
  4760. }
  4761. e = this.entity();
  4762. if (e) {
  4763. value.push(e);
  4764. }
  4765. if (parserInput.peek(',')) {
  4766. value.push(new (tree.Anonymous)(',', parserInput.i));
  4767. parserInput.$char(',');
  4768. }
  4769. } while (e);
  4770. done = testCurrentChar();
  4771. if (value.length > 0) {
  4772. value = new (tree.Expression)(value);
  4773. if (done) {
  4774. return value;
  4775. }
  4776. else {
  4777. result.push(value);
  4778. }
  4779. // Preserve space before $parseUntil as it will not
  4780. if (parserInput.prevChar() === ' ') {
  4781. result.push(new tree.Anonymous(' ', index));
  4782. }
  4783. }
  4784. parserInput.save();
  4785. value = parserInput.$parseUntil(tok);
  4786. if (value) {
  4787. if (typeof value === 'string') {
  4788. error("Expected '".concat(value, "'"), 'Parse');
  4789. }
  4790. if (value.length === 1 && value[0] === ' ') {
  4791. parserInput.forget();
  4792. return new tree.Anonymous('', index);
  4793. }
  4794. var item = void 0;
  4795. for (i = 0; i < value.length; i++) {
  4796. item = value[i];
  4797. if (Array.isArray(item)) {
  4798. // Treat actual quotes as normal quoted values
  4799. result.push(new tree.Quoted(item[0], item[1], true, index, fileInfo));
  4800. }
  4801. else {
  4802. if (i === value.length - 1) {
  4803. item = item.trim();
  4804. }
  4805. // Treat like quoted values, but replace vars like unquoted expressions
  4806. var quote = new tree.Quoted('\'', item, true, index, fileInfo);
  4807. if (!item.startsWith('@{')) {
  4808. quote.variableRegex = /@([\w-]+)/g;
  4809. }
  4810. quote.propRegex = /\$([\w-]+)/g;
  4811. result.push(quote);
  4812. }
  4813. }
  4814. parserInput.forget();
  4815. return new tree.Expression(result, true);
  4816. }
  4817. parserInput.restore();
  4818. },
  4819. //
  4820. // An @import atrule
  4821. //
  4822. // @import "lib";
  4823. //
  4824. // Depending on our environment, importing is done differently:
  4825. // In the browser, it's an XHR request, in Node, it would be a
  4826. // file-system operation. The function used for importing is
  4827. // stored in `import`, which we pass to the Import constructor.
  4828. //
  4829. 'import': function () {
  4830. var path;
  4831. var features;
  4832. var index = parserInput.i;
  4833. var dir = parserInput.$re(/^@import\s+/);
  4834. if (dir) {
  4835. var options = (dir ? this.importOptions() : null) || {};
  4836. if ((path = this.entities.quoted() || this.entities.url())) {
  4837. features = this.mediaFeatures({});
  4838. if (!parserInput.$char(';')) {
  4839. parserInput.i = index;
  4840. error('missing semi-colon or unrecognised media features on import');
  4841. }
  4842. features = features && new (tree.Value)(features);
  4843. return new (tree.Import)(path, features, options, index + currentIndex, fileInfo);
  4844. }
  4845. else {
  4846. parserInput.i = index;
  4847. error('malformed import statement');
  4848. }
  4849. }
  4850. },
  4851. importOptions: function () {
  4852. var o;
  4853. var options = {};
  4854. var optionName;
  4855. var value;
  4856. // list of options, surrounded by parens
  4857. if (!parserInput.$char('(')) {
  4858. return null;
  4859. }
  4860. do {
  4861. o = this.importOption();
  4862. if (o) {
  4863. optionName = o;
  4864. value = true;
  4865. switch (optionName) {
  4866. case 'css':
  4867. optionName = 'less';
  4868. value = false;
  4869. break;
  4870. case 'once':
  4871. optionName = 'multiple';
  4872. value = false;
  4873. break;
  4874. }
  4875. options[optionName] = value;
  4876. if (!parserInput.$char(',')) {
  4877. break;
  4878. }
  4879. }
  4880. } while (o);
  4881. expectChar(')');
  4882. return options;
  4883. },
  4884. importOption: function () {
  4885. var opt = parserInput.$re(/^(less|css|multiple|once|inline|reference|optional)/);
  4886. if (opt) {
  4887. return opt[1];
  4888. }
  4889. },
  4890. mediaFeature: function (syntaxOptions) {
  4891. var entities = this.entities;
  4892. var nodes = [];
  4893. var e;
  4894. var p;
  4895. var rangeP;
  4896. parserInput.save();
  4897. do {
  4898. e = entities.declarationCall.bind(this)() || entities.keyword() || entities.variable() || entities.mixinLookup();
  4899. if (e) {
  4900. nodes.push(e);
  4901. }
  4902. else if (parserInput.$char('(')) {
  4903. p = this.property();
  4904. parserInput.save();
  4905. if (!p && syntaxOptions.queryInParens && parserInput.$re(/^[0-9a-z-]*\s*([<>]=|<=|>=|[<>]|=)/)) {
  4906. parserInput.restore();
  4907. p = this.condition();
  4908. parserInput.save();
  4909. rangeP = this.atomicCondition(null, p.rvalue);
  4910. if (!rangeP) {
  4911. parserInput.restore();
  4912. }
  4913. }
  4914. else {
  4915. parserInput.restore();
  4916. e = this.value();
  4917. }
  4918. if (parserInput.$char(')')) {
  4919. if (p && !e) {
  4920. nodes.push(new (tree.Paren)(new (tree.QueryInParens)(p.op, p.lvalue, p.rvalue, rangeP ? rangeP.op : null, rangeP ? rangeP.rvalue : null, p._index)));
  4921. e = p;
  4922. }
  4923. else if (p && e) {
  4924. nodes.push(new (tree.Paren)(new (tree.Declaration)(p, e, null, null, parserInput.i + currentIndex, fileInfo, true)));
  4925. }
  4926. else if (e) {
  4927. nodes.push(new (tree.Paren)(e));
  4928. }
  4929. else {
  4930. error('badly formed media feature definition');
  4931. }
  4932. }
  4933. else {
  4934. error('Missing closing \')\'', 'Parse');
  4935. }
  4936. }
  4937. } while (e);
  4938. parserInput.forget();
  4939. if (nodes.length > 0) {
  4940. return new (tree.Expression)(nodes);
  4941. }
  4942. },
  4943. mediaFeatures: function (syntaxOptions) {
  4944. var entities = this.entities;
  4945. var features = [];
  4946. var e;
  4947. do {
  4948. e = this.mediaFeature(syntaxOptions);
  4949. if (e) {
  4950. features.push(e);
  4951. if (!parserInput.$char(',')) {
  4952. break;
  4953. }
  4954. }
  4955. else {
  4956. e = entities.variable() || entities.mixinLookup();
  4957. if (e) {
  4958. features.push(e);
  4959. if (!parserInput.$char(',')) {
  4960. break;
  4961. }
  4962. }
  4963. }
  4964. } while (e);
  4965. return features.length > 0 ? features : null;
  4966. },
  4967. prepareAndGetNestableAtRule: function (treeType, index, debugInfo, syntaxOptions) {
  4968. var features = this.mediaFeatures(syntaxOptions);
  4969. var rules = this.block();
  4970. if (!rules) {
  4971. error('media definitions require block statements after any features');
  4972. }
  4973. parserInput.forget();
  4974. var atRule = new (treeType)(rules, features, index + currentIndex, fileInfo);
  4975. if (context.dumpLineNumbers) {
  4976. atRule.debugInfo = debugInfo;
  4977. }
  4978. return atRule;
  4979. },
  4980. nestableAtRule: function () {
  4981. var debugInfo;
  4982. var index = parserInput.i;
  4983. if (context.dumpLineNumbers) {
  4984. debugInfo = getDebugInfo(index);
  4985. }
  4986. parserInput.save();
  4987. if (parserInput.$peekChar('@')) {
  4988. if (parserInput.$str('@media')) {
  4989. return this.prepareAndGetNestableAtRule(tree.Media, index, debugInfo, MediaSyntaxOptions);
  4990. }
  4991. if (parserInput.$str('@container')) {
  4992. return this.prepareAndGetNestableAtRule(tree.Container, index, debugInfo, ContainerSyntaxOptions);
  4993. }
  4994. }
  4995. parserInput.restore();
  4996. },
  4997. //
  4998. // A @plugin directive, used to import plugins dynamically.
  4999. //
  5000. // @plugin (args) "lib";
  5001. //
  5002. plugin: function () {
  5003. var path;
  5004. var args;
  5005. var options;
  5006. var index = parserInput.i;
  5007. var dir = parserInput.$re(/^@plugin\s+/);
  5008. if (dir) {
  5009. args = this.pluginArgs();
  5010. if (args) {
  5011. options = {
  5012. pluginArgs: args,
  5013. isPlugin: true
  5014. };
  5015. }
  5016. else {
  5017. options = { isPlugin: true };
  5018. }
  5019. if ((path = this.entities.quoted() || this.entities.url())) {
  5020. if (!parserInput.$char(';')) {
  5021. parserInput.i = index;
  5022. error('missing semi-colon on @plugin');
  5023. }
  5024. return new (tree.Import)(path, null, options, index + currentIndex, fileInfo);
  5025. }
  5026. else {
  5027. parserInput.i = index;
  5028. error('malformed @plugin statement');
  5029. }
  5030. }
  5031. },
  5032. pluginArgs: function () {
  5033. // list of options, surrounded by parens
  5034. parserInput.save();
  5035. if (!parserInput.$char('(')) {
  5036. parserInput.restore();
  5037. return null;
  5038. }
  5039. var args = parserInput.$re(/^\s*([^);]+)\)\s*/);
  5040. if (args[1]) {
  5041. parserInput.forget();
  5042. return args[1].trim();
  5043. }
  5044. else {
  5045. parserInput.restore();
  5046. return null;
  5047. }
  5048. },
  5049. //
  5050. // A CSS AtRule
  5051. //
  5052. // @charset "utf-8";
  5053. //
  5054. atrule: function () {
  5055. var index = parserInput.i;
  5056. var name;
  5057. var value;
  5058. var rules;
  5059. var nonVendorSpecificName;
  5060. var hasIdentifier;
  5061. var hasExpression;
  5062. var hasUnknown;
  5063. var hasBlock = true;
  5064. var isRooted = true;
  5065. if (parserInput.currentChar() !== '@') {
  5066. return;
  5067. }
  5068. value = this['import']() || this.plugin() || this.nestableAtRule();
  5069. if (value) {
  5070. return value;
  5071. }
  5072. parserInput.save();
  5073. name = parserInput.$re(/^@[a-z-]+/);
  5074. if (!name) {
  5075. return;
  5076. }
  5077. nonVendorSpecificName = name;
  5078. if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {
  5079. nonVendorSpecificName = "@".concat(name.slice(name.indexOf('-', 2) + 1));
  5080. }
  5081. switch (nonVendorSpecificName) {
  5082. case '@charset':
  5083. hasIdentifier = true;
  5084. hasBlock = false;
  5085. break;
  5086. case '@namespace':
  5087. hasExpression = true;
  5088. hasBlock = false;
  5089. break;
  5090. case '@keyframes':
  5091. case '@counter-style':
  5092. hasIdentifier = true;
  5093. break;
  5094. case '@document':
  5095. case '@supports':
  5096. hasUnknown = true;
  5097. isRooted = false;
  5098. break;
  5099. default:
  5100. hasUnknown = true;
  5101. break;
  5102. }
  5103. parserInput.commentStore.length = 0;
  5104. if (hasIdentifier) {
  5105. value = this.entity();
  5106. if (!value) {
  5107. error("expected ".concat(name, " identifier"));
  5108. }
  5109. }
  5110. else if (hasExpression) {
  5111. value = this.expression();
  5112. if (!value) {
  5113. error("expected ".concat(name, " expression"));
  5114. }
  5115. }
  5116. else if (hasUnknown) {
  5117. value = this.permissiveValue(/^[{;]/);
  5118. hasBlock = (parserInput.currentChar() === '{');
  5119. if (!value) {
  5120. if (!hasBlock && parserInput.currentChar() !== ';') {
  5121. error("".concat(name, " rule is missing block or ending semi-colon"));
  5122. }
  5123. }
  5124. else if (!value.value) {
  5125. value = null;
  5126. }
  5127. }
  5128. if (hasBlock) {
  5129. rules = this.blockRuleset();
  5130. }
  5131. if (rules || (!hasBlock && value && parserInput.$char(';'))) {
  5132. parserInput.forget();
  5133. return new (tree.AtRule)(name, value, rules, index + currentIndex, fileInfo, context.dumpLineNumbers ? getDebugInfo(index) : null, isRooted);
  5134. }
  5135. parserInput.restore('at-rule options not recognised');
  5136. },
  5137. //
  5138. // A Value is a comma-delimited list of Expressions
  5139. //
  5140. // font-family: Baskerville, Georgia, serif;
  5141. //
  5142. // In a Rule, a Value represents everything after the `:`,
  5143. // and before the `;`.
  5144. //
  5145. value: function () {
  5146. var e;
  5147. var expressions = [];
  5148. var index = parserInput.i;
  5149. do {
  5150. e = this.expression();
  5151. if (e) {
  5152. expressions.push(e);
  5153. if (!parserInput.$char(',')) {
  5154. break;
  5155. }
  5156. }
  5157. } while (e);
  5158. if (expressions.length > 0) {
  5159. return new (tree.Value)(expressions, index + currentIndex);
  5160. }
  5161. },
  5162. important: function () {
  5163. if (parserInput.currentChar() === '!') {
  5164. return parserInput.$re(/^! *important/);
  5165. }
  5166. },
  5167. sub: function () {
  5168. var a;
  5169. var e;
  5170. parserInput.save();
  5171. if (parserInput.$char('(')) {
  5172. a = this.addition();
  5173. if (a && parserInput.$char(')')) {
  5174. parserInput.forget();
  5175. e = new (tree.Expression)([a]);
  5176. e.parens = true;
  5177. return e;
  5178. }
  5179. parserInput.restore('Expected \')\'');
  5180. return;
  5181. }
  5182. parserInput.restore();
  5183. },
  5184. multiplication: function () {
  5185. var m;
  5186. var a;
  5187. var op;
  5188. var operation;
  5189. var isSpaced;
  5190. m = this.operand();
  5191. if (m) {
  5192. isSpaced = parserInput.isWhitespace(-1);
  5193. while (true) {
  5194. if (parserInput.peek(/^\/[*/]/)) {
  5195. break;
  5196. }
  5197. parserInput.save();
  5198. op = parserInput.$char('/') || parserInput.$char('*') || parserInput.$str('./');
  5199. if (!op) {
  5200. parserInput.forget();
  5201. break;
  5202. }
  5203. a = this.operand();
  5204. if (!a) {
  5205. parserInput.restore();
  5206. break;
  5207. }
  5208. parserInput.forget();
  5209. m.parensInOp = true;
  5210. a.parensInOp = true;
  5211. operation = new (tree.Operation)(op, [operation || m, a], isSpaced);
  5212. isSpaced = parserInput.isWhitespace(-1);
  5213. }
  5214. return operation || m;
  5215. }
  5216. },
  5217. addition: function () {
  5218. var m;
  5219. var a;
  5220. var op;
  5221. var operation;
  5222. var isSpaced;
  5223. m = this.multiplication();
  5224. if (m) {
  5225. isSpaced = parserInput.isWhitespace(-1);
  5226. while (true) {
  5227. op = parserInput.$re(/^[-+]\s+/) || (!isSpaced && (parserInput.$char('+') || parserInput.$char('-')));
  5228. if (!op) {
  5229. break;
  5230. }
  5231. a = this.multiplication();
  5232. if (!a) {
  5233. break;
  5234. }
  5235. m.parensInOp = true;
  5236. a.parensInOp = true;
  5237. operation = new (tree.Operation)(op, [operation || m, a], isSpaced);
  5238. isSpaced = parserInput.isWhitespace(-1);
  5239. }
  5240. return operation || m;
  5241. }
  5242. },
  5243. conditions: function () {
  5244. var a;
  5245. var b;
  5246. var index = parserInput.i;
  5247. var condition;
  5248. a = this.condition(true);
  5249. if (a) {
  5250. while (true) {
  5251. if (!parserInput.peek(/^,\s*(not\s*)?\(/) || !parserInput.$char(',')) {
  5252. break;
  5253. }
  5254. b = this.condition(true);
  5255. if (!b) {
  5256. break;
  5257. }
  5258. condition = new (tree.Condition)('or', condition || a, b, index + currentIndex);
  5259. }
  5260. return condition || a;
  5261. }
  5262. },
  5263. condition: function (needsParens) {
  5264. var result;
  5265. var logical;
  5266. var next;
  5267. function or() {
  5268. return parserInput.$str('or');
  5269. }
  5270. result = this.conditionAnd(needsParens);
  5271. if (!result) {
  5272. return;
  5273. }
  5274. logical = or();
  5275. if (logical) {
  5276. next = this.condition(needsParens);
  5277. if (next) {
  5278. result = new (tree.Condition)(logical, result, next);
  5279. }
  5280. else {
  5281. return;
  5282. }
  5283. }
  5284. return result;
  5285. },
  5286. conditionAnd: function (needsParens) {
  5287. var result;
  5288. var logical;
  5289. var next;
  5290. var self = this;
  5291. function insideCondition() {
  5292. var cond = self.negatedCondition(needsParens) || self.parenthesisCondition(needsParens);
  5293. if (!cond && !needsParens) {
  5294. return self.atomicCondition(needsParens);
  5295. }
  5296. return cond;
  5297. }
  5298. function and() {
  5299. return parserInput.$str('and');
  5300. }
  5301. result = insideCondition();
  5302. if (!result) {
  5303. return;
  5304. }
  5305. logical = and();
  5306. if (logical) {
  5307. next = this.conditionAnd(needsParens);
  5308. if (next) {
  5309. result = new (tree.Condition)(logical, result, next);
  5310. }
  5311. else {
  5312. return;
  5313. }
  5314. }
  5315. return result;
  5316. },
  5317. negatedCondition: function (needsParens) {
  5318. if (parserInput.$str('not')) {
  5319. var result = this.parenthesisCondition(needsParens);
  5320. if (result) {
  5321. result.negate = !result.negate;
  5322. }
  5323. return result;
  5324. }
  5325. },
  5326. parenthesisCondition: function (needsParens) {
  5327. function tryConditionFollowedByParenthesis(me) {
  5328. var body;
  5329. parserInput.save();
  5330. body = me.condition(needsParens);
  5331. if (!body) {
  5332. parserInput.restore();
  5333. return;
  5334. }
  5335. if (!parserInput.$char(')')) {
  5336. parserInput.restore();
  5337. return;
  5338. }
  5339. parserInput.forget();
  5340. return body;
  5341. }
  5342. var body;
  5343. parserInput.save();
  5344. if (!parserInput.$str('(')) {
  5345. parserInput.restore();
  5346. return;
  5347. }
  5348. body = tryConditionFollowedByParenthesis(this);
  5349. if (body) {
  5350. parserInput.forget();
  5351. return body;
  5352. }
  5353. body = this.atomicCondition(needsParens);
  5354. if (!body) {
  5355. parserInput.restore();
  5356. return;
  5357. }
  5358. if (!parserInput.$char(')')) {
  5359. parserInput.restore("expected ')' got '".concat(parserInput.currentChar(), "'"));
  5360. return;
  5361. }
  5362. parserInput.forget();
  5363. return body;
  5364. },
  5365. atomicCondition: function (needsParens, preparsedCond) {
  5366. var entities = this.entities;
  5367. var index = parserInput.i;
  5368. var a;
  5369. var b;
  5370. var c;
  5371. var op;
  5372. var cond = (function () {
  5373. return this.addition() || entities.keyword() || entities.quoted() || entities.mixinLookup();
  5374. }).bind(this);
  5375. if (preparsedCond) {
  5376. a = preparsedCond;
  5377. }
  5378. else {
  5379. a = cond();
  5380. }
  5381. if (a) {
  5382. if (parserInput.$char('>')) {
  5383. if (parserInput.$char('=')) {
  5384. op = '>=';
  5385. }
  5386. else {
  5387. op = '>';
  5388. }
  5389. }
  5390. else if (parserInput.$char('<')) {
  5391. if (parserInput.$char('=')) {
  5392. op = '<=';
  5393. }
  5394. else {
  5395. op = '<';
  5396. }
  5397. }
  5398. else if (parserInput.$char('=')) {
  5399. if (parserInput.$char('>')) {
  5400. op = '=>';
  5401. }
  5402. else if (parserInput.$char('<')) {
  5403. op = '=<';
  5404. }
  5405. else {
  5406. op = '=';
  5407. }
  5408. }
  5409. if (op) {
  5410. b = cond();
  5411. if (b) {
  5412. c = new (tree.Condition)(op, a, b, index + currentIndex, false);
  5413. }
  5414. else {
  5415. error('expected expression');
  5416. }
  5417. }
  5418. else if (!preparsedCond) {
  5419. c = new (tree.Condition)('=', a, new (tree.Keyword)('true'), index + currentIndex, false);
  5420. }
  5421. return c;
  5422. }
  5423. },
  5424. //
  5425. // An operand is anything that can be part of an operation,
  5426. // such as a Color, or a Variable
  5427. //
  5428. operand: function () {
  5429. var entities = this.entities;
  5430. var negate;
  5431. if (parserInput.peek(/^-[@$(]/)) {
  5432. negate = parserInput.$char('-');
  5433. }
  5434. var o = this.sub() || entities.dimension() ||
  5435. entities.color() || entities.variable() ||
  5436. entities.property() || entities.call() ||
  5437. entities.quoted(true) || entities.colorKeyword() ||
  5438. entities.mixinLookup();
  5439. if (negate) {
  5440. o.parensInOp = true;
  5441. o = new (tree.Negative)(o);
  5442. }
  5443. return o;
  5444. },
  5445. //
  5446. // Expressions either represent mathematical operations,
  5447. // or white-space delimited Entities.
  5448. //
  5449. // 1px solid black
  5450. // @var * 2
  5451. //
  5452. expression: function () {
  5453. var entities = [];
  5454. var e;
  5455. var delim;
  5456. var index = parserInput.i;
  5457. do {
  5458. e = this.comment();
  5459. if (e && !e.isLineComment) {
  5460. entities.push(e);
  5461. continue;
  5462. }
  5463. e = this.addition() || this.entity();
  5464. if (e instanceof tree.Comment) {
  5465. e = null;
  5466. }
  5467. if (e) {
  5468. entities.push(e);
  5469. // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here
  5470. if (!parserInput.peek(/^\/[/*]/)) {
  5471. delim = parserInput.$char('/');
  5472. if (delim) {
  5473. entities.push(new (tree.Anonymous)(delim, index + currentIndex));
  5474. }
  5475. }
  5476. }
  5477. } while (e);
  5478. if (entities.length > 0) {
  5479. return new (tree.Expression)(entities);
  5480. }
  5481. },
  5482. property: function () {
  5483. var name = parserInput.$re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/);
  5484. if (name) {
  5485. return name[1];
  5486. }
  5487. },
  5488. ruleProperty: function () {
  5489. var name = [];
  5490. var index = [];
  5491. var s;
  5492. var k;
  5493. parserInput.save();
  5494. var simpleProperty = parserInput.$re(/^([_a-zA-Z0-9-]+)\s*:/);
  5495. if (simpleProperty) {
  5496. name = [new (tree.Keyword)(simpleProperty[1])];
  5497. parserInput.forget();
  5498. return name;
  5499. }
  5500. function match(re) {
  5501. var i = parserInput.i;
  5502. var chunk = parserInput.$re(re);
  5503. if (chunk) {
  5504. index.push(i);
  5505. return name.push(chunk[1]);
  5506. }
  5507. }
  5508. match(/^(\*?)/);
  5509. while (true) {
  5510. if (!match(/^((?:[\w-]+)|(?:[@$]\{[\w-]+\}))/)) {
  5511. break;
  5512. }
  5513. }
  5514. if ((name.length > 1) && match(/^((?:\+_|\+)?)\s*:/)) {
  5515. parserInput.forget();
  5516. // at last, we have the complete match now. move forward,
  5517. // convert name particles to tree objects and return:
  5518. if (name[0] === '') {
  5519. name.shift();
  5520. index.shift();
  5521. }
  5522. for (k = 0; k < name.length; k++) {
  5523. s = name[k];
  5524. name[k] = (s.charAt(0) !== '@' && s.charAt(0) !== '$') ?
  5525. new (tree.Keyword)(s) :
  5526. (s.charAt(0) === '@' ?
  5527. new (tree.Variable)("@".concat(s.slice(2, -1)), index[k] + currentIndex, fileInfo) :
  5528. new (tree.Property)("$".concat(s.slice(2, -1)), index[k] + currentIndex, fileInfo));
  5529. }
  5530. return name;
  5531. }
  5532. parserInput.restore();
  5533. }
  5534. }
  5535. };
  5536. };
  5537. Parser.serializeVars = function (vars) {
  5538. var s = '';
  5539. for (var name_1 in vars) {
  5540. if (Object.hasOwnProperty.call(vars, name_1)) {
  5541. var value = vars[name_1];
  5542. s += "".concat(((name_1[0] === '@') ? '' : '@') + name_1, ": ").concat(value).concat((String(value).slice(-1) === ';') ? '' : ';');
  5543. }
  5544. }
  5545. return s;
  5546. };
  5547. var Selector = function (elements, extendList, condition, index, currentFileInfo, visibilityInfo) {
  5548. this.extendList = extendList;
  5549. this.condition = condition;
  5550. this.evaldCondition = !condition;
  5551. this._index = index;
  5552. this._fileInfo = currentFileInfo;
  5553. this.elements = this.getElements(elements);
  5554. this.mixinElements_ = undefined;
  5555. this.copyVisibilityInfo(visibilityInfo);
  5556. this.setParent(this.elements, this);
  5557. };
  5558. Selector.prototype = Object.assign(new Node(), {
  5559. type: 'Selector',
  5560. accept: function (visitor) {
  5561. if (this.elements) {
  5562. this.elements = visitor.visitArray(this.elements);
  5563. }
  5564. if (this.extendList) {
  5565. this.extendList = visitor.visitArray(this.extendList);
  5566. }
  5567. if (this.condition) {
  5568. this.condition = visitor.visit(this.condition);
  5569. }
  5570. },
  5571. createDerived: function (elements, extendList, evaldCondition) {
  5572. elements = this.getElements(elements);
  5573. var newSelector = new Selector(elements, extendList || this.extendList, null, this.getIndex(), this.fileInfo(), this.visibilityInfo());
  5574. newSelector.evaldCondition = (!isNullOrUndefined(evaldCondition)) ? evaldCondition : this.evaldCondition;
  5575. newSelector.mediaEmpty = this.mediaEmpty;
  5576. return newSelector;
  5577. },
  5578. getElements: function (els) {
  5579. if (!els) {
  5580. return [new Element('', '&', false, this._index, this._fileInfo)];
  5581. }
  5582. if (typeof els === 'string') {
  5583. new Parser(this.parse.context, this.parse.importManager, this._fileInfo, this._index).parseNode(els, ['selector'], function (err, result) {
  5584. if (err) {
  5585. throw new LessError({
  5586. index: err.index,
  5587. message: err.message
  5588. }, this.parse.imports, this._fileInfo.filename);
  5589. }
  5590. els = result[0].elements;
  5591. });
  5592. }
  5593. return els;
  5594. },
  5595. createEmptySelectors: function () {
  5596. var el = new Element('', '&', false, this._index, this._fileInfo), sels = [new Selector([el], null, null, this._index, this._fileInfo)];
  5597. sels[0].mediaEmpty = true;
  5598. return sels;
  5599. },
  5600. match: function (other) {
  5601. var elements = this.elements;
  5602. var len = elements.length;
  5603. var olen;
  5604. var i;
  5605. other = other.mixinElements();
  5606. olen = other.length;
  5607. if (olen === 0 || len < olen) {
  5608. return 0;
  5609. }
  5610. else {
  5611. for (i = 0; i < olen; i++) {
  5612. if (elements[i].value !== other[i]) {
  5613. return 0;
  5614. }
  5615. }
  5616. }
  5617. return olen; // return number of matched elements
  5618. },
  5619. mixinElements: function () {
  5620. if (this.mixinElements_) {
  5621. return this.mixinElements_;
  5622. }
  5623. var elements = this.elements.map(function (v) {
  5624. return v.combinator.value + (v.value.value || v.value);
  5625. }).join('').match(/[,&#*.\w-]([\w-]|(\\.))*/g);
  5626. if (elements) {
  5627. if (elements[0] === '&') {
  5628. elements.shift();
  5629. }
  5630. }
  5631. else {
  5632. elements = [];
  5633. }
  5634. return (this.mixinElements_ = elements);
  5635. },
  5636. isJustParentSelector: function () {
  5637. return !this.mediaEmpty &&
  5638. this.elements.length === 1 &&
  5639. this.elements[0].value === '&' &&
  5640. (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === '');
  5641. },
  5642. eval: function (context) {
  5643. var evaldCondition = this.condition && this.condition.eval(context);
  5644. var elements = this.elements;
  5645. var extendList = this.extendList;
  5646. elements = elements && elements.map(function (e) { return e.eval(context); });
  5647. extendList = extendList && extendList.map(function (extend) { return extend.eval(context); });
  5648. return this.createDerived(elements, extendList, evaldCondition);
  5649. },
  5650. genCSS: function (context, output) {
  5651. var i, element;
  5652. if ((!context || !context.firstSelector) && this.elements[0].combinator.value === '') {
  5653. output.add(' ', this.fileInfo(), this.getIndex());
  5654. }
  5655. for (i = 0; i < this.elements.length; i++) {
  5656. element = this.elements[i];
  5657. element.genCSS(context, output);
  5658. }
  5659. },
  5660. getIsOutput: function () {
  5661. return this.evaldCondition;
  5662. }
  5663. });
  5664. var Value = function (value) {
  5665. if (!value) {
  5666. throw new Error('Value requires an array argument');
  5667. }
  5668. if (!Array.isArray(value)) {
  5669. this.value = [value];
  5670. }
  5671. else {
  5672. this.value = value;
  5673. }
  5674. };
  5675. Value.prototype = Object.assign(new Node(), {
  5676. type: 'Value',
  5677. accept: function (visitor) {
  5678. if (this.value) {
  5679. this.value = visitor.visitArray(this.value);
  5680. }
  5681. },
  5682. eval: function (context) {
  5683. if (this.value.length === 1) {
  5684. return this.value[0].eval(context);
  5685. }
  5686. else {
  5687. return new Value(this.value.map(function (v) {
  5688. return v.eval(context);
  5689. }));
  5690. }
  5691. },
  5692. genCSS: function (context, output) {
  5693. var i;
  5694. for (i = 0; i < this.value.length; i++) {
  5695. this.value[i].genCSS(context, output);
  5696. if (i + 1 < this.value.length) {
  5697. output.add((context && context.compress) ? ',' : ', ');
  5698. }
  5699. }
  5700. }
  5701. });
  5702. var Keyword = function (value) {
  5703. this.value = value;
  5704. };
  5705. Keyword.prototype = Object.assign(new Node(), {
  5706. type: 'Keyword',
  5707. genCSS: function (context, output) {
  5708. if (this.value === '%') {
  5709. throw { type: 'Syntax', message: 'Invalid % without number' };
  5710. }
  5711. output.add(this.value);
  5712. }
  5713. });
  5714. Keyword.True = new Keyword('true');
  5715. Keyword.False = new Keyword('false');
  5716. var MATH$1 = Math$1;
  5717. function evalName(context, name) {
  5718. var value = '';
  5719. var i;
  5720. var n = name.length;
  5721. var output = { add: function (s) { value += s; } };
  5722. for (i = 0; i < n; i++) {
  5723. name[i].eval(context).genCSS(context, output);
  5724. }
  5725. return value;
  5726. }
  5727. var Declaration = function (name, value, important, merge, index, currentFileInfo, inline, variable) {
  5728. this.name = name;
  5729. this.value = (value instanceof Node) ? value : new Value([value ? new Anonymous(value) : null]);
  5730. this.important = important ? " ".concat(important.trim()) : '';
  5731. this.merge = merge;
  5732. this._index = index;
  5733. this._fileInfo = currentFileInfo;
  5734. this.inline = inline || false;
  5735. this.variable = (variable !== undefined) ? variable
  5736. : (name.charAt && (name.charAt(0) === '@'));
  5737. this.allowRoot = true;
  5738. this.setParent(this.value, this);
  5739. };
  5740. Declaration.prototype = Object.assign(new Node(), {
  5741. type: 'Declaration',
  5742. genCSS: function (context, output) {
  5743. output.add(this.name + (context.compress ? ':' : ': '), this.fileInfo(), this.getIndex());
  5744. try {
  5745. this.value.genCSS(context, output);
  5746. }
  5747. catch (e) {
  5748. e.index = this._index;
  5749. e.filename = this._fileInfo.filename;
  5750. throw e;
  5751. }
  5752. output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? '' : ';'), this._fileInfo, this._index);
  5753. },
  5754. eval: function (context) {
  5755. var mathBypass = false, prevMath, name = this.name, evaldValue, variable = this.variable;
  5756. if (typeof name !== 'string') {
  5757. // expand 'primitive' name directly to get
  5758. // things faster (~10% for benchmark.less):
  5759. name = (name.length === 1) && (name[0] instanceof Keyword) ?
  5760. name[0].value : evalName(context, name);
  5761. variable = false; // never treat expanded interpolation as new variable name
  5762. }
  5763. // @todo remove when parens-division is default
  5764. if (name === 'font' && context.math === MATH$1.ALWAYS) {
  5765. mathBypass = true;
  5766. prevMath = context.math;
  5767. context.math = MATH$1.PARENS_DIVISION;
  5768. }
  5769. try {
  5770. context.importantScope.push({});
  5771. evaldValue = this.value.eval(context);
  5772. if (!this.variable && evaldValue.type === 'DetachedRuleset') {
  5773. throw { message: 'Rulesets cannot be evaluated on a property.',
  5774. index: this.getIndex(), filename: this.fileInfo().filename };
  5775. }
  5776. var important = this.important;
  5777. var importantResult = context.importantScope.pop();
  5778. if (!important && importantResult.important) {
  5779. important = importantResult.important;
  5780. }
  5781. return new Declaration(name, evaldValue, important, this.merge, this.getIndex(), this.fileInfo(), this.inline, variable);
  5782. }
  5783. catch (e) {
  5784. if (typeof e.index !== 'number') {
  5785. e.index = this.getIndex();
  5786. e.filename = this.fileInfo().filename;
  5787. }
  5788. throw e;
  5789. }
  5790. finally {
  5791. if (mathBypass) {
  5792. context.math = prevMath;
  5793. }
  5794. }
  5795. },
  5796. makeImportant: function () {
  5797. return new Declaration(this.name, this.value, '!important', this.merge, this.getIndex(), this.fileInfo(), this.inline);
  5798. }
  5799. });
  5800. function asComment(ctx) {
  5801. return "/* line ".concat(ctx.debugInfo.lineNumber, ", ").concat(ctx.debugInfo.fileName, " */\n");
  5802. }
  5803. function asMediaQuery(ctx) {
  5804. var filenameWithProtocol = ctx.debugInfo.fileName;
  5805. if (!/^[a-z]+:\/\//i.test(filenameWithProtocol)) {
  5806. filenameWithProtocol = "file://".concat(filenameWithProtocol);
  5807. }
  5808. return "@media -sass-debug-info{filename{font-family:".concat(filenameWithProtocol.replace(/([.:/\\])/g, function (a) {
  5809. if (a == '\\') {
  5810. a = '/';
  5811. }
  5812. return "\\".concat(a);
  5813. }), "}line{font-family:\\00003").concat(ctx.debugInfo.lineNumber, "}}\n");
  5814. }
  5815. function debugInfo(context, ctx, lineSeparator) {
  5816. var result = '';
  5817. if (context.dumpLineNumbers && !context.compress) {
  5818. switch (context.dumpLineNumbers) {
  5819. case 'comments':
  5820. result = asComment(ctx);
  5821. break;
  5822. case 'mediaquery':
  5823. result = asMediaQuery(ctx);
  5824. break;
  5825. case 'all':
  5826. result = asComment(ctx) + (lineSeparator || '') + asMediaQuery(ctx);
  5827. break;
  5828. }
  5829. }
  5830. return result;
  5831. }
  5832. var Comment = function (value, isLineComment, index, currentFileInfo) {
  5833. this.value = value;
  5834. this.isLineComment = isLineComment;
  5835. this._index = index;
  5836. this._fileInfo = currentFileInfo;
  5837. this.allowRoot = true;
  5838. };
  5839. Comment.prototype = Object.assign(new Node(), {
  5840. type: 'Comment',
  5841. genCSS: function (context, output) {
  5842. if (this.debugInfo) {
  5843. output.add(debugInfo(context, this), this.fileInfo(), this.getIndex());
  5844. }
  5845. output.add(this.value);
  5846. },
  5847. isSilent: function (context) {
  5848. var isCompressed = context.compress && this.value[2] !== '!';
  5849. return this.isLineComment || isCompressed;
  5850. }
  5851. });
  5852. var defaultFunc = {
  5853. eval: function () {
  5854. var v = this.value_;
  5855. var e = this.error_;
  5856. if (e) {
  5857. throw e;
  5858. }
  5859. if (!isNullOrUndefined(v)) {
  5860. return v ? Keyword.True : Keyword.False;
  5861. }
  5862. },
  5863. value: function (v) {
  5864. this.value_ = v;
  5865. },
  5866. error: function (e) {
  5867. this.error_ = e;
  5868. },
  5869. reset: function () {
  5870. this.value_ = this.error_ = null;
  5871. }
  5872. };
  5873. var Ruleset = function (selectors, rules, strictImports, visibilityInfo) {
  5874. this.selectors = selectors;
  5875. this.rules = rules;
  5876. this._lookups = {};
  5877. this._variables = null;
  5878. this._properties = null;
  5879. this.strictImports = strictImports;
  5880. this.copyVisibilityInfo(visibilityInfo);
  5881. this.allowRoot = true;
  5882. this.setParent(this.selectors, this);
  5883. this.setParent(this.rules, this);
  5884. };
  5885. Ruleset.prototype = Object.assign(new Node(), {
  5886. type: 'Ruleset',
  5887. isRuleset: true,
  5888. isRulesetLike: function () { return true; },
  5889. accept: function (visitor) {
  5890. if (this.paths) {
  5891. this.paths = visitor.visitArray(this.paths, true);
  5892. }
  5893. else if (this.selectors) {
  5894. this.selectors = visitor.visitArray(this.selectors);
  5895. }
  5896. if (this.rules && this.rules.length) {
  5897. this.rules = visitor.visitArray(this.rules);
  5898. }
  5899. },
  5900. eval: function (context) {
  5901. var selectors;
  5902. var selCnt;
  5903. var selector;
  5904. var i;
  5905. var hasVariable;
  5906. var hasOnePassingSelector = false;
  5907. if (this.selectors && (selCnt = this.selectors.length)) {
  5908. selectors = new Array(selCnt);
  5909. defaultFunc.error({
  5910. type: 'Syntax',
  5911. message: 'it is currently only allowed in parametric mixin guards,'
  5912. });
  5913. for (i = 0; i < selCnt; i++) {
  5914. selector = this.selectors[i].eval(context);
  5915. for (var j = 0; j < selector.elements.length; j++) {
  5916. if (selector.elements[j].isVariable) {
  5917. hasVariable = true;
  5918. break;
  5919. }
  5920. }
  5921. selectors[i] = selector;
  5922. if (selector.evaldCondition) {
  5923. hasOnePassingSelector = true;
  5924. }
  5925. }
  5926. if (hasVariable) {
  5927. var toParseSelectors = new Array(selCnt);
  5928. for (i = 0; i < selCnt; i++) {
  5929. selector = selectors[i];
  5930. toParseSelectors[i] = selector.toCSS(context);
  5931. }
  5932. var startingIndex = selectors[0].getIndex();
  5933. var selectorFileInfo = selectors[0].fileInfo();
  5934. new Parser(context, this.parse.importManager, selectorFileInfo, startingIndex).parseNode(toParseSelectors.join(','), ['selectors'], function (err, result) {
  5935. if (result) {
  5936. selectors = flattenArray(result);
  5937. }
  5938. });
  5939. }
  5940. defaultFunc.reset();
  5941. }
  5942. else {
  5943. hasOnePassingSelector = true;
  5944. }
  5945. var rules = this.rules ? copyArray(this.rules) : null;
  5946. var ruleset = new Ruleset(selectors, rules, this.strictImports, this.visibilityInfo());
  5947. var rule;
  5948. var subRule;
  5949. ruleset.originalRuleset = this;
  5950. ruleset.root = this.root;
  5951. ruleset.firstRoot = this.firstRoot;
  5952. ruleset.allowImports = this.allowImports;
  5953. if (this.debugInfo) {
  5954. ruleset.debugInfo = this.debugInfo;
  5955. }
  5956. if (!hasOnePassingSelector) {
  5957. rules.length = 0;
  5958. }
  5959. // inherit a function registry from the frames stack when possible;
  5960. // otherwise from the global registry
  5961. ruleset.functionRegistry = (function (frames) {
  5962. var i = 0;
  5963. var n = frames.length;
  5964. var found;
  5965. for (; i !== n; ++i) {
  5966. found = frames[i].functionRegistry;
  5967. if (found) {
  5968. return found;
  5969. }
  5970. }
  5971. return functionRegistry;
  5972. }(context.frames)).inherit();
  5973. // push the current ruleset to the frames stack
  5974. var ctxFrames = context.frames;
  5975. ctxFrames.unshift(ruleset);
  5976. // currrent selectors
  5977. var ctxSelectors = context.selectors;
  5978. if (!ctxSelectors) {
  5979. context.selectors = ctxSelectors = [];
  5980. }
  5981. ctxSelectors.unshift(this.selectors);
  5982. // Evaluate imports
  5983. if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
  5984. ruleset.evalImports(context);
  5985. }
  5986. // Store the frames around mixin definitions,
  5987. // so they can be evaluated like closures when the time comes.
  5988. var rsRules = ruleset.rules;
  5989. for (i = 0; (rule = rsRules[i]); i++) {
  5990. if (rule.evalFirst) {
  5991. rsRules[i] = rule.eval(context);
  5992. }
  5993. }
  5994. var mediaBlockCount = (context.mediaBlocks && context.mediaBlocks.length) || 0;
  5995. // Evaluate mixin calls.
  5996. for (i = 0; (rule = rsRules[i]); i++) {
  5997. if (rule.type === 'MixinCall') {
  5998. /* jshint loopfunc:true */
  5999. rules = rule.eval(context).filter(function (r) {
  6000. if ((r instanceof Declaration) && r.variable) {
  6001. // do not pollute the scope if the variable is
  6002. // already there. consider returning false here
  6003. // but we need a way to "return" variable from mixins
  6004. return !(ruleset.variable(r.name));
  6005. }
  6006. return true;
  6007. });
  6008. rsRules.splice.apply(rsRules, [i, 1].concat(rules));
  6009. i += rules.length - 1;
  6010. ruleset.resetCache();
  6011. }
  6012. else if (rule.type === 'VariableCall') {
  6013. /* jshint loopfunc:true */
  6014. rules = rule.eval(context).rules.filter(function (r) {
  6015. if ((r instanceof Declaration) && r.variable) {
  6016. // do not pollute the scope at all
  6017. return false;
  6018. }
  6019. return true;
  6020. });
  6021. rsRules.splice.apply(rsRules, [i, 1].concat(rules));
  6022. i += rules.length - 1;
  6023. ruleset.resetCache();
  6024. }
  6025. }
  6026. // Evaluate everything else
  6027. for (i = 0; (rule = rsRules[i]); i++) {
  6028. if (!rule.evalFirst) {
  6029. rsRules[i] = rule = rule.eval ? rule.eval(context) : rule;
  6030. }
  6031. }
  6032. // Evaluate everything else
  6033. for (i = 0; (rule = rsRules[i]); i++) {
  6034. // for rulesets, check if it is a css guard and can be removed
  6035. if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) {
  6036. // check if it can be folded in (e.g. & where)
  6037. if (rule.selectors[0] && rule.selectors[0].isJustParentSelector()) {
  6038. rsRules.splice(i--, 1);
  6039. for (var j = 0; (subRule = rule.rules[j]); j++) {
  6040. if (subRule instanceof Node) {
  6041. subRule.copyVisibilityInfo(rule.visibilityInfo());
  6042. if (!(subRule instanceof Declaration) || !subRule.variable) {
  6043. rsRules.splice(++i, 0, subRule);
  6044. }
  6045. }
  6046. }
  6047. }
  6048. }
  6049. }
  6050. // Pop the stack
  6051. ctxFrames.shift();
  6052. ctxSelectors.shift();
  6053. if (context.mediaBlocks) {
  6054. for (i = mediaBlockCount; i < context.mediaBlocks.length; i++) {
  6055. context.mediaBlocks[i].bubbleSelectors(selectors);
  6056. }
  6057. }
  6058. return ruleset;
  6059. },
  6060. evalImports: function (context) {
  6061. var rules = this.rules;
  6062. var i;
  6063. var importRules;
  6064. if (!rules) {
  6065. return;
  6066. }
  6067. for (i = 0; i < rules.length; i++) {
  6068. if (rules[i].type === 'Import') {
  6069. importRules = rules[i].eval(context);
  6070. if (importRules && (importRules.length || importRules.length === 0)) {
  6071. rules.splice.apply(rules, [i, 1].concat(importRules));
  6072. i += importRules.length - 1;
  6073. }
  6074. else {
  6075. rules.splice(i, 1, importRules);
  6076. }
  6077. this.resetCache();
  6078. }
  6079. }
  6080. },
  6081. makeImportant: function () {
  6082. var result = new Ruleset(this.selectors, this.rules.map(function (r) {
  6083. if (r.makeImportant) {
  6084. return r.makeImportant();
  6085. }
  6086. else {
  6087. return r;
  6088. }
  6089. }), this.strictImports, this.visibilityInfo());
  6090. return result;
  6091. },
  6092. matchArgs: function (args) {
  6093. return !args || args.length === 0;
  6094. },
  6095. // lets you call a css selector with a guard
  6096. matchCondition: function (args, context) {
  6097. var lastSelector = this.selectors[this.selectors.length - 1];
  6098. if (!lastSelector.evaldCondition) {
  6099. return false;
  6100. }
  6101. if (lastSelector.condition &&
  6102. !lastSelector.condition.eval(new contexts.Eval(context, context.frames))) {
  6103. return false;
  6104. }
  6105. return true;
  6106. },
  6107. resetCache: function () {
  6108. this._rulesets = null;
  6109. this._variables = null;
  6110. this._properties = null;
  6111. this._lookups = {};
  6112. },
  6113. variables: function () {
  6114. if (!this._variables) {
  6115. this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) {
  6116. if (r instanceof Declaration && r.variable === true) {
  6117. hash[r.name] = r;
  6118. }
  6119. // when evaluating variables in an import statement, imports have not been eval'd
  6120. // so we need to go inside import statements.
  6121. // guard against root being a string (in the case of inlined less)
  6122. if (r.type === 'Import' && r.root && r.root.variables) {
  6123. var vars = r.root.variables();
  6124. for (var name_1 in vars) {
  6125. // eslint-disable-next-line no-prototype-builtins
  6126. if (vars.hasOwnProperty(name_1)) {
  6127. hash[name_1] = r.root.variable(name_1);
  6128. }
  6129. }
  6130. }
  6131. return hash;
  6132. }, {});
  6133. }
  6134. return this._variables;
  6135. },
  6136. properties: function () {
  6137. if (!this._properties) {
  6138. this._properties = !this.rules ? {} : this.rules.reduce(function (hash, r) {
  6139. if (r instanceof Declaration && r.variable !== true) {
  6140. var name_2 = (r.name.length === 1) && (r.name[0] instanceof Keyword) ?
  6141. r.name[0].value : r.name;
  6142. // Properties don't overwrite as they can merge
  6143. if (!hash["$".concat(name_2)]) {
  6144. hash["$".concat(name_2)] = [r];
  6145. }
  6146. else {
  6147. hash["$".concat(name_2)].push(r);
  6148. }
  6149. }
  6150. return hash;
  6151. }, {});
  6152. }
  6153. return this._properties;
  6154. },
  6155. variable: function (name) {
  6156. var decl = this.variables()[name];
  6157. if (decl) {
  6158. return this.parseValue(decl);
  6159. }
  6160. },
  6161. property: function (name) {
  6162. var decl = this.properties()[name];
  6163. if (decl) {
  6164. return this.parseValue(decl);
  6165. }
  6166. },
  6167. lastDeclaration: function () {
  6168. for (var i_1 = this.rules.length; i_1 > 0; i_1--) {
  6169. var decl = this.rules[i_1 - 1];
  6170. if (decl instanceof Declaration) {
  6171. return this.parseValue(decl);
  6172. }
  6173. }
  6174. },
  6175. parseValue: function (toParse) {
  6176. var self = this;
  6177. function transformDeclaration(decl) {
  6178. if (decl.value instanceof Anonymous && !decl.parsed) {
  6179. if (typeof decl.value.value === 'string') {
  6180. new Parser(this.parse.context, this.parse.importManager, decl.fileInfo(), decl.value.getIndex()).parseNode(decl.value.value, ['value', 'important'], function (err, result) {
  6181. if (err) {
  6182. decl.parsed = true;
  6183. }
  6184. if (result) {
  6185. decl.value = result[0];
  6186. decl.important = result[1] || '';
  6187. decl.parsed = true;
  6188. }
  6189. });
  6190. }
  6191. else {
  6192. decl.parsed = true;
  6193. }
  6194. return decl;
  6195. }
  6196. else {
  6197. return decl;
  6198. }
  6199. }
  6200. if (!Array.isArray(toParse)) {
  6201. return transformDeclaration.call(self, toParse);
  6202. }
  6203. else {
  6204. var nodes_1 = [];
  6205. toParse.forEach(function (n) {
  6206. nodes_1.push(transformDeclaration.call(self, n));
  6207. });
  6208. return nodes_1;
  6209. }
  6210. },
  6211. rulesets: function () {
  6212. if (!this.rules) {
  6213. return [];
  6214. }
  6215. var filtRules = [];
  6216. var rules = this.rules;
  6217. var i;
  6218. var rule;
  6219. for (i = 0; (rule = rules[i]); i++) {
  6220. if (rule.isRuleset) {
  6221. filtRules.push(rule);
  6222. }
  6223. }
  6224. return filtRules;
  6225. },
  6226. prependRule: function (rule) {
  6227. var rules = this.rules;
  6228. if (rules) {
  6229. rules.unshift(rule);
  6230. }
  6231. else {
  6232. this.rules = [rule];
  6233. }
  6234. this.setParent(rule, this);
  6235. },
  6236. find: function (selector, self, filter) {
  6237. self = self || this;
  6238. var rules = [];
  6239. var match;
  6240. var foundMixins;
  6241. var key = selector.toCSS();
  6242. if (key in this._lookups) {
  6243. return this._lookups[key];
  6244. }
  6245. this.rulesets().forEach(function (rule) {
  6246. if (rule !== self) {
  6247. for (var j = 0; j < rule.selectors.length; j++) {
  6248. match = selector.match(rule.selectors[j]);
  6249. if (match) {
  6250. if (selector.elements.length > match) {
  6251. if (!filter || filter(rule)) {
  6252. foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter);
  6253. for (var i_2 = 0; i_2 < foundMixins.length; ++i_2) {
  6254. foundMixins[i_2].path.push(rule);
  6255. }
  6256. Array.prototype.push.apply(rules, foundMixins);
  6257. }
  6258. }
  6259. else {
  6260. rules.push({ rule: rule, path: [] });
  6261. }
  6262. break;
  6263. }
  6264. }
  6265. }
  6266. });
  6267. this._lookups[key] = rules;
  6268. return rules;
  6269. },
  6270. genCSS: function (context, output) {
  6271. var i;
  6272. var j;
  6273. var charsetRuleNodes = [];
  6274. var ruleNodes = [];
  6275. var // Line number debugging
  6276. debugInfo$1;
  6277. var rule;
  6278. var path;
  6279. context.tabLevel = (context.tabLevel || 0);
  6280. if (!this.root) {
  6281. context.tabLevel++;
  6282. }
  6283. var tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(' ');
  6284. var tabSetStr = context.compress ? '' : Array(context.tabLevel).join(' ');
  6285. var sep;
  6286. var charsetNodeIndex = 0;
  6287. var importNodeIndex = 0;
  6288. for (i = 0; (rule = this.rules[i]); i++) {
  6289. if (rule instanceof Comment) {
  6290. if (importNodeIndex === i) {
  6291. importNodeIndex++;
  6292. }
  6293. ruleNodes.push(rule);
  6294. }
  6295. else if (rule.isCharset && rule.isCharset()) {
  6296. ruleNodes.splice(charsetNodeIndex, 0, rule);
  6297. charsetNodeIndex++;
  6298. importNodeIndex++;
  6299. }
  6300. else if (rule.type === 'Import') {
  6301. ruleNodes.splice(importNodeIndex, 0, rule);
  6302. importNodeIndex++;
  6303. }
  6304. else {
  6305. ruleNodes.push(rule);
  6306. }
  6307. }
  6308. ruleNodes = charsetRuleNodes.concat(ruleNodes);
  6309. // If this is the root node, we don't render
  6310. // a selector, or {}.
  6311. if (!this.root) {
  6312. debugInfo$1 = debugInfo(context, this, tabSetStr);
  6313. if (debugInfo$1) {
  6314. output.add(debugInfo$1);
  6315. output.add(tabSetStr);
  6316. }
  6317. var paths = this.paths;
  6318. var pathCnt = paths.length;
  6319. var pathSubCnt = void 0;
  6320. sep = context.compress ? ',' : (",\n".concat(tabSetStr));
  6321. for (i = 0; i < pathCnt; i++) {
  6322. path = paths[i];
  6323. if (!(pathSubCnt = path.length)) {
  6324. continue;
  6325. }
  6326. if (i > 0) {
  6327. output.add(sep);
  6328. }
  6329. context.firstSelector = true;
  6330. path[0].genCSS(context, output);
  6331. context.firstSelector = false;
  6332. for (j = 1; j < pathSubCnt; j++) {
  6333. path[j].genCSS(context, output);
  6334. }
  6335. }
  6336. output.add((context.compress ? '{' : ' {\n') + tabRuleStr);
  6337. }
  6338. // Compile rules and rulesets
  6339. for (i = 0; (rule = ruleNodes[i]); i++) {
  6340. if (i + 1 === ruleNodes.length) {
  6341. context.lastRule = true;
  6342. }
  6343. var currentLastRule = context.lastRule;
  6344. if (rule.isRulesetLike(rule)) {
  6345. context.lastRule = false;
  6346. }
  6347. if (rule.genCSS) {
  6348. rule.genCSS(context, output);
  6349. }
  6350. else if (rule.value) {
  6351. output.add(rule.value.toString());
  6352. }
  6353. context.lastRule = currentLastRule;
  6354. if (!context.lastRule && rule.isVisible()) {
  6355. output.add(context.compress ? '' : ("\n".concat(tabRuleStr)));
  6356. }
  6357. else {
  6358. context.lastRule = false;
  6359. }
  6360. }
  6361. if (!this.root) {
  6362. output.add((context.compress ? '}' : "\n".concat(tabSetStr, "}")));
  6363. context.tabLevel--;
  6364. }
  6365. if (!output.isEmpty() && !context.compress && this.firstRoot) {
  6366. output.add('\n');
  6367. }
  6368. },
  6369. joinSelectors: function (paths, context, selectors) {
  6370. for (var s = 0; s < selectors.length; s++) {
  6371. this.joinSelector(paths, context, selectors[s]);
  6372. }
  6373. },
  6374. joinSelector: function (paths, context, selector) {
  6375. function createParenthesis(elementsToPak, originalElement) {
  6376. var replacementParen, j;
  6377. if (elementsToPak.length === 0) {
  6378. replacementParen = new Paren(elementsToPak[0]);
  6379. }
  6380. else {
  6381. var insideParent = new Array(elementsToPak.length);
  6382. for (j = 0; j < elementsToPak.length; j++) {
  6383. insideParent[j] = new Element(null, elementsToPak[j], originalElement.isVariable, originalElement._index, originalElement._fileInfo);
  6384. }
  6385. replacementParen = new Paren(new Selector(insideParent));
  6386. }
  6387. return replacementParen;
  6388. }
  6389. function createSelector(containedElement, originalElement) {
  6390. var element, selector;
  6391. element = new Element(null, containedElement, originalElement.isVariable, originalElement._index, originalElement._fileInfo);
  6392. selector = new Selector([element]);
  6393. return selector;
  6394. }
  6395. // joins selector path from `beginningPath` with selector path in `addPath`
  6396. // `replacedElement` contains element that is being replaced by `addPath`
  6397. // returns concatenated path
  6398. function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) {
  6399. var newSelectorPath, lastSelector, newJoinedSelector;
  6400. // our new selector path
  6401. newSelectorPath = [];
  6402. // construct the joined selector - if & is the first thing this will be empty,
  6403. // if not newJoinedSelector will be the last set of elements in the selector
  6404. if (beginningPath.length > 0) {
  6405. newSelectorPath = copyArray(beginningPath);
  6406. lastSelector = newSelectorPath.pop();
  6407. newJoinedSelector = originalSelector.createDerived(copyArray(lastSelector.elements));
  6408. }
  6409. else {
  6410. newJoinedSelector = originalSelector.createDerived([]);
  6411. }
  6412. if (addPath.length > 0) {
  6413. // /deep/ is a CSS4 selector - (removed, so should deprecate)
  6414. // that is valid without anything in front of it
  6415. // so if the & does not have a combinator that is "" or " " then
  6416. // and there is a combinator on the parent, then grab that.
  6417. // this also allows + a { & .b { .a & { ... though not sure why you would want to do that
  6418. var combinator = replacedElement.combinator;
  6419. var parentEl = addPath[0].elements[0];
  6420. if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) {
  6421. combinator = parentEl.combinator;
  6422. }
  6423. // join the elements so far with the first part of the parent
  6424. newJoinedSelector.elements.push(new Element(combinator, parentEl.value, replacedElement.isVariable, replacedElement._index, replacedElement._fileInfo));
  6425. newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1));
  6426. }
  6427. // now add the joined selector - but only if it is not empty
  6428. if (newJoinedSelector.elements.length !== 0) {
  6429. newSelectorPath.push(newJoinedSelector);
  6430. }
  6431. // put together the parent selectors after the join (e.g. the rest of the parent)
  6432. if (addPath.length > 1) {
  6433. var restOfPath = addPath.slice(1);
  6434. restOfPath = restOfPath.map(function (selector) {
  6435. return selector.createDerived(selector.elements, []);
  6436. });
  6437. newSelectorPath = newSelectorPath.concat(restOfPath);
  6438. }
  6439. return newSelectorPath;
  6440. }
  6441. // joins selector path from `beginningPath` with every selector path in `addPaths` array
  6442. // `replacedElement` contains element that is being replaced by `addPath`
  6443. // returns array with all concatenated paths
  6444. function addAllReplacementsIntoPath(beginningPath, addPaths, replacedElement, originalSelector, result) {
  6445. var j;
  6446. for (j = 0; j < beginningPath.length; j++) {
  6447. var newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector);
  6448. result.push(newSelectorPath);
  6449. }
  6450. return result;
  6451. }
  6452. function mergeElementsOnToSelectors(elements, selectors) {
  6453. var i, sel;
  6454. if (elements.length === 0) {
  6455. return;
  6456. }
  6457. if (selectors.length === 0) {
  6458. selectors.push([new Selector(elements)]);
  6459. return;
  6460. }
  6461. for (i = 0; (sel = selectors[i]); i++) {
  6462. // if the previous thing in sel is a parent this needs to join on to it
  6463. if (sel.length > 0) {
  6464. sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements));
  6465. }
  6466. else {
  6467. sel.push(new Selector(elements));
  6468. }
  6469. }
  6470. }
  6471. // replace all parent selectors inside `inSelector` by content of `context` array
  6472. // resulting selectors are returned inside `paths` array
  6473. // returns true if `inSelector` contained at least one parent selector
  6474. function replaceParentSelector(paths, context, inSelector) {
  6475. // The paths are [[Selector]]
  6476. // The first list is a list of comma separated selectors
  6477. // The inner list is a list of inheritance separated selectors
  6478. // e.g.
  6479. // .a, .b {
  6480. // .c {
  6481. // }
  6482. // }
  6483. // == [[.a] [.c]] [[.b] [.c]]
  6484. //
  6485. var i, j, k, currentElements, newSelectors, selectorsMultiplied, sel, el, hadParentSelector = false, length, lastSelector;
  6486. function findNestedSelector(element) {
  6487. var maybeSelector;
  6488. if (!(element.value instanceof Paren)) {
  6489. return null;
  6490. }
  6491. maybeSelector = element.value.value;
  6492. if (!(maybeSelector instanceof Selector)) {
  6493. return null;
  6494. }
  6495. return maybeSelector;
  6496. }
  6497. // the elements from the current selector so far
  6498. currentElements = [];
  6499. // the current list of new selectors to add to the path.
  6500. // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
  6501. // by the parents
  6502. newSelectors = [
  6503. []
  6504. ];
  6505. for (i = 0; (el = inSelector.elements[i]); i++) {
  6506. // non parent reference elements just get added
  6507. if (el.value !== '&') {
  6508. var nestedSelector = findNestedSelector(el);
  6509. if (nestedSelector !== null) {
  6510. // merge the current list of non parent selector elements
  6511. // on to the current list of selectors to add
  6512. mergeElementsOnToSelectors(currentElements, newSelectors);
  6513. var nestedPaths = [];
  6514. var replaced = void 0;
  6515. var replacedNewSelectors = [];
  6516. replaced = replaceParentSelector(nestedPaths, context, nestedSelector);
  6517. hadParentSelector = hadParentSelector || replaced;
  6518. // the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors
  6519. for (k = 0; k < nestedPaths.length; k++) {
  6520. var replacementSelector = createSelector(createParenthesis(nestedPaths[k], el), el);
  6521. addAllReplacementsIntoPath(newSelectors, [replacementSelector], el, inSelector, replacedNewSelectors);
  6522. }
  6523. newSelectors = replacedNewSelectors;
  6524. currentElements = [];
  6525. }
  6526. else {
  6527. currentElements.push(el);
  6528. }
  6529. }
  6530. else {
  6531. hadParentSelector = true;
  6532. // the new list of selectors to add
  6533. selectorsMultiplied = [];
  6534. // merge the current list of non parent selector elements
  6535. // on to the current list of selectors to add
  6536. mergeElementsOnToSelectors(currentElements, newSelectors);
  6537. // loop through our current selectors
  6538. for (j = 0; j < newSelectors.length; j++) {
  6539. sel = newSelectors[j];
  6540. // if we don't have any parent paths, the & might be in a mixin so that it can be used
  6541. // whether there are parents or not
  6542. if (context.length === 0) {
  6543. // the combinator used on el should now be applied to the next element instead so that
  6544. // it is not lost
  6545. if (sel.length > 0) {
  6546. sel[0].elements.push(new Element(el.combinator, '', el.isVariable, el._index, el._fileInfo));
  6547. }
  6548. selectorsMultiplied.push(sel);
  6549. }
  6550. else {
  6551. // and the parent selectors
  6552. for (k = 0; k < context.length; k++) {
  6553. // We need to put the current selectors
  6554. // then join the last selector's elements on to the parents selectors
  6555. var newSelectorPath = addReplacementIntoPath(sel, context[k], el, inSelector);
  6556. // add that to our new set of selectors
  6557. selectorsMultiplied.push(newSelectorPath);
  6558. }
  6559. }
  6560. }
  6561. // our new selectors has been multiplied, so reset the state
  6562. newSelectors = selectorsMultiplied;
  6563. currentElements = [];
  6564. }
  6565. }
  6566. // if we have any elements left over (e.g. .a& .b == .b)
  6567. // add them on to all the current selectors
  6568. mergeElementsOnToSelectors(currentElements, newSelectors);
  6569. for (i = 0; i < newSelectors.length; i++) {
  6570. length = newSelectors[i].length;
  6571. if (length > 0) {
  6572. paths.push(newSelectors[i]);
  6573. lastSelector = newSelectors[i][length - 1];
  6574. newSelectors[i][length - 1] = lastSelector.createDerived(lastSelector.elements, inSelector.extendList);
  6575. }
  6576. }
  6577. return hadParentSelector;
  6578. }
  6579. function deriveSelector(visibilityInfo, deriveFrom) {
  6580. var newSelector = deriveFrom.createDerived(deriveFrom.elements, deriveFrom.extendList, deriveFrom.evaldCondition);
  6581. newSelector.copyVisibilityInfo(visibilityInfo);
  6582. return newSelector;
  6583. }
  6584. // joinSelector code follows
  6585. var i, newPaths, hadParentSelector;
  6586. newPaths = [];
  6587. hadParentSelector = replaceParentSelector(newPaths, context, selector);
  6588. if (!hadParentSelector) {
  6589. if (context.length > 0) {
  6590. newPaths = [];
  6591. for (i = 0; i < context.length; i++) {
  6592. var concatenated = context[i].map(deriveSelector.bind(this, selector.visibilityInfo()));
  6593. concatenated.push(selector);
  6594. newPaths.push(concatenated);
  6595. }
  6596. }
  6597. else {
  6598. newPaths = [[selector]];
  6599. }
  6600. }
  6601. for (i = 0; i < newPaths.length; i++) {
  6602. paths.push(newPaths[i]);
  6603. }
  6604. }
  6605. });
  6606. var AtRule = function (name, value, rules, index, currentFileInfo, debugInfo, isRooted, visibilityInfo) {
  6607. var i;
  6608. this.name = name;
  6609. this.value = (value instanceof Node) ? value : (value ? new Anonymous(value) : value);
  6610. if (rules) {
  6611. if (Array.isArray(rules)) {
  6612. this.rules = rules;
  6613. }
  6614. else {
  6615. this.rules = [rules];
  6616. this.rules[0].selectors = (new Selector([], null, null, index, currentFileInfo)).createEmptySelectors();
  6617. }
  6618. for (i = 0; i < this.rules.length; i++) {
  6619. this.rules[i].allowImports = true;
  6620. }
  6621. this.setParent(this.rules, this);
  6622. }
  6623. this._index = index;
  6624. this._fileInfo = currentFileInfo;
  6625. this.debugInfo = debugInfo;
  6626. this.isRooted = isRooted || false;
  6627. this.copyVisibilityInfo(visibilityInfo);
  6628. this.allowRoot = true;
  6629. };
  6630. AtRule.prototype = Object.assign(new Node(), {
  6631. type: 'AtRule',
  6632. accept: function (visitor) {
  6633. var value = this.value, rules = this.rules;
  6634. if (rules) {
  6635. this.rules = visitor.visitArray(rules);
  6636. }
  6637. if (value) {
  6638. this.value = visitor.visit(value);
  6639. }
  6640. },
  6641. isRulesetLike: function () {
  6642. return this.rules || !this.isCharset();
  6643. },
  6644. isCharset: function () {
  6645. return '@charset' === this.name;
  6646. },
  6647. genCSS: function (context, output) {
  6648. var value = this.value, rules = this.rules;
  6649. output.add(this.name, this.fileInfo(), this.getIndex());
  6650. if (value) {
  6651. output.add(' ');
  6652. value.genCSS(context, output);
  6653. }
  6654. if (rules) {
  6655. this.outputRuleset(context, output, rules);
  6656. }
  6657. else {
  6658. output.add(';');
  6659. }
  6660. },
  6661. eval: function (context) {
  6662. var mediaPathBackup, mediaBlocksBackup, value = this.value, rules = this.rules;
  6663. // media stored inside other atrule should not bubble over it
  6664. // backpup media bubbling information
  6665. mediaPathBackup = context.mediaPath;
  6666. mediaBlocksBackup = context.mediaBlocks;
  6667. // deleted media bubbling information
  6668. context.mediaPath = [];
  6669. context.mediaBlocks = [];
  6670. if (value) {
  6671. value = value.eval(context);
  6672. }
  6673. if (rules) {
  6674. // assuming that there is only one rule at this point - that is how parser constructs the rule
  6675. rules = [rules[0].eval(context)];
  6676. rules[0].root = true;
  6677. }
  6678. // restore media bubbling information
  6679. context.mediaPath = mediaPathBackup;
  6680. context.mediaBlocks = mediaBlocksBackup;
  6681. return new AtRule(this.name, value, rules, this.getIndex(), this.fileInfo(), this.debugInfo, this.isRooted, this.visibilityInfo());
  6682. },
  6683. variable: function (name) {
  6684. if (this.rules) {
  6685. // assuming that there is only one rule at this point - that is how parser constructs the rule
  6686. return Ruleset.prototype.variable.call(this.rules[0], name);
  6687. }
  6688. },
  6689. find: function () {
  6690. if (this.rules) {
  6691. // assuming that there is only one rule at this point - that is how parser constructs the rule
  6692. return Ruleset.prototype.find.apply(this.rules[0], arguments);
  6693. }
  6694. },
  6695. rulesets: function () {
  6696. if (this.rules) {
  6697. // assuming that there is only one rule at this point - that is how parser constructs the rule
  6698. return Ruleset.prototype.rulesets.apply(this.rules[0]);
  6699. }
  6700. },
  6701. outputRuleset: function (context, output, rules) {
  6702. var ruleCnt = rules.length;
  6703. var i;
  6704. context.tabLevel = (context.tabLevel | 0) + 1;
  6705. // Compressed
  6706. if (context.compress) {
  6707. output.add('{');
  6708. for (i = 0; i < ruleCnt; i++) {
  6709. rules[i].genCSS(context, output);
  6710. }
  6711. output.add('}');
  6712. context.tabLevel--;
  6713. return;
  6714. }
  6715. // Non-compressed
  6716. var tabSetStr = "\n".concat(Array(context.tabLevel).join(' ')), tabRuleStr = "".concat(tabSetStr, " ");
  6717. if (!ruleCnt) {
  6718. output.add(" {".concat(tabSetStr, "}"));
  6719. }
  6720. else {
  6721. output.add(" {".concat(tabRuleStr));
  6722. rules[0].genCSS(context, output);
  6723. for (i = 1; i < ruleCnt; i++) {
  6724. output.add(tabRuleStr);
  6725. rules[i].genCSS(context, output);
  6726. }
  6727. output.add("".concat(tabSetStr, "}"));
  6728. }
  6729. context.tabLevel--;
  6730. }
  6731. });
  6732. var DetachedRuleset = function (ruleset, frames) {
  6733. this.ruleset = ruleset;
  6734. this.frames = frames;
  6735. this.setParent(this.ruleset, this);
  6736. };
  6737. DetachedRuleset.prototype = Object.assign(new Node(), {
  6738. type: 'DetachedRuleset',
  6739. evalFirst: true,
  6740. accept: function (visitor) {
  6741. this.ruleset = visitor.visit(this.ruleset);
  6742. },
  6743. eval: function (context) {
  6744. var frames = this.frames || copyArray(context.frames);
  6745. return new DetachedRuleset(this.ruleset, frames);
  6746. },
  6747. callEval: function (context) {
  6748. return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context);
  6749. }
  6750. });
  6751. var Unit = function (numerator, denominator, backupUnit) {
  6752. this.numerator = numerator ? copyArray(numerator).sort() : [];
  6753. this.denominator = denominator ? copyArray(denominator).sort() : [];
  6754. if (backupUnit) {
  6755. this.backupUnit = backupUnit;
  6756. }
  6757. else if (numerator && numerator.length) {
  6758. this.backupUnit = numerator[0];
  6759. }
  6760. };
  6761. Unit.prototype = Object.assign(new Node(), {
  6762. type: 'Unit',
  6763. clone: function () {
  6764. return new Unit(copyArray(this.numerator), copyArray(this.denominator), this.backupUnit);
  6765. },
  6766. genCSS: function (context, output) {
  6767. // Dimension checks the unit is singular and throws an error if in strict math mode.
  6768. var strictUnits = context && context.strictUnits;
  6769. if (this.numerator.length === 1) {
  6770. output.add(this.numerator[0]); // the ideal situation
  6771. }
  6772. else if (!strictUnits && this.backupUnit) {
  6773. output.add(this.backupUnit);
  6774. }
  6775. else if (!strictUnits && this.denominator.length) {
  6776. output.add(this.denominator[0]);
  6777. }
  6778. },
  6779. toString: function () {
  6780. var i, returnStr = this.numerator.join('*');
  6781. for (i = 0; i < this.denominator.length; i++) {
  6782. returnStr += "/".concat(this.denominator[i]);
  6783. }
  6784. return returnStr;
  6785. },
  6786. compare: function (other) {
  6787. return this.is(other.toString()) ? 0 : undefined;
  6788. },
  6789. is: function (unitString) {
  6790. return this.toString().toUpperCase() === unitString.toUpperCase();
  6791. },
  6792. isLength: function () {
  6793. return RegExp('^(px|em|ex|ch|rem|in|cm|mm|pc|pt|ex|vw|vh|vmin|vmax)$', 'gi').test(this.toCSS());
  6794. },
  6795. isEmpty: function () {
  6796. return this.numerator.length === 0 && this.denominator.length === 0;
  6797. },
  6798. isSingular: function () {
  6799. return this.numerator.length <= 1 && this.denominator.length === 0;
  6800. },
  6801. map: function (callback) {
  6802. var i;
  6803. for (i = 0; i < this.numerator.length; i++) {
  6804. this.numerator[i] = callback(this.numerator[i], false);
  6805. }
  6806. for (i = 0; i < this.denominator.length; i++) {
  6807. this.denominator[i] = callback(this.denominator[i], true);
  6808. }
  6809. },
  6810. usedUnits: function () {
  6811. var group;
  6812. var result = {};
  6813. var mapUnit;
  6814. var groupName;
  6815. mapUnit = function (atomicUnit) {
  6816. // eslint-disable-next-line no-prototype-builtins
  6817. if (group.hasOwnProperty(atomicUnit) && !result[groupName]) {
  6818. result[groupName] = atomicUnit;
  6819. }
  6820. return atomicUnit;
  6821. };
  6822. for (groupName in unitConversions) {
  6823. // eslint-disable-next-line no-prototype-builtins
  6824. if (unitConversions.hasOwnProperty(groupName)) {
  6825. group = unitConversions[groupName];
  6826. this.map(mapUnit);
  6827. }
  6828. }
  6829. return result;
  6830. },
  6831. cancel: function () {
  6832. var counter = {};
  6833. var atomicUnit;
  6834. var i;
  6835. for (i = 0; i < this.numerator.length; i++) {
  6836. atomicUnit = this.numerator[i];
  6837. counter[atomicUnit] = (counter[atomicUnit] || 0) + 1;
  6838. }
  6839. for (i = 0; i < this.denominator.length; i++) {
  6840. atomicUnit = this.denominator[i];
  6841. counter[atomicUnit] = (counter[atomicUnit] || 0) - 1;
  6842. }
  6843. this.numerator = [];
  6844. this.denominator = [];
  6845. for (atomicUnit in counter) {
  6846. // eslint-disable-next-line no-prototype-builtins
  6847. if (counter.hasOwnProperty(atomicUnit)) {
  6848. var count = counter[atomicUnit];
  6849. if (count > 0) {
  6850. for (i = 0; i < count; i++) {
  6851. this.numerator.push(atomicUnit);
  6852. }
  6853. }
  6854. else if (count < 0) {
  6855. for (i = 0; i < -count; i++) {
  6856. this.denominator.push(atomicUnit);
  6857. }
  6858. }
  6859. }
  6860. }
  6861. this.numerator.sort();
  6862. this.denominator.sort();
  6863. }
  6864. });
  6865. /* eslint-disable no-prototype-builtins */
  6866. //
  6867. // A number with a unit
  6868. //
  6869. var Dimension = function (value, unit) {
  6870. this.value = parseFloat(value);
  6871. if (isNaN(this.value)) {
  6872. throw new Error('Dimension is not a number.');
  6873. }
  6874. this.unit = (unit && unit instanceof Unit) ? unit :
  6875. new Unit(unit ? [unit] : undefined);
  6876. this.setParent(this.unit, this);
  6877. };
  6878. Dimension.prototype = Object.assign(new Node(), {
  6879. type: 'Dimension',
  6880. accept: function (visitor) {
  6881. this.unit = visitor.visit(this.unit);
  6882. },
  6883. // remove when Nodes have JSDoc types
  6884. // eslint-disable-next-line no-unused-vars
  6885. eval: function (context) {
  6886. return this;
  6887. },
  6888. toColor: function () {
  6889. return new Color([this.value, this.value, this.value]);
  6890. },
  6891. genCSS: function (context, output) {
  6892. if ((context && context.strictUnits) && !this.unit.isSingular()) {
  6893. throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: ".concat(this.unit.toString()));
  6894. }
  6895. var value = this.fround(context, this.value);
  6896. var strValue = String(value);
  6897. if (value !== 0 && value < 0.000001 && value > -0.000001) {
  6898. // would be output 1e-6 etc.
  6899. strValue = value.toFixed(20).replace(/0+$/, '');
  6900. }
  6901. if (context && context.compress) {
  6902. // Zero values doesn't need a unit
  6903. if (value === 0 && this.unit.isLength()) {
  6904. output.add(strValue);
  6905. return;
  6906. }
  6907. // Float values doesn't need a leading zero
  6908. if (value > 0 && value < 1) {
  6909. strValue = (strValue).substr(1);
  6910. }
  6911. }
  6912. output.add(strValue);
  6913. this.unit.genCSS(context, output);
  6914. },
  6915. // In an operation between two Dimensions,
  6916. // we default to the first Dimension's unit,
  6917. // so `1px + 2` will yield `3px`.
  6918. operate: function (context, op, other) {
  6919. /* jshint noempty:false */
  6920. var value = this._operate(context, op, this.value, other.value);
  6921. var unit = this.unit.clone();
  6922. if (op === '+' || op === '-') {
  6923. if (unit.numerator.length === 0 && unit.denominator.length === 0) {
  6924. unit = other.unit.clone();
  6925. if (this.unit.backupUnit) {
  6926. unit.backupUnit = this.unit.backupUnit;
  6927. }
  6928. }
  6929. else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) ;
  6930. else {
  6931. other = other.convertTo(this.unit.usedUnits());
  6932. if (context.strictUnits && other.unit.toString() !== unit.toString()) {
  6933. throw new Error('Incompatible units. Change the units or use the unit function. '
  6934. + "Bad units: '".concat(unit.toString(), "' and '").concat(other.unit.toString(), "'."));
  6935. }
  6936. value = this._operate(context, op, this.value, other.value);
  6937. }
  6938. }
  6939. else if (op === '*') {
  6940. unit.numerator = unit.numerator.concat(other.unit.numerator).sort();
  6941. unit.denominator = unit.denominator.concat(other.unit.denominator).sort();
  6942. unit.cancel();
  6943. }
  6944. else if (op === '/') {
  6945. unit.numerator = unit.numerator.concat(other.unit.denominator).sort();
  6946. unit.denominator = unit.denominator.concat(other.unit.numerator).sort();
  6947. unit.cancel();
  6948. }
  6949. return new Dimension(value, unit);
  6950. },
  6951. compare: function (other) {
  6952. var a, b;
  6953. if (!(other instanceof Dimension)) {
  6954. return undefined;
  6955. }
  6956. if (this.unit.isEmpty() || other.unit.isEmpty()) {
  6957. a = this;
  6958. b = other;
  6959. }
  6960. else {
  6961. a = this.unify();
  6962. b = other.unify();
  6963. if (a.unit.compare(b.unit) !== 0) {
  6964. return undefined;
  6965. }
  6966. }
  6967. return Node.numericCompare(a.value, b.value);
  6968. },
  6969. unify: function () {
  6970. return this.convertTo({ length: 'px', duration: 's', angle: 'rad' });
  6971. },
  6972. convertTo: function (conversions) {
  6973. var value = this.value;
  6974. var unit = this.unit.clone();
  6975. var i;
  6976. var groupName;
  6977. var group;
  6978. var targetUnit;
  6979. var derivedConversions = {};
  6980. var applyUnit;
  6981. if (typeof conversions === 'string') {
  6982. for (i in unitConversions) {
  6983. if (unitConversions[i].hasOwnProperty(conversions)) {
  6984. derivedConversions = {};
  6985. derivedConversions[i] = conversions;
  6986. }
  6987. }
  6988. conversions = derivedConversions;
  6989. }
  6990. applyUnit = function (atomicUnit, denominator) {
  6991. if (group.hasOwnProperty(atomicUnit)) {
  6992. if (denominator) {
  6993. value = value / (group[atomicUnit] / group[targetUnit]);
  6994. }
  6995. else {
  6996. value = value * (group[atomicUnit] / group[targetUnit]);
  6997. }
  6998. return targetUnit;
  6999. }
  7000. return atomicUnit;
  7001. };
  7002. for (groupName in conversions) {
  7003. if (conversions.hasOwnProperty(groupName)) {
  7004. targetUnit = conversions[groupName];
  7005. group = unitConversions[groupName];
  7006. unit.map(applyUnit);
  7007. }
  7008. }
  7009. unit.cancel();
  7010. return new Dimension(value, unit);
  7011. }
  7012. });
  7013. var MATH = Math$1;
  7014. var Operation = function (op, operands, isSpaced) {
  7015. this.op = op.trim();
  7016. this.operands = operands;
  7017. this.isSpaced = isSpaced;
  7018. };
  7019. Operation.prototype = Object.assign(new Node(), {
  7020. type: 'Operation',
  7021. accept: function (visitor) {
  7022. this.operands = visitor.visitArray(this.operands);
  7023. },
  7024. eval: function (context) {
  7025. var a = this.operands[0].eval(context), b = this.operands[1].eval(context), op;
  7026. if (context.isMathOn(this.op)) {
  7027. op = this.op === './' ? '/' : this.op;
  7028. if (a instanceof Dimension && b instanceof Color) {
  7029. a = a.toColor();
  7030. }
  7031. if (b instanceof Dimension && a instanceof Color) {
  7032. b = b.toColor();
  7033. }
  7034. if (!a.operate || !b.operate) {
  7035. if ((a instanceof Operation || b instanceof Operation)
  7036. && a.op === '/' && context.math === MATH.PARENS_DIVISION) {
  7037. return new Operation(this.op, [a, b], this.isSpaced);
  7038. }
  7039. throw { type: 'Operation',
  7040. message: 'Operation on an invalid type' };
  7041. }
  7042. return a.operate(context, op, b);
  7043. }
  7044. else {
  7045. return new Operation(this.op, [a, b], this.isSpaced);
  7046. }
  7047. },
  7048. genCSS: function (context, output) {
  7049. this.operands[0].genCSS(context, output);
  7050. if (this.isSpaced) {
  7051. output.add(' ');
  7052. }
  7053. output.add(this.op);
  7054. if (this.isSpaced) {
  7055. output.add(' ');
  7056. }
  7057. this.operands[1].genCSS(context, output);
  7058. }
  7059. });
  7060. var Expression = function (value, noSpacing) {
  7061. this.value = value;
  7062. this.noSpacing = noSpacing;
  7063. if (!value) {
  7064. throw new Error('Expression requires an array parameter');
  7065. }
  7066. };
  7067. Expression.prototype = Object.assign(new Node(), {
  7068. type: 'Expression',
  7069. accept: function (visitor) {
  7070. this.value = visitor.visitArray(this.value);
  7071. },
  7072. eval: function (context) {
  7073. var returnValue;
  7074. var mathOn = context.isMathOn();
  7075. var inParenthesis = this.parens;
  7076. var doubleParen = false;
  7077. if (inParenthesis) {
  7078. context.inParenthesis();
  7079. }
  7080. if (this.value.length > 1) {
  7081. returnValue = new Expression(this.value.map(function (e) {
  7082. if (!e.eval) {
  7083. return e;
  7084. }
  7085. return e.eval(context);
  7086. }), this.noSpacing);
  7087. }
  7088. else if (this.value.length === 1) {
  7089. if (this.value[0].parens && !this.value[0].parensInOp && !context.inCalc) {
  7090. doubleParen = true;
  7091. }
  7092. returnValue = this.value[0].eval(context);
  7093. }
  7094. else {
  7095. returnValue = this;
  7096. }
  7097. if (inParenthesis) {
  7098. context.outOfParenthesis();
  7099. }
  7100. if (this.parens && this.parensInOp && !mathOn && !doubleParen
  7101. && (!(returnValue instanceof Dimension))) {
  7102. returnValue = new Paren(returnValue);
  7103. }
  7104. return returnValue;
  7105. },
  7106. genCSS: function (context, output) {
  7107. for (var i_1 = 0; i_1 < this.value.length; i_1++) {
  7108. this.value[i_1].genCSS(context, output);
  7109. if (!this.noSpacing && i_1 + 1 < this.value.length) {
  7110. if (i_1 + 1 < this.value.length && !(this.value[i_1 + 1] instanceof Anonymous) ||
  7111. this.value[i_1 + 1] instanceof Anonymous && this.value[i_1 + 1].value !== ',') {
  7112. output.add(' ');
  7113. }
  7114. }
  7115. }
  7116. },
  7117. throwAwayComments: function () {
  7118. this.value = this.value.filter(function (v) {
  7119. return !(v instanceof Comment);
  7120. });
  7121. }
  7122. });
  7123. var functionCaller = /** @class */ (function () {
  7124. function functionCaller(name, context, index, currentFileInfo) {
  7125. this.name = name.toLowerCase();
  7126. this.index = index;
  7127. this.context = context;
  7128. this.currentFileInfo = currentFileInfo;
  7129. this.func = context.frames[0].functionRegistry.get(this.name);
  7130. }
  7131. functionCaller.prototype.isValid = function () {
  7132. return Boolean(this.func);
  7133. };
  7134. functionCaller.prototype.call = function (args) {
  7135. var _this = this;
  7136. if (!(Array.isArray(args))) {
  7137. args = [args];
  7138. }
  7139. var evalArgs = this.func.evalArgs;
  7140. if (evalArgs !== false) {
  7141. args = args.map(function (a) { return a.eval(_this.context); });
  7142. }
  7143. var commentFilter = function (item) { return !(item.type === 'Comment'); };
  7144. // This code is terrible and should be replaced as per this issue...
  7145. // https://github.com/less/less.js/issues/2477
  7146. args = args
  7147. .filter(commentFilter)
  7148. .map(function (item) {
  7149. if (item.type === 'Expression') {
  7150. var subNodes = item.value.filter(commentFilter);
  7151. if (subNodes.length === 1) {
  7152. // https://github.com/less/less.js/issues/3616
  7153. if (item.parens && subNodes[0].op === '/') {
  7154. return item;
  7155. }
  7156. return subNodes[0];
  7157. }
  7158. else {
  7159. return new Expression(subNodes);
  7160. }
  7161. }
  7162. return item;
  7163. });
  7164. if (evalArgs === false) {
  7165. return this.func.apply(this, __spreadArray([this.context], args, false));
  7166. }
  7167. return this.func.apply(this, args);
  7168. };
  7169. return functionCaller;
  7170. }());
  7171. //
  7172. // A function call node.
  7173. //
  7174. var Call = function (name, args, index, currentFileInfo) {
  7175. this.name = name;
  7176. this.args = args;
  7177. this.calc = name === 'calc';
  7178. this._index = index;
  7179. this._fileInfo = currentFileInfo;
  7180. };
  7181. Call.prototype = Object.assign(new Node(), {
  7182. type: 'Call',
  7183. accept: function (visitor) {
  7184. if (this.args) {
  7185. this.args = visitor.visitArray(this.args);
  7186. }
  7187. },
  7188. //
  7189. // When evaluating a function call,
  7190. // we either find the function in the functionRegistry,
  7191. // in which case we call it, passing the evaluated arguments,
  7192. // if this returns null or we cannot find the function, we
  7193. // simply print it out as it appeared originally [2].
  7194. //
  7195. // The reason why we evaluate the arguments, is in the case where
  7196. // we try to pass a variable to a function, like: `saturate(@color)`.
  7197. // The function should receive the value, not the variable.
  7198. //
  7199. eval: function (context) {
  7200. var _this = this;
  7201. /**
  7202. * Turn off math for calc(), and switch back on for evaluating nested functions
  7203. */
  7204. var currentMathContext = context.mathOn;
  7205. context.mathOn = !this.calc;
  7206. if (this.calc || context.inCalc) {
  7207. context.enterCalc();
  7208. }
  7209. var exitCalc = function () {
  7210. if (_this.calc || context.inCalc) {
  7211. context.exitCalc();
  7212. }
  7213. context.mathOn = currentMathContext;
  7214. };
  7215. var result;
  7216. var funcCaller = new functionCaller(this.name, context, this.getIndex(), this.fileInfo());
  7217. if (funcCaller.isValid()) {
  7218. try {
  7219. result = funcCaller.call(this.args);
  7220. exitCalc();
  7221. }
  7222. catch (e) {
  7223. // eslint-disable-next-line no-prototype-builtins
  7224. if (e.hasOwnProperty('line') && e.hasOwnProperty('column')) {
  7225. throw e;
  7226. }
  7227. throw {
  7228. type: e.type || 'Runtime',
  7229. message: "Error evaluating function `".concat(this.name, "`").concat(e.message ? ": ".concat(e.message) : ''),
  7230. index: this.getIndex(),
  7231. filename: this.fileInfo().filename,
  7232. line: e.lineNumber,
  7233. column: e.columnNumber
  7234. };
  7235. }
  7236. }
  7237. if (result !== null && result !== undefined) {
  7238. // Results that that are not nodes are cast as Anonymous nodes
  7239. // Falsy values or booleans are returned as empty nodes
  7240. if (!(result instanceof Node)) {
  7241. if (!result || result === true) {
  7242. result = new Anonymous(null);
  7243. }
  7244. else {
  7245. result = new Anonymous(result.toString());
  7246. }
  7247. }
  7248. result._index = this._index;
  7249. result._fileInfo = this._fileInfo;
  7250. return result;
  7251. }
  7252. var args = this.args.map(function (a) { return a.eval(context); });
  7253. exitCalc();
  7254. return new Call(this.name, args, this.getIndex(), this.fileInfo());
  7255. },
  7256. genCSS: function (context, output) {
  7257. output.add("".concat(this.name, "("), this.fileInfo(), this.getIndex());
  7258. for (var i_1 = 0; i_1 < this.args.length; i_1++) {
  7259. this.args[i_1].genCSS(context, output);
  7260. if (i_1 + 1 < this.args.length) {
  7261. output.add(', ');
  7262. }
  7263. }
  7264. output.add(')');
  7265. }
  7266. });
  7267. var Variable = function (name, index, currentFileInfo) {
  7268. this.name = name;
  7269. this._index = index;
  7270. this._fileInfo = currentFileInfo;
  7271. };
  7272. Variable.prototype = Object.assign(new Node(), {
  7273. type: 'Variable',
  7274. eval: function (context) {
  7275. var variable, name = this.name;
  7276. if (name.indexOf('@@') === 0) {
  7277. name = "@".concat(new Variable(name.slice(1), this.getIndex(), this.fileInfo()).eval(context).value);
  7278. }
  7279. if (this.evaluating) {
  7280. throw { type: 'Name',
  7281. message: "Recursive variable definition for ".concat(name),
  7282. filename: this.fileInfo().filename,
  7283. index: this.getIndex() };
  7284. }
  7285. this.evaluating = true;
  7286. variable = this.find(context.frames, function (frame) {
  7287. var v = frame.variable(name);
  7288. if (v) {
  7289. if (v.important) {
  7290. var importantScope = context.importantScope[context.importantScope.length - 1];
  7291. importantScope.important = v.important;
  7292. }
  7293. // If in calc, wrap vars in a function call to cascade evaluate args first
  7294. if (context.inCalc) {
  7295. return (new Call('_SELF', [v.value])).eval(context);
  7296. }
  7297. else {
  7298. return v.value.eval(context);
  7299. }
  7300. }
  7301. });
  7302. if (variable) {
  7303. this.evaluating = false;
  7304. return variable;
  7305. }
  7306. else {
  7307. throw { type: 'Name',
  7308. message: "variable ".concat(name, " is undefined"),
  7309. filename: this.fileInfo().filename,
  7310. index: this.getIndex() };
  7311. }
  7312. },
  7313. find: function (obj, fun) {
  7314. for (var i_1 = 0, r = void 0; i_1 < obj.length; i_1++) {
  7315. r = fun.call(obj, obj[i_1]);
  7316. if (r) {
  7317. return r;
  7318. }
  7319. }
  7320. return null;
  7321. }
  7322. });
  7323. var Property = function (name, index, currentFileInfo) {
  7324. this.name = name;
  7325. this._index = index;
  7326. this._fileInfo = currentFileInfo;
  7327. };
  7328. Property.prototype = Object.assign(new Node(), {
  7329. type: 'Property',
  7330. eval: function (context) {
  7331. var property;
  7332. var name = this.name;
  7333. // TODO: shorten this reference
  7334. var mergeRules = context.pluginManager.less.visitors.ToCSSVisitor.prototype._mergeRules;
  7335. if (this.evaluating) {
  7336. throw { type: 'Name',
  7337. message: "Recursive property reference for ".concat(name),
  7338. filename: this.fileInfo().filename,
  7339. index: this.getIndex() };
  7340. }
  7341. this.evaluating = true;
  7342. property = this.find(context.frames, function (frame) {
  7343. var v;
  7344. var vArr = frame.property(name);
  7345. if (vArr) {
  7346. for (var i_1 = 0; i_1 < vArr.length; i_1++) {
  7347. v = vArr[i_1];
  7348. vArr[i_1] = new Declaration(v.name, v.value, v.important, v.merge, v.index, v.currentFileInfo, v.inline, v.variable);
  7349. }
  7350. mergeRules(vArr);
  7351. v = vArr[vArr.length - 1];
  7352. if (v.important) {
  7353. var importantScope = context.importantScope[context.importantScope.length - 1];
  7354. importantScope.important = v.important;
  7355. }
  7356. v = v.value.eval(context);
  7357. return v;
  7358. }
  7359. });
  7360. if (property) {
  7361. this.evaluating = false;
  7362. return property;
  7363. }
  7364. else {
  7365. throw { type: 'Name',
  7366. message: "Property '".concat(name, "' is undefined"),
  7367. filename: this.currentFileInfo.filename,
  7368. index: this.index };
  7369. }
  7370. },
  7371. find: function (obj, fun) {
  7372. for (var i_2 = 0, r = void 0; i_2 < obj.length; i_2++) {
  7373. r = fun.call(obj, obj[i_2]);
  7374. if (r) {
  7375. return r;
  7376. }
  7377. }
  7378. return null;
  7379. }
  7380. });
  7381. var Attribute = function (key, op, value, cif) {
  7382. this.key = key;
  7383. this.op = op;
  7384. this.value = value;
  7385. this.cif = cif;
  7386. };
  7387. Attribute.prototype = Object.assign(new Node(), {
  7388. type: 'Attribute',
  7389. eval: function (context) {
  7390. return new Attribute(this.key.eval ? this.key.eval(context) : this.key, this.op, (this.value && this.value.eval) ? this.value.eval(context) : this.value, this.cif);
  7391. },
  7392. genCSS: function (context, output) {
  7393. output.add(this.toCSS(context));
  7394. },
  7395. toCSS: function (context) {
  7396. var value = this.key.toCSS ? this.key.toCSS(context) : this.key;
  7397. if (this.op) {
  7398. value += this.op;
  7399. value += (this.value.toCSS ? this.value.toCSS(context) : this.value);
  7400. }
  7401. if (this.cif) {
  7402. value = value + ' ' + this.cif;
  7403. }
  7404. return "[".concat(value, "]");
  7405. }
  7406. });
  7407. var Quoted = function (str, content, escaped, index, currentFileInfo) {
  7408. this.escaped = (escaped === undefined) ? true : escaped;
  7409. this.value = content || '';
  7410. this.quote = str.charAt(0);
  7411. this._index = index;
  7412. this._fileInfo = currentFileInfo;
  7413. this.variableRegex = /@\{([\w-]+)\}/g;
  7414. this.propRegex = /\$\{([\w-]+)\}/g;
  7415. this.allowRoot = escaped;
  7416. };
  7417. Quoted.prototype = Object.assign(new Node(), {
  7418. type: 'Quoted',
  7419. genCSS: function (context, output) {
  7420. if (!this.escaped) {
  7421. output.add(this.quote, this.fileInfo(), this.getIndex());
  7422. }
  7423. output.add(this.value);
  7424. if (!this.escaped) {
  7425. output.add(this.quote);
  7426. }
  7427. },
  7428. containsVariables: function () {
  7429. return this.value.match(this.variableRegex);
  7430. },
  7431. eval: function (context) {
  7432. var that = this;
  7433. var value = this.value;
  7434. var variableReplacement = function (_, name) {
  7435. var v = new Variable("@".concat(name), that.getIndex(), that.fileInfo()).eval(context, true);
  7436. return (v instanceof Quoted) ? v.value : v.toCSS();
  7437. };
  7438. var propertyReplacement = function (_, name) {
  7439. var v = new Property("$".concat(name), that.getIndex(), that.fileInfo()).eval(context, true);
  7440. return (v instanceof Quoted) ? v.value : v.toCSS();
  7441. };
  7442. function iterativeReplace(value, regexp, replacementFnc) {
  7443. var evaluatedValue = value;
  7444. do {
  7445. value = evaluatedValue.toString();
  7446. evaluatedValue = value.replace(regexp, replacementFnc);
  7447. } while (value !== evaluatedValue);
  7448. return evaluatedValue;
  7449. }
  7450. value = iterativeReplace(value, this.variableRegex, variableReplacement);
  7451. value = iterativeReplace(value, this.propRegex, propertyReplacement);
  7452. return new Quoted(this.quote + value + this.quote, value, this.escaped, this.getIndex(), this.fileInfo());
  7453. },
  7454. compare: function (other) {
  7455. // when comparing quoted strings allow the quote to differ
  7456. if (other.type === 'Quoted' && !this.escaped && !other.escaped) {
  7457. return Node.numericCompare(this.value, other.value);
  7458. }
  7459. else {
  7460. return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;
  7461. }
  7462. }
  7463. });
  7464. function escapePath(path) {
  7465. return path.replace(/[()'"\s]/g, function (match) { return "\\".concat(match); });
  7466. }
  7467. var URL = function (val, index, currentFileInfo, isEvald) {
  7468. this.value = val;
  7469. this._index = index;
  7470. this._fileInfo = currentFileInfo;
  7471. this.isEvald = isEvald;
  7472. };
  7473. URL.prototype = Object.assign(new Node(), {
  7474. type: 'Url',
  7475. accept: function (visitor) {
  7476. this.value = visitor.visit(this.value);
  7477. },
  7478. genCSS: function (context, output) {
  7479. output.add('url(');
  7480. this.value.genCSS(context, output);
  7481. output.add(')');
  7482. },
  7483. eval: function (context) {
  7484. var val = this.value.eval(context);
  7485. var rootpath;
  7486. if (!this.isEvald) {
  7487. // Add the rootpath if the URL requires a rewrite
  7488. rootpath = this.fileInfo() && this.fileInfo().rootpath;
  7489. if (typeof rootpath === 'string' &&
  7490. typeof val.value === 'string' &&
  7491. context.pathRequiresRewrite(val.value)) {
  7492. if (!val.quote) {
  7493. rootpath = escapePath(rootpath);
  7494. }
  7495. val.value = context.rewritePath(val.value, rootpath);
  7496. }
  7497. else {
  7498. val.value = context.normalizePath(val.value);
  7499. }
  7500. // Add url args if enabled
  7501. if (context.urlArgs) {
  7502. if (!val.value.match(/^\s*data:/)) {
  7503. var delimiter = val.value.indexOf('?') === -1 ? '?' : '&';
  7504. var urlArgs = delimiter + context.urlArgs;
  7505. if (val.value.indexOf('#') !== -1) {
  7506. val.value = val.value.replace('#', "".concat(urlArgs, "#"));
  7507. }
  7508. else {
  7509. val.value += urlArgs;
  7510. }
  7511. }
  7512. }
  7513. }
  7514. return new URL(val, this.getIndex(), this.fileInfo(), true);
  7515. }
  7516. });
  7517. var NestableAtRulePrototype = {
  7518. isRulesetLike: function () {
  7519. return true;
  7520. },
  7521. accept: function (visitor) {
  7522. if (this.features) {
  7523. this.features = visitor.visit(this.features);
  7524. }
  7525. if (this.rules) {
  7526. this.rules = visitor.visitArray(this.rules);
  7527. }
  7528. },
  7529. evalTop: function (context) {
  7530. var result = this;
  7531. // Render all dependent Media blocks.
  7532. if (context.mediaBlocks.length > 1) {
  7533. var selectors = (new Selector([], null, null, this.getIndex(), this.fileInfo())).createEmptySelectors();
  7534. result = new Ruleset(selectors, context.mediaBlocks);
  7535. result.multiMedia = true;
  7536. result.copyVisibilityInfo(this.visibilityInfo());
  7537. this.setParent(result, this);
  7538. }
  7539. delete context.mediaBlocks;
  7540. delete context.mediaPath;
  7541. return result;
  7542. },
  7543. evalNested: function (context) {
  7544. var i;
  7545. var value;
  7546. var path = context.mediaPath.concat([this]);
  7547. // Extract the media-query conditions separated with `,` (OR).
  7548. for (i = 0; i < path.length; i++) {
  7549. if (path[i].type !== this.type) {
  7550. context.mediaBlocks.splice(i, 1);
  7551. return this;
  7552. }
  7553. value = path[i].features instanceof Value ?
  7554. path[i].features.value : path[i].features;
  7555. path[i] = Array.isArray(value) ? value : [value];
  7556. }
  7557. // Trace all permutations to generate the resulting media-query.
  7558. //
  7559. // (a, b and c) with nested (d, e) ->
  7560. // a and d
  7561. // a and e
  7562. // b and c and d
  7563. // b and c and e
  7564. this.features = new Value(this.permute(path).map(function (path) {
  7565. path = path.map(function (fragment) { return fragment.toCSS ? fragment : new Anonymous(fragment); });
  7566. for (i = path.length - 1; i > 0; i--) {
  7567. path.splice(i, 0, new Anonymous('and'));
  7568. }
  7569. return new Expression(path);
  7570. }));
  7571. this.setParent(this.features, this);
  7572. // Fake a tree-node that doesn't output anything.
  7573. return new Ruleset([], []);
  7574. },
  7575. permute: function (arr) {
  7576. if (arr.length === 0) {
  7577. return [];
  7578. }
  7579. else if (arr.length === 1) {
  7580. return arr[0];
  7581. }
  7582. else {
  7583. var result = [];
  7584. var rest = this.permute(arr.slice(1));
  7585. for (var i_1 = 0; i_1 < rest.length; i_1++) {
  7586. for (var j = 0; j < arr[0].length; j++) {
  7587. result.push([arr[0][j]].concat(rest[i_1]));
  7588. }
  7589. }
  7590. return result;
  7591. }
  7592. },
  7593. bubbleSelectors: function (selectors) {
  7594. if (!selectors) {
  7595. return;
  7596. }
  7597. this.rules = [new Ruleset(copyArray(selectors), [this.rules[0]])];
  7598. this.setParent(this.rules, this);
  7599. }
  7600. };
  7601. var Media = function (value, features, index, currentFileInfo, visibilityInfo) {
  7602. this._index = index;
  7603. this._fileInfo = currentFileInfo;
  7604. var selectors = (new Selector([], null, null, this._index, this._fileInfo)).createEmptySelectors();
  7605. this.features = new Value(features);
  7606. this.rules = [new Ruleset(selectors, value)];
  7607. this.rules[0].allowImports = true;
  7608. this.copyVisibilityInfo(visibilityInfo);
  7609. this.allowRoot = true;
  7610. this.setParent(selectors, this);
  7611. this.setParent(this.features, this);
  7612. this.setParent(this.rules, this);
  7613. };
  7614. Media.prototype = Object.assign(new AtRule(), __assign(__assign({ type: 'Media' }, NestableAtRulePrototype), { genCSS: function (context, output) {
  7615. output.add('@media ', this._fileInfo, this._index);
  7616. this.features.genCSS(context, output);
  7617. this.outputRuleset(context, output, this.rules);
  7618. }, eval: function (context) {
  7619. if (!context.mediaBlocks) {
  7620. context.mediaBlocks = [];
  7621. context.mediaPath = [];
  7622. }
  7623. var media = new Media(null, [], this._index, this._fileInfo, this.visibilityInfo());
  7624. if (this.debugInfo) {
  7625. this.rules[0].debugInfo = this.debugInfo;
  7626. media.debugInfo = this.debugInfo;
  7627. }
  7628. media.features = this.features.eval(context);
  7629. context.mediaPath.push(media);
  7630. context.mediaBlocks.push(media);
  7631. this.rules[0].functionRegistry = context.frames[0].functionRegistry.inherit();
  7632. context.frames.unshift(this.rules[0]);
  7633. media.rules = [this.rules[0].eval(context)];
  7634. context.frames.shift();
  7635. context.mediaPath.pop();
  7636. return context.mediaPath.length === 0 ? media.evalTop(context) :
  7637. media.evalNested(context);
  7638. } }));
  7639. //
  7640. // CSS @import node
  7641. //
  7642. // The general strategy here is that we don't want to wait
  7643. // for the parsing to be completed, before we start importing
  7644. // the file. That's because in the context of a browser,
  7645. // most of the time will be spent waiting for the server to respond.
  7646. //
  7647. // On creation, we push the import path to our import queue, though
  7648. // `import,push`, we also pass it a callback, which it'll call once
  7649. // the file has been fetched, and parsed.
  7650. //
  7651. var Import = function (path, features, options, index, currentFileInfo, visibilityInfo) {
  7652. this.options = options;
  7653. this._index = index;
  7654. this._fileInfo = currentFileInfo;
  7655. this.path = path;
  7656. this.features = features;
  7657. this.allowRoot = true;
  7658. if (this.options.less !== undefined || this.options.inline) {
  7659. this.css = !this.options.less || this.options.inline;
  7660. }
  7661. else {
  7662. var pathValue = this.getPath();
  7663. if (pathValue && /[#.&?]css([?;].*)?$/.test(pathValue)) {
  7664. this.css = true;
  7665. }
  7666. }
  7667. this.copyVisibilityInfo(visibilityInfo);
  7668. this.setParent(this.features, this);
  7669. this.setParent(this.path, this);
  7670. };
  7671. Import.prototype = Object.assign(new Node(), {
  7672. type: 'Import',
  7673. accept: function (visitor) {
  7674. if (this.features) {
  7675. this.features = visitor.visit(this.features);
  7676. }
  7677. this.path = visitor.visit(this.path);
  7678. if (!this.options.isPlugin && !this.options.inline && this.root) {
  7679. this.root = visitor.visit(this.root);
  7680. }
  7681. },
  7682. genCSS: function (context, output) {
  7683. if (this.css && this.path._fileInfo.reference === undefined) {
  7684. output.add('@import ', this._fileInfo, this._index);
  7685. this.path.genCSS(context, output);
  7686. if (this.features) {
  7687. output.add(' ');
  7688. this.features.genCSS(context, output);
  7689. }
  7690. output.add(';');
  7691. }
  7692. },
  7693. getPath: function () {
  7694. return (this.path instanceof URL) ?
  7695. this.path.value.value : this.path.value;
  7696. },
  7697. isVariableImport: function () {
  7698. var path = this.path;
  7699. if (path instanceof URL) {
  7700. path = path.value;
  7701. }
  7702. if (path instanceof Quoted) {
  7703. return path.containsVariables();
  7704. }
  7705. return true;
  7706. },
  7707. evalForImport: function (context) {
  7708. var path = this.path;
  7709. if (path instanceof URL) {
  7710. path = path.value;
  7711. }
  7712. return new Import(path.eval(context), this.features, this.options, this._index, this._fileInfo, this.visibilityInfo());
  7713. },
  7714. evalPath: function (context) {
  7715. var path = this.path.eval(context);
  7716. var fileInfo = this._fileInfo;
  7717. if (!(path instanceof URL)) {
  7718. // Add the rootpath if the URL requires a rewrite
  7719. var pathValue = path.value;
  7720. if (fileInfo &&
  7721. pathValue &&
  7722. context.pathRequiresRewrite(pathValue)) {
  7723. path.value = context.rewritePath(pathValue, fileInfo.rootpath);
  7724. }
  7725. else {
  7726. path.value = context.normalizePath(path.value);
  7727. }
  7728. }
  7729. return path;
  7730. },
  7731. eval: function (context) {
  7732. var result = this.doEval(context);
  7733. if (this.options.reference || this.blocksVisibility()) {
  7734. if (result.length || result.length === 0) {
  7735. result.forEach(function (node) {
  7736. node.addVisibilityBlock();
  7737. });
  7738. }
  7739. else {
  7740. result.addVisibilityBlock();
  7741. }
  7742. }
  7743. return result;
  7744. },
  7745. doEval: function (context) {
  7746. var ruleset;
  7747. var registry;
  7748. var features = this.features && this.features.eval(context);
  7749. if (this.options.isPlugin) {
  7750. if (this.root && this.root.eval) {
  7751. try {
  7752. this.root.eval(context);
  7753. }
  7754. catch (e) {
  7755. e.message = 'Plugin error during evaluation';
  7756. throw new LessError(e, this.root.imports, this.root.filename);
  7757. }
  7758. }
  7759. registry = context.frames[0] && context.frames[0].functionRegistry;
  7760. if (registry && this.root && this.root.functions) {
  7761. registry.addMultiple(this.root.functions);
  7762. }
  7763. return [];
  7764. }
  7765. if (this.skip) {
  7766. if (typeof this.skip === 'function') {
  7767. this.skip = this.skip();
  7768. }
  7769. if (this.skip) {
  7770. return [];
  7771. }
  7772. }
  7773. if (this.options.inline) {
  7774. var contents = new Anonymous(this.root, 0, {
  7775. filename: this.importedFilename,
  7776. reference: this.path._fileInfo && this.path._fileInfo.reference
  7777. }, true, true);
  7778. return this.features ? new Media([contents], this.features.value) : [contents];
  7779. }
  7780. else if (this.css) {
  7781. var newImport = new Import(this.evalPath(context), features, this.options, this._index);
  7782. if (!newImport.css && this.error) {
  7783. throw this.error;
  7784. }
  7785. return newImport;
  7786. }
  7787. else if (this.root) {
  7788. ruleset = new Ruleset(null, copyArray(this.root.rules));
  7789. ruleset.evalImports(context);
  7790. return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules;
  7791. }
  7792. else {
  7793. return [];
  7794. }
  7795. }
  7796. });
  7797. var JsEvalNode = function () { };
  7798. JsEvalNode.prototype = Object.assign(new Node(), {
  7799. evaluateJavaScript: function (expression, context) {
  7800. var result;
  7801. var that = this;
  7802. var evalContext = {};
  7803. if (!context.javascriptEnabled) {
  7804. throw { message: 'Inline JavaScript is not enabled. Is it set in your options?',
  7805. filename: this.fileInfo().filename,
  7806. index: this.getIndex() };
  7807. }
  7808. expression = expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
  7809. return that.jsify(new Variable("@".concat(name), that.getIndex(), that.fileInfo()).eval(context));
  7810. });
  7811. try {
  7812. expression = new Function("return (".concat(expression, ")"));
  7813. }
  7814. catch (e) {
  7815. throw { message: "JavaScript evaluation error: ".concat(e.message, " from `").concat(expression, "`"),
  7816. filename: this.fileInfo().filename,
  7817. index: this.getIndex() };
  7818. }
  7819. var variables = context.frames[0].variables();
  7820. for (var k in variables) {
  7821. // eslint-disable-next-line no-prototype-builtins
  7822. if (variables.hasOwnProperty(k)) {
  7823. evalContext[k.slice(1)] = {
  7824. value: variables[k].value,
  7825. toJS: function () {
  7826. return this.value.eval(context).toCSS();
  7827. }
  7828. };
  7829. }
  7830. }
  7831. try {
  7832. result = expression.call(evalContext);
  7833. }
  7834. catch (e) {
  7835. throw { message: "JavaScript evaluation error: '".concat(e.name, ": ").concat(e.message.replace(/["]/g, '\''), "'"),
  7836. filename: this.fileInfo().filename,
  7837. index: this.getIndex() };
  7838. }
  7839. return result;
  7840. },
  7841. jsify: function (obj) {
  7842. if (Array.isArray(obj.value) && (obj.value.length > 1)) {
  7843. return "[".concat(obj.value.map(function (v) { return v.toCSS(); }).join(', '), "]");
  7844. }
  7845. else {
  7846. return obj.toCSS();
  7847. }
  7848. }
  7849. });
  7850. var JavaScript = function (string, escaped, index, currentFileInfo) {
  7851. this.escaped = escaped;
  7852. this.expression = string;
  7853. this._index = index;
  7854. this._fileInfo = currentFileInfo;
  7855. };
  7856. JavaScript.prototype = Object.assign(new JsEvalNode(), {
  7857. type: 'JavaScript',
  7858. eval: function (context) {
  7859. var result = this.evaluateJavaScript(this.expression, context);
  7860. var type = typeof result;
  7861. if (type === 'number' && !isNaN(result)) {
  7862. return new Dimension(result);
  7863. }
  7864. else if (type === 'string') {
  7865. return new Quoted("\"".concat(result, "\""), result, this.escaped, this._index);
  7866. }
  7867. else if (Array.isArray(result)) {
  7868. return new Anonymous(result.join(', '));
  7869. }
  7870. else {
  7871. return new Anonymous(result);
  7872. }
  7873. }
  7874. });
  7875. var Assignment = function (key, val) {
  7876. this.key = key;
  7877. this.value = val;
  7878. };
  7879. Assignment.prototype = Object.assign(new Node(), {
  7880. type: 'Assignment',
  7881. accept: function (visitor) {
  7882. this.value = visitor.visit(this.value);
  7883. },
  7884. eval: function (context) {
  7885. if (this.value.eval) {
  7886. return new Assignment(this.key, this.value.eval(context));
  7887. }
  7888. return this;
  7889. },
  7890. genCSS: function (context, output) {
  7891. output.add("".concat(this.key, "="));
  7892. if (this.value.genCSS) {
  7893. this.value.genCSS(context, output);
  7894. }
  7895. else {
  7896. output.add(this.value);
  7897. }
  7898. }
  7899. });
  7900. var Condition = function (op, l, r, i, negate) {
  7901. this.op = op.trim();
  7902. this.lvalue = l;
  7903. this.rvalue = r;
  7904. this._index = i;
  7905. this.negate = negate;
  7906. };
  7907. Condition.prototype = Object.assign(new Node(), {
  7908. type: 'Condition',
  7909. accept: function (visitor) {
  7910. this.lvalue = visitor.visit(this.lvalue);
  7911. this.rvalue = visitor.visit(this.rvalue);
  7912. },
  7913. eval: function (context) {
  7914. var result = (function (op, a, b) {
  7915. switch (op) {
  7916. case 'and': return a && b;
  7917. case 'or': return a || b;
  7918. default:
  7919. switch (Node.compare(a, b)) {
  7920. case -1:
  7921. return op === '<' || op === '=<' || op === '<=';
  7922. case 0:
  7923. return op === '=' || op === '>=' || op === '=<' || op === '<=';
  7924. case 1:
  7925. return op === '>' || op === '>=';
  7926. default:
  7927. return false;
  7928. }
  7929. }
  7930. })(this.op, this.lvalue.eval(context), this.rvalue.eval(context));
  7931. return this.negate ? !result : result;
  7932. }
  7933. });
  7934. var QueryInParens = function (op, l, m, op2, r, i) {
  7935. this.op = op.trim();
  7936. this.lvalue = l;
  7937. this.mvalue = m;
  7938. this.op2 = op2 ? op2.trim() : null;
  7939. this.rvalue = r;
  7940. this._index = i;
  7941. this.mvalues = [];
  7942. };
  7943. QueryInParens.prototype = Object.assign(new Node(), {
  7944. type: 'QueryInParens',
  7945. accept: function (visitor) {
  7946. this.lvalue = visitor.visit(this.lvalue);
  7947. this.mvalue = visitor.visit(this.mvalue);
  7948. if (this.rvalue) {
  7949. this.rvalue = visitor.visit(this.rvalue);
  7950. }
  7951. },
  7952. eval: function (context) {
  7953. this.lvalue = this.lvalue.eval(context);
  7954. var variableDeclaration;
  7955. var rule;
  7956. for (var i_1 = 0; (rule = context.frames[i_1]); i_1++) {
  7957. if (rule.type === 'Ruleset') {
  7958. variableDeclaration = rule.rules.find(function (r) {
  7959. if ((r instanceof Declaration) && r.variable) {
  7960. return true;
  7961. }
  7962. return false;
  7963. });
  7964. if (variableDeclaration) {
  7965. break;
  7966. }
  7967. }
  7968. }
  7969. if (!this.mvalueCopy) {
  7970. this.mvalueCopy = copy(this.mvalue);
  7971. }
  7972. if (variableDeclaration) {
  7973. this.mvalue = this.mvalueCopy;
  7974. this.mvalue = this.mvalue.eval(context);
  7975. this.mvalues.push(this.mvalue);
  7976. }
  7977. else {
  7978. this.mvalue = this.mvalue.eval(context);
  7979. }
  7980. if (this.rvalue) {
  7981. this.rvalue = this.rvalue.eval(context);
  7982. }
  7983. return this;
  7984. },
  7985. genCSS: function (context, output) {
  7986. this.lvalue.genCSS(context, output);
  7987. output.add(' ' + this.op + ' ');
  7988. if (this.mvalues.length > 0) {
  7989. this.mvalue = this.mvalues.shift();
  7990. }
  7991. this.mvalue.genCSS(context, output);
  7992. if (this.rvalue) {
  7993. output.add(' ' + this.op2 + ' ');
  7994. this.rvalue.genCSS(context, output);
  7995. }
  7996. },
  7997. });
  7998. var Container = function (value, features, index, currentFileInfo, visibilityInfo) {
  7999. this._index = index;
  8000. this._fileInfo = currentFileInfo;
  8001. var selectors = (new Selector([], null, null, this._index, this._fileInfo)).createEmptySelectors();
  8002. this.features = new Value(features);
  8003. this.rules = [new Ruleset(selectors, value)];
  8004. this.rules[0].allowImports = true;
  8005. this.copyVisibilityInfo(visibilityInfo);
  8006. this.allowRoot = true;
  8007. this.setParent(selectors, this);
  8008. this.setParent(this.features, this);
  8009. this.setParent(this.rules, this);
  8010. };
  8011. Container.prototype = Object.assign(new AtRule(), __assign(__assign({ type: 'Container' }, NestableAtRulePrototype), { genCSS: function (context, output) {
  8012. output.add('@container ', this._fileInfo, this._index);
  8013. this.features.genCSS(context, output);
  8014. this.outputRuleset(context, output, this.rules);
  8015. }, eval: function (context) {
  8016. if (!context.mediaBlocks) {
  8017. context.mediaBlocks = [];
  8018. context.mediaPath = [];
  8019. }
  8020. var media = new Container(null, [], this._index, this._fileInfo, this.visibilityInfo());
  8021. if (this.debugInfo) {
  8022. this.rules[0].debugInfo = this.debugInfo;
  8023. media.debugInfo = this.debugInfo;
  8024. }
  8025. media.features = this.features.eval(context);
  8026. context.mediaPath.push(media);
  8027. context.mediaBlocks.push(media);
  8028. this.rules[0].functionRegistry = context.frames[0].functionRegistry.inherit();
  8029. context.frames.unshift(this.rules[0]);
  8030. media.rules = [this.rules[0].eval(context)];
  8031. context.frames.shift();
  8032. context.mediaPath.pop();
  8033. return context.mediaPath.length === 0 ? media.evalTop(context) :
  8034. media.evalNested(context);
  8035. } }));
  8036. var UnicodeDescriptor = function (value) {
  8037. this.value = value;
  8038. };
  8039. UnicodeDescriptor.prototype = Object.assign(new Node(), {
  8040. type: 'UnicodeDescriptor'
  8041. });
  8042. var Negative = function (node) {
  8043. this.value = node;
  8044. };
  8045. Negative.prototype = Object.assign(new Node(), {
  8046. type: 'Negative',
  8047. genCSS: function (context, output) {
  8048. output.add('-');
  8049. this.value.genCSS(context, output);
  8050. },
  8051. eval: function (context) {
  8052. if (context.isMathOn()) {
  8053. return (new Operation('*', [new Dimension(-1), this.value])).eval(context);
  8054. }
  8055. return new Negative(this.value.eval(context));
  8056. }
  8057. });
  8058. var Extend = function (selector, option, index, currentFileInfo, visibilityInfo) {
  8059. this.selector = selector;
  8060. this.option = option;
  8061. this.object_id = Extend.next_id++;
  8062. this.parent_ids = [this.object_id];
  8063. this._index = index;
  8064. this._fileInfo = currentFileInfo;
  8065. this.copyVisibilityInfo(visibilityInfo);
  8066. this.allowRoot = true;
  8067. switch (option) {
  8068. case 'all':
  8069. this.allowBefore = true;
  8070. this.allowAfter = true;
  8071. break;
  8072. default:
  8073. this.allowBefore = false;
  8074. this.allowAfter = false;
  8075. break;
  8076. }
  8077. this.setParent(this.selector, this);
  8078. };
  8079. Extend.prototype = Object.assign(new Node(), {
  8080. type: 'Extend',
  8081. accept: function (visitor) {
  8082. this.selector = visitor.visit(this.selector);
  8083. },
  8084. eval: function (context) {
  8085. return new Extend(this.selector.eval(context), this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo());
  8086. },
  8087. // remove when Nodes have JSDoc types
  8088. // eslint-disable-next-line no-unused-vars
  8089. clone: function (context) {
  8090. return new Extend(this.selector, this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo());
  8091. },
  8092. // it concatenates (joins) all selectors in selector array
  8093. findSelfSelectors: function (selectors) {
  8094. var selfElements = [], i, selectorElements;
  8095. for (i = 0; i < selectors.length; i++) {
  8096. selectorElements = selectors[i].elements;
  8097. // duplicate the logic in genCSS function inside the selector node.
  8098. // future TODO - move both logics into the selector joiner visitor
  8099. if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === '') {
  8100. selectorElements[0].combinator.value = ' ';
  8101. }
  8102. selfElements = selfElements.concat(selectors[i].elements);
  8103. }
  8104. this.selfSelectors = [new Selector(selfElements)];
  8105. this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo());
  8106. }
  8107. });
  8108. Extend.next_id = 0;
  8109. var VariableCall = function (variable, index, currentFileInfo) {
  8110. this.variable = variable;
  8111. this._index = index;
  8112. this._fileInfo = currentFileInfo;
  8113. this.allowRoot = true;
  8114. };
  8115. VariableCall.prototype = Object.assign(new Node(), {
  8116. type: 'VariableCall',
  8117. eval: function (context) {
  8118. var rules;
  8119. var detachedRuleset = new Variable(this.variable, this.getIndex(), this.fileInfo()).eval(context);
  8120. var error = new LessError({ message: "Could not evaluate variable call ".concat(this.variable) });
  8121. if (!detachedRuleset.ruleset) {
  8122. if (detachedRuleset.rules) {
  8123. rules = detachedRuleset;
  8124. }
  8125. else if (Array.isArray(detachedRuleset)) {
  8126. rules = new Ruleset('', detachedRuleset);
  8127. }
  8128. else if (Array.isArray(detachedRuleset.value)) {
  8129. rules = new Ruleset('', detachedRuleset.value);
  8130. }
  8131. else {
  8132. throw error;
  8133. }
  8134. detachedRuleset = new DetachedRuleset(rules);
  8135. }
  8136. if (detachedRuleset.ruleset) {
  8137. return detachedRuleset.callEval(context);
  8138. }
  8139. throw error;
  8140. }
  8141. });
  8142. var NamespaceValue = function (ruleCall, lookups, index, fileInfo) {
  8143. this.value = ruleCall;
  8144. this.lookups = lookups;
  8145. this._index = index;
  8146. this._fileInfo = fileInfo;
  8147. };
  8148. NamespaceValue.prototype = Object.assign(new Node(), {
  8149. type: 'NamespaceValue',
  8150. eval: function (context) {
  8151. var i, name, rules = this.value.eval(context);
  8152. for (i = 0; i < this.lookups.length; i++) {
  8153. name = this.lookups[i];
  8154. /**
  8155. * Eval'd DRs return rulesets.
  8156. * Eval'd mixins return rules, so let's make a ruleset if we need it.
  8157. * We need to do this because of late parsing of values
  8158. */
  8159. if (Array.isArray(rules)) {
  8160. rules = new Ruleset([new Selector()], rules);
  8161. }
  8162. if (name === '') {
  8163. rules = rules.lastDeclaration();
  8164. }
  8165. else if (name.charAt(0) === '@') {
  8166. if (name.charAt(1) === '@') {
  8167. name = "@".concat(new Variable(name.substr(1)).eval(context).value);
  8168. }
  8169. if (rules.variables) {
  8170. rules = rules.variable(name);
  8171. }
  8172. if (!rules) {
  8173. throw { type: 'Name',
  8174. message: "variable ".concat(name, " not found"),
  8175. filename: this.fileInfo().filename,
  8176. index: this.getIndex() };
  8177. }
  8178. }
  8179. else {
  8180. if (name.substring(0, 2) === '$@') {
  8181. name = "$".concat(new Variable(name.substr(1)).eval(context).value);
  8182. }
  8183. else {
  8184. name = name.charAt(0) === '$' ? name : "$".concat(name);
  8185. }
  8186. if (rules.properties) {
  8187. rules = rules.property(name);
  8188. }
  8189. if (!rules) {
  8190. throw { type: 'Name',
  8191. message: "property \"".concat(name.substr(1), "\" not found"),
  8192. filename: this.fileInfo().filename,
  8193. index: this.getIndex() };
  8194. }
  8195. // Properties are an array of values, since a ruleset can have multiple props.
  8196. // We pick the last one (the "cascaded" value)
  8197. rules = rules[rules.length - 1];
  8198. }
  8199. if (rules.value) {
  8200. rules = rules.eval(context).value;
  8201. }
  8202. if (rules.ruleset) {
  8203. rules = rules.ruleset.eval(context);
  8204. }
  8205. }
  8206. return rules;
  8207. }
  8208. });
  8209. var Definition = function (name, params, rules, condition, variadic, frames, visibilityInfo) {
  8210. this.name = name || 'anonymous mixin';
  8211. this.selectors = [new Selector([new Element(null, name, false, this._index, this._fileInfo)])];
  8212. this.params = params;
  8213. this.condition = condition;
  8214. this.variadic = variadic;
  8215. this.arity = params.length;
  8216. this.rules = rules;
  8217. this._lookups = {};
  8218. var optionalParameters = [];
  8219. this.required = params.reduce(function (count, p) {
  8220. if (!p.name || (p.name && !p.value)) {
  8221. return count + 1;
  8222. }
  8223. else {
  8224. optionalParameters.push(p.name);
  8225. return count;
  8226. }
  8227. }, 0);
  8228. this.optionalParameters = optionalParameters;
  8229. this.frames = frames;
  8230. this.copyVisibilityInfo(visibilityInfo);
  8231. this.allowRoot = true;
  8232. };
  8233. Definition.prototype = Object.assign(new Ruleset(), {
  8234. type: 'MixinDefinition',
  8235. evalFirst: true,
  8236. accept: function (visitor) {
  8237. if (this.params && this.params.length) {
  8238. this.params = visitor.visitArray(this.params);
  8239. }
  8240. this.rules = visitor.visitArray(this.rules);
  8241. if (this.condition) {
  8242. this.condition = visitor.visit(this.condition);
  8243. }
  8244. },
  8245. evalParams: function (context, mixinEnv, args, evaldArguments) {
  8246. /* jshint boss:true */
  8247. var frame = new Ruleset(null, null);
  8248. var varargs;
  8249. var arg;
  8250. var params = copyArray(this.params);
  8251. var i;
  8252. var j;
  8253. var val;
  8254. var name;
  8255. var isNamedFound;
  8256. var argIndex;
  8257. var argsLength = 0;
  8258. if (mixinEnv.frames && mixinEnv.frames[0] && mixinEnv.frames[0].functionRegistry) {
  8259. frame.functionRegistry = mixinEnv.frames[0].functionRegistry.inherit();
  8260. }
  8261. mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames));
  8262. if (args) {
  8263. args = copyArray(args);
  8264. argsLength = args.length;
  8265. for (i = 0; i < argsLength; i++) {
  8266. arg = args[i];
  8267. if (name = (arg && arg.name)) {
  8268. isNamedFound = false;
  8269. for (j = 0; j < params.length; j++) {
  8270. if (!evaldArguments[j] && name === params[j].name) {
  8271. evaldArguments[j] = arg.value.eval(context);
  8272. frame.prependRule(new Declaration(name, arg.value.eval(context)));
  8273. isNamedFound = true;
  8274. break;
  8275. }
  8276. }
  8277. if (isNamedFound) {
  8278. args.splice(i, 1);
  8279. i--;
  8280. continue;
  8281. }
  8282. else {
  8283. throw { type: 'Runtime', message: "Named argument for ".concat(this.name, " ").concat(args[i].name, " not found") };
  8284. }
  8285. }
  8286. }
  8287. }
  8288. argIndex = 0;
  8289. for (i = 0; i < params.length; i++) {
  8290. if (evaldArguments[i]) {
  8291. continue;
  8292. }
  8293. arg = args && args[argIndex];
  8294. if (name = params[i].name) {
  8295. if (params[i].variadic) {
  8296. varargs = [];
  8297. for (j = argIndex; j < argsLength; j++) {
  8298. varargs.push(args[j].value.eval(context));
  8299. }
  8300. frame.prependRule(new Declaration(name, new Expression(varargs).eval(context)));
  8301. }
  8302. else {
  8303. val = arg && arg.value;
  8304. if (val) {
  8305. // This was a mixin call, pass in a detached ruleset of it's eval'd rules
  8306. if (Array.isArray(val)) {
  8307. val = new DetachedRuleset(new Ruleset('', val));
  8308. }
  8309. else {
  8310. val = val.eval(context);
  8311. }
  8312. }
  8313. else if (params[i].value) {
  8314. val = params[i].value.eval(mixinEnv);
  8315. frame.resetCache();
  8316. }
  8317. else {
  8318. throw { type: 'Runtime', message: "wrong number of arguments for ".concat(this.name, " (").concat(argsLength, " for ").concat(this.arity, ")") };
  8319. }
  8320. frame.prependRule(new Declaration(name, val));
  8321. evaldArguments[i] = val;
  8322. }
  8323. }
  8324. if (params[i].variadic && args) {
  8325. for (j = argIndex; j < argsLength; j++) {
  8326. evaldArguments[j] = args[j].value.eval(context);
  8327. }
  8328. }
  8329. argIndex++;
  8330. }
  8331. return frame;
  8332. },
  8333. makeImportant: function () {
  8334. var rules = !this.rules ? this.rules : this.rules.map(function (r) {
  8335. if (r.makeImportant) {
  8336. return r.makeImportant(true);
  8337. }
  8338. else {
  8339. return r;
  8340. }
  8341. });
  8342. var result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames);
  8343. return result;
  8344. },
  8345. eval: function (context) {
  8346. return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || copyArray(context.frames));
  8347. },
  8348. evalCall: function (context, args, important) {
  8349. var _arguments = [];
  8350. var mixinFrames = this.frames ? this.frames.concat(context.frames) : context.frames;
  8351. var frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments);
  8352. var rules;
  8353. var ruleset;
  8354. frame.prependRule(new Declaration('@arguments', new Expression(_arguments).eval(context)));
  8355. rules = copyArray(this.rules);
  8356. ruleset = new Ruleset(null, rules);
  8357. ruleset.originalRuleset = this;
  8358. ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames)));
  8359. if (important) {
  8360. ruleset = ruleset.makeImportant();
  8361. }
  8362. return ruleset;
  8363. },
  8364. matchCondition: function (args, context) {
  8365. if (this.condition && !this.condition.eval(new contexts.Eval(context, [this.evalParams(context, /* the parameter variables */ new contexts.Eval(context, this.frames ? this.frames.concat(context.frames) : context.frames), args, [])]
  8366. .concat(this.frames || []) // the parent namespace/mixin frames
  8367. .concat(context.frames)))) { // the current environment frames
  8368. return false;
  8369. }
  8370. return true;
  8371. },
  8372. matchArgs: function (args, context) {
  8373. var allArgsCnt = (args && args.length) || 0;
  8374. var len;
  8375. var optionalParameters = this.optionalParameters;
  8376. var requiredArgsCnt = !args ? 0 : args.reduce(function (count, p) {
  8377. if (optionalParameters.indexOf(p.name) < 0) {
  8378. return count + 1;
  8379. }
  8380. else {
  8381. return count;
  8382. }
  8383. }, 0);
  8384. if (!this.variadic) {
  8385. if (requiredArgsCnt < this.required) {
  8386. return false;
  8387. }
  8388. if (allArgsCnt > this.params.length) {
  8389. return false;
  8390. }
  8391. }
  8392. else {
  8393. if (requiredArgsCnt < (this.required - 1)) {
  8394. return false;
  8395. }
  8396. }
  8397. // check patterns
  8398. len = Math.min(requiredArgsCnt, this.arity);
  8399. for (var i_1 = 0; i_1 < len; i_1++) {
  8400. if (!this.params[i_1].name && !this.params[i_1].variadic) {
  8401. if (args[i_1].value.eval(context).toCSS() != this.params[i_1].value.eval(context).toCSS()) {
  8402. return false;
  8403. }
  8404. }
  8405. }
  8406. return true;
  8407. }
  8408. });
  8409. var MixinCall = function (elements, args, index, currentFileInfo, important) {
  8410. this.selector = new Selector(elements);
  8411. this.arguments = args || [];
  8412. this._index = index;
  8413. this._fileInfo = currentFileInfo;
  8414. this.important = important;
  8415. this.allowRoot = true;
  8416. this.setParent(this.selector, this);
  8417. };
  8418. MixinCall.prototype = Object.assign(new Node(), {
  8419. type: 'MixinCall',
  8420. accept: function (visitor) {
  8421. if (this.selector) {
  8422. this.selector = visitor.visit(this.selector);
  8423. }
  8424. if (this.arguments.length) {
  8425. this.arguments = visitor.visitArray(this.arguments);
  8426. }
  8427. },
  8428. eval: function (context) {
  8429. var mixins;
  8430. var mixin;
  8431. var mixinPath;
  8432. var args = [];
  8433. var arg;
  8434. var argValue;
  8435. var rules = [];
  8436. var match = false;
  8437. var i;
  8438. var m;
  8439. var f;
  8440. var isRecursive;
  8441. var isOneFound;
  8442. var candidates = [];
  8443. var candidate;
  8444. var conditionResult = [];
  8445. var defaultResult;
  8446. var defFalseEitherCase = -1;
  8447. var defNone = 0;
  8448. var defTrue = 1;
  8449. var defFalse = 2;
  8450. var count;
  8451. var originalRuleset;
  8452. var noArgumentsFilter;
  8453. this.selector = this.selector.eval(context);
  8454. function calcDefGroup(mixin, mixinPath) {
  8455. var f, p, namespace;
  8456. for (f = 0; f < 2; f++) {
  8457. conditionResult[f] = true;
  8458. defaultFunc.value(f);
  8459. for (p = 0; p < mixinPath.length && conditionResult[f]; p++) {
  8460. namespace = mixinPath[p];
  8461. if (namespace.matchCondition) {
  8462. conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context);
  8463. }
  8464. }
  8465. if (mixin.matchCondition) {
  8466. conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context);
  8467. }
  8468. }
  8469. if (conditionResult[0] || conditionResult[1]) {
  8470. if (conditionResult[0] != conditionResult[1]) {
  8471. return conditionResult[1] ?
  8472. defTrue : defFalse;
  8473. }
  8474. return defNone;
  8475. }
  8476. return defFalseEitherCase;
  8477. }
  8478. for (i = 0; i < this.arguments.length; i++) {
  8479. arg = this.arguments[i];
  8480. argValue = arg.value.eval(context);
  8481. if (arg.expand && Array.isArray(argValue.value)) {
  8482. argValue = argValue.value;
  8483. for (m = 0; m < argValue.length; m++) {
  8484. args.push({ value: argValue[m] });
  8485. }
  8486. }
  8487. else {
  8488. args.push({ name: arg.name, value: argValue });
  8489. }
  8490. }
  8491. noArgumentsFilter = function (rule) { return rule.matchArgs(null, context); };
  8492. for (i = 0; i < context.frames.length; i++) {
  8493. if ((mixins = context.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) {
  8494. isOneFound = true;
  8495. // To make `default()` function independent of definition order we have two "subpasses" here.
  8496. // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),
  8497. // and build candidate list with corresponding flags. Then, when we know all possible matches,
  8498. // we make a final decision.
  8499. for (m = 0; m < mixins.length; m++) {
  8500. mixin = mixins[m].rule;
  8501. mixinPath = mixins[m].path;
  8502. isRecursive = false;
  8503. for (f = 0; f < context.frames.length; f++) {
  8504. if ((!(mixin instanceof Definition)) && mixin === (context.frames[f].originalRuleset || context.frames[f])) {
  8505. isRecursive = true;
  8506. break;
  8507. }
  8508. }
  8509. if (isRecursive) {
  8510. continue;
  8511. }
  8512. if (mixin.matchArgs(args, context)) {
  8513. candidate = { mixin: mixin, group: calcDefGroup(mixin, mixinPath) };
  8514. if (candidate.group !== defFalseEitherCase) {
  8515. candidates.push(candidate);
  8516. }
  8517. match = true;
  8518. }
  8519. }
  8520. defaultFunc.reset();
  8521. count = [0, 0, 0];
  8522. for (m = 0; m < candidates.length; m++) {
  8523. count[candidates[m].group]++;
  8524. }
  8525. if (count[defNone] > 0) {
  8526. defaultResult = defFalse;
  8527. }
  8528. else {
  8529. defaultResult = defTrue;
  8530. if ((count[defTrue] + count[defFalse]) > 1) {
  8531. throw { type: 'Runtime',
  8532. message: "Ambiguous use of `default()` found when matching for `".concat(this.format(args), "`"),
  8533. index: this.getIndex(), filename: this.fileInfo().filename };
  8534. }
  8535. }
  8536. for (m = 0; m < candidates.length; m++) {
  8537. candidate = candidates[m].group;
  8538. if ((candidate === defNone) || (candidate === defaultResult)) {
  8539. try {
  8540. mixin = candidates[m].mixin;
  8541. if (!(mixin instanceof Definition)) {
  8542. originalRuleset = mixin.originalRuleset || mixin;
  8543. mixin = new Definition('', [], mixin.rules, null, false, null, originalRuleset.visibilityInfo());
  8544. mixin.originalRuleset = originalRuleset;
  8545. }
  8546. var newRules = mixin.evalCall(context, args, this.important).rules;
  8547. this._setVisibilityToReplacement(newRules);
  8548. Array.prototype.push.apply(rules, newRules);
  8549. }
  8550. catch (e) {
  8551. throw { message: e.message, index: this.getIndex(), filename: this.fileInfo().filename, stack: e.stack };
  8552. }
  8553. }
  8554. }
  8555. if (match) {
  8556. return rules;
  8557. }
  8558. }
  8559. }
  8560. if (isOneFound) {
  8561. throw { type: 'Runtime',
  8562. message: "No matching definition was found for `".concat(this.format(args), "`"),
  8563. index: this.getIndex(), filename: this.fileInfo().filename };
  8564. }
  8565. else {
  8566. throw { type: 'Name',
  8567. message: "".concat(this.selector.toCSS().trim(), " is undefined"),
  8568. index: this.getIndex(), filename: this.fileInfo().filename };
  8569. }
  8570. },
  8571. _setVisibilityToReplacement: function (replacement) {
  8572. var i, rule;
  8573. if (this.blocksVisibility()) {
  8574. for (i = 0; i < replacement.length; i++) {
  8575. rule = replacement[i];
  8576. rule.addVisibilityBlock();
  8577. }
  8578. }
  8579. },
  8580. format: function (args) {
  8581. return "".concat(this.selector.toCSS().trim(), "(").concat(args ? args.map(function (a) {
  8582. var argValue = '';
  8583. if (a.name) {
  8584. argValue += "".concat(a.name, ":");
  8585. }
  8586. if (a.value.toCSS) {
  8587. argValue += a.value.toCSS();
  8588. }
  8589. else {
  8590. argValue += '???';
  8591. }
  8592. return argValue;
  8593. }).join(', ') : '', ")");
  8594. }
  8595. });
  8596. var tree = {
  8597. Node: Node,
  8598. Color: Color,
  8599. AtRule: AtRule,
  8600. DetachedRuleset: DetachedRuleset,
  8601. Operation: Operation,
  8602. Dimension: Dimension,
  8603. Unit: Unit,
  8604. Keyword: Keyword,
  8605. Variable: Variable,
  8606. Property: Property,
  8607. Ruleset: Ruleset,
  8608. Element: Element,
  8609. Attribute: Attribute,
  8610. Combinator: Combinator,
  8611. Selector: Selector,
  8612. Quoted: Quoted,
  8613. Expression: Expression,
  8614. Declaration: Declaration,
  8615. Call: Call,
  8616. URL: URL,
  8617. Import: Import,
  8618. Comment: Comment,
  8619. Anonymous: Anonymous,
  8620. Value: Value,
  8621. JavaScript: JavaScript,
  8622. Assignment: Assignment,
  8623. Condition: Condition,
  8624. Paren: Paren,
  8625. Media: Media,
  8626. Container: Container,
  8627. QueryInParens: QueryInParens,
  8628. UnicodeDescriptor: UnicodeDescriptor,
  8629. Negative: Negative,
  8630. Extend: Extend,
  8631. VariableCall: VariableCall,
  8632. NamespaceValue: NamespaceValue,
  8633. mixin: {
  8634. Call: MixinCall,
  8635. Definition: Definition
  8636. }
  8637. };
  8638. var AbstractFileManager = /** @class */ (function () {
  8639. function AbstractFileManager() {
  8640. }
  8641. AbstractFileManager.prototype.getPath = function (filename) {
  8642. var j = filename.lastIndexOf('?');
  8643. if (j > 0) {
  8644. filename = filename.slice(0, j);
  8645. }
  8646. j = filename.lastIndexOf('/');
  8647. if (j < 0) {
  8648. j = filename.lastIndexOf('\\');
  8649. }
  8650. if (j < 0) {
  8651. return '';
  8652. }
  8653. return filename.slice(0, j + 1);
  8654. };
  8655. AbstractFileManager.prototype.tryAppendExtension = function (path, ext) {
  8656. return /(\.[a-z]*$)|([?;].*)$/.test(path) ? path : path + ext;
  8657. };
  8658. AbstractFileManager.prototype.tryAppendLessExtension = function (path) {
  8659. return this.tryAppendExtension(path, '.less');
  8660. };
  8661. AbstractFileManager.prototype.supportsSync = function () {
  8662. return false;
  8663. };
  8664. AbstractFileManager.prototype.alwaysMakePathsAbsolute = function () {
  8665. return false;
  8666. };
  8667. AbstractFileManager.prototype.isPathAbsolute = function (filename) {
  8668. return (/^(?:[a-z-]+:|\/|\\|#)/i).test(filename);
  8669. };
  8670. // TODO: pull out / replace?
  8671. AbstractFileManager.prototype.join = function (basePath, laterPath) {
  8672. if (!basePath) {
  8673. return laterPath;
  8674. }
  8675. return basePath + laterPath;
  8676. };
  8677. AbstractFileManager.prototype.pathDiff = function (url, baseUrl) {
  8678. // diff between two paths to create a relative path
  8679. var urlParts = this.extractUrlParts(url);
  8680. var baseUrlParts = this.extractUrlParts(baseUrl);
  8681. var i;
  8682. var max;
  8683. var urlDirectories;
  8684. var baseUrlDirectories;
  8685. var diff = '';
  8686. if (urlParts.hostPart !== baseUrlParts.hostPart) {
  8687. return '';
  8688. }
  8689. max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);
  8690. for (i = 0; i < max; i++) {
  8691. if (baseUrlParts.directories[i] !== urlParts.directories[i]) {
  8692. break;
  8693. }
  8694. }
  8695. baseUrlDirectories = baseUrlParts.directories.slice(i);
  8696. urlDirectories = urlParts.directories.slice(i);
  8697. for (i = 0; i < baseUrlDirectories.length - 1; i++) {
  8698. diff += '../';
  8699. }
  8700. for (i = 0; i < urlDirectories.length - 1; i++) {
  8701. diff += "".concat(urlDirectories[i], "/");
  8702. }
  8703. return diff;
  8704. };
  8705. /**
  8706. * Helper function, not part of API.
  8707. * This should be replaceable by newer Node / Browser APIs
  8708. *
  8709. * @param {string} url
  8710. * @param {string} baseUrl
  8711. */
  8712. AbstractFileManager.prototype.extractUrlParts = function (url, baseUrl) {
  8713. // urlParts[1] = protocol://hostname/ OR /
  8714. // urlParts[2] = / if path relative to host base
  8715. // urlParts[3] = directories
  8716. // urlParts[4] = filename
  8717. // urlParts[5] = parameters
  8718. var urlPartsRegex = /^((?:[a-z-]+:)?\/{2}(?:[^/?#]*\/)|([/\\]))?((?:[^/\\?#]*[/\\])*)([^/\\?#]*)([#?].*)?$/i;
  8719. var urlParts = url.match(urlPartsRegex);
  8720. var returner = {};
  8721. var rawDirectories = [];
  8722. var directories = [];
  8723. var i;
  8724. var baseUrlParts;
  8725. if (!urlParts) {
  8726. throw new Error("Could not parse sheet href - '".concat(url, "'"));
  8727. }
  8728. // Stylesheets in IE don't always return the full path
  8729. if (baseUrl && (!urlParts[1] || urlParts[2])) {
  8730. baseUrlParts = baseUrl.match(urlPartsRegex);
  8731. if (!baseUrlParts) {
  8732. throw new Error("Could not parse page url - '".concat(baseUrl, "'"));
  8733. }
  8734. urlParts[1] = urlParts[1] || baseUrlParts[1] || '';
  8735. if (!urlParts[2]) {
  8736. urlParts[3] = baseUrlParts[3] + urlParts[3];
  8737. }
  8738. }
  8739. if (urlParts[3]) {
  8740. rawDirectories = urlParts[3].replace(/\\/g, '/').split('/');
  8741. // collapse '..' and skip '.'
  8742. for (i = 0; i < rawDirectories.length; i++) {
  8743. if (rawDirectories[i] === '..') {
  8744. directories.pop();
  8745. }
  8746. else if (rawDirectories[i] !== '.') {
  8747. directories.push(rawDirectories[i]);
  8748. }
  8749. }
  8750. }
  8751. returner.hostPart = urlParts[1];
  8752. returner.directories = directories;
  8753. returner.rawPath = (urlParts[1] || '') + rawDirectories.join('/');
  8754. returner.path = (urlParts[1] || '') + directories.join('/');
  8755. returner.filename = urlParts[4];
  8756. returner.fileUrl = returner.path + (urlParts[4] || '');
  8757. returner.url = returner.fileUrl + (urlParts[5] || '');
  8758. return returner;
  8759. };
  8760. return AbstractFileManager;
  8761. }());
  8762. var AbstractPluginLoader = /** @class */ (function () {
  8763. function AbstractPluginLoader() {
  8764. // Implemented by Node.js plugin loader
  8765. this.require = function () {
  8766. return null;
  8767. };
  8768. }
  8769. AbstractPluginLoader.prototype.evalPlugin = function (contents, context, imports, pluginOptions, fileInfo) {
  8770. var loader, registry, pluginObj, localModule, pluginManager, filename, result;
  8771. pluginManager = context.pluginManager;
  8772. if (fileInfo) {
  8773. if (typeof fileInfo === 'string') {
  8774. filename = fileInfo;
  8775. }
  8776. else {
  8777. filename = fileInfo.filename;
  8778. }
  8779. }
  8780. var shortname = (new this.less.FileManager()).extractUrlParts(filename).filename;
  8781. if (filename) {
  8782. pluginObj = pluginManager.get(filename);
  8783. if (pluginObj) {
  8784. result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
  8785. if (result) {
  8786. return result;
  8787. }
  8788. try {
  8789. if (pluginObj.use) {
  8790. pluginObj.use.call(this.context, pluginObj);
  8791. }
  8792. }
  8793. catch (e) {
  8794. e.message = e.message || 'Error during @plugin call';
  8795. return new LessError(e, imports, filename);
  8796. }
  8797. return pluginObj;
  8798. }
  8799. }
  8800. localModule = {
  8801. exports: {},
  8802. pluginManager: pluginManager,
  8803. fileInfo: fileInfo
  8804. };
  8805. registry = functionRegistry.create();
  8806. var registerPlugin = function (obj) {
  8807. pluginObj = obj;
  8808. };
  8809. try {
  8810. loader = new Function('module', 'require', 'registerPlugin', 'functions', 'tree', 'less', 'fileInfo', contents);
  8811. loader(localModule, this.require(filename), registerPlugin, registry, this.less.tree, this.less, fileInfo);
  8812. }
  8813. catch (e) {
  8814. return new LessError(e, imports, filename);
  8815. }
  8816. if (!pluginObj) {
  8817. pluginObj = localModule.exports;
  8818. }
  8819. pluginObj = this.validatePlugin(pluginObj, filename, shortname);
  8820. if (pluginObj instanceof LessError) {
  8821. return pluginObj;
  8822. }
  8823. if (pluginObj) {
  8824. pluginObj.imports = imports;
  8825. pluginObj.filename = filename;
  8826. // For < 3.x (or unspecified minVersion) - setOptions() before install()
  8827. if (!pluginObj.minVersion || this.compareVersion('3.0.0', pluginObj.minVersion) < 0) {
  8828. result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
  8829. if (result) {
  8830. return result;
  8831. }
  8832. }
  8833. // Run on first load
  8834. pluginManager.addPlugin(pluginObj, fileInfo.filename, registry);
  8835. pluginObj.functions = registry.getLocalFunctions();
  8836. // Need to call setOptions again because the pluginObj might have functions
  8837. result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
  8838. if (result) {
  8839. return result;
  8840. }
  8841. // Run every @plugin call
  8842. try {
  8843. if (pluginObj.use) {
  8844. pluginObj.use.call(this.context, pluginObj);
  8845. }
  8846. }
  8847. catch (e) {
  8848. e.message = e.message || 'Error during @plugin call';
  8849. return new LessError(e, imports, filename);
  8850. }
  8851. }
  8852. else {
  8853. return new LessError({ message: 'Not a valid plugin' }, imports, filename);
  8854. }
  8855. return pluginObj;
  8856. };
  8857. AbstractPluginLoader.prototype.trySetOptions = function (plugin, filename, name, options) {
  8858. if (options && !plugin.setOptions) {
  8859. return new LessError({
  8860. message: "Options have been provided but the plugin ".concat(name, " does not support any options.")
  8861. });
  8862. }
  8863. try {
  8864. plugin.setOptions && plugin.setOptions(options);
  8865. }
  8866. catch (e) {
  8867. return new LessError(e);
  8868. }
  8869. };
  8870. AbstractPluginLoader.prototype.validatePlugin = function (plugin, filename, name) {
  8871. if (plugin) {
  8872. // support plugins being a function
  8873. // so that the plugin can be more usable programmatically
  8874. if (typeof plugin === 'function') {
  8875. plugin = new plugin();
  8876. }
  8877. if (plugin.minVersion) {
  8878. if (this.compareVersion(plugin.minVersion, this.less.version) < 0) {
  8879. return new LessError({
  8880. message: "Plugin ".concat(name, " requires version ").concat(this.versionToString(plugin.minVersion))
  8881. });
  8882. }
  8883. }
  8884. return plugin;
  8885. }
  8886. return null;
  8887. };
  8888. AbstractPluginLoader.prototype.compareVersion = function (aVersion, bVersion) {
  8889. if (typeof aVersion === 'string') {
  8890. aVersion = aVersion.match(/^(\d+)\.?(\d+)?\.?(\d+)?/);
  8891. aVersion.shift();
  8892. }
  8893. for (var i_1 = 0; i_1 < aVersion.length; i_1++) {
  8894. if (aVersion[i_1] !== bVersion[i_1]) {
  8895. return parseInt(aVersion[i_1]) > parseInt(bVersion[i_1]) ? -1 : 1;
  8896. }
  8897. }
  8898. return 0;
  8899. };
  8900. AbstractPluginLoader.prototype.versionToString = function (version) {
  8901. var versionString = '';
  8902. for (var i_2 = 0; i_2 < version.length; i_2++) {
  8903. versionString += (versionString ? '.' : '') + version[i_2];
  8904. }
  8905. return versionString;
  8906. };
  8907. AbstractPluginLoader.prototype.printUsage = function (plugins) {
  8908. for (var i_3 = 0; i_3 < plugins.length; i_3++) {
  8909. var plugin = plugins[i_3];
  8910. if (plugin.printUsage) {
  8911. plugin.printUsage();
  8912. }
  8913. }
  8914. };
  8915. return AbstractPluginLoader;
  8916. }());
  8917. function boolean(condition) {
  8918. return condition ? Keyword.True : Keyword.False;
  8919. }
  8920. /**
  8921. * Functions with evalArgs set to false are sent context
  8922. * as the first argument.
  8923. */
  8924. function If(context, condition, trueValue, falseValue) {
  8925. return condition.eval(context) ? trueValue.eval(context)
  8926. : (falseValue ? falseValue.eval(context) : new Anonymous);
  8927. }
  8928. If.evalArgs = false;
  8929. function isdefined(context, variable) {
  8930. try {
  8931. variable.eval(context);
  8932. return Keyword.True;
  8933. }
  8934. catch (e) {
  8935. return Keyword.False;
  8936. }
  8937. }
  8938. isdefined.evalArgs = false;
  8939. var boolean$1 = { isdefined: isdefined, boolean: boolean, 'if': If };
  8940. var colorFunctions;
  8941. function clamp(val) {
  8942. return Math.min(1, Math.max(0, val));
  8943. }
  8944. function hsla(origColor, hsl) {
  8945. var color = colorFunctions.hsla(hsl.h, hsl.s, hsl.l, hsl.a);
  8946. if (color) {
  8947. if (origColor.value &&
  8948. /^(rgb|hsl)/.test(origColor.value)) {
  8949. color.value = origColor.value;
  8950. }
  8951. else {
  8952. color.value = 'rgb';
  8953. }
  8954. return color;
  8955. }
  8956. }
  8957. function toHSL(color) {
  8958. if (color.toHSL) {
  8959. return color.toHSL();
  8960. }
  8961. else {
  8962. throw new Error('Argument cannot be evaluated to a color');
  8963. }
  8964. }
  8965. function toHSV(color) {
  8966. if (color.toHSV) {
  8967. return color.toHSV();
  8968. }
  8969. else {
  8970. throw new Error('Argument cannot be evaluated to a color');
  8971. }
  8972. }
  8973. function number$1(n) {
  8974. if (n instanceof Dimension) {
  8975. return parseFloat(n.unit.is('%') ? n.value / 100 : n.value);
  8976. }
  8977. else if (typeof n === 'number') {
  8978. return n;
  8979. }
  8980. else {
  8981. throw {
  8982. type: 'Argument',
  8983. message: 'color functions take numbers as parameters'
  8984. };
  8985. }
  8986. }
  8987. function scaled(n, size) {
  8988. if (n instanceof Dimension && n.unit.is('%')) {
  8989. return parseFloat(n.value * size / 100);
  8990. }
  8991. else {
  8992. return number$1(n);
  8993. }
  8994. }
  8995. colorFunctions = {
  8996. rgb: function (r, g, b) {
  8997. var a = 1;
  8998. /**
  8999. * Comma-less syntax
  9000. * e.g. rgb(0 128 255 / 50%)
  9001. */
  9002. if (r instanceof Expression) {
  9003. var val = r.value;
  9004. r = val[0];
  9005. g = val[1];
  9006. b = val[2];
  9007. /**
  9008. * @todo - should this be normalized in
  9009. * function caller? Or parsed differently?
  9010. */
  9011. if (b instanceof Operation) {
  9012. var op = b;
  9013. b = op.operands[0];
  9014. a = op.operands[1];
  9015. }
  9016. }
  9017. var color = colorFunctions.rgba(r, g, b, a);
  9018. if (color) {
  9019. color.value = 'rgb';
  9020. return color;
  9021. }
  9022. },
  9023. rgba: function (r, g, b, a) {
  9024. try {
  9025. if (r instanceof Color) {
  9026. if (g) {
  9027. a = number$1(g);
  9028. }
  9029. else {
  9030. a = r.alpha;
  9031. }
  9032. return new Color(r.rgb, a, 'rgba');
  9033. }
  9034. var rgb = [r, g, b].map(function (c) { return scaled(c, 255); });
  9035. a = number$1(a);
  9036. return new Color(rgb, a, 'rgba');
  9037. }
  9038. catch (e) { }
  9039. },
  9040. hsl: function (h, s, l) {
  9041. var a = 1;
  9042. if (h instanceof Expression) {
  9043. var val = h.value;
  9044. h = val[0];
  9045. s = val[1];
  9046. l = val[2];
  9047. if (l instanceof Operation) {
  9048. var op = l;
  9049. l = op.operands[0];
  9050. a = op.operands[1];
  9051. }
  9052. }
  9053. var color = colorFunctions.hsla(h, s, l, a);
  9054. if (color) {
  9055. color.value = 'hsl';
  9056. return color;
  9057. }
  9058. },
  9059. hsla: function (h, s, l, a) {
  9060. var m1;
  9061. var m2;
  9062. function hue(h) {
  9063. h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
  9064. if (h * 6 < 1) {
  9065. return m1 + (m2 - m1) * h * 6;
  9066. }
  9067. else if (h * 2 < 1) {
  9068. return m2;
  9069. }
  9070. else if (h * 3 < 2) {
  9071. return m1 + (m2 - m1) * (2 / 3 - h) * 6;
  9072. }
  9073. else {
  9074. return m1;
  9075. }
  9076. }
  9077. try {
  9078. if (h instanceof Color) {
  9079. if (s) {
  9080. a = number$1(s);
  9081. }
  9082. else {
  9083. a = h.alpha;
  9084. }
  9085. return new Color(h.rgb, a, 'hsla');
  9086. }
  9087. h = (number$1(h) % 360) / 360;
  9088. s = clamp(number$1(s));
  9089. l = clamp(number$1(l));
  9090. a = clamp(number$1(a));
  9091. m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
  9092. m1 = l * 2 - m2;
  9093. var rgb = [
  9094. hue(h + 1 / 3) * 255,
  9095. hue(h) * 255,
  9096. hue(h - 1 / 3) * 255
  9097. ];
  9098. a = number$1(a);
  9099. return new Color(rgb, a, 'hsla');
  9100. }
  9101. catch (e) { }
  9102. },
  9103. hsv: function (h, s, v) {
  9104. return colorFunctions.hsva(h, s, v, 1.0);
  9105. },
  9106. hsva: function (h, s, v, a) {
  9107. h = ((number$1(h) % 360) / 360) * 360;
  9108. s = number$1(s);
  9109. v = number$1(v);
  9110. a = number$1(a);
  9111. var i;
  9112. var f;
  9113. i = Math.floor((h / 60) % 6);
  9114. f = (h / 60) - i;
  9115. var vs = [v,
  9116. v * (1 - s),
  9117. v * (1 - f * s),
  9118. v * (1 - (1 - f) * s)];
  9119. var perm = [[0, 3, 1],
  9120. [2, 0, 1],
  9121. [1, 0, 3],
  9122. [1, 2, 0],
  9123. [3, 1, 0],
  9124. [0, 1, 2]];
  9125. return colorFunctions.rgba(vs[perm[i][0]] * 255, vs[perm[i][1]] * 255, vs[perm[i][2]] * 255, a);
  9126. },
  9127. hue: function (color) {
  9128. return new Dimension(toHSL(color).h);
  9129. },
  9130. saturation: function (color) {
  9131. return new Dimension(toHSL(color).s * 100, '%');
  9132. },
  9133. lightness: function (color) {
  9134. return new Dimension(toHSL(color).l * 100, '%');
  9135. },
  9136. hsvhue: function (color) {
  9137. return new Dimension(toHSV(color).h);
  9138. },
  9139. hsvsaturation: function (color) {
  9140. return new Dimension(toHSV(color).s * 100, '%');
  9141. },
  9142. hsvvalue: function (color) {
  9143. return new Dimension(toHSV(color).v * 100, '%');
  9144. },
  9145. red: function (color) {
  9146. return new Dimension(color.rgb[0]);
  9147. },
  9148. green: function (color) {
  9149. return new Dimension(color.rgb[1]);
  9150. },
  9151. blue: function (color) {
  9152. return new Dimension(color.rgb[2]);
  9153. },
  9154. alpha: function (color) {
  9155. return new Dimension(toHSL(color).a);
  9156. },
  9157. luma: function (color) {
  9158. return new Dimension(color.luma() * color.alpha * 100, '%');
  9159. },
  9160. luminance: function (color) {
  9161. var luminance = (0.2126 * color.rgb[0] / 255) +
  9162. (0.7152 * color.rgb[1] / 255) +
  9163. (0.0722 * color.rgb[2] / 255);
  9164. return new Dimension(luminance * color.alpha * 100, '%');
  9165. },
  9166. saturate: function (color, amount, method) {
  9167. // filter: saturate(3.2);
  9168. // should be kept as is, so check for color
  9169. if (!color.rgb) {
  9170. return null;
  9171. }
  9172. var hsl = toHSL(color);
  9173. if (typeof method !== 'undefined' && method.value === 'relative') {
  9174. hsl.s += hsl.s * amount.value / 100;
  9175. }
  9176. else {
  9177. hsl.s += amount.value / 100;
  9178. }
  9179. hsl.s = clamp(hsl.s);
  9180. return hsla(color, hsl);
  9181. },
  9182. desaturate: function (color, amount, method) {
  9183. var hsl = toHSL(color);
  9184. if (typeof method !== 'undefined' && method.value === 'relative') {
  9185. hsl.s -= hsl.s * amount.value / 100;
  9186. }
  9187. else {
  9188. hsl.s -= amount.value / 100;
  9189. }
  9190. hsl.s = clamp(hsl.s);
  9191. return hsla(color, hsl);
  9192. },
  9193. lighten: function (color, amount, method) {
  9194. var hsl = toHSL(color);
  9195. if (typeof method !== 'undefined' && method.value === 'relative') {
  9196. hsl.l += hsl.l * amount.value / 100;
  9197. }
  9198. else {
  9199. hsl.l += amount.value / 100;
  9200. }
  9201. hsl.l = clamp(hsl.l);
  9202. return hsla(color, hsl);
  9203. },
  9204. darken: function (color, amount, method) {
  9205. var hsl = toHSL(color);
  9206. if (typeof method !== 'undefined' && method.value === 'relative') {
  9207. hsl.l -= hsl.l * amount.value / 100;
  9208. }
  9209. else {
  9210. hsl.l -= amount.value / 100;
  9211. }
  9212. hsl.l = clamp(hsl.l);
  9213. return hsla(color, hsl);
  9214. },
  9215. fadein: function (color, amount, method) {
  9216. var hsl = toHSL(color);
  9217. if (typeof method !== 'undefined' && method.value === 'relative') {
  9218. hsl.a += hsl.a * amount.value / 100;
  9219. }
  9220. else {
  9221. hsl.a += amount.value / 100;
  9222. }
  9223. hsl.a = clamp(hsl.a);
  9224. return hsla(color, hsl);
  9225. },
  9226. fadeout: function (color, amount, method) {
  9227. var hsl = toHSL(color);
  9228. if (typeof method !== 'undefined' && method.value === 'relative') {
  9229. hsl.a -= hsl.a * amount.value / 100;
  9230. }
  9231. else {
  9232. hsl.a -= amount.value / 100;
  9233. }
  9234. hsl.a = clamp(hsl.a);
  9235. return hsla(color, hsl);
  9236. },
  9237. fade: function (color, amount) {
  9238. var hsl = toHSL(color);
  9239. hsl.a = amount.value / 100;
  9240. hsl.a = clamp(hsl.a);
  9241. return hsla(color, hsl);
  9242. },
  9243. spin: function (color, amount) {
  9244. var hsl = toHSL(color);
  9245. var hue = (hsl.h + amount.value) % 360;
  9246. hsl.h = hue < 0 ? 360 + hue : hue;
  9247. return hsla(color, hsl);
  9248. },
  9249. //
  9250. // Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein
  9251. // http://sass-lang.com
  9252. //
  9253. mix: function (color1, color2, weight) {
  9254. if (!weight) {
  9255. weight = new Dimension(50);
  9256. }
  9257. var p = weight.value / 100.0;
  9258. var w = p * 2 - 1;
  9259. var a = toHSL(color1).a - toHSL(color2).a;
  9260. var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
  9261. var w2 = 1 - w1;
  9262. var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
  9263. color1.rgb[1] * w1 + color2.rgb[1] * w2,
  9264. color1.rgb[2] * w1 + color2.rgb[2] * w2];
  9265. var alpha = color1.alpha * p + color2.alpha * (1 - p);
  9266. return new Color(rgb, alpha);
  9267. },
  9268. greyscale: function (color) {
  9269. return colorFunctions.desaturate(color, new Dimension(100));
  9270. },
  9271. contrast: function (color, dark, light, threshold) {
  9272. // filter: contrast(3.2);
  9273. // should be kept as is, so check for color
  9274. if (!color.rgb) {
  9275. return null;
  9276. }
  9277. if (typeof light === 'undefined') {
  9278. light = colorFunctions.rgba(255, 255, 255, 1.0);
  9279. }
  9280. if (typeof dark === 'undefined') {
  9281. dark = colorFunctions.rgba(0, 0, 0, 1.0);
  9282. }
  9283. // Figure out which is actually light and dark:
  9284. if (dark.luma() > light.luma()) {
  9285. var t = light;
  9286. light = dark;
  9287. dark = t;
  9288. }
  9289. if (typeof threshold === 'undefined') {
  9290. threshold = 0.43;
  9291. }
  9292. else {
  9293. threshold = number$1(threshold);
  9294. }
  9295. if (color.luma() < threshold) {
  9296. return light;
  9297. }
  9298. else {
  9299. return dark;
  9300. }
  9301. },
  9302. // Changes made in 2.7.0 - Reverted in 3.0.0
  9303. // contrast: function (color, color1, color2, threshold) {
  9304. // // Return which of `color1` and `color2` has the greatest contrast with `color`
  9305. // // according to the standard WCAG contrast ratio calculation.
  9306. // // http://www.w3.org/TR/WCAG20/#contrast-ratiodef
  9307. // // The threshold param is no longer used, in line with SASS.
  9308. // // filter: contrast(3.2);
  9309. // // should be kept as is, so check for color
  9310. // if (!color.rgb) {
  9311. // return null;
  9312. // }
  9313. // if (typeof color1 === 'undefined') {
  9314. // color1 = colorFunctions.rgba(0, 0, 0, 1.0);
  9315. // }
  9316. // if (typeof color2 === 'undefined') {
  9317. // color2 = colorFunctions.rgba(255, 255, 255, 1.0);
  9318. // }
  9319. // var contrast1, contrast2;
  9320. // var luma = color.luma();
  9321. // var luma1 = color1.luma();
  9322. // var luma2 = color2.luma();
  9323. // // Calculate contrast ratios for each color
  9324. // if (luma > luma1) {
  9325. // contrast1 = (luma + 0.05) / (luma1 + 0.05);
  9326. // } else {
  9327. // contrast1 = (luma1 + 0.05) / (luma + 0.05);
  9328. // }
  9329. // if (luma > luma2) {
  9330. // contrast2 = (luma + 0.05) / (luma2 + 0.05);
  9331. // } else {
  9332. // contrast2 = (luma2 + 0.05) / (luma + 0.05);
  9333. // }
  9334. // if (contrast1 > contrast2) {
  9335. // return color1;
  9336. // } else {
  9337. // return color2;
  9338. // }
  9339. // },
  9340. argb: function (color) {
  9341. return new Anonymous(color.toARGB());
  9342. },
  9343. color: function (c) {
  9344. if ((c instanceof Quoted) &&
  9345. (/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})$/i.test(c.value))) {
  9346. var val = c.value.slice(1);
  9347. return new Color(val, undefined, "#".concat(val));
  9348. }
  9349. if ((c instanceof Color) || (c = Color.fromKeyword(c.value))) {
  9350. c.value = undefined;
  9351. return c;
  9352. }
  9353. throw {
  9354. type: 'Argument',
  9355. message: 'argument must be a color keyword or 3|4|6|8 digit hex e.g. #FFF'
  9356. };
  9357. },
  9358. tint: function (color, amount) {
  9359. return colorFunctions.mix(colorFunctions.rgb(255, 255, 255), color, amount);
  9360. },
  9361. shade: function (color, amount) {
  9362. return colorFunctions.mix(colorFunctions.rgb(0, 0, 0), color, amount);
  9363. }
  9364. };
  9365. var color = colorFunctions;
  9366. // Color Blending
  9367. // ref: http://www.w3.org/TR/compositing-1
  9368. function colorBlend(mode, color1, color2) {
  9369. var ab = color1.alpha; // result
  9370. var // backdrop
  9371. cb;
  9372. var as = color2.alpha;
  9373. var // source
  9374. cs;
  9375. var ar;
  9376. var cr;
  9377. var r = [];
  9378. ar = as + ab * (1 - as);
  9379. for (var i_1 = 0; i_1 < 3; i_1++) {
  9380. cb = color1.rgb[i_1] / 255;
  9381. cs = color2.rgb[i_1] / 255;
  9382. cr = mode(cb, cs);
  9383. if (ar) {
  9384. cr = (as * cs + ab * (cb -
  9385. as * (cb + cs - cr))) / ar;
  9386. }
  9387. r[i_1] = cr * 255;
  9388. }
  9389. return new Color(r, ar);
  9390. }
  9391. var colorBlendModeFunctions = {
  9392. multiply: function (cb, cs) {
  9393. return cb * cs;
  9394. },
  9395. screen: function (cb, cs) {
  9396. return cb + cs - cb * cs;
  9397. },
  9398. overlay: function (cb, cs) {
  9399. cb *= 2;
  9400. return (cb <= 1) ?
  9401. colorBlendModeFunctions.multiply(cb, cs) :
  9402. colorBlendModeFunctions.screen(cb - 1, cs);
  9403. },
  9404. softlight: function (cb, cs) {
  9405. var d = 1;
  9406. var e = cb;
  9407. if (cs > 0.5) {
  9408. e = 1;
  9409. d = (cb > 0.25) ? Math.sqrt(cb)
  9410. : ((16 * cb - 12) * cb + 4) * cb;
  9411. }
  9412. return cb - (1 - 2 * cs) * e * (d - cb);
  9413. },
  9414. hardlight: function (cb, cs) {
  9415. return colorBlendModeFunctions.overlay(cs, cb);
  9416. },
  9417. difference: function (cb, cs) {
  9418. return Math.abs(cb - cs);
  9419. },
  9420. exclusion: function (cb, cs) {
  9421. return cb + cs - 2 * cb * cs;
  9422. },
  9423. // non-w3c functions:
  9424. average: function (cb, cs) {
  9425. return (cb + cs) / 2;
  9426. },
  9427. negation: function (cb, cs) {
  9428. return 1 - Math.abs(cb + cs - 1);
  9429. }
  9430. };
  9431. for (var f$1 in colorBlendModeFunctions) {
  9432. // eslint-disable-next-line no-prototype-builtins
  9433. if (colorBlendModeFunctions.hasOwnProperty(f$1)) {
  9434. colorBlend[f$1] = colorBlend.bind(null, colorBlendModeFunctions[f$1]);
  9435. }
  9436. }
  9437. var dataUri = (function (environment) {
  9438. var fallback = function (functionThis, node) { return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context); };
  9439. return { 'data-uri': function (mimetypeNode, filePathNode) {
  9440. if (!filePathNode) {
  9441. filePathNode = mimetypeNode;
  9442. mimetypeNode = null;
  9443. }
  9444. var mimetype = mimetypeNode && mimetypeNode.value;
  9445. var filePath = filePathNode.value;
  9446. var currentFileInfo = this.currentFileInfo;
  9447. var currentDirectory = currentFileInfo.rewriteUrls ?
  9448. currentFileInfo.currentDirectory : currentFileInfo.entryPath;
  9449. var fragmentStart = filePath.indexOf('#');
  9450. var fragment = '';
  9451. if (fragmentStart !== -1) {
  9452. fragment = filePath.slice(fragmentStart);
  9453. filePath = filePath.slice(0, fragmentStart);
  9454. }
  9455. var context = clone(this.context);
  9456. context.rawBuffer = true;
  9457. var fileManager = environment.getFileManager(filePath, currentDirectory, context, environment, true);
  9458. if (!fileManager) {
  9459. return fallback(this, filePathNode);
  9460. }
  9461. var useBase64 = false;
  9462. // detect the mimetype if not given
  9463. if (!mimetypeNode) {
  9464. mimetype = environment.mimeLookup(filePath);
  9465. if (mimetype === 'image/svg+xml') {
  9466. useBase64 = false;
  9467. }
  9468. else {
  9469. // use base 64 unless it's an ASCII or UTF-8 format
  9470. var charset = environment.charsetLookup(mimetype);
  9471. useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0;
  9472. }
  9473. if (useBase64) {
  9474. mimetype += ';base64';
  9475. }
  9476. }
  9477. else {
  9478. useBase64 = /;base64$/.test(mimetype);
  9479. }
  9480. var fileSync = fileManager.loadFileSync(filePath, currentDirectory, context, environment);
  9481. if (!fileSync.contents) {
  9482. logger$1.warn("Skipped data-uri embedding of ".concat(filePath, " because file not found"));
  9483. return fallback(this, filePathNode || mimetypeNode);
  9484. }
  9485. var buf = fileSync.contents;
  9486. if (useBase64 && !environment.encodeBase64) {
  9487. return fallback(this, filePathNode);
  9488. }
  9489. buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf);
  9490. var uri = "data:".concat(mimetype, ",").concat(buf).concat(fragment);
  9491. return new URL(new Quoted("\"".concat(uri, "\""), uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);
  9492. } };
  9493. });
  9494. var getItemsFromNode = function (node) {
  9495. // handle non-array values as an array of length 1
  9496. // return 'undefined' if index is invalid
  9497. var items = Array.isArray(node.value) ?
  9498. node.value : Array(node);
  9499. return items;
  9500. };
  9501. var list = {
  9502. _SELF: function (n) {
  9503. return n;
  9504. },
  9505. '~': function () {
  9506. var expr = [];
  9507. for (var _i = 0; _i < arguments.length; _i++) {
  9508. expr[_i] = arguments[_i];
  9509. }
  9510. if (expr.length === 1) {
  9511. return expr[0];
  9512. }
  9513. return new Value(expr);
  9514. },
  9515. extract: function (values, index) {
  9516. // (1-based index)
  9517. index = index.value - 1;
  9518. return getItemsFromNode(values)[index];
  9519. },
  9520. length: function (values) {
  9521. return new Dimension(getItemsFromNode(values).length);
  9522. },
  9523. /**
  9524. * Creates a Less list of incremental values.
  9525. * Modeled after Lodash's range function, also exists natively in PHP
  9526. *
  9527. * @param {Dimension} [start=1]
  9528. * @param {Dimension} end - e.g. 10 or 10px - unit is added to output
  9529. * @param {Dimension} [step=1]
  9530. */
  9531. range: function (start, end, step) {
  9532. var from;
  9533. var to;
  9534. var stepValue = 1;
  9535. var list = [];
  9536. if (end) {
  9537. to = end;
  9538. from = start.value;
  9539. if (step) {
  9540. stepValue = step.value;
  9541. }
  9542. }
  9543. else {
  9544. from = 1;
  9545. to = start;
  9546. }
  9547. for (var i_1 = from; i_1 <= to.value; i_1 += stepValue) {
  9548. list.push(new Dimension(i_1, to.unit));
  9549. }
  9550. return new Expression(list);
  9551. },
  9552. each: function (list, rs) {
  9553. var _this = this;
  9554. var rules = [];
  9555. var newRules;
  9556. var iterator;
  9557. var tryEval = function (val) {
  9558. if (val instanceof Node) {
  9559. return val.eval(_this.context);
  9560. }
  9561. return val;
  9562. };
  9563. if (list.value && !(list instanceof Quoted)) {
  9564. if (Array.isArray(list.value)) {
  9565. iterator = list.value.map(tryEval);
  9566. }
  9567. else {
  9568. iterator = [tryEval(list.value)];
  9569. }
  9570. }
  9571. else if (list.ruleset) {
  9572. iterator = tryEval(list.ruleset).rules;
  9573. }
  9574. else if (list.rules) {
  9575. iterator = list.rules.map(tryEval);
  9576. }
  9577. else if (Array.isArray(list)) {
  9578. iterator = list.map(tryEval);
  9579. }
  9580. else {
  9581. iterator = [tryEval(list)];
  9582. }
  9583. var valueName = '@value';
  9584. var keyName = '@key';
  9585. var indexName = '@index';
  9586. if (rs.params) {
  9587. valueName = rs.params[0] && rs.params[0].name;
  9588. keyName = rs.params[1] && rs.params[1].name;
  9589. indexName = rs.params[2] && rs.params[2].name;
  9590. rs = rs.rules;
  9591. }
  9592. else {
  9593. rs = rs.ruleset;
  9594. }
  9595. for (var i_2 = 0; i_2 < iterator.length; i_2++) {
  9596. var key = void 0;
  9597. var value = void 0;
  9598. var item = iterator[i_2];
  9599. if (item instanceof Declaration) {
  9600. key = typeof item.name === 'string' ? item.name : item.name[0].value;
  9601. value = item.value;
  9602. }
  9603. else {
  9604. key = new Dimension(i_2 + 1);
  9605. value = item;
  9606. }
  9607. if (item instanceof Comment) {
  9608. continue;
  9609. }
  9610. newRules = rs.rules.slice(0);
  9611. if (valueName) {
  9612. newRules.push(new Declaration(valueName, value, false, false, this.index, this.currentFileInfo));
  9613. }
  9614. if (indexName) {
  9615. newRules.push(new Declaration(indexName, new Dimension(i_2 + 1), false, false, this.index, this.currentFileInfo));
  9616. }
  9617. if (keyName) {
  9618. newRules.push(new Declaration(keyName, key, false, false, this.index, this.currentFileInfo));
  9619. }
  9620. rules.push(new Ruleset([new (Selector)([new Element('', '&')])], newRules, rs.strictImports, rs.visibilityInfo()));
  9621. }
  9622. return new Ruleset([new (Selector)([new Element('', '&')])], rules, rs.strictImports, rs.visibilityInfo()).eval(this.context);
  9623. }
  9624. };
  9625. var MathHelper = function (fn, unit, n) {
  9626. if (!(n instanceof Dimension)) {
  9627. throw { type: 'Argument', message: 'argument must be a number' };
  9628. }
  9629. if (unit === null) {
  9630. unit = n.unit;
  9631. }
  9632. else {
  9633. n = n.unify();
  9634. }
  9635. return new Dimension(fn(parseFloat(n.value)), unit);
  9636. };
  9637. var mathFunctions = {
  9638. // name, unit
  9639. ceil: null,
  9640. floor: null,
  9641. sqrt: null,
  9642. abs: null,
  9643. tan: '',
  9644. sin: '',
  9645. cos: '',
  9646. atan: 'rad',
  9647. asin: 'rad',
  9648. acos: 'rad'
  9649. };
  9650. for (var f in mathFunctions) {
  9651. // eslint-disable-next-line no-prototype-builtins
  9652. if (mathFunctions.hasOwnProperty(f)) {
  9653. mathFunctions[f] = MathHelper.bind(null, Math[f], mathFunctions[f]);
  9654. }
  9655. }
  9656. mathFunctions.round = function (n, f) {
  9657. var fraction = typeof f === 'undefined' ? 0 : f.value;
  9658. return MathHelper(function (num) { return num.toFixed(fraction); }, null, n);
  9659. };
  9660. var minMax = function (isMin, args) {
  9661. var _this = this;
  9662. args = Array.prototype.slice.call(args);
  9663. switch (args.length) {
  9664. case 0: throw { type: 'Argument', message: 'one or more arguments required' };
  9665. }
  9666. var i; // key is the unit.toString() for unified Dimension values,
  9667. var j;
  9668. var current;
  9669. var currentUnified;
  9670. var referenceUnified;
  9671. var unit;
  9672. var unitStatic;
  9673. var unitClone;
  9674. var // elems only contains original argument values.
  9675. order = [];
  9676. var values = {};
  9677. // value is the index into the order array.
  9678. for (i = 0; i < args.length; i++) {
  9679. current = args[i];
  9680. if (!(current instanceof Dimension)) {
  9681. if (Array.isArray(args[i].value)) {
  9682. Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value));
  9683. continue;
  9684. }
  9685. else {
  9686. throw { type: 'Argument', message: 'incompatible types' };
  9687. }
  9688. }
  9689. currentUnified = current.unit.toString() === '' && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify();
  9690. unit = currentUnified.unit.toString() === '' && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString();
  9691. unitStatic = unit !== '' && unitStatic === undefined || unit !== '' && order[0].unify().unit.toString() === '' ? unit : unitStatic;
  9692. unitClone = unit !== '' && unitClone === undefined ? current.unit.toString() : unitClone;
  9693. j = values[''] !== undefined && unit !== '' && unit === unitStatic ? values[''] : values[unit];
  9694. if (j === undefined) {
  9695. if (unitStatic !== undefined && unit !== unitStatic) {
  9696. throw { type: 'Argument', message: 'incompatible types' };
  9697. }
  9698. values[unit] = order.length;
  9699. order.push(current);
  9700. continue;
  9701. }
  9702. referenceUnified = order[j].unit.toString() === '' && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify();
  9703. if (isMin && currentUnified.value < referenceUnified.value ||
  9704. !isMin && currentUnified.value > referenceUnified.value) {
  9705. order[j] = current;
  9706. }
  9707. }
  9708. if (order.length == 1) {
  9709. return order[0];
  9710. }
  9711. args = order.map(function (a) { return a.toCSS(_this.context); }).join(this.context.compress ? ',' : ', ');
  9712. return new Anonymous("".concat(isMin ? 'min' : 'max', "(").concat(args, ")"));
  9713. };
  9714. var number = {
  9715. min: function () {
  9716. var args = [];
  9717. for (var _i = 0; _i < arguments.length; _i++) {
  9718. args[_i] = arguments[_i];
  9719. }
  9720. try {
  9721. return minMax.call(this, true, args);
  9722. }
  9723. catch (e) { }
  9724. },
  9725. max: function () {
  9726. var args = [];
  9727. for (var _i = 0; _i < arguments.length; _i++) {
  9728. args[_i] = arguments[_i];
  9729. }
  9730. try {
  9731. return minMax.call(this, false, args);
  9732. }
  9733. catch (e) { }
  9734. },
  9735. convert: function (val, unit) {
  9736. return val.convertTo(unit.value);
  9737. },
  9738. pi: function () {
  9739. return new Dimension(Math.PI);
  9740. },
  9741. mod: function (a, b) {
  9742. return new Dimension(a.value % b.value, a.unit);
  9743. },
  9744. pow: function (x, y) {
  9745. if (typeof x === 'number' && typeof y === 'number') {
  9746. x = new Dimension(x);
  9747. y = new Dimension(y);
  9748. }
  9749. else if (!(x instanceof Dimension) || !(y instanceof Dimension)) {
  9750. throw { type: 'Argument', message: 'arguments must be numbers' };
  9751. }
  9752. return new Dimension(Math.pow(x.value, y.value), x.unit);
  9753. },
  9754. percentage: function (n) {
  9755. var result = MathHelper(function (num) { return num * 100; }, '%', n);
  9756. return result;
  9757. }
  9758. };
  9759. var string = {
  9760. e: function (str) {
  9761. return new Quoted('"', str instanceof JavaScript ? str.evaluated : str.value, true);
  9762. },
  9763. escape: function (str) {
  9764. return new Anonymous(encodeURI(str.value).replace(/=/g, '%3D').replace(/:/g, '%3A').replace(/#/g, '%23').replace(/;/g, '%3B')
  9765. .replace(/\(/g, '%28').replace(/\)/g, '%29'));
  9766. },
  9767. replace: function (string, pattern, replacement, flags) {
  9768. var result = string.value;
  9769. replacement = (replacement.type === 'Quoted') ?
  9770. replacement.value : replacement.toCSS();
  9771. result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement);
  9772. return new Quoted(string.quote || '', result, string.escaped);
  9773. },
  9774. '%': function (string /* arg, arg, ... */) {
  9775. var args = Array.prototype.slice.call(arguments, 1);
  9776. var result = string.value;
  9777. var _loop_1 = function (i_1) {
  9778. /* jshint loopfunc:true */
  9779. result = result.replace(/%[sda]/i, function (token) {
  9780. var value = ((args[i_1].type === 'Quoted') &&
  9781. token.match(/s/i)) ? args[i_1].value : args[i_1].toCSS();
  9782. return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
  9783. });
  9784. };
  9785. for (var i_1 = 0; i_1 < args.length; i_1++) {
  9786. _loop_1(i_1);
  9787. }
  9788. result = result.replace(/%%/g, '%');
  9789. return new Quoted(string.quote || '', result, string.escaped);
  9790. }
  9791. };
  9792. var svg = (function () {
  9793. return { 'svg-gradient': function (direction) {
  9794. var stops;
  9795. var gradientDirectionSvg;
  9796. var gradientType = 'linear';
  9797. var rectangleDimension = 'x="0" y="0" width="1" height="1"';
  9798. var renderEnv = { compress: false };
  9799. var returner;
  9800. var directionValue = direction.toCSS(renderEnv);
  9801. var i;
  9802. var color;
  9803. var position;
  9804. var positionValue;
  9805. var alpha;
  9806. function throwArgumentDescriptor() {
  9807. throw { type: 'Argument',
  9808. message: 'svg-gradient expects direction, start_color [start_position], [color position,]...,' +
  9809. ' end_color [end_position] or direction, color list' };
  9810. }
  9811. if (arguments.length == 2) {
  9812. if (arguments[1].value.length < 2) {
  9813. throwArgumentDescriptor();
  9814. }
  9815. stops = arguments[1].value;
  9816. }
  9817. else if (arguments.length < 3) {
  9818. throwArgumentDescriptor();
  9819. }
  9820. else {
  9821. stops = Array.prototype.slice.call(arguments, 1);
  9822. }
  9823. switch (directionValue) {
  9824. case 'to bottom':
  9825. gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"';
  9826. break;
  9827. case 'to right':
  9828. gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"';
  9829. break;
  9830. case 'to bottom right':
  9831. gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"';
  9832. break;
  9833. case 'to top right':
  9834. gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"';
  9835. break;
  9836. case 'ellipse':
  9837. case 'ellipse at center':
  9838. gradientType = 'radial';
  9839. gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"';
  9840. rectangleDimension = 'x="-50" y="-50" width="101" height="101"';
  9841. break;
  9842. default:
  9843. throw { type: 'Argument', message: 'svg-gradient direction must be \'to bottom\', \'to right\',' +
  9844. ' \'to bottom right\', \'to top right\' or \'ellipse at center\'' };
  9845. }
  9846. returner = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1 1\"><".concat(gradientType, "Gradient id=\"g\" ").concat(gradientDirectionSvg, ">");
  9847. for (i = 0; i < stops.length; i += 1) {
  9848. if (stops[i] instanceof Expression) {
  9849. color = stops[i].value[0];
  9850. position = stops[i].value[1];
  9851. }
  9852. else {
  9853. color = stops[i];
  9854. position = undefined;
  9855. }
  9856. if (!(color instanceof Color) || (!((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension))) {
  9857. throwArgumentDescriptor();
  9858. }
  9859. positionValue = position ? position.toCSS(renderEnv) : i === 0 ? '0%' : '100%';
  9860. alpha = color.alpha;
  9861. returner += "<stop offset=\"".concat(positionValue, "\" stop-color=\"").concat(color.toRGB(), "\"").concat(alpha < 1 ? " stop-opacity=\"".concat(alpha, "\"") : '', "/>");
  9862. }
  9863. returner += "</".concat(gradientType, "Gradient><rect ").concat(rectangleDimension, " fill=\"url(#g)\" /></svg>");
  9864. returner = encodeURIComponent(returner);
  9865. returner = "data:image/svg+xml,".concat(returner);
  9866. return new URL(new Quoted("'".concat(returner, "'"), returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);
  9867. } };
  9868. });
  9869. var isa = function (n, Type) { return (n instanceof Type) ? Keyword.True : Keyword.False; };
  9870. var isunit = function (n, unit) {
  9871. if (unit === undefined) {
  9872. throw { type: 'Argument', message: 'missing the required second argument to isunit.' };
  9873. }
  9874. unit = typeof unit.value === 'string' ? unit.value : unit;
  9875. if (typeof unit !== 'string') {
  9876. throw { type: 'Argument', message: 'Second argument to isunit should be a unit or a string.' };
  9877. }
  9878. return (n instanceof Dimension) && n.unit.is(unit) ? Keyword.True : Keyword.False;
  9879. };
  9880. var types = {
  9881. isruleset: function (n) {
  9882. return isa(n, DetachedRuleset);
  9883. },
  9884. iscolor: function (n) {
  9885. return isa(n, Color);
  9886. },
  9887. isnumber: function (n) {
  9888. return isa(n, Dimension);
  9889. },
  9890. isstring: function (n) {
  9891. return isa(n, Quoted);
  9892. },
  9893. iskeyword: function (n) {
  9894. return isa(n, Keyword);
  9895. },
  9896. isurl: function (n) {
  9897. return isa(n, URL);
  9898. },
  9899. ispixel: function (n) {
  9900. return isunit(n, 'px');
  9901. },
  9902. ispercentage: function (n) {
  9903. return isunit(n, '%');
  9904. },
  9905. isem: function (n) {
  9906. return isunit(n, 'em');
  9907. },
  9908. isunit: isunit,
  9909. unit: function (val, unit) {
  9910. if (!(val instanceof Dimension)) {
  9911. throw { type: 'Argument',
  9912. message: "the first argument to unit must be a number".concat(val instanceof Operation ? '. Have you forgotten parenthesis?' : '') };
  9913. }
  9914. if (unit) {
  9915. if (unit instanceof Keyword) {
  9916. unit = unit.value;
  9917. }
  9918. else {
  9919. unit = unit.toCSS();
  9920. }
  9921. }
  9922. else {
  9923. unit = '';
  9924. }
  9925. return new Dimension(val.value, unit);
  9926. },
  9927. 'get-unit': function (n) {
  9928. return new Anonymous(n.unit);
  9929. }
  9930. };
  9931. var styleExpression = function (args) {
  9932. var _this = this;
  9933. args = Array.prototype.slice.call(args);
  9934. switch (args.length) {
  9935. case 0: throw { type: 'Argument', message: 'one or more arguments required' };
  9936. }
  9937. var entityList = [new Variable(args[0].value, this.index, this.currentFileInfo).eval(this.context)];
  9938. args = entityList.map(function (a) { return a.toCSS(_this.context); }).join(this.context.compress ? ',' : ', ');
  9939. return new Variable("style(".concat(args, ")"));
  9940. };
  9941. var style$1 = {
  9942. style: function () {
  9943. var args = [];
  9944. for (var _i = 0; _i < arguments.length; _i++) {
  9945. args[_i] = arguments[_i];
  9946. }
  9947. try {
  9948. return styleExpression.call(this, args);
  9949. }
  9950. catch (e) { }
  9951. },
  9952. };
  9953. var functions = (function (environment) {
  9954. var functions = { functionRegistry: functionRegistry, functionCaller: functionCaller };
  9955. // register functions
  9956. functionRegistry.addMultiple(boolean$1);
  9957. functionRegistry.add('default', defaultFunc.eval.bind(defaultFunc));
  9958. functionRegistry.addMultiple(color);
  9959. functionRegistry.addMultiple(colorBlend);
  9960. functionRegistry.addMultiple(dataUri(environment));
  9961. functionRegistry.addMultiple(list);
  9962. functionRegistry.addMultiple(mathFunctions);
  9963. functionRegistry.addMultiple(number);
  9964. functionRegistry.addMultiple(string);
  9965. functionRegistry.addMultiple(svg());
  9966. functionRegistry.addMultiple(types);
  9967. functionRegistry.addMultiple(style$1);
  9968. return functions;
  9969. });
  9970. function transformTree (root, options) {
  9971. options = options || {};
  9972. var evaldRoot;
  9973. var variables = options.variables;
  9974. var evalEnv = new contexts.Eval(options);
  9975. //
  9976. // Allows setting variables with a hash, so:
  9977. //
  9978. // `{ color: new tree.Color('#f01') }` will become:
  9979. //
  9980. // new tree.Declaration('@color',
  9981. // new tree.Value([
  9982. // new tree.Expression([
  9983. // new tree.Color('#f01')
  9984. // ])
  9985. // ])
  9986. // )
  9987. //
  9988. if (typeof variables === 'object' && !Array.isArray(variables)) {
  9989. variables = Object.keys(variables).map(function (k) {
  9990. var value = variables[k];
  9991. if (!(value instanceof tree.Value)) {
  9992. if (!(value instanceof tree.Expression)) {
  9993. value = new tree.Expression([value]);
  9994. }
  9995. value = new tree.Value([value]);
  9996. }
  9997. return new tree.Declaration("@".concat(k), value, false, null, 0);
  9998. });
  9999. evalEnv.frames = [new tree.Ruleset(null, variables)];
  10000. }
  10001. var visitors$1 = [
  10002. new visitors.JoinSelectorVisitor(),
  10003. new visitors.MarkVisibleSelectorsVisitor(true),
  10004. new visitors.ExtendVisitor(),
  10005. new visitors.ToCSSVisitor({ compress: Boolean(options.compress) })
  10006. ];
  10007. var preEvalVisitors = [];
  10008. var v;
  10009. var visitorIterator;
  10010. /**
  10011. * first() / get() allows visitors to be added while visiting
  10012. *
  10013. * @todo Add scoping for visitors just like functions for @plugin; right now they're global
  10014. */
  10015. if (options.pluginManager) {
  10016. visitorIterator = options.pluginManager.visitor();
  10017. for (var i_1 = 0; i_1 < 2; i_1++) {
  10018. visitorIterator.first();
  10019. while ((v = visitorIterator.get())) {
  10020. if (v.isPreEvalVisitor) {
  10021. if (i_1 === 0 || preEvalVisitors.indexOf(v) === -1) {
  10022. preEvalVisitors.push(v);
  10023. v.run(root);
  10024. }
  10025. }
  10026. else {
  10027. if (i_1 === 0 || visitors$1.indexOf(v) === -1) {
  10028. if (v.isPreVisitor) {
  10029. visitors$1.unshift(v);
  10030. }
  10031. else {
  10032. visitors$1.push(v);
  10033. }
  10034. }
  10035. }
  10036. }
  10037. }
  10038. }
  10039. evaldRoot = root.eval(evalEnv);
  10040. for (var i_2 = 0; i_2 < visitors$1.length; i_2++) {
  10041. visitors$1[i_2].run(evaldRoot);
  10042. }
  10043. // Run any remaining visitors added after eval pass
  10044. if (options.pluginManager) {
  10045. visitorIterator.first();
  10046. while ((v = visitorIterator.get())) {
  10047. if (visitors$1.indexOf(v) === -1 && preEvalVisitors.indexOf(v) === -1) {
  10048. v.run(evaldRoot);
  10049. }
  10050. }
  10051. }
  10052. return evaldRoot;
  10053. }
  10054. /**
  10055. * Plugin Manager
  10056. */
  10057. var PluginManager = /** @class */ (function () {
  10058. function PluginManager(less) {
  10059. this.less = less;
  10060. this.visitors = [];
  10061. this.preProcessors = [];
  10062. this.postProcessors = [];
  10063. this.installedPlugins = [];
  10064. this.fileManagers = [];
  10065. this.iterator = -1;
  10066. this.pluginCache = {};
  10067. this.Loader = new less.PluginLoader(less);
  10068. }
  10069. /**
  10070. * Adds all the plugins in the array
  10071. * @param {Array} plugins
  10072. */
  10073. PluginManager.prototype.addPlugins = function (plugins) {
  10074. if (plugins) {
  10075. for (var i_1 = 0; i_1 < plugins.length; i_1++) {
  10076. this.addPlugin(plugins[i_1]);
  10077. }
  10078. }
  10079. };
  10080. /**
  10081. *
  10082. * @param plugin
  10083. * @param {String} filename
  10084. */
  10085. PluginManager.prototype.addPlugin = function (plugin, filename, functionRegistry) {
  10086. this.installedPlugins.push(plugin);
  10087. if (filename) {
  10088. this.pluginCache[filename] = plugin;
  10089. }
  10090. if (plugin.install) {
  10091. plugin.install(this.less, this, functionRegistry || this.less.functions.functionRegistry);
  10092. }
  10093. };
  10094. /**
  10095. *
  10096. * @param filename
  10097. */
  10098. PluginManager.prototype.get = function (filename) {
  10099. return this.pluginCache[filename];
  10100. };
  10101. /**
  10102. * Adds a visitor. The visitor object has options on itself to determine
  10103. * when it should run.
  10104. * @param visitor
  10105. */
  10106. PluginManager.prototype.addVisitor = function (visitor) {
  10107. this.visitors.push(visitor);
  10108. };
  10109. /**
  10110. * Adds a pre processor object
  10111. * @param {object} preProcessor
  10112. * @param {number} priority - guidelines 1 = before import, 1000 = import, 2000 = after import
  10113. */
  10114. PluginManager.prototype.addPreProcessor = function (preProcessor, priority) {
  10115. var indexToInsertAt;
  10116. for (indexToInsertAt = 0; indexToInsertAt < this.preProcessors.length; indexToInsertAt++) {
  10117. if (this.preProcessors[indexToInsertAt].priority >= priority) {
  10118. break;
  10119. }
  10120. }
  10121. this.preProcessors.splice(indexToInsertAt, 0, { preProcessor: preProcessor, priority: priority });
  10122. };
  10123. /**
  10124. * Adds a post processor object
  10125. * @param {object} postProcessor
  10126. * @param {number} priority - guidelines 1 = before compression, 1000 = compression, 2000 = after compression
  10127. */
  10128. PluginManager.prototype.addPostProcessor = function (postProcessor, priority) {
  10129. var indexToInsertAt;
  10130. for (indexToInsertAt = 0; indexToInsertAt < this.postProcessors.length; indexToInsertAt++) {
  10131. if (this.postProcessors[indexToInsertAt].priority >= priority) {
  10132. break;
  10133. }
  10134. }
  10135. this.postProcessors.splice(indexToInsertAt, 0, { postProcessor: postProcessor, priority: priority });
  10136. };
  10137. /**
  10138. *
  10139. * @param manager
  10140. */
  10141. PluginManager.prototype.addFileManager = function (manager) {
  10142. this.fileManagers.push(manager);
  10143. };
  10144. /**
  10145. *
  10146. * @returns {Array}
  10147. * @private
  10148. */
  10149. PluginManager.prototype.getPreProcessors = function () {
  10150. var preProcessors = [];
  10151. for (var i_2 = 0; i_2 < this.preProcessors.length; i_2++) {
  10152. preProcessors.push(this.preProcessors[i_2].preProcessor);
  10153. }
  10154. return preProcessors;
  10155. };
  10156. /**
  10157. *
  10158. * @returns {Array}
  10159. * @private
  10160. */
  10161. PluginManager.prototype.getPostProcessors = function () {
  10162. var postProcessors = [];
  10163. for (var i_3 = 0; i_3 < this.postProcessors.length; i_3++) {
  10164. postProcessors.push(this.postProcessors[i_3].postProcessor);
  10165. }
  10166. return postProcessors;
  10167. };
  10168. /**
  10169. *
  10170. * @returns {Array}
  10171. * @private
  10172. */
  10173. PluginManager.prototype.getVisitors = function () {
  10174. return this.visitors;
  10175. };
  10176. PluginManager.prototype.visitor = function () {
  10177. var self = this;
  10178. return {
  10179. first: function () {
  10180. self.iterator = -1;
  10181. return self.visitors[self.iterator];
  10182. },
  10183. get: function () {
  10184. self.iterator += 1;
  10185. return self.visitors[self.iterator];
  10186. }
  10187. };
  10188. };
  10189. /**
  10190. *
  10191. * @returns {Array}
  10192. * @private
  10193. */
  10194. PluginManager.prototype.getFileManagers = function () {
  10195. return this.fileManagers;
  10196. };
  10197. return PluginManager;
  10198. }());
  10199. var pm;
  10200. var PluginManagerFactory = function (less, newFactory) {
  10201. if (newFactory || !pm) {
  10202. pm = new PluginManager(less);
  10203. }
  10204. return pm;
  10205. };
  10206. function SourceMapOutput (environment) {
  10207. var SourceMapOutput = /** @class */ (function () {
  10208. function SourceMapOutput(options) {
  10209. this._css = [];
  10210. this._rootNode = options.rootNode;
  10211. this._contentsMap = options.contentsMap;
  10212. this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap;
  10213. if (options.sourceMapFilename) {
  10214. this._sourceMapFilename = options.sourceMapFilename.replace(/\\/g, '/');
  10215. }
  10216. this._outputFilename = options.outputFilename;
  10217. this.sourceMapURL = options.sourceMapURL;
  10218. if (options.sourceMapBasepath) {
  10219. this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/');
  10220. }
  10221. if (options.sourceMapRootpath) {
  10222. this._sourceMapRootpath = options.sourceMapRootpath.replace(/\\/g, '/');
  10223. if (this._sourceMapRootpath.charAt(this._sourceMapRootpath.length - 1) !== '/') {
  10224. this._sourceMapRootpath += '/';
  10225. }
  10226. }
  10227. else {
  10228. this._sourceMapRootpath = '';
  10229. }
  10230. this._outputSourceFiles = options.outputSourceFiles;
  10231. this._sourceMapGeneratorConstructor = environment.getSourceMapGenerator();
  10232. this._lineNumber = 0;
  10233. this._column = 0;
  10234. }
  10235. SourceMapOutput.prototype.removeBasepath = function (path) {
  10236. if (this._sourceMapBasepath && path.indexOf(this._sourceMapBasepath) === 0) {
  10237. path = path.substring(this._sourceMapBasepath.length);
  10238. if (path.charAt(0) === '\\' || path.charAt(0) === '/') {
  10239. path = path.substring(1);
  10240. }
  10241. }
  10242. return path;
  10243. };
  10244. SourceMapOutput.prototype.normalizeFilename = function (filename) {
  10245. filename = filename.replace(/\\/g, '/');
  10246. filename = this.removeBasepath(filename);
  10247. return (this._sourceMapRootpath || '') + filename;
  10248. };
  10249. SourceMapOutput.prototype.add = function (chunk, fileInfo, index, mapLines) {
  10250. // ignore adding empty strings
  10251. if (!chunk) {
  10252. return;
  10253. }
  10254. var lines, sourceLines, columns, sourceColumns, i;
  10255. if (fileInfo && fileInfo.filename) {
  10256. var inputSource = this._contentsMap[fileInfo.filename];
  10257. // remove vars/banner added to the top of the file
  10258. if (this._contentsIgnoredCharsMap[fileInfo.filename]) {
  10259. // adjust the index
  10260. index -= this._contentsIgnoredCharsMap[fileInfo.filename];
  10261. if (index < 0) {
  10262. index = 0;
  10263. }
  10264. // adjust the source
  10265. inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]);
  10266. }
  10267. /**
  10268. * ignore empty content, or failsafe
  10269. * if contents map is incorrect
  10270. */
  10271. if (inputSource === undefined) {
  10272. this._css.push(chunk);
  10273. return;
  10274. }
  10275. inputSource = inputSource.substring(0, index);
  10276. sourceLines = inputSource.split('\n');
  10277. sourceColumns = sourceLines[sourceLines.length - 1];
  10278. }
  10279. lines = chunk.split('\n');
  10280. columns = lines[lines.length - 1];
  10281. if (fileInfo && fileInfo.filename) {
  10282. if (!mapLines) {
  10283. this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column },
  10284. original: { line: sourceLines.length, column: sourceColumns.length },
  10285. source: this.normalizeFilename(fileInfo.filename) });
  10286. }
  10287. else {
  10288. for (i = 0; i < lines.length; i++) {
  10289. this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0 },
  10290. original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0 },
  10291. source: this.normalizeFilename(fileInfo.filename) });
  10292. }
  10293. }
  10294. }
  10295. if (lines.length === 1) {
  10296. this._column += columns.length;
  10297. }
  10298. else {
  10299. this._lineNumber += lines.length - 1;
  10300. this._column = columns.length;
  10301. }
  10302. this._css.push(chunk);
  10303. };
  10304. SourceMapOutput.prototype.isEmpty = function () {
  10305. return this._css.length === 0;
  10306. };
  10307. SourceMapOutput.prototype.toCSS = function (context) {
  10308. this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null });
  10309. if (this._outputSourceFiles) {
  10310. for (var filename in this._contentsMap) {
  10311. // eslint-disable-next-line no-prototype-builtins
  10312. if (this._contentsMap.hasOwnProperty(filename)) {
  10313. var source = this._contentsMap[filename];
  10314. if (this._contentsIgnoredCharsMap[filename]) {
  10315. source = source.slice(this._contentsIgnoredCharsMap[filename]);
  10316. }
  10317. this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source);
  10318. }
  10319. }
  10320. }
  10321. this._rootNode.genCSS(context, this);
  10322. if (this._css.length > 0) {
  10323. var sourceMapURL = void 0;
  10324. var sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON());
  10325. if (this.sourceMapURL) {
  10326. sourceMapURL = this.sourceMapURL;
  10327. }
  10328. else if (this._sourceMapFilename) {
  10329. sourceMapURL = this._sourceMapFilename;
  10330. }
  10331. this.sourceMapURL = sourceMapURL;
  10332. this.sourceMap = sourceMapContent;
  10333. }
  10334. return this._css.join('');
  10335. };
  10336. return SourceMapOutput;
  10337. }());
  10338. return SourceMapOutput;
  10339. }
  10340. function SourceMapBuilder (SourceMapOutput, environment) {
  10341. var SourceMapBuilder = /** @class */ (function () {
  10342. function SourceMapBuilder(options) {
  10343. this.options = options;
  10344. }
  10345. SourceMapBuilder.prototype.toCSS = function (rootNode, options, imports) {
  10346. var sourceMapOutput = new SourceMapOutput({
  10347. contentsIgnoredCharsMap: imports.contentsIgnoredChars,
  10348. rootNode: rootNode,
  10349. contentsMap: imports.contents,
  10350. sourceMapFilename: this.options.sourceMapFilename,
  10351. sourceMapURL: this.options.sourceMapURL,
  10352. outputFilename: this.options.sourceMapOutputFilename,
  10353. sourceMapBasepath: this.options.sourceMapBasepath,
  10354. sourceMapRootpath: this.options.sourceMapRootpath,
  10355. outputSourceFiles: this.options.outputSourceFiles,
  10356. sourceMapGenerator: this.options.sourceMapGenerator,
  10357. sourceMapFileInline: this.options.sourceMapFileInline,
  10358. disableSourcemapAnnotation: this.options.disableSourcemapAnnotation
  10359. });
  10360. var css = sourceMapOutput.toCSS(options);
  10361. this.sourceMap = sourceMapOutput.sourceMap;
  10362. this.sourceMapURL = sourceMapOutput.sourceMapURL;
  10363. if (this.options.sourceMapInputFilename) {
  10364. this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename);
  10365. }
  10366. if (this.options.sourceMapBasepath !== undefined && this.sourceMapURL !== undefined) {
  10367. this.sourceMapURL = sourceMapOutput.removeBasepath(this.sourceMapURL);
  10368. }
  10369. return css + this.getCSSAppendage();
  10370. };
  10371. SourceMapBuilder.prototype.getCSSAppendage = function () {
  10372. var sourceMapURL = this.sourceMapURL;
  10373. if (this.options.sourceMapFileInline) {
  10374. if (this.sourceMap === undefined) {
  10375. return '';
  10376. }
  10377. sourceMapURL = "data:application/json;base64,".concat(environment.encodeBase64(this.sourceMap));
  10378. }
  10379. if (this.options.disableSourcemapAnnotation) {
  10380. return '';
  10381. }
  10382. if (sourceMapURL) {
  10383. return "/*# sourceMappingURL=".concat(sourceMapURL, " */");
  10384. }
  10385. return '';
  10386. };
  10387. SourceMapBuilder.prototype.getExternalSourceMap = function () {
  10388. return this.sourceMap;
  10389. };
  10390. SourceMapBuilder.prototype.setExternalSourceMap = function (sourceMap) {
  10391. this.sourceMap = sourceMap;
  10392. };
  10393. SourceMapBuilder.prototype.isInline = function () {
  10394. return this.options.sourceMapFileInline;
  10395. };
  10396. SourceMapBuilder.prototype.getSourceMapURL = function () {
  10397. return this.sourceMapURL;
  10398. };
  10399. SourceMapBuilder.prototype.getOutputFilename = function () {
  10400. return this.options.sourceMapOutputFilename;
  10401. };
  10402. SourceMapBuilder.prototype.getInputFilename = function () {
  10403. return this.sourceMapInputFilename;
  10404. };
  10405. return SourceMapBuilder;
  10406. }());
  10407. return SourceMapBuilder;
  10408. }
  10409. function ParseTree (SourceMapBuilder) {
  10410. var ParseTree = /** @class */ (function () {
  10411. function ParseTree(root, imports) {
  10412. this.root = root;
  10413. this.imports = imports;
  10414. }
  10415. ParseTree.prototype.toCSS = function (options) {
  10416. var evaldRoot;
  10417. var result = {};
  10418. var sourceMapBuilder;
  10419. try {
  10420. evaldRoot = transformTree(this.root, options);
  10421. }
  10422. catch (e) {
  10423. throw new LessError(e, this.imports);
  10424. }
  10425. try {
  10426. var compress = Boolean(options.compress);
  10427. if (compress) {
  10428. logger$1.warn('The compress option has been deprecated. ' +
  10429. 'We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.');
  10430. }
  10431. var toCSSOptions = {
  10432. compress: compress,
  10433. dumpLineNumbers: options.dumpLineNumbers,
  10434. strictUnits: Boolean(options.strictUnits),
  10435. numPrecision: 8
  10436. };
  10437. if (options.sourceMap) {
  10438. sourceMapBuilder = new SourceMapBuilder(options.sourceMap);
  10439. result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports);
  10440. }
  10441. else {
  10442. result.css = evaldRoot.toCSS(toCSSOptions);
  10443. }
  10444. }
  10445. catch (e) {
  10446. throw new LessError(e, this.imports);
  10447. }
  10448. if (options.pluginManager) {
  10449. var postProcessors = options.pluginManager.getPostProcessors();
  10450. for (var i_1 = 0; i_1 < postProcessors.length; i_1++) {
  10451. result.css = postProcessors[i_1].process(result.css, { sourceMap: sourceMapBuilder, options: options, imports: this.imports });
  10452. }
  10453. }
  10454. if (options.sourceMap) {
  10455. result.map = sourceMapBuilder.getExternalSourceMap();
  10456. }
  10457. result.imports = [];
  10458. for (var file_1 in this.imports.files) {
  10459. if (Object.prototype.hasOwnProperty.call(this.imports.files, file_1) && file_1 !== this.imports.rootFilename) {
  10460. result.imports.push(file_1);
  10461. }
  10462. }
  10463. return result;
  10464. };
  10465. return ParseTree;
  10466. }());
  10467. return ParseTree;
  10468. }
  10469. function ImportManager (environment) {
  10470. // FileInfo = {
  10471. // 'rewriteUrls' - option - whether to adjust URL's to be relative
  10472. // 'filename' - full resolved filename of current file
  10473. // 'rootpath' - path to append to normal URLs for this node
  10474. // 'currentDirectory' - path to the current file, absolute
  10475. // 'rootFilename' - filename of the base file
  10476. // 'entryPath' - absolute path to the entry file
  10477. // 'reference' - whether the file should not be output and only output parts that are referenced
  10478. var ImportManager = /** @class */ (function () {
  10479. function ImportManager(less, context, rootFileInfo) {
  10480. this.less = less;
  10481. this.rootFilename = rootFileInfo.filename;
  10482. this.paths = context.paths || []; // Search paths, when importing
  10483. this.contents = {}; // map - filename to contents of all the files
  10484. this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore
  10485. this.mime = context.mime;
  10486. this.error = null;
  10487. this.context = context;
  10488. // Deprecated? Unused outside of here, could be useful.
  10489. this.queue = []; // Files which haven't been imported yet
  10490. this.files = {}; // Holds the imported parse trees.
  10491. }
  10492. /**
  10493. * Add an import to be imported
  10494. * @param path - the raw path
  10495. * @param tryAppendExtension - whether to try appending a file extension (.less or .js if the path has no extension)
  10496. * @param currentFileInfo - the current file info (used for instance to work out relative paths)
  10497. * @param importOptions - import options
  10498. * @param callback - callback for when it is imported
  10499. */
  10500. ImportManager.prototype.push = function (path, tryAppendExtension, currentFileInfo, importOptions, callback) {
  10501. var importManager = this, pluginLoader = this.context.pluginManager.Loader;
  10502. this.queue.push(path);
  10503. var fileParsedFunc = function (e, root, fullPath) {
  10504. importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue
  10505. var importedEqualsRoot = fullPath === importManager.rootFilename;
  10506. if (importOptions.optional && e) {
  10507. callback(null, { rules: [] }, false, null);
  10508. logger$1.info("The file ".concat(fullPath, " was skipped because it was not found and the import was marked optional."));
  10509. }
  10510. else {
  10511. // Inline imports aren't cached here.
  10512. // If we start to cache them, please make sure they won't conflict with non-inline imports of the
  10513. // same name as they used to do before this comment and the condition below have been added.
  10514. if (!importManager.files[fullPath] && !importOptions.inline) {
  10515. importManager.files[fullPath] = { root: root, options: importOptions };
  10516. }
  10517. if (e && !importManager.error) {
  10518. importManager.error = e;
  10519. }
  10520. callback(e, root, importedEqualsRoot, fullPath);
  10521. }
  10522. };
  10523. var newFileInfo = {
  10524. rewriteUrls: this.context.rewriteUrls,
  10525. entryPath: currentFileInfo.entryPath,
  10526. rootpath: currentFileInfo.rootpath,
  10527. rootFilename: currentFileInfo.rootFilename
  10528. };
  10529. var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment);
  10530. if (!fileManager) {
  10531. fileParsedFunc({ message: "Could not find a file-manager for ".concat(path) });
  10532. return;
  10533. }
  10534. var loadFileCallback = function (loadedFile) {
  10535. var plugin;
  10536. var resolvedFilename = loadedFile.filename;
  10537. var contents = loadedFile.contents.replace(/^\uFEFF/, '');
  10538. // Pass on an updated rootpath if path of imported file is relative and file
  10539. // is in a (sub|sup) directory
  10540. //
  10541. // Examples:
  10542. // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/',
  10543. // then rootpath should become 'less/module/nav/'
  10544. // - If path of imported file is '../mixins.less' and rootpath is 'less/',
  10545. // then rootpath should become 'less/../'
  10546. newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename);
  10547. if (newFileInfo.rewriteUrls) {
  10548. newFileInfo.rootpath = fileManager.join((importManager.context.rootpath || ''), fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath));
  10549. if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) {
  10550. newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath);
  10551. }
  10552. }
  10553. newFileInfo.filename = resolvedFilename;
  10554. var newEnv = new contexts.Parse(importManager.context);
  10555. newEnv.processImports = false;
  10556. importManager.contents[resolvedFilename] = contents;
  10557. if (currentFileInfo.reference || importOptions.reference) {
  10558. newFileInfo.reference = true;
  10559. }
  10560. if (importOptions.isPlugin) {
  10561. plugin = pluginLoader.evalPlugin(contents, newEnv, importManager, importOptions.pluginArgs, newFileInfo);
  10562. if (plugin instanceof LessError) {
  10563. fileParsedFunc(plugin, null, resolvedFilename);
  10564. }
  10565. else {
  10566. fileParsedFunc(null, plugin, resolvedFilename);
  10567. }
  10568. }
  10569. else if (importOptions.inline) {
  10570. fileParsedFunc(null, contents, resolvedFilename);
  10571. }
  10572. else {
  10573. // import (multiple) parse trees apparently get altered and can't be cached.
  10574. // TODO: investigate why this is
  10575. if (importManager.files[resolvedFilename]
  10576. && !importManager.files[resolvedFilename].options.multiple
  10577. && !importOptions.multiple) {
  10578. fileParsedFunc(null, importManager.files[resolvedFilename].root, resolvedFilename);
  10579. }
  10580. else {
  10581. new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) {
  10582. fileParsedFunc(e, root, resolvedFilename);
  10583. });
  10584. }
  10585. }
  10586. };
  10587. var loadedFile;
  10588. var promise;
  10589. var context = clone(this.context);
  10590. if (tryAppendExtension) {
  10591. context.ext = importOptions.isPlugin ? '.js' : '.less';
  10592. }
  10593. if (importOptions.isPlugin) {
  10594. context.mime = 'application/javascript';
  10595. if (context.syncImport) {
  10596. loadedFile = pluginLoader.loadPluginSync(path, currentFileInfo.currentDirectory, context, environment, fileManager);
  10597. }
  10598. else {
  10599. promise = pluginLoader.loadPlugin(path, currentFileInfo.currentDirectory, context, environment, fileManager);
  10600. }
  10601. }
  10602. else {
  10603. if (context.syncImport) {
  10604. loadedFile = fileManager.loadFileSync(path, currentFileInfo.currentDirectory, context, environment);
  10605. }
  10606. else {
  10607. promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, context, environment, function (err, loadedFile) {
  10608. if (err) {
  10609. fileParsedFunc(err);
  10610. }
  10611. else {
  10612. loadFileCallback(loadedFile);
  10613. }
  10614. });
  10615. }
  10616. }
  10617. if (loadedFile) {
  10618. if (!loadedFile.filename) {
  10619. fileParsedFunc(loadedFile);
  10620. }
  10621. else {
  10622. loadFileCallback(loadedFile);
  10623. }
  10624. }
  10625. else if (promise) {
  10626. promise.then(loadFileCallback, fileParsedFunc);
  10627. }
  10628. };
  10629. return ImportManager;
  10630. }());
  10631. return ImportManager;
  10632. }
  10633. function Parse (environment, ParseTree, ImportManager) {
  10634. var parse = function (input, options, callback) {
  10635. if (typeof options === 'function') {
  10636. callback = options;
  10637. options = copyOptions(this.options, {});
  10638. }
  10639. else {
  10640. options = copyOptions(this.options, options || {});
  10641. }
  10642. if (!callback) {
  10643. var self_1 = this;
  10644. return new Promise(function (resolve, reject) {
  10645. parse.call(self_1, input, options, function (err, output) {
  10646. if (err) {
  10647. reject(err);
  10648. }
  10649. else {
  10650. resolve(output);
  10651. }
  10652. });
  10653. });
  10654. }
  10655. else {
  10656. var context_1;
  10657. var rootFileInfo = void 0;
  10658. var pluginManager_1 = new PluginManagerFactory(this, !options.reUsePluginManager);
  10659. options.pluginManager = pluginManager_1;
  10660. context_1 = new contexts.Parse(options);
  10661. if (options.rootFileInfo) {
  10662. rootFileInfo = options.rootFileInfo;
  10663. }
  10664. else {
  10665. var filename = options.filename || 'input';
  10666. var entryPath = filename.replace(/[^/\\]*$/, '');
  10667. rootFileInfo = {
  10668. filename: filename,
  10669. rewriteUrls: context_1.rewriteUrls,
  10670. rootpath: context_1.rootpath || '',
  10671. currentDirectory: entryPath,
  10672. entryPath: entryPath,
  10673. rootFilename: filename
  10674. };
  10675. // add in a missing trailing slash
  10676. if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== '/') {
  10677. rootFileInfo.rootpath += '/';
  10678. }
  10679. }
  10680. var imports_1 = new ImportManager(this, context_1, rootFileInfo);
  10681. this.importManager = imports_1;
  10682. // TODO: allow the plugins to be just a list of paths or names
  10683. // Do an async plugin queue like lessc
  10684. if (options.plugins) {
  10685. options.plugins.forEach(function (plugin) {
  10686. var evalResult, contents;
  10687. if (plugin.fileContent) {
  10688. contents = plugin.fileContent.replace(/^\uFEFF/, '');
  10689. evalResult = pluginManager_1.Loader.evalPlugin(contents, context_1, imports_1, plugin.options, plugin.filename);
  10690. if (evalResult instanceof LessError) {
  10691. return callback(evalResult);
  10692. }
  10693. }
  10694. else {
  10695. pluginManager_1.addPlugin(plugin);
  10696. }
  10697. });
  10698. }
  10699. new Parser(context_1, imports_1, rootFileInfo)
  10700. .parse(input, function (e, root) {
  10701. if (e) {
  10702. return callback(e);
  10703. }
  10704. callback(null, root, imports_1, options);
  10705. }, options);
  10706. }
  10707. };
  10708. return parse;
  10709. }
  10710. function Render (environment, ParseTree) {
  10711. var render = function (input, options, callback) {
  10712. if (typeof options === 'function') {
  10713. callback = options;
  10714. options = copyOptions(this.options, {});
  10715. }
  10716. else {
  10717. options = copyOptions(this.options, options || {});
  10718. }
  10719. if (!callback) {
  10720. var self_1 = this;
  10721. return new Promise(function (resolve, reject) {
  10722. render.call(self_1, input, options, function (err, output) {
  10723. if (err) {
  10724. reject(err);
  10725. }
  10726. else {
  10727. resolve(output);
  10728. }
  10729. });
  10730. });
  10731. }
  10732. else {
  10733. this.parse(input, options, function (err, root, imports, options) {
  10734. if (err) {
  10735. return callback(err);
  10736. }
  10737. var result;
  10738. try {
  10739. var parseTree = new ParseTree(root, imports);
  10740. result = parseTree.toCSS(options);
  10741. }
  10742. catch (err) {
  10743. return callback(err);
  10744. }
  10745. callback(null, result);
  10746. });
  10747. }
  10748. };
  10749. return render;
  10750. }
  10751. var version = "4.2.2";
  10752. function parseNodeVersion(version) {
  10753. var match = version.match(/^v(\d{1,2})\.(\d{1,2})\.(\d{1,2})(?:-([0-9A-Za-z-.]+))?(?:\+([0-9A-Za-z-.]+))?$/); // eslint-disable-line max-len
  10754. if (!match) {
  10755. throw new Error('Unable to parse: ' + version);
  10756. }
  10757. var res = {
  10758. major: parseInt(match[1], 10),
  10759. minor: parseInt(match[2], 10),
  10760. patch: parseInt(match[3], 10),
  10761. pre: match[4] || '',
  10762. build: match[5] || '',
  10763. };
  10764. return res;
  10765. }
  10766. var parseNodeVersion_1 = parseNodeVersion;
  10767. function lessRoot (environment, fileManagers) {
  10768. var sourceMapOutput, sourceMapBuilder, parseTree, importManager;
  10769. environment = new Environment(environment, fileManagers);
  10770. sourceMapOutput = SourceMapOutput(environment);
  10771. sourceMapBuilder = SourceMapBuilder(sourceMapOutput, environment);
  10772. parseTree = ParseTree(sourceMapBuilder);
  10773. importManager = ImportManager(environment);
  10774. var render = Render(environment, parseTree);
  10775. var parse = Parse(environment, parseTree, importManager);
  10776. var v = parseNodeVersion_1("v".concat(version));
  10777. var initial = {
  10778. version: [v.major, v.minor, v.patch],
  10779. data: data,
  10780. tree: tree,
  10781. Environment: Environment,
  10782. AbstractFileManager: AbstractFileManager,
  10783. AbstractPluginLoader: AbstractPluginLoader,
  10784. environment: environment,
  10785. visitors: visitors,
  10786. Parser: Parser,
  10787. functions: functions(environment),
  10788. contexts: contexts,
  10789. SourceMapOutput: sourceMapOutput,
  10790. SourceMapBuilder: sourceMapBuilder,
  10791. ParseTree: parseTree,
  10792. ImportManager: importManager,
  10793. render: render,
  10794. parse: parse,
  10795. LessError: LessError,
  10796. transformTree: transformTree,
  10797. utils: utils,
  10798. PluginManager: PluginManagerFactory,
  10799. logger: logger$1
  10800. };
  10801. // Create a public API
  10802. var ctor = function (t) {
  10803. return function () {
  10804. var obj = Object.create(t.prototype);
  10805. t.apply(obj, Array.prototype.slice.call(arguments, 0));
  10806. return obj;
  10807. };
  10808. };
  10809. var t;
  10810. var api = Object.create(initial);
  10811. for (var n in initial.tree) {
  10812. /* eslint guard-for-in: 0 */
  10813. t = initial.tree[n];
  10814. if (typeof t === 'function') {
  10815. api[n.toLowerCase()] = ctor(t);
  10816. }
  10817. else {
  10818. api[n] = Object.create(null);
  10819. for (var o in t) {
  10820. /* eslint guard-for-in: 0 */
  10821. api[n][o.toLowerCase()] = ctor(t[o]);
  10822. }
  10823. }
  10824. }
  10825. /**
  10826. * Some of the functions assume a `this` context of the API object,
  10827. * which causes it to fail when wrapped for ES6 imports.
  10828. *
  10829. * An assumed `this` should be removed in the future.
  10830. */
  10831. initial.parse = initial.parse.bind(api);
  10832. initial.render = initial.render.bind(api);
  10833. return api;
  10834. }
  10835. var options$1;
  10836. var logger;
  10837. var fileCache = {};
  10838. // TODOS - move log somewhere. pathDiff and doing something similar in node. use pathDiff in the other browser file for the initial load
  10839. var FileManager = function () { };
  10840. FileManager.prototype = Object.assign(new AbstractFileManager(), {
  10841. alwaysMakePathsAbsolute: function () {
  10842. return true;
  10843. },
  10844. join: function (basePath, laterPath) {
  10845. if (!basePath) {
  10846. return laterPath;
  10847. }
  10848. return this.extractUrlParts(laterPath, basePath).path;
  10849. },
  10850. doXHR: function (url, type, callback, errback) {
  10851. var xhr = new XMLHttpRequest();
  10852. var async = options$1.isFileProtocol ? options$1.fileAsync : true;
  10853. if (typeof xhr.overrideMimeType === 'function') {
  10854. xhr.overrideMimeType('text/css');
  10855. }
  10856. logger.debug("XHR: Getting '".concat(url, "'"));
  10857. xhr.open('GET', url, async);
  10858. xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
  10859. xhr.send(null);
  10860. function handleResponse(xhr, callback, errback) {
  10861. if (xhr.status >= 200 && xhr.status < 300) {
  10862. callback(xhr.responseText, xhr.getResponseHeader('Last-Modified'));
  10863. }
  10864. else if (typeof errback === 'function') {
  10865. errback(xhr.status, url);
  10866. }
  10867. }
  10868. if (options$1.isFileProtocol && !options$1.fileAsync) {
  10869. if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
  10870. callback(xhr.responseText);
  10871. }
  10872. else {
  10873. errback(xhr.status, url);
  10874. }
  10875. }
  10876. else if (async) {
  10877. xhr.onreadystatechange = function () {
  10878. if (xhr.readyState == 4) {
  10879. handleResponse(xhr, callback, errback);
  10880. }
  10881. };
  10882. }
  10883. else {
  10884. handleResponse(xhr, callback, errback);
  10885. }
  10886. },
  10887. supports: function () {
  10888. return true;
  10889. },
  10890. clearFileCache: function () {
  10891. fileCache = {};
  10892. },
  10893. loadFile: function (filename, currentDirectory, options) {
  10894. // TODO: Add prefix support like less-node?
  10895. // What about multiple paths?
  10896. if (currentDirectory && !this.isPathAbsolute(filename)) {
  10897. filename = currentDirectory + filename;
  10898. }
  10899. filename = options.ext ? this.tryAppendExtension(filename, options.ext) : filename;
  10900. options = options || {};
  10901. // sheet may be set to the stylesheet for the initial load or a collection of properties including
  10902. // some context variables for imports
  10903. var hrefParts = this.extractUrlParts(filename, window.location.href);
  10904. var href = hrefParts.url;
  10905. var self = this;
  10906. return new Promise(function (resolve, reject) {
  10907. if (options.useFileCache && fileCache[href]) {
  10908. try {
  10909. var lessText_1 = fileCache[href];
  10910. return resolve({ contents: lessText_1, filename: href, webInfo: { lastModified: new Date() } });
  10911. }
  10912. catch (e) {
  10913. return reject({ filename: href, message: "Error loading file ".concat(href, " error was ").concat(e.message) });
  10914. }
  10915. }
  10916. self.doXHR(href, options.mime, function doXHRCallback(data, lastModified) {
  10917. // per file cache
  10918. fileCache[href] = data;
  10919. // Use remote copy (re-parse)
  10920. resolve({ contents: data, filename: href, webInfo: { lastModified: lastModified } });
  10921. }, function doXHRError(status, url) {
  10922. reject({ type: 'File', message: "'".concat(url, "' wasn't found (").concat(status, ")"), href: href });
  10923. });
  10924. });
  10925. }
  10926. });
  10927. var FM = (function (opts, log) {
  10928. options$1 = opts;
  10929. logger = log;
  10930. return FileManager;
  10931. });
  10932. /**
  10933. * @todo Add tests for browser `@plugin`
  10934. */
  10935. /**
  10936. * Browser Plugin Loader
  10937. */
  10938. var PluginLoader = function (less) {
  10939. this.less = less;
  10940. // Should we shim this.require for browser? Probably not?
  10941. };
  10942. PluginLoader.prototype = Object.assign(new AbstractPluginLoader(), {
  10943. loadPlugin: function (filename, basePath, context, environment, fileManager) {
  10944. return new Promise(function (fulfill, reject) {
  10945. fileManager.loadFile(filename, basePath, context, environment)
  10946. .then(fulfill).catch(reject);
  10947. });
  10948. }
  10949. });
  10950. var LogListener = (function (less, options) {
  10951. var logLevel_debug = 4;
  10952. var logLevel_info = 3;
  10953. var logLevel_warn = 2;
  10954. var logLevel_error = 1;
  10955. // The amount of logging in the javascript console.
  10956. // 3 - Debug, information and errors
  10957. // 2 - Information and errors
  10958. // 1 - Errors
  10959. // 0 - None
  10960. // Defaults to 2
  10961. options.logLevel = typeof options.logLevel !== 'undefined' ? options.logLevel : (options.env === 'development' ? logLevel_info : logLevel_error);
  10962. if (!options.loggers) {
  10963. options.loggers = [{
  10964. debug: function (msg) {
  10965. if (options.logLevel >= logLevel_debug) {
  10966. console.log(msg);
  10967. }
  10968. },
  10969. info: function (msg) {
  10970. if (options.logLevel >= logLevel_info) {
  10971. console.log(msg);
  10972. }
  10973. },
  10974. warn: function (msg) {
  10975. if (options.logLevel >= logLevel_warn) {
  10976. console.warn(msg);
  10977. }
  10978. },
  10979. error: function (msg) {
  10980. if (options.logLevel >= logLevel_error) {
  10981. console.error(msg);
  10982. }
  10983. }
  10984. }];
  10985. }
  10986. for (var i_1 = 0; i_1 < options.loggers.length; i_1++) {
  10987. less.logger.addListener(options.loggers[i_1]);
  10988. }
  10989. });
  10990. var ErrorReporting = (function (window, less, options) {
  10991. function errorHTML(e, rootHref) {
  10992. var id = "less-error-message:".concat(extractId(rootHref || ''));
  10993. var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
  10994. var elem = window.document.createElement('div');
  10995. var timer;
  10996. var content;
  10997. var errors = [];
  10998. var filename = e.filename || rootHref;
  10999. var filenameNoPath = filename.match(/([^/]+(\?.*)?)$/)[1];
  11000. elem.id = id;
  11001. elem.className = 'less-error-message';
  11002. content = "<h3>".concat(e.type || 'Syntax', "Error: ").concat(e.message || 'There is an error in your .less file') +
  11003. "</h3><p>in <a href=\"".concat(filename, "\">").concat(filenameNoPath, "</a> ");
  11004. var errorline = function (e, i, classname) {
  11005. if (e.extract[i] !== undefined) {
  11006. errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
  11007. .replace(/\{class\}/, classname)
  11008. .replace(/\{content\}/, e.extract[i]));
  11009. }
  11010. };
  11011. if (e.line) {
  11012. errorline(e, 0, '');
  11013. errorline(e, 1, 'line');
  11014. errorline(e, 2, '');
  11015. content += "on line ".concat(e.line, ", column ").concat(e.column + 1, ":</p><ul>").concat(errors.join(''), "</ul>");
  11016. }
  11017. if (e.stack && (e.extract || options.logLevel >= 4)) {
  11018. content += "<br/>Stack Trace</br />".concat(e.stack.split('\n').slice(1).join('<br/>'));
  11019. }
  11020. elem.innerHTML = content;
  11021. // CSS for error messages
  11022. browser.createCSS(window.document, [
  11023. '.less-error-message ul, .less-error-message li {',
  11024. 'list-style-type: none;',
  11025. 'margin-right: 15px;',
  11026. 'padding: 4px 0;',
  11027. 'margin: 0;',
  11028. '}',
  11029. '.less-error-message label {',
  11030. 'font-size: 12px;',
  11031. 'margin-right: 15px;',
  11032. 'padding: 4px 0;',
  11033. 'color: #cc7777;',
  11034. '}',
  11035. '.less-error-message pre {',
  11036. 'color: #dd6666;',
  11037. 'padding: 4px 0;',
  11038. 'margin: 0;',
  11039. 'display: inline-block;',
  11040. '}',
  11041. '.less-error-message pre.line {',
  11042. 'color: #ff0000;',
  11043. '}',
  11044. '.less-error-message h3 {',
  11045. 'font-size: 20px;',
  11046. 'font-weight: bold;',
  11047. 'padding: 15px 0 5px 0;',
  11048. 'margin: 0;',
  11049. '}',
  11050. '.less-error-message a {',
  11051. 'color: #10a',
  11052. '}',
  11053. '.less-error-message .error {',
  11054. 'color: red;',
  11055. 'font-weight: bold;',
  11056. 'padding-bottom: 2px;',
  11057. 'border-bottom: 1px dashed red;',
  11058. '}'
  11059. ].join('\n'), { title: 'error-message' });
  11060. elem.style.cssText = [
  11061. 'font-family: Arial, sans-serif',
  11062. 'border: 1px solid #e00',
  11063. 'background-color: #eee',
  11064. 'border-radius: 5px',
  11065. '-webkit-border-radius: 5px',
  11066. '-moz-border-radius: 5px',
  11067. 'color: #e00',
  11068. 'padding: 15px',
  11069. 'margin-bottom: 15px'
  11070. ].join(';');
  11071. if (options.env === 'development') {
  11072. timer = setInterval(function () {
  11073. var document = window.document;
  11074. var body = document.body;
  11075. if (body) {
  11076. if (document.getElementById(id)) {
  11077. body.replaceChild(elem, document.getElementById(id));
  11078. }
  11079. else {
  11080. body.insertBefore(elem, body.firstChild);
  11081. }
  11082. clearInterval(timer);
  11083. }
  11084. }, 10);
  11085. }
  11086. }
  11087. function removeErrorHTML(path) {
  11088. var node = window.document.getElementById("less-error-message:".concat(extractId(path)));
  11089. if (node) {
  11090. node.parentNode.removeChild(node);
  11091. }
  11092. }
  11093. function removeError(path) {
  11094. if (!options.errorReporting || options.errorReporting === 'html') {
  11095. removeErrorHTML(path);
  11096. }
  11097. else if (options.errorReporting === 'console') ;
  11098. else if (typeof options.errorReporting === 'function') {
  11099. options.errorReporting('remove', path);
  11100. }
  11101. }
  11102. function errorConsole(e, rootHref) {
  11103. var template = '{line} {content}';
  11104. var filename = e.filename || rootHref;
  11105. var errors = [];
  11106. var content = "".concat(e.type || 'Syntax', "Error: ").concat(e.message || 'There is an error in your .less file', " in ").concat(filename);
  11107. var errorline = function (e, i, classname) {
  11108. if (e.extract[i] !== undefined) {
  11109. errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
  11110. .replace(/\{class\}/, classname)
  11111. .replace(/\{content\}/, e.extract[i]));
  11112. }
  11113. };
  11114. if (e.line) {
  11115. errorline(e, 0, '');
  11116. errorline(e, 1, 'line');
  11117. errorline(e, 2, '');
  11118. content += " on line ".concat(e.line, ", column ").concat(e.column + 1, ":\n").concat(errors.join('\n'));
  11119. }
  11120. if (e.stack && (e.extract || options.logLevel >= 4)) {
  11121. content += "\nStack Trace\n".concat(e.stack);
  11122. }
  11123. less.logger.error(content);
  11124. }
  11125. function error(e, rootHref) {
  11126. if (!options.errorReporting || options.errorReporting === 'html') {
  11127. errorHTML(e, rootHref);
  11128. }
  11129. else if (options.errorReporting === 'console') {
  11130. errorConsole(e, rootHref);
  11131. }
  11132. else if (typeof options.errorReporting === 'function') {
  11133. options.errorReporting('add', e, rootHref);
  11134. }
  11135. }
  11136. return {
  11137. add: error,
  11138. remove: removeError
  11139. };
  11140. });
  11141. // Cache system is a bit outdated and could do with work
  11142. var Cache = (function (window, options, logger) {
  11143. var cache = null;
  11144. if (options.env !== 'development') {
  11145. try {
  11146. cache = (typeof window.localStorage === 'undefined') ? null : window.localStorage;
  11147. }
  11148. catch (_) { }
  11149. }
  11150. return {
  11151. setCSS: function (path, lastModified, modifyVars, styles) {
  11152. if (cache) {
  11153. logger.info("saving ".concat(path, " to cache."));
  11154. try {
  11155. cache.setItem(path, styles);
  11156. cache.setItem("".concat(path, ":timestamp"), lastModified);
  11157. if (modifyVars) {
  11158. cache.setItem("".concat(path, ":vars"), JSON.stringify(modifyVars));
  11159. }
  11160. }
  11161. catch (e) {
  11162. // TODO - could do with adding more robust error handling
  11163. logger.error("failed to save \"".concat(path, "\" to local storage for caching."));
  11164. }
  11165. }
  11166. },
  11167. getCSS: function (path, webInfo, modifyVars) {
  11168. var css = cache && cache.getItem(path);
  11169. var timestamp = cache && cache.getItem("".concat(path, ":timestamp"));
  11170. var vars = cache && cache.getItem("".concat(path, ":vars"));
  11171. modifyVars = modifyVars || {};
  11172. vars = vars || '{}'; // if not set, treat as the JSON representation of an empty object
  11173. if (timestamp && webInfo.lastModified &&
  11174. (new Date(webInfo.lastModified).valueOf() ===
  11175. new Date(timestamp).valueOf()) &&
  11176. JSON.stringify(modifyVars) === vars) {
  11177. // Use local copy
  11178. return css;
  11179. }
  11180. }
  11181. };
  11182. });
  11183. var ImageSize = (function () {
  11184. function imageSize() {
  11185. throw {
  11186. type: 'Runtime',
  11187. message: 'Image size functions are not supported in browser version of less'
  11188. };
  11189. }
  11190. var imageFunctions = {
  11191. 'image-size': function (filePathNode) {
  11192. imageSize();
  11193. return -1;
  11194. },
  11195. 'image-width': function (filePathNode) {
  11196. imageSize();
  11197. return -1;
  11198. },
  11199. 'image-height': function (filePathNode) {
  11200. imageSize();
  11201. return -1;
  11202. }
  11203. };
  11204. functionRegistry.addMultiple(imageFunctions);
  11205. });
  11206. //
  11207. var root = (function (window, options) {
  11208. var document = window.document;
  11209. var less = lessRoot();
  11210. less.options = options;
  11211. var environment = less.environment;
  11212. var FileManager = FM(options, less.logger);
  11213. var fileManager = new FileManager();
  11214. environment.addFileManager(fileManager);
  11215. less.FileManager = FileManager;
  11216. less.PluginLoader = PluginLoader;
  11217. LogListener(less, options);
  11218. var errors = ErrorReporting(window, less, options);
  11219. var cache = less.cache = options.cache || Cache(window, options, less.logger);
  11220. ImageSize(less.environment);
  11221. // Setup user functions - Deprecate?
  11222. if (options.functions) {
  11223. less.functions.functionRegistry.addMultiple(options.functions);
  11224. }
  11225. var typePattern = /^text\/(x-)?less$/;
  11226. function clone(obj) {
  11227. var cloned = {};
  11228. for (var prop in obj) {
  11229. if (Object.prototype.hasOwnProperty.call(obj, prop)) {
  11230. cloned[prop] = obj[prop];
  11231. }
  11232. }
  11233. return cloned;
  11234. }
  11235. // only really needed for phantom
  11236. function bind(func, thisArg) {
  11237. var curryArgs = Array.prototype.slice.call(arguments, 2);
  11238. return function () {
  11239. var args = curryArgs.concat(Array.prototype.slice.call(arguments, 0));
  11240. return func.apply(thisArg, args);
  11241. };
  11242. }
  11243. function loadStyles(modifyVars) {
  11244. var styles = document.getElementsByTagName('style');
  11245. var style;
  11246. for (var i_1 = 0; i_1 < styles.length; i_1++) {
  11247. style = styles[i_1];
  11248. if (style.type.match(typePattern)) {
  11249. var instanceOptions = clone(options);
  11250. instanceOptions.modifyVars = modifyVars;
  11251. var lessText_1 = style.innerHTML || '';
  11252. instanceOptions.filename = document.location.href.replace(/#.*$/, '');
  11253. /* jshint loopfunc:true */
  11254. // use closure to store current style
  11255. less.render(lessText_1, instanceOptions, bind(function (style, e, result) {
  11256. if (e) {
  11257. errors.add(e, 'inline');
  11258. }
  11259. else {
  11260. style.type = 'text/css';
  11261. if (style.styleSheet) {
  11262. style.styleSheet.cssText = result.css;
  11263. }
  11264. else {
  11265. style.innerHTML = result.css;
  11266. }
  11267. }
  11268. }, null, style));
  11269. }
  11270. }
  11271. }
  11272. function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) {
  11273. var instanceOptions = clone(options);
  11274. addDataAttr(instanceOptions, sheet);
  11275. instanceOptions.mime = sheet.type;
  11276. if (modifyVars) {
  11277. instanceOptions.modifyVars = modifyVars;
  11278. }
  11279. function loadInitialFileCallback(loadedFile) {
  11280. var data = loadedFile.contents;
  11281. var path = loadedFile.filename;
  11282. var webInfo = loadedFile.webInfo;
  11283. var newFileInfo = {
  11284. currentDirectory: fileManager.getPath(path),
  11285. filename: path,
  11286. rootFilename: path,
  11287. rewriteUrls: instanceOptions.rewriteUrls
  11288. };
  11289. newFileInfo.entryPath = newFileInfo.currentDirectory;
  11290. newFileInfo.rootpath = instanceOptions.rootpath || newFileInfo.currentDirectory;
  11291. if (webInfo) {
  11292. webInfo.remaining = remaining;
  11293. var css = cache.getCSS(path, webInfo, instanceOptions.modifyVars);
  11294. if (!reload && css) {
  11295. webInfo.local = true;
  11296. callback(null, css, data, sheet, webInfo, path);
  11297. return;
  11298. }
  11299. }
  11300. // TODO add tests around how this behaves when reloading
  11301. errors.remove(path);
  11302. instanceOptions.rootFileInfo = newFileInfo;
  11303. less.render(data, instanceOptions, function (e, result) {
  11304. if (e) {
  11305. e.href = path;
  11306. callback(e);
  11307. }
  11308. else {
  11309. cache.setCSS(sheet.href, webInfo.lastModified, instanceOptions.modifyVars, result.css);
  11310. callback(null, result.css, data, sheet, webInfo, path);
  11311. }
  11312. });
  11313. }
  11314. fileManager.loadFile(sheet.href, null, instanceOptions, environment)
  11315. .then(function (loadedFile) {
  11316. loadInitialFileCallback(loadedFile);
  11317. }).catch(function (err) {
  11318. console.log(err);
  11319. callback(err);
  11320. });
  11321. }
  11322. function loadStyleSheets(callback, reload, modifyVars) {
  11323. for (var i_2 = 0; i_2 < less.sheets.length; i_2++) {
  11324. loadStyleSheet(less.sheets[i_2], callback, reload, less.sheets.length - (i_2 + 1), modifyVars);
  11325. }
  11326. }
  11327. function initRunningMode() {
  11328. if (less.env === 'development') {
  11329. less.watchTimer = setInterval(function () {
  11330. if (less.watchMode) {
  11331. fileManager.clearFileCache();
  11332. /**
  11333. * @todo remove when this is typed with JSDoc
  11334. */
  11335. // eslint-disable-next-line no-unused-vars
  11336. loadStyleSheets(function (e, css, _, sheet, webInfo) {
  11337. if (e) {
  11338. errors.add(e, e.href || sheet.href);
  11339. }
  11340. else if (css) {
  11341. browser.createCSS(window.document, css, sheet);
  11342. }
  11343. });
  11344. }
  11345. }, options.poll);
  11346. }
  11347. }
  11348. //
  11349. // Watch mode
  11350. //
  11351. less.watch = function () {
  11352. if (!less.watchMode) {
  11353. less.env = 'development';
  11354. initRunningMode();
  11355. }
  11356. this.watchMode = true;
  11357. return true;
  11358. };
  11359. less.unwatch = function () { clearInterval(less.watchTimer); this.watchMode = false; return false; };
  11360. //
  11361. // Synchronously get all <link> tags with the 'rel' attribute set to
  11362. // "stylesheet/less".
  11363. //
  11364. less.registerStylesheetsImmediately = function () {
  11365. var links = document.getElementsByTagName('link');
  11366. less.sheets = [];
  11367. for (var i_3 = 0; i_3 < links.length; i_3++) {
  11368. if (links[i_3].rel === 'stylesheet/less' || (links[i_3].rel.match(/stylesheet/) &&
  11369. (links[i_3].type.match(typePattern)))) {
  11370. less.sheets.push(links[i_3]);
  11371. }
  11372. }
  11373. };
  11374. //
  11375. // Asynchronously get all <link> tags with the 'rel' attribute set to
  11376. // "stylesheet/less", returning a Promise.
  11377. //
  11378. less.registerStylesheets = function () { return new Promise(function (resolve) {
  11379. less.registerStylesheetsImmediately();
  11380. resolve();
  11381. }); };
  11382. //
  11383. // With this function, it's possible to alter variables and re-render
  11384. // CSS without reloading less-files
  11385. //
  11386. less.modifyVars = function (record) { return less.refresh(true, record, false); };
  11387. less.refresh = function (reload, modifyVars, clearFileCache) {
  11388. if ((reload || clearFileCache) && clearFileCache !== false) {
  11389. fileManager.clearFileCache();
  11390. }
  11391. return new Promise(function (resolve, reject) {
  11392. var startTime;
  11393. var endTime;
  11394. var totalMilliseconds;
  11395. var remainingSheets;
  11396. startTime = endTime = new Date();
  11397. // Set counter for remaining unprocessed sheets
  11398. remainingSheets = less.sheets.length;
  11399. if (remainingSheets === 0) {
  11400. endTime = new Date();
  11401. totalMilliseconds = endTime - startTime;
  11402. less.logger.info('Less has finished and no sheets were loaded.');
  11403. resolve({
  11404. startTime: startTime,
  11405. endTime: endTime,
  11406. totalMilliseconds: totalMilliseconds,
  11407. sheets: less.sheets.length
  11408. });
  11409. }
  11410. else {
  11411. // Relies on less.sheets array, callback seems to be guaranteed to be called for every element of the array
  11412. loadStyleSheets(function (e, css, _, sheet, webInfo) {
  11413. if (e) {
  11414. errors.add(e, e.href || sheet.href);
  11415. reject(e);
  11416. return;
  11417. }
  11418. if (webInfo.local) {
  11419. less.logger.info("Loading ".concat(sheet.href, " from cache."));
  11420. }
  11421. else {
  11422. less.logger.info("Rendered ".concat(sheet.href, " successfully."));
  11423. }
  11424. browser.createCSS(window.document, css, sheet);
  11425. less.logger.info("CSS for ".concat(sheet.href, " generated in ").concat(new Date() - endTime, "ms"));
  11426. // Count completed sheet
  11427. remainingSheets--;
  11428. // Check if the last remaining sheet was processed and then call the promise
  11429. if (remainingSheets === 0) {
  11430. totalMilliseconds = new Date() - startTime;
  11431. less.logger.info("Less has finished. CSS generated in ".concat(totalMilliseconds, "ms"));
  11432. resolve({
  11433. startTime: startTime,
  11434. endTime: endTime,
  11435. totalMilliseconds: totalMilliseconds,
  11436. sheets: less.sheets.length
  11437. });
  11438. }
  11439. endTime = new Date();
  11440. }, reload, modifyVars);
  11441. }
  11442. loadStyles(modifyVars);
  11443. });
  11444. };
  11445. less.refreshStyles = loadStyles;
  11446. return less;
  11447. });
  11448. /**
  11449. * Kicks off less and compiles any stylesheets
  11450. * used in the browser distributed version of less
  11451. * to kick-start less using the browser api
  11452. */
  11453. var options = defaultOptions();
  11454. if (window.less) {
  11455. for (var key in window.less) {
  11456. if (Object.prototype.hasOwnProperty.call(window.less, key)) {
  11457. options[key] = window.less[key];
  11458. }
  11459. }
  11460. }
  11461. addDefaultOptions(window, options);
  11462. options.plugins = options.plugins || [];
  11463. if (window.LESS_PLUGINS) {
  11464. options.plugins = options.plugins.concat(window.LESS_PLUGINS);
  11465. }
  11466. var less = root(window, options);
  11467. window.less = less;
  11468. var css;
  11469. var head;
  11470. var style;
  11471. // Always restore page visibility
  11472. function resolveOrReject(data) {
  11473. if (data.filename) {
  11474. console.warn(data);
  11475. }
  11476. if (!options.async) {
  11477. head.removeChild(style);
  11478. }
  11479. }
  11480. if (options.onReady) {
  11481. if (/!watch/.test(window.location.hash)) {
  11482. less.watch();
  11483. }
  11484. // Simulate synchronous stylesheet loading by hiding page rendering
  11485. if (!options.async) {
  11486. css = 'body { display: none !important }';
  11487. head = document.head || document.getElementsByTagName('head')[0];
  11488. style = document.createElement('style');
  11489. style.type = 'text/css';
  11490. if (style.styleSheet) {
  11491. style.styleSheet.cssText = css;
  11492. }
  11493. else {
  11494. style.appendChild(document.createTextNode(css));
  11495. }
  11496. head.appendChild(style);
  11497. }
  11498. less.registerStylesheetsImmediately();
  11499. less.pageLoadFinished = less.refresh(less.env === 'development').then(resolveOrReject, resolveOrReject);
  11500. }
  11501. return less;
  11502. }));