less.js 457 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548
  1. /**
  2. * Less - Leaner CSS v3.11.1
  3. * http://lesscss.org
  4. *
  5. * Copyright (c) 2009-2020, 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 = global || self, global.less = factory());
  14. }(this, (function () { 'use strict';
  15. // Export a new default each time
  16. var defaultOptions = (function () { return ({
  17. /* Inline Javascript - @plugin still allowed */
  18. javascriptEnabled: false,
  19. /* Outputs a makefile import dependency list to stdout. */
  20. depends: false,
  21. /* (DEPRECATED) Compress using less built-in compression.
  22. * This does an okay job but does not utilise all the tricks of
  23. * dedicated css compression. */
  24. compress: false,
  25. /* Runs the less parser and just reports errors without any output. */
  26. lint: false,
  27. /* Sets available include paths.
  28. * If the file in an @import rule does not exist at that exact location,
  29. * less will look for it at the location(s) passed to this option.
  30. * You might use this for instance to specify a path to a library which
  31. * you want to be referenced simply and relatively in the less files. */
  32. paths: [],
  33. /* color output in the terminal */
  34. color: true,
  35. /* The strictImports controls whether the compiler will allow an @import inside of either
  36. * @media blocks or (a later addition) other selector blocks.
  37. * See: https://github.com/less/less.js/issues/656 */
  38. strictImports: false,
  39. /* Allow Imports from Insecure HTTPS Hosts */
  40. insecure: false,
  41. /* Allows you to add a path to every generated import and url in your css.
  42. * This does not affect less import statements that are processed, just ones
  43. * that are left in the output css. */
  44. rootpath: '',
  45. /* By default URLs are kept as-is, so if you import a file in a sub-directory
  46. * that references an image, exactly the same URL will be output in the css.
  47. * This option allows you to re-write URL's in imported files so that the
  48. * URL is always relative to the base imported file */
  49. rewriteUrls: false,
  50. /* How to process math
  51. * 0 always - eagerly try to solve all operations
  52. * 1 parens-division - require parens for division "/"
  53. * 2 parens | strict - require parens for all operations
  54. * 3 strict-legacy - legacy strict behavior (super-strict)
  55. */
  56. math: 0,
  57. /* Without this option, less attempts to guess at the output unit when it does maths. */
  58. strictUnits: false,
  59. /* Effectively the declaration is put at the top of your base Less file,
  60. * meaning it can be used but it also can be overridden if this variable
  61. * is defined in the file. */
  62. globalVars: null,
  63. /* As opposed to the global variable option, this puts the declaration at the
  64. * end of your base file, meaning it will override anything defined in your Less file. */
  65. modifyVars: null,
  66. /* This option allows you to specify a argument to go on to every URL. */
  67. urlArgs: ''
  68. }); });
  69. function extractId(href) {
  70. return href.replace(/^[a-z-]+:\/+?[^\/]+/, '') // Remove protocol & domain
  71. .replace(/[\?\&]livereload=\w+/, '') // Remove LiveReload cachebuster
  72. .replace(/^\//, '') // Remove root /
  73. .replace(/\.[a-zA-Z]+$/, '') // Remove simple extension
  74. .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
  75. .replace(/\./g, ':'); // Replace dots with colons(for valid id)
  76. }
  77. function addDataAttr(options, tag) {
  78. for (var opt in tag.dataset) {
  79. if (tag.dataset.hasOwnProperty(opt)) {
  80. if (opt === 'env' || opt === 'dumpLineNumbers' || opt === 'rootpath' || opt === 'errorReporting') {
  81. options[opt] = tag.dataset[opt];
  82. }
  83. else {
  84. try {
  85. options[opt] = JSON.parse(tag.dataset[opt]);
  86. }
  87. catch (_) { }
  88. }
  89. }
  90. }
  91. }
  92. var browser = {
  93. createCSS: function (document, styles, sheet) {
  94. // Strip the query-string
  95. var href = sheet.href || '';
  96. // If there is no title set, use the filename, minus the extension
  97. var id = "less:" + (sheet.title || extractId(href));
  98. // If this has already been inserted into the DOM, we may need to replace it
  99. var oldStyleNode = document.getElementById(id);
  100. var keepOldStyleNode = false;
  101. // Create a new stylesheet node for insertion or (if necessary) replacement
  102. var styleNode = document.createElement('style');
  103. styleNode.setAttribute('type', 'text/css');
  104. if (sheet.media) {
  105. styleNode.setAttribute('media', sheet.media);
  106. }
  107. styleNode.id = id;
  108. if (!styleNode.styleSheet) {
  109. styleNode.appendChild(document.createTextNode(styles));
  110. // If new contents match contents of oldStyleNode, don't replace oldStyleNode
  111. keepOldStyleNode = (oldStyleNode !== null && oldStyleNode.childNodes.length > 0 && styleNode.childNodes.length > 0 &&
  112. oldStyleNode.firstChild.nodeValue === styleNode.firstChild.nodeValue);
  113. }
  114. var head = document.getElementsByTagName('head')[0];
  115. // If there is no oldStyleNode, just append; otherwise, only append if we need
  116. // to replace oldStyleNode with an updated stylesheet
  117. if (oldStyleNode === null || keepOldStyleNode === false) {
  118. var nextEl = sheet && sheet.nextSibling || null;
  119. if (nextEl) {
  120. nextEl.parentNode.insertBefore(styleNode, nextEl);
  121. }
  122. else {
  123. head.appendChild(styleNode);
  124. }
  125. }
  126. if (oldStyleNode && keepOldStyleNode === false) {
  127. oldStyleNode.parentNode.removeChild(oldStyleNode);
  128. }
  129. // For IE.
  130. // This needs to happen *after* the style element is added to the DOM, otherwise IE 7 and 8 may crash.
  131. // See http://social.msdn.microsoft.com/Forums/en-US/7e081b65-878a-4c22-8e68-c10d39c2ed32/internet-explorer-crashes-appending-style-element-to-head
  132. if (styleNode.styleSheet) {
  133. try {
  134. styleNode.styleSheet.cssText = styles;
  135. }
  136. catch (e) {
  137. throw new Error('Couldn\'t reassign styleSheet.cssText.');
  138. }
  139. }
  140. },
  141. currentScript: function (window) {
  142. var document = window.document;
  143. return document.currentScript || (function () {
  144. var scripts = document.getElementsByTagName('script');
  145. return scripts[scripts.length - 1];
  146. })();
  147. }
  148. };
  149. var addDefaultOptions = (function (window, options) {
  150. // use options from the current script tag data attribues
  151. addDataAttr(options, browser.currentScript(window));
  152. if (options.isFileProtocol === undefined) {
  153. options.isFileProtocol = /^(file|(chrome|safari)(-extension)?|resource|qrc|app):/.test(window.location.protocol);
  154. }
  155. // Load styles asynchronously (default: false)
  156. //
  157. // This is set to `false` by default, so that the body
  158. // doesn't start loading before the stylesheets are parsed.
  159. // Setting this to `true` can result in flickering.
  160. //
  161. options.async = options.async || false;
  162. options.fileAsync = options.fileAsync || false;
  163. // Interval between watch polls
  164. options.poll = options.poll || (options.isFileProtocol ? 1000 : 1500);
  165. options.env = options.env || (window.location.hostname == '127.0.0.1' ||
  166. window.location.hostname == '0.0.0.0' ||
  167. window.location.hostname == 'localhost' ||
  168. (window.location.port &&
  169. window.location.port.length > 0) ||
  170. options.isFileProtocol ? 'development'
  171. : 'production');
  172. var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(window.location.hash);
  173. if (dumpLineNumbers) {
  174. options.dumpLineNumbers = dumpLineNumbers[1];
  175. }
  176. if (options.useFileCache === undefined) {
  177. options.useFileCache = true;
  178. }
  179. if (options.onReady === undefined) {
  180. options.onReady = true;
  181. }
  182. if (options.relativeUrls) {
  183. options.rewriteUrls = 'all';
  184. }
  185. });
  186. /*! *****************************************************************************
  187. Copyright (c) Microsoft Corporation. All rights reserved.
  188. Licensed under the Apache License, Version 2.0 (the "License"); you may not use
  189. this file except in compliance with the License. You may obtain a copy of the
  190. License at http://www.apache.org/licenses/LICENSE-2.0
  191. THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  192. KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
  193. WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
  194. MERCHANTABLITY OR NON-INFRINGEMENT.
  195. See the Apache Version 2.0 License for specific language governing permissions
  196. and limitations under the License.
  197. ***************************************************************************** */
  198. /* global Reflect, Promise */
  199. var extendStatics = function(d, b) {
  200. extendStatics = Object.setPrototypeOf ||
  201. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  202. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  203. return extendStatics(d, b);
  204. };
  205. function __extends(d, b) {
  206. extendStatics(d, b);
  207. function __() { this.constructor = d; }
  208. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  209. }
  210. function __spreadArrays() {
  211. for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
  212. for (var r = Array(s), k = 0, i = 0; i < il; i++)
  213. for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
  214. r[k] = a[j];
  215. return r;
  216. }
  217. var colors = {
  218. 'aliceblue': '#f0f8ff',
  219. 'antiquewhite': '#faebd7',
  220. 'aqua': '#00ffff',
  221. 'aquamarine': '#7fffd4',
  222. 'azure': '#f0ffff',
  223. 'beige': '#f5f5dc',
  224. 'bisque': '#ffe4c4',
  225. 'black': '#000000',
  226. 'blanchedalmond': '#ffebcd',
  227. 'blue': '#0000ff',
  228. 'blueviolet': '#8a2be2',
  229. 'brown': '#a52a2a',
  230. 'burlywood': '#deb887',
  231. 'cadetblue': '#5f9ea0',
  232. 'chartreuse': '#7fff00',
  233. 'chocolate': '#d2691e',
  234. 'coral': '#ff7f50',
  235. 'cornflowerblue': '#6495ed',
  236. 'cornsilk': '#fff8dc',
  237. 'crimson': '#dc143c',
  238. 'cyan': '#00ffff',
  239. 'darkblue': '#00008b',
  240. 'darkcyan': '#008b8b',
  241. 'darkgoldenrod': '#b8860b',
  242. 'darkgray': '#a9a9a9',
  243. 'darkgrey': '#a9a9a9',
  244. 'darkgreen': '#006400',
  245. 'darkkhaki': '#bdb76b',
  246. 'darkmagenta': '#8b008b',
  247. 'darkolivegreen': '#556b2f',
  248. 'darkorange': '#ff8c00',
  249. 'darkorchid': '#9932cc',
  250. 'darkred': '#8b0000',
  251. 'darksalmon': '#e9967a',
  252. 'darkseagreen': '#8fbc8f',
  253. 'darkslateblue': '#483d8b',
  254. 'darkslategray': '#2f4f4f',
  255. 'darkslategrey': '#2f4f4f',
  256. 'darkturquoise': '#00ced1',
  257. 'darkviolet': '#9400d3',
  258. 'deeppink': '#ff1493',
  259. 'deepskyblue': '#00bfff',
  260. 'dimgray': '#696969',
  261. 'dimgrey': '#696969',
  262. 'dodgerblue': '#1e90ff',
  263. 'firebrick': '#b22222',
  264. 'floralwhite': '#fffaf0',
  265. 'forestgreen': '#228b22',
  266. 'fuchsia': '#ff00ff',
  267. 'gainsboro': '#dcdcdc',
  268. 'ghostwhite': '#f8f8ff',
  269. 'gold': '#ffd700',
  270. 'goldenrod': '#daa520',
  271. 'gray': '#808080',
  272. 'grey': '#808080',
  273. 'green': '#008000',
  274. 'greenyellow': '#adff2f',
  275. 'honeydew': '#f0fff0',
  276. 'hotpink': '#ff69b4',
  277. 'indianred': '#cd5c5c',
  278. 'indigo': '#4b0082',
  279. 'ivory': '#fffff0',
  280. 'khaki': '#f0e68c',
  281. 'lavender': '#e6e6fa',
  282. 'lavenderblush': '#fff0f5',
  283. 'lawngreen': '#7cfc00',
  284. 'lemonchiffon': '#fffacd',
  285. 'lightblue': '#add8e6',
  286. 'lightcoral': '#f08080',
  287. 'lightcyan': '#e0ffff',
  288. 'lightgoldenrodyellow': '#fafad2',
  289. 'lightgray': '#d3d3d3',
  290. 'lightgrey': '#d3d3d3',
  291. 'lightgreen': '#90ee90',
  292. 'lightpink': '#ffb6c1',
  293. 'lightsalmon': '#ffa07a',
  294. 'lightseagreen': '#20b2aa',
  295. 'lightskyblue': '#87cefa',
  296. 'lightslategray': '#778899',
  297. 'lightslategrey': '#778899',
  298. 'lightsteelblue': '#b0c4de',
  299. 'lightyellow': '#ffffe0',
  300. 'lime': '#00ff00',
  301. 'limegreen': '#32cd32',
  302. 'linen': '#faf0e6',
  303. 'magenta': '#ff00ff',
  304. 'maroon': '#800000',
  305. 'mediumaquamarine': '#66cdaa',
  306. 'mediumblue': '#0000cd',
  307. 'mediumorchid': '#ba55d3',
  308. 'mediumpurple': '#9370d8',
  309. 'mediumseagreen': '#3cb371',
  310. 'mediumslateblue': '#7b68ee',
  311. 'mediumspringgreen': '#00fa9a',
  312. 'mediumturquoise': '#48d1cc',
  313. 'mediumvioletred': '#c71585',
  314. 'midnightblue': '#191970',
  315. 'mintcream': '#f5fffa',
  316. 'mistyrose': '#ffe4e1',
  317. 'moccasin': '#ffe4b5',
  318. 'navajowhite': '#ffdead',
  319. 'navy': '#000080',
  320. 'oldlace': '#fdf5e6',
  321. 'olive': '#808000',
  322. 'olivedrab': '#6b8e23',
  323. 'orange': '#ffa500',
  324. 'orangered': '#ff4500',
  325. 'orchid': '#da70d6',
  326. 'palegoldenrod': '#eee8aa',
  327. 'palegreen': '#98fb98',
  328. 'paleturquoise': '#afeeee',
  329. 'palevioletred': '#d87093',
  330. 'papayawhip': '#ffefd5',
  331. 'peachpuff': '#ffdab9',
  332. 'peru': '#cd853f',
  333. 'pink': '#ffc0cb',
  334. 'plum': '#dda0dd',
  335. 'powderblue': '#b0e0e6',
  336. 'purple': '#800080',
  337. 'rebeccapurple': '#663399',
  338. 'red': '#ff0000',
  339. 'rosybrown': '#bc8f8f',
  340. 'royalblue': '#4169e1',
  341. 'saddlebrown': '#8b4513',
  342. 'salmon': '#fa8072',
  343. 'sandybrown': '#f4a460',
  344. 'seagreen': '#2e8b57',
  345. 'seashell': '#fff5ee',
  346. 'sienna': '#a0522d',
  347. 'silver': '#c0c0c0',
  348. 'skyblue': '#87ceeb',
  349. 'slateblue': '#6a5acd',
  350. 'slategray': '#708090',
  351. 'slategrey': '#708090',
  352. 'snow': '#fffafa',
  353. 'springgreen': '#00ff7f',
  354. 'steelblue': '#4682b4',
  355. 'tan': '#d2b48c',
  356. 'teal': '#008080',
  357. 'thistle': '#d8bfd8',
  358. 'tomato': '#ff6347',
  359. 'turquoise': '#40e0d0',
  360. 'violet': '#ee82ee',
  361. 'wheat': '#f5deb3',
  362. 'white': '#ffffff',
  363. 'whitesmoke': '#f5f5f5',
  364. 'yellow': '#ffff00',
  365. 'yellowgreen': '#9acd32'
  366. };
  367. var unitConversions = {
  368. length: {
  369. 'm': 1,
  370. 'cm': 0.01,
  371. 'mm': 0.001,
  372. 'in': 0.0254,
  373. 'px': 0.0254 / 96,
  374. 'pt': 0.0254 / 72,
  375. 'pc': 0.0254 / 72 * 12
  376. },
  377. duration: {
  378. 's': 1,
  379. 'ms': 0.001
  380. },
  381. angle: {
  382. 'rad': 1 / (2 * Math.PI),
  383. 'deg': 1 / 360,
  384. 'grad': 1 / 400,
  385. 'turn': 1
  386. }
  387. };
  388. var data = { colors: colors, unitConversions: unitConversions };
  389. var Node = /** @class */ (function () {
  390. function Node() {
  391. this.parent = null;
  392. this.visibilityBlocks = undefined;
  393. this.nodeVisible = undefined;
  394. this.rootNode = null;
  395. this.parsed = null;
  396. var self = this;
  397. Object.defineProperty(this, 'currentFileInfo', {
  398. get: function () { return self.fileInfo(); }
  399. });
  400. Object.defineProperty(this, 'index', {
  401. get: function () { return self.getIndex(); }
  402. });
  403. }
  404. Node.prototype.setParent = function (nodes, parent) {
  405. function set(node) {
  406. if (node && node instanceof Node) {
  407. node.parent = parent;
  408. }
  409. }
  410. if (Array.isArray(nodes)) {
  411. nodes.forEach(set);
  412. }
  413. else {
  414. set(nodes);
  415. }
  416. };
  417. Node.prototype.getIndex = function () {
  418. return this._index || (this.parent && this.parent.getIndex()) || 0;
  419. };
  420. Node.prototype.fileInfo = function () {
  421. return this._fileInfo || (this.parent && this.parent.fileInfo()) || {};
  422. };
  423. Node.prototype.isRulesetLike = function () {
  424. return false;
  425. };
  426. Node.prototype.toCSS = function (context) {
  427. var strs = [];
  428. this.genCSS(context, {
  429. add: function (chunk, fileInfo, index) {
  430. strs.push(chunk);
  431. },
  432. isEmpty: function () {
  433. return strs.length === 0;
  434. }
  435. });
  436. return strs.join('');
  437. };
  438. Node.prototype.genCSS = function (context, output) {
  439. output.add(this.value);
  440. };
  441. Node.prototype.accept = function (visitor) {
  442. this.value = visitor.visit(this.value);
  443. };
  444. Node.prototype.eval = function () { return this; };
  445. Node.prototype._operate = function (context, op, a, b) {
  446. switch (op) {
  447. case '+': return a + b;
  448. case '-': return a - b;
  449. case '*': return a * b;
  450. case '/': return a / b;
  451. }
  452. };
  453. Node.prototype.fround = function (context, value) {
  454. var precision = context && context.numPrecision;
  455. // add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999...) are properly rounded:
  456. return (precision) ? Number((value + 2e-16).toFixed(precision)) : value;
  457. };
  458. // Returns true if this node represents root of ast imported by reference
  459. Node.prototype.blocksVisibility = function () {
  460. if (this.visibilityBlocks == null) {
  461. this.visibilityBlocks = 0;
  462. }
  463. return this.visibilityBlocks !== 0;
  464. };
  465. Node.prototype.addVisibilityBlock = function () {
  466. if (this.visibilityBlocks == null) {
  467. this.visibilityBlocks = 0;
  468. }
  469. this.visibilityBlocks = this.visibilityBlocks + 1;
  470. };
  471. Node.prototype.removeVisibilityBlock = function () {
  472. if (this.visibilityBlocks == null) {
  473. this.visibilityBlocks = 0;
  474. }
  475. this.visibilityBlocks = this.visibilityBlocks - 1;
  476. };
  477. // Turns on node visibility - if called node will be shown in output regardless
  478. // of whether it comes from import by reference or not
  479. Node.prototype.ensureVisibility = function () {
  480. this.nodeVisible = true;
  481. };
  482. // Turns off node visibility - if called node will NOT be shown in output regardless
  483. // of whether it comes from import by reference or not
  484. Node.prototype.ensureInvisibility = function () {
  485. this.nodeVisible = false;
  486. };
  487. // return values:
  488. // false - the node must not be visible
  489. // true - the node must be visible
  490. // undefined or null - the node has the same visibility as its parent
  491. Node.prototype.isVisible = function () {
  492. return this.nodeVisible;
  493. };
  494. Node.prototype.visibilityInfo = function () {
  495. return {
  496. visibilityBlocks: this.visibilityBlocks,
  497. nodeVisible: this.nodeVisible
  498. };
  499. };
  500. Node.prototype.copyVisibilityInfo = function (info) {
  501. if (!info) {
  502. return;
  503. }
  504. this.visibilityBlocks = info.visibilityBlocks;
  505. this.nodeVisible = info.nodeVisible;
  506. };
  507. return Node;
  508. }());
  509. Node.compare = function (a, b) {
  510. /* returns:
  511. -1: a < b
  512. 0: a = b
  513. 1: a > b
  514. and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */
  515. if ((a.compare) &&
  516. // for "symmetric results" force toCSS-based comparison
  517. // of Quoted or Anonymous if either value is one of those
  518. !(b.type === 'Quoted' || b.type === 'Anonymous')) {
  519. return a.compare(b);
  520. }
  521. else if (b.compare) {
  522. return -b.compare(a);
  523. }
  524. else if (a.type !== b.type) {
  525. return undefined;
  526. }
  527. a = a.value;
  528. b = b.value;
  529. if (!Array.isArray(a)) {
  530. return a === b ? 0 : undefined;
  531. }
  532. if (a.length !== b.length) {
  533. return undefined;
  534. }
  535. for (var i_1 = 0; i_1 < a.length; i_1++) {
  536. if (Node.compare(a[i_1], b[i_1]) !== 0) {
  537. return undefined;
  538. }
  539. }
  540. return 0;
  541. };
  542. Node.numericCompare = function (a, b) { return a < b ? -1
  543. : a === b ? 0
  544. : a > b ? 1 : undefined; };
  545. //
  546. // RGB Colors - #ff0014, #eee
  547. //
  548. var Color = /** @class */ (function (_super) {
  549. __extends(Color, _super);
  550. function Color(rgb, a, originalForm) {
  551. var _this = _super.call(this) || this;
  552. var self = _this;
  553. //
  554. // The end goal here, is to parse the arguments
  555. // into an integer triplet, such as `128, 255, 0`
  556. //
  557. // This facilitates operations and conversions.
  558. //
  559. if (Array.isArray(rgb)) {
  560. _this.rgb = rgb;
  561. }
  562. else if (rgb.length >= 6) {
  563. _this.rgb = [];
  564. rgb.match(/.{2}/g).map(function (c, i) {
  565. if (i < 3) {
  566. self.rgb.push(parseInt(c, 16));
  567. }
  568. else {
  569. self.alpha = (parseInt(c, 16)) / 255;
  570. }
  571. });
  572. }
  573. else {
  574. _this.rgb = [];
  575. rgb.split('').map(function (c, i) {
  576. if (i < 3) {
  577. self.rgb.push(parseInt(c + c, 16));
  578. }
  579. else {
  580. self.alpha = (parseInt(c + c, 16)) / 255;
  581. }
  582. });
  583. }
  584. _this.alpha = _this.alpha || (typeof a === 'number' ? a : 1);
  585. if (typeof originalForm !== 'undefined') {
  586. _this.value = originalForm;
  587. }
  588. return _this;
  589. }
  590. Color.prototype.luma = function () {
  591. var r = this.rgb[0] / 255;
  592. var g = this.rgb[1] / 255;
  593. var b = this.rgb[2] / 255;
  594. r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4);
  595. g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4);
  596. b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4);
  597. return 0.2126 * r + 0.7152 * g + 0.0722 * b;
  598. };
  599. Color.prototype.genCSS = function (context, output) {
  600. output.add(this.toCSS(context));
  601. };
  602. Color.prototype.toCSS = function (context, doNotCompress) {
  603. var compress = context && context.compress && !doNotCompress;
  604. var color;
  605. var alpha;
  606. var colorFunction;
  607. var args = [];
  608. // `value` is set if this color was originally
  609. // converted from a named color string so we need
  610. // to respect this and try to output named color too.
  611. alpha = this.fround(context, this.alpha);
  612. if (this.value) {
  613. if (this.value.indexOf('rgb') === 0) {
  614. if (alpha < 1) {
  615. colorFunction = 'rgba';
  616. }
  617. }
  618. else if (this.value.indexOf('hsl') === 0) {
  619. if (alpha < 1) {
  620. colorFunction = 'hsla';
  621. }
  622. else {
  623. colorFunction = 'hsl';
  624. }
  625. }
  626. else {
  627. return this.value;
  628. }
  629. }
  630. else {
  631. if (alpha < 1) {
  632. colorFunction = 'rgba';
  633. }
  634. }
  635. switch (colorFunction) {
  636. case 'rgba':
  637. args = this.rgb.map(function (c) { return clamp(Math.round(c), 255); }).concat(clamp(alpha, 1));
  638. break;
  639. case 'hsla':
  640. args.push(clamp(alpha, 1));
  641. case 'hsl':
  642. color = this.toHSL();
  643. args = [
  644. this.fround(context, color.h),
  645. this.fround(context, color.s * 100) + "%",
  646. this.fround(context, color.l * 100) + "%"
  647. ].concat(args);
  648. }
  649. if (colorFunction) {
  650. // Values are capped between `0` and `255`, rounded and zero-padded.
  651. return colorFunction + "(" + args.join("," + (compress ? '' : ' ')) + ")";
  652. }
  653. color = this.toRGB();
  654. if (compress) {
  655. var splitcolor = color.split('');
  656. // Convert color to short format
  657. if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) {
  658. color = "#" + splitcolor[1] + splitcolor[3] + splitcolor[5];
  659. }
  660. }
  661. return color;
  662. };
  663. //
  664. // Operations have to be done per-channel, if not,
  665. // channels will spill onto each other. Once we have
  666. // our result, in the form of an integer triplet,
  667. // we create a new Color node to hold the result.
  668. //
  669. Color.prototype.operate = function (context, op, other) {
  670. var rgb = new Array(3);
  671. var alpha = this.alpha * (1 - other.alpha) + other.alpha;
  672. for (var c = 0; c < 3; c++) {
  673. rgb[c] = this._operate(context, op, this.rgb[c], other.rgb[c]);
  674. }
  675. return new Color(rgb, alpha);
  676. };
  677. Color.prototype.toRGB = function () {
  678. return toHex(this.rgb);
  679. };
  680. Color.prototype.toHSL = function () {
  681. var r = this.rgb[0] / 255;
  682. var g = this.rgb[1] / 255;
  683. var b = this.rgb[2] / 255;
  684. var a = this.alpha;
  685. var max = Math.max(r, g, b);
  686. var min = Math.min(r, g, b);
  687. var h;
  688. var s;
  689. var l = (max + min) / 2;
  690. var d = max - min;
  691. if (max === min) {
  692. h = s = 0;
  693. }
  694. else {
  695. s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
  696. switch (max) {
  697. case r:
  698. h = (g - b) / d + (g < b ? 6 : 0);
  699. break;
  700. case g:
  701. h = (b - r) / d + 2;
  702. break;
  703. case b:
  704. h = (r - g) / d + 4;
  705. break;
  706. }
  707. h /= 6;
  708. }
  709. return { h: h * 360, s: s, l: l, a: a };
  710. };
  711. // Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
  712. Color.prototype.toHSV = function () {
  713. var r = this.rgb[0] / 255;
  714. var g = this.rgb[1] / 255;
  715. var b = this.rgb[2] / 255;
  716. var a = this.alpha;
  717. var max = Math.max(r, g, b);
  718. var min = Math.min(r, g, b);
  719. var h;
  720. var s;
  721. var v = max;
  722. var d = max - min;
  723. if (max === 0) {
  724. s = 0;
  725. }
  726. else {
  727. s = d / max;
  728. }
  729. if (max === min) {
  730. h = 0;
  731. }
  732. else {
  733. switch (max) {
  734. case r:
  735. h = (g - b) / d + (g < b ? 6 : 0);
  736. break;
  737. case g:
  738. h = (b - r) / d + 2;
  739. break;
  740. case b:
  741. h = (r - g) / d + 4;
  742. break;
  743. }
  744. h /= 6;
  745. }
  746. return { h: h * 360, s: s, v: v, a: a };
  747. };
  748. Color.prototype.toARGB = function () {
  749. return toHex([this.alpha * 255].concat(this.rgb));
  750. };
  751. Color.prototype.compare = function (x) {
  752. return (x.rgb &&
  753. x.rgb[0] === this.rgb[0] &&
  754. x.rgb[1] === this.rgb[1] &&
  755. x.rgb[2] === this.rgb[2] &&
  756. x.alpha === this.alpha) ? 0 : undefined;
  757. };
  758. return Color;
  759. }(Node));
  760. Color.prototype.type = 'Color';
  761. function clamp(v, max) {
  762. return Math.min(Math.max(v, 0), max);
  763. }
  764. function toHex(v) {
  765. return "#" + v.map(function (c) {
  766. c = clamp(Math.round(c), 255);
  767. return (c < 16 ? '0' : '') + c.toString(16);
  768. }).join('');
  769. }
  770. Color.fromKeyword = function (keyword) {
  771. var c;
  772. var key = keyword.toLowerCase();
  773. if (colors.hasOwnProperty(key)) {
  774. c = new Color(colors[key].slice(1));
  775. }
  776. else if (key === 'transparent') {
  777. c = new Color([0, 0, 0], 0);
  778. }
  779. if (c) {
  780. c.value = keyword;
  781. return c;
  782. }
  783. };
  784. var Paren = /** @class */ (function (_super) {
  785. __extends(Paren, _super);
  786. function Paren(node) {
  787. var _this = _super.call(this) || this;
  788. _this.value = node;
  789. return _this;
  790. }
  791. Paren.prototype.genCSS = function (context, output) {
  792. output.add('(');
  793. this.value.genCSS(context, output);
  794. output.add(')');
  795. };
  796. Paren.prototype.eval = function (context) {
  797. return new Paren(this.value.eval(context));
  798. };
  799. return Paren;
  800. }(Node));
  801. Paren.prototype.type = 'Paren';
  802. var _noSpaceCombinators = {
  803. '': true,
  804. ' ': true,
  805. '|': true
  806. };
  807. var Combinator = /** @class */ (function (_super) {
  808. __extends(Combinator, _super);
  809. function Combinator(value) {
  810. var _this = _super.call(this) || this;
  811. if (value === ' ') {
  812. _this.value = ' ';
  813. _this.emptyOrWhitespace = true;
  814. }
  815. else {
  816. _this.value = value ? value.trim() : '';
  817. _this.emptyOrWhitespace = _this.value === '';
  818. }
  819. return _this;
  820. }
  821. Combinator.prototype.genCSS = function (context, output) {
  822. var spaceOrEmpty = (context.compress || _noSpaceCombinators[this.value]) ? '' : ' ';
  823. output.add(spaceOrEmpty + this.value + spaceOrEmpty);
  824. };
  825. return Combinator;
  826. }(Node));
  827. Combinator.prototype.type = 'Combinator';
  828. var Element = /** @class */ (function (_super) {
  829. __extends(Element, _super);
  830. function Element(combinator, value, isVariable, index, currentFileInfo, visibilityInfo) {
  831. var _this = _super.call(this) || this;
  832. _this.combinator = combinator instanceof Combinator ?
  833. combinator : new Combinator(combinator);
  834. if (typeof value === 'string') {
  835. _this.value = value.trim();
  836. }
  837. else if (value) {
  838. _this.value = value;
  839. }
  840. else {
  841. _this.value = '';
  842. }
  843. _this.isVariable = isVariable;
  844. _this._index = index;
  845. _this._fileInfo = currentFileInfo;
  846. _this.copyVisibilityInfo(visibilityInfo);
  847. _this.setParent(_this.combinator, _this);
  848. return _this;
  849. }
  850. Element.prototype.accept = function (visitor) {
  851. var value = this.value;
  852. this.combinator = visitor.visit(this.combinator);
  853. if (typeof value === 'object') {
  854. this.value = visitor.visit(value);
  855. }
  856. };
  857. Element.prototype.eval = function (context) {
  858. return new Element(this.combinator, this.value.eval ? this.value.eval(context) : this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo());
  859. };
  860. Element.prototype.clone = function () {
  861. return new Element(this.combinator, this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo());
  862. };
  863. Element.prototype.genCSS = function (context, output) {
  864. output.add(this.toCSS(context), this.fileInfo(), this.getIndex());
  865. };
  866. Element.prototype.toCSS = function (context) {
  867. if (context === void 0) { context = {}; }
  868. var value = this.value;
  869. var firstSelector = context.firstSelector;
  870. if (value instanceof Paren) {
  871. // selector in parens should not be affected by outer selector
  872. // flags (breaks only interpolated selectors - see #1973)
  873. context.firstSelector = true;
  874. }
  875. value = value.toCSS ? value.toCSS(context) : value;
  876. context.firstSelector = firstSelector;
  877. if (value === '' && this.combinator.value.charAt(0) === '&') {
  878. return '';
  879. }
  880. else {
  881. return this.combinator.toCSS(context) + value;
  882. }
  883. };
  884. return Element;
  885. }(Node));
  886. Element.prototype.type = 'Element';
  887. var Math$1 = {
  888. ALWAYS: 0,
  889. PARENS_DIVISION: 1,
  890. PARENS: 2,
  891. STRICT_LEGACY: 3
  892. };
  893. var RewriteUrls = {
  894. OFF: 0,
  895. LOCAL: 1,
  896. ALL: 2
  897. };
  898. function createCommonjsModule(fn, module) {
  899. return module = { exports: {} }, fn(module, module.exports), module.exports;
  900. }
  901. var clone_1 = createCommonjsModule(function (module) {
  902. var clone = (function () {
  903. function _instanceof(obj, type) {
  904. return type != null && obj instanceof type;
  905. }
  906. var nativeMap;
  907. try {
  908. nativeMap = Map;
  909. }
  910. catch (_) {
  911. // maybe a reference error because no `Map`. Give it a dummy value that no
  912. // value will ever be an instanceof.
  913. nativeMap = function () { };
  914. }
  915. var nativeSet;
  916. try {
  917. nativeSet = Set;
  918. }
  919. catch (_) {
  920. nativeSet = function () { };
  921. }
  922. var nativePromise;
  923. try {
  924. nativePromise = Promise;
  925. }
  926. catch (_) {
  927. nativePromise = function () { };
  928. }
  929. /**
  930. * Clones (copies) an Object using deep copying.
  931. *
  932. * This function supports circular references by default, but if you are certain
  933. * there are no circular references in your object, you can save some CPU time
  934. * by calling clone(obj, false).
  935. *
  936. * Caution: if `circular` is false and `parent` contains circular references,
  937. * your program may enter an infinite loop and crash.
  938. *
  939. * @param `parent` - the object to be cloned
  940. * @param `circular` - set to true if the object to be cloned may contain
  941. * circular references. (optional - true by default)
  942. * @param `depth` - set to a number if the object is only to be cloned to
  943. * a particular depth. (optional - defaults to Infinity)
  944. * @param `prototype` - sets the prototype to be used when cloning an object.
  945. * (optional - defaults to parent prototype).
  946. * @param `includeNonEnumerable` - set to true if the non-enumerable properties
  947. * should be cloned as well. Non-enumerable properties on the prototype
  948. * chain will be ignored. (optional - false by default)
  949. */
  950. function clone(parent, circular, depth, prototype, includeNonEnumerable) {
  951. if (typeof circular === 'object') {
  952. depth = circular.depth;
  953. prototype = circular.prototype;
  954. includeNonEnumerable = circular.includeNonEnumerable;
  955. circular = circular.circular;
  956. }
  957. // maintain two arrays for circular references, where corresponding parents
  958. // and children have the same index
  959. var allParents = [];
  960. var allChildren = [];
  961. var useBuffer = typeof Buffer != 'undefined';
  962. if (typeof circular == 'undefined')
  963. circular = true;
  964. if (typeof depth == 'undefined')
  965. depth = Infinity;
  966. // recurse this function so we don't reset allParents and allChildren
  967. function _clone(parent, depth) {
  968. // cloning null always returns null
  969. if (parent === null)
  970. return null;
  971. if (depth === 0)
  972. return parent;
  973. var child;
  974. var proto;
  975. if (typeof parent != 'object') {
  976. return parent;
  977. }
  978. if (_instanceof(parent, nativeMap)) {
  979. child = new nativeMap();
  980. }
  981. else if (_instanceof(parent, nativeSet)) {
  982. child = new nativeSet();
  983. }
  984. else if (_instanceof(parent, nativePromise)) {
  985. child = new nativePromise(function (resolve, reject) {
  986. parent.then(function (value) {
  987. resolve(_clone(value, depth - 1));
  988. }, function (err) {
  989. reject(_clone(err, depth - 1));
  990. });
  991. });
  992. }
  993. else if (clone.__isArray(parent)) {
  994. child = [];
  995. }
  996. else if (clone.__isRegExp(parent)) {
  997. child = new RegExp(parent.source, __getRegExpFlags(parent));
  998. if (parent.lastIndex)
  999. child.lastIndex = parent.lastIndex;
  1000. }
  1001. else if (clone.__isDate(parent)) {
  1002. child = new Date(parent.getTime());
  1003. }
  1004. else if (useBuffer && Buffer.isBuffer(parent)) {
  1005. if (Buffer.allocUnsafe) {
  1006. // Node.js >= 4.5.0
  1007. child = Buffer.allocUnsafe(parent.length);
  1008. }
  1009. else {
  1010. // Older Node.js versions
  1011. child = new Buffer(parent.length);
  1012. }
  1013. parent.copy(child);
  1014. return child;
  1015. }
  1016. else if (_instanceof(parent, Error)) {
  1017. child = Object.create(parent);
  1018. }
  1019. else {
  1020. if (typeof prototype == 'undefined') {
  1021. proto = Object.getPrototypeOf(parent);
  1022. child = Object.create(proto);
  1023. }
  1024. else {
  1025. child = Object.create(prototype);
  1026. proto = prototype;
  1027. }
  1028. }
  1029. if (circular) {
  1030. var index = allParents.indexOf(parent);
  1031. if (index != -1) {
  1032. return allChildren[index];
  1033. }
  1034. allParents.push(parent);
  1035. allChildren.push(child);
  1036. }
  1037. if (_instanceof(parent, nativeMap)) {
  1038. parent.forEach(function (value, key) {
  1039. var keyChild = _clone(key, depth - 1);
  1040. var valueChild = _clone(value, depth - 1);
  1041. child.set(keyChild, valueChild);
  1042. });
  1043. }
  1044. if (_instanceof(parent, nativeSet)) {
  1045. parent.forEach(function (value) {
  1046. var entryChild = _clone(value, depth - 1);
  1047. child.add(entryChild);
  1048. });
  1049. }
  1050. for (var i in parent) {
  1051. var attrs;
  1052. if (proto) {
  1053. attrs = Object.getOwnPropertyDescriptor(proto, i);
  1054. }
  1055. if (attrs && attrs.set == null) {
  1056. continue;
  1057. }
  1058. child[i] = _clone(parent[i], depth - 1);
  1059. }
  1060. if (Object.getOwnPropertySymbols) {
  1061. var symbols = Object.getOwnPropertySymbols(parent);
  1062. for (var i = 0; i < symbols.length; i++) {
  1063. // Don't need to worry about cloning a symbol because it is a primitive,
  1064. // like a number or string.
  1065. var symbol = symbols[i];
  1066. var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);
  1067. if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {
  1068. continue;
  1069. }
  1070. child[symbol] = _clone(parent[symbol], depth - 1);
  1071. if (!descriptor.enumerable) {
  1072. Object.defineProperty(child, symbol, {
  1073. enumerable: false
  1074. });
  1075. }
  1076. }
  1077. }
  1078. if (includeNonEnumerable) {
  1079. var allPropertyNames = Object.getOwnPropertyNames(parent);
  1080. for (var i = 0; i < allPropertyNames.length; i++) {
  1081. var propertyName = allPropertyNames[i];
  1082. var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);
  1083. if (descriptor && descriptor.enumerable) {
  1084. continue;
  1085. }
  1086. child[propertyName] = _clone(parent[propertyName], depth - 1);
  1087. Object.defineProperty(child, propertyName, {
  1088. enumerable: false
  1089. });
  1090. }
  1091. }
  1092. return child;
  1093. }
  1094. return _clone(parent, depth);
  1095. }
  1096. /**
  1097. * Simple flat clone using prototype, accepts only objects, usefull for property
  1098. * override on FLAT configuration object (no nested props).
  1099. *
  1100. * USE WITH CAUTION! This may not behave as you wish if you do not know how this
  1101. * works.
  1102. */
  1103. clone.clonePrototype = function clonePrototype(parent) {
  1104. if (parent === null)
  1105. return null;
  1106. var c = function () { };
  1107. c.prototype = parent;
  1108. return new c();
  1109. };
  1110. // private utility functions
  1111. function __objToStr(o) {
  1112. return Object.prototype.toString.call(o);
  1113. }
  1114. clone.__objToStr = __objToStr;
  1115. function __isDate(o) {
  1116. return typeof o === 'object' && __objToStr(o) === '[object Date]';
  1117. }
  1118. clone.__isDate = __isDate;
  1119. function __isArray(o) {
  1120. return typeof o === 'object' && __objToStr(o) === '[object Array]';
  1121. }
  1122. clone.__isArray = __isArray;
  1123. function __isRegExp(o) {
  1124. return typeof o === 'object' && __objToStr(o) === '[object RegExp]';
  1125. }
  1126. clone.__isRegExp = __isRegExp;
  1127. function __getRegExpFlags(re) {
  1128. var flags = '';
  1129. if (re.global)
  1130. flags += 'g';
  1131. if (re.ignoreCase)
  1132. flags += 'i';
  1133. if (re.multiline)
  1134. flags += 'm';
  1135. return flags;
  1136. }
  1137. clone.__getRegExpFlags = __getRegExpFlags;
  1138. return clone;
  1139. })();
  1140. if ( module.exports) {
  1141. module.exports = clone;
  1142. }
  1143. });
  1144. /* jshint proto: true */
  1145. function getLocation(index, inputStream) {
  1146. var n = index + 1;
  1147. var line = null;
  1148. var column = -1;
  1149. while (--n >= 0 && inputStream.charAt(n) !== '\n') {
  1150. column++;
  1151. }
  1152. if (typeof index === 'number') {
  1153. line = (inputStream.slice(0, index).match(/\n/g) || '').length;
  1154. }
  1155. return {
  1156. line: line,
  1157. column: column
  1158. };
  1159. }
  1160. function copyArray(arr) {
  1161. var i;
  1162. var length = arr.length;
  1163. var copy = new Array(length);
  1164. for (i = 0; i < length; i++) {
  1165. copy[i] = arr[i];
  1166. }
  1167. return copy;
  1168. }
  1169. function clone(obj) {
  1170. var cloned = {};
  1171. for (var prop in obj) {
  1172. if (obj.hasOwnProperty(prop)) {
  1173. cloned[prop] = obj[prop];
  1174. }
  1175. }
  1176. return cloned;
  1177. }
  1178. function defaults(obj1, obj2) {
  1179. var newObj = obj2 || {};
  1180. if (!obj2._defaults) {
  1181. newObj = {};
  1182. var defaults_1 = clone_1(obj1);
  1183. newObj._defaults = defaults_1;
  1184. var cloned = obj2 ? clone_1(obj2) : {};
  1185. Object.assign(newObj, defaults_1, cloned);
  1186. }
  1187. return newObj;
  1188. }
  1189. function copyOptions(obj1, obj2) {
  1190. if (obj2 && obj2._defaults) {
  1191. return obj2;
  1192. }
  1193. var opts = defaults(obj1, obj2);
  1194. if (opts.strictMath) {
  1195. opts.math = Math$1.STRICT_LEGACY;
  1196. }
  1197. // Back compat with changed relativeUrls option
  1198. if (opts.relativeUrls) {
  1199. opts.rewriteUrls = RewriteUrls.ALL;
  1200. }
  1201. if (typeof opts.math === 'string') {
  1202. switch (opts.math.toLowerCase()) {
  1203. case 'always':
  1204. opts.math = Math$1.ALWAYS;
  1205. break;
  1206. case 'parens-division':
  1207. opts.math = Math$1.PARENS_DIVISION;
  1208. break;
  1209. case 'strict':
  1210. case 'parens':
  1211. opts.math = Math$1.PARENS;
  1212. break;
  1213. case 'strict-legacy':
  1214. opts.math = Math$1.STRICT_LEGACY;
  1215. }
  1216. }
  1217. if (typeof opts.rewriteUrls === 'string') {
  1218. switch (opts.rewriteUrls.toLowerCase()) {
  1219. case 'off':
  1220. opts.rewriteUrls = RewriteUrls.OFF;
  1221. break;
  1222. case 'local':
  1223. opts.rewriteUrls = RewriteUrls.LOCAL;
  1224. break;
  1225. case 'all':
  1226. opts.rewriteUrls = RewriteUrls.ALL;
  1227. break;
  1228. }
  1229. }
  1230. return opts;
  1231. }
  1232. function merge(obj1, obj2) {
  1233. for (var prop in obj2) {
  1234. if (obj2.hasOwnProperty(prop)) {
  1235. obj1[prop] = obj2[prop];
  1236. }
  1237. }
  1238. return obj1;
  1239. }
  1240. function flattenArray(arr, result) {
  1241. if (result === void 0) { result = []; }
  1242. for (var i_1 = 0, length_1 = arr.length; i_1 < length_1; i_1++) {
  1243. var value = arr[i_1];
  1244. if (Array.isArray(value)) {
  1245. flattenArray(value, result);
  1246. }
  1247. else {
  1248. if (value !== undefined) {
  1249. result.push(value);
  1250. }
  1251. }
  1252. }
  1253. return result;
  1254. }
  1255. var utils = /*#__PURE__*/Object.freeze({
  1256. __proto__: null,
  1257. getLocation: getLocation,
  1258. copyArray: copyArray,
  1259. clone: clone,
  1260. defaults: defaults,
  1261. copyOptions: copyOptions,
  1262. merge: merge,
  1263. flattenArray: flattenArray
  1264. });
  1265. var anonymousFunc = /(<anonymous>|Function):(\d+):(\d+)/;
  1266. /**
  1267. * This is a centralized class of any error that could be thrown internally (mostly by the parser).
  1268. * Besides standard .message it keeps some additional data like a path to the file where the error
  1269. * occurred along with line and column numbers.
  1270. *
  1271. * @class
  1272. * @extends Error
  1273. * @type {module.LessError}
  1274. *
  1275. * @prop {string} type
  1276. * @prop {string} filename
  1277. * @prop {number} index
  1278. * @prop {number} line
  1279. * @prop {number} column
  1280. * @prop {number} callLine
  1281. * @prop {number} callExtract
  1282. * @prop {string[]} extract
  1283. *
  1284. * @param {Object} e - An error object to wrap around or just a descriptive object
  1285. * @param {Object} fileContentMap - An object with file contents in 'contents' property (like importManager) @todo - move to fileManager?
  1286. * @param {string} [currentFilename]
  1287. */
  1288. var LessError = function LessError(e, fileContentMap, currentFilename) {
  1289. Error.call(this);
  1290. var filename = e.filename || currentFilename;
  1291. this.message = e.message;
  1292. this.stack = e.stack;
  1293. if (fileContentMap && filename) {
  1294. var input = fileContentMap.contents[filename];
  1295. var loc = getLocation(e.index, input);
  1296. var line = loc.line;
  1297. var col = loc.column;
  1298. var callLine = e.call && getLocation(e.call, input).line;
  1299. var lines = input ? input.split('\n') : '';
  1300. this.type = e.type || 'Syntax';
  1301. this.filename = filename;
  1302. this.index = e.index;
  1303. this.line = typeof line === 'number' ? line + 1 : null;
  1304. this.column = col;
  1305. if (!this.line && this.stack) {
  1306. var found = this.stack.match(anonymousFunc);
  1307. /**
  1308. * We have to figure out how this environment stringifies anonymous functions
  1309. * so we can correctly map plugin errors.
  1310. *
  1311. * Note, in Node 8, the output of anonymous funcs varied based on parameters
  1312. * being present or not, so we inject dummy params.
  1313. */
  1314. var func = new Function('a', 'throw new Error()');
  1315. var lineAdjust = 0;
  1316. try {
  1317. func();
  1318. }
  1319. catch (e) {
  1320. var match = e.stack.match(anonymousFunc);
  1321. var line_1 = parseInt(match[2]);
  1322. lineAdjust = 1 - line_1;
  1323. }
  1324. if (found) {
  1325. if (found[2]) {
  1326. this.line = parseInt(found[2]) + lineAdjust;
  1327. }
  1328. if (found[3]) {
  1329. this.column = parseInt(found[3]);
  1330. }
  1331. }
  1332. }
  1333. this.callLine = callLine + 1;
  1334. this.callExtract = lines[callLine];
  1335. this.extract = [
  1336. lines[this.line - 2],
  1337. lines[this.line - 1],
  1338. lines[this.line]
  1339. ];
  1340. }
  1341. };
  1342. if (typeof Object.create === 'undefined') {
  1343. var F = function () { };
  1344. F.prototype = Error.prototype;
  1345. LessError.prototype = new F();
  1346. }
  1347. else {
  1348. LessError.prototype = Object.create(Error.prototype);
  1349. }
  1350. LessError.prototype.constructor = LessError;
  1351. /**
  1352. * An overridden version of the default Object.prototype.toString
  1353. * which uses additional information to create a helpful message.
  1354. *
  1355. * @param {Object} options
  1356. * @returns {string}
  1357. */
  1358. LessError.prototype.toString = function (options) {
  1359. if (options === void 0) { options = {}; }
  1360. var message = '';
  1361. var extract = this.extract || [];
  1362. var error = [];
  1363. var stylize = function (str) { return str; };
  1364. if (options.stylize) {
  1365. var type = typeof options.stylize;
  1366. if (type !== 'function') {
  1367. throw Error("options.stylize should be a function, got a " + type + "!");
  1368. }
  1369. stylize = options.stylize;
  1370. }
  1371. if (this.line !== null) {
  1372. if (typeof extract[0] === 'string') {
  1373. error.push(stylize(this.line - 1 + " " + extract[0], 'grey'));
  1374. }
  1375. if (typeof extract[1] === 'string') {
  1376. var errorTxt = this.line + " ";
  1377. if (extract[1]) {
  1378. errorTxt += extract[1].slice(0, this.column) +
  1379. stylize(stylize(stylize(extract[1].substr(this.column, 1), 'bold') +
  1380. extract[1].slice(this.column + 1), 'red'), 'inverse');
  1381. }
  1382. error.push(errorTxt);
  1383. }
  1384. if (typeof extract[2] === 'string') {
  1385. error.push(stylize(this.line + 1 + " " + extract[2], 'grey'));
  1386. }
  1387. error = error.join('\n') + stylize('', 'reset') + "\n";
  1388. }
  1389. message += stylize(this.type + "Error: " + this.message, 'red');
  1390. if (this.filename) {
  1391. message += stylize(' in ', 'red') + this.filename;
  1392. }
  1393. if (this.line) {
  1394. message += stylize(" on line " + this.line + ", column " + (this.column + 1) + ":", 'grey');
  1395. }
  1396. message += "\n" + error;
  1397. if (this.callLine) {
  1398. message += stylize('from ', 'red') + (this.filename || '') + "/n";
  1399. message += stylize(this.callLine, 'grey') + " " + this.callExtract + "/n";
  1400. }
  1401. return message;
  1402. };
  1403. var Selector = /** @class */ (function (_super) {
  1404. __extends(Selector, _super);
  1405. function Selector(elements, extendList, condition, index, currentFileInfo, visibilityInfo) {
  1406. var _this = _super.call(this) || this;
  1407. _this.extendList = extendList;
  1408. _this.condition = condition;
  1409. _this.evaldCondition = !condition;
  1410. _this._index = index;
  1411. _this._fileInfo = currentFileInfo;
  1412. _this.elements = _this.getElements(elements);
  1413. _this.mixinElements_ = undefined;
  1414. _this.copyVisibilityInfo(visibilityInfo);
  1415. _this.setParent(_this.elements, _this);
  1416. return _this;
  1417. }
  1418. Selector.prototype.accept = function (visitor) {
  1419. if (this.elements) {
  1420. this.elements = visitor.visitArray(this.elements);
  1421. }
  1422. if (this.extendList) {
  1423. this.extendList = visitor.visitArray(this.extendList);
  1424. }
  1425. if (this.condition) {
  1426. this.condition = visitor.visit(this.condition);
  1427. }
  1428. };
  1429. Selector.prototype.createDerived = function (elements, extendList, evaldCondition) {
  1430. elements = this.getElements(elements);
  1431. var newSelector = new Selector(elements, extendList || this.extendList, null, this.getIndex(), this.fileInfo(), this.visibilityInfo());
  1432. newSelector.evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition;
  1433. newSelector.mediaEmpty = this.mediaEmpty;
  1434. return newSelector;
  1435. };
  1436. Selector.prototype.getElements = function (els) {
  1437. if (!els) {
  1438. return [new Element('', '&', false, this._index, this._fileInfo)];
  1439. }
  1440. if (typeof els === 'string') {
  1441. this.parse.parseNode(els, ['selector'], this._index, this._fileInfo, function (err, result) {
  1442. if (err) {
  1443. throw new LessError({
  1444. index: err.index,
  1445. message: err.message
  1446. }, this.parse.imports, this._fileInfo.filename);
  1447. }
  1448. els = result[0].elements;
  1449. });
  1450. }
  1451. return els;
  1452. };
  1453. Selector.prototype.createEmptySelectors = function () {
  1454. var el = new Element('', '&', false, this._index, this._fileInfo);
  1455. var sels = [new Selector([el], null, null, this._index, this._fileInfo)];
  1456. sels[0].mediaEmpty = true;
  1457. return sels;
  1458. };
  1459. Selector.prototype.match = function (other) {
  1460. var elements = this.elements;
  1461. var len = elements.length;
  1462. var olen;
  1463. var i;
  1464. other = other.mixinElements();
  1465. olen = other.length;
  1466. if (olen === 0 || len < olen) {
  1467. return 0;
  1468. }
  1469. else {
  1470. for (i = 0; i < olen; i++) {
  1471. if (elements[i].value !== other[i]) {
  1472. return 0;
  1473. }
  1474. }
  1475. }
  1476. return olen; // return number of matched elements
  1477. };
  1478. Selector.prototype.mixinElements = function () {
  1479. if (this.mixinElements_) {
  1480. return this.mixinElements_;
  1481. }
  1482. var elements = this.elements.map(function (v) { return v.combinator.value + (v.value.value || v.value); }).join('').match(/[,&#\*\.\w-]([\w-]|(\\.))*/g);
  1483. if (elements) {
  1484. if (elements[0] === '&') {
  1485. elements.shift();
  1486. }
  1487. }
  1488. else {
  1489. elements = [];
  1490. }
  1491. return (this.mixinElements_ = elements);
  1492. };
  1493. Selector.prototype.isJustParentSelector = function () {
  1494. return !this.mediaEmpty &&
  1495. this.elements.length === 1 &&
  1496. this.elements[0].value === '&' &&
  1497. (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === '');
  1498. };
  1499. Selector.prototype.eval = function (context) {
  1500. var evaldCondition = this.condition && this.condition.eval(context);
  1501. var elements = this.elements;
  1502. var extendList = this.extendList;
  1503. elements = elements && elements.map(function (e) { return e.eval(context); });
  1504. extendList = extendList && extendList.map(function (extend) { return extend.eval(context); });
  1505. return this.createDerived(elements, extendList, evaldCondition);
  1506. };
  1507. Selector.prototype.genCSS = function (context, output) {
  1508. var i;
  1509. var element;
  1510. if ((!context || !context.firstSelector) && this.elements[0].combinator.value === '') {
  1511. output.add(' ', this.fileInfo(), this.getIndex());
  1512. }
  1513. for (i = 0; i < this.elements.length; i++) {
  1514. element = this.elements[i];
  1515. element.genCSS(context, output);
  1516. }
  1517. };
  1518. Selector.prototype.getIsOutput = function () {
  1519. return this.evaldCondition;
  1520. };
  1521. return Selector;
  1522. }(Node));
  1523. Selector.prototype.type = 'Selector';
  1524. var Value = /** @class */ (function (_super) {
  1525. __extends(Value, _super);
  1526. function Value(value) {
  1527. var _this = _super.call(this) || this;
  1528. if (!value) {
  1529. throw new Error('Value requires an array argument');
  1530. }
  1531. if (!Array.isArray(value)) {
  1532. _this.value = [value];
  1533. }
  1534. else {
  1535. _this.value = value;
  1536. }
  1537. return _this;
  1538. }
  1539. Value.prototype.accept = function (visitor) {
  1540. if (this.value) {
  1541. this.value = visitor.visitArray(this.value);
  1542. }
  1543. };
  1544. Value.prototype.eval = function (context) {
  1545. if (this.value.length === 1) {
  1546. return this.value[0].eval(context);
  1547. }
  1548. else {
  1549. return new Value(this.value.map(function (v) { return v.eval(context); }));
  1550. }
  1551. };
  1552. Value.prototype.genCSS = function (context, output) {
  1553. var i;
  1554. for (i = 0; i < this.value.length; i++) {
  1555. this.value[i].genCSS(context, output);
  1556. if (i + 1 < this.value.length) {
  1557. output.add((context && context.compress) ? ',' : ', ');
  1558. }
  1559. }
  1560. };
  1561. return Value;
  1562. }(Node));
  1563. Value.prototype.type = 'Value';
  1564. var Keyword = /** @class */ (function (_super) {
  1565. __extends(Keyword, _super);
  1566. function Keyword(value) {
  1567. var _this = _super.call(this) || this;
  1568. _this.value = value;
  1569. return _this;
  1570. }
  1571. Keyword.prototype.genCSS = function (context, output) {
  1572. if (this.value === '%') {
  1573. throw { type: 'Syntax', message: 'Invalid % without number' };
  1574. }
  1575. output.add(this.value);
  1576. };
  1577. return Keyword;
  1578. }(Node));
  1579. Keyword.prototype.type = 'Keyword';
  1580. Keyword.True = new Keyword('true');
  1581. Keyword.False = new Keyword('false');
  1582. var Anonymous = /** @class */ (function (_super) {
  1583. __extends(Anonymous, _super);
  1584. function Anonymous(value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) {
  1585. var _this = _super.call(this) || this;
  1586. _this.value = value;
  1587. _this._index = index;
  1588. _this._fileInfo = currentFileInfo;
  1589. _this.mapLines = mapLines;
  1590. _this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike;
  1591. _this.allowRoot = true;
  1592. _this.copyVisibilityInfo(visibilityInfo);
  1593. return _this;
  1594. }
  1595. Anonymous.prototype.eval = function () {
  1596. return new Anonymous(this.value, this._index, this._fileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo());
  1597. };
  1598. Anonymous.prototype.compare = function (other) {
  1599. return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;
  1600. };
  1601. Anonymous.prototype.isRulesetLike = function () {
  1602. return this.rulesetLike;
  1603. };
  1604. Anonymous.prototype.genCSS = function (context, output) {
  1605. this.nodeVisible = Boolean(this.value);
  1606. if (this.nodeVisible) {
  1607. output.add(this.value, this._fileInfo, this._index, this.mapLines);
  1608. }
  1609. };
  1610. return Anonymous;
  1611. }(Node));
  1612. Anonymous.prototype.type = 'Anonymous';
  1613. var MATH = Math$1;
  1614. var Declaration = /** @class */ (function (_super) {
  1615. __extends(Declaration, _super);
  1616. function Declaration(name, value, important, merge, index, currentFileInfo, inline, variable) {
  1617. var _this = _super.call(this) || this;
  1618. _this.name = name;
  1619. _this.value = (value instanceof Node) ? value : new Value([value ? new Anonymous(value) : null]);
  1620. _this.important = important ? " " + important.trim() : '';
  1621. _this.merge = merge;
  1622. _this._index = index;
  1623. _this._fileInfo = currentFileInfo;
  1624. _this.inline = inline || false;
  1625. _this.variable = (variable !== undefined) ? variable
  1626. : (name.charAt && (name.charAt(0) === '@'));
  1627. _this.allowRoot = true;
  1628. _this.setParent(_this.value, _this);
  1629. return _this;
  1630. }
  1631. Declaration.prototype.genCSS = function (context, output) {
  1632. output.add(this.name + (context.compress ? ':' : ': '), this.fileInfo(), this.getIndex());
  1633. try {
  1634. this.value.genCSS(context, output);
  1635. }
  1636. catch (e) {
  1637. e.index = this._index;
  1638. e.filename = this._fileInfo.filename;
  1639. throw e;
  1640. }
  1641. output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? '' : ';'), this._fileInfo, this._index);
  1642. };
  1643. Declaration.prototype.eval = function (context) {
  1644. var mathBypass = false;
  1645. var prevMath;
  1646. var name = this.name;
  1647. var evaldValue;
  1648. var variable = this.variable;
  1649. if (typeof name !== 'string') {
  1650. // expand 'primitive' name directly to get
  1651. // things faster (~10% for benchmark.less):
  1652. name = (name.length === 1) && (name[0] instanceof Keyword) ?
  1653. name[0].value : evalName(context, name);
  1654. variable = false; // never treat expanded interpolation as new variable name
  1655. }
  1656. // @todo remove when parens-division is default
  1657. if (name === 'font' && context.math === MATH.ALWAYS) {
  1658. mathBypass = true;
  1659. prevMath = context.math;
  1660. context.math = MATH.PARENS_DIVISION;
  1661. }
  1662. try {
  1663. context.importantScope.push({});
  1664. evaldValue = this.value.eval(context);
  1665. if (!this.variable && evaldValue.type === 'DetachedRuleset') {
  1666. throw { message: 'Rulesets cannot be evaluated on a property.',
  1667. index: this.getIndex(), filename: this.fileInfo().filename };
  1668. }
  1669. var important = this.important;
  1670. var importantResult = context.importantScope.pop();
  1671. if (!important && importantResult.important) {
  1672. important = importantResult.important;
  1673. }
  1674. return new Declaration(name, evaldValue, important, this.merge, this.getIndex(), this.fileInfo(), this.inline, variable);
  1675. }
  1676. catch (e) {
  1677. if (typeof e.index !== 'number') {
  1678. e.index = this.getIndex();
  1679. e.filename = this.fileInfo().filename;
  1680. }
  1681. throw e;
  1682. }
  1683. finally {
  1684. if (mathBypass) {
  1685. context.math = prevMath;
  1686. }
  1687. }
  1688. };
  1689. Declaration.prototype.makeImportant = function () {
  1690. return new Declaration(this.name, this.value, '!important', this.merge, this.getIndex(), this.fileInfo(), this.inline);
  1691. };
  1692. return Declaration;
  1693. }(Node));
  1694. function evalName(context, name) {
  1695. var value = '';
  1696. var i;
  1697. var n = name.length;
  1698. var output = { add: function (s) { value += s; } };
  1699. for (i = 0; i < n; i++) {
  1700. name[i].eval(context).genCSS(context, output);
  1701. }
  1702. return value;
  1703. }
  1704. Declaration.prototype.type = 'Declaration';
  1705. var debugInfo = function (context, ctx, lineSeparator) {
  1706. var result = '';
  1707. if (context.dumpLineNumbers && !context.compress) {
  1708. switch (context.dumpLineNumbers) {
  1709. case 'comments':
  1710. result = debugInfo.asComment(ctx);
  1711. break;
  1712. case 'mediaquery':
  1713. result = debugInfo.asMediaQuery(ctx);
  1714. break;
  1715. case 'all':
  1716. result = debugInfo.asComment(ctx) + (lineSeparator || '') + debugInfo.asMediaQuery(ctx);
  1717. break;
  1718. }
  1719. }
  1720. return result;
  1721. };
  1722. debugInfo.asComment = function (ctx) { return "/* line " + ctx.debugInfo.lineNumber + ", " + ctx.debugInfo.fileName + " */\n"; };
  1723. debugInfo.asMediaQuery = function (ctx) {
  1724. var filenameWithProtocol = ctx.debugInfo.fileName;
  1725. if (!/^[a-z]+:\/\//i.test(filenameWithProtocol)) {
  1726. filenameWithProtocol = "file://" + filenameWithProtocol;
  1727. }
  1728. return "@media -sass-debug-info{filename{font-family:" + filenameWithProtocol.replace(/([.:\/\\])/g, function (a) {
  1729. if (a == '\\') {
  1730. a = '\/';
  1731. }
  1732. return "\\" + a;
  1733. }) + "}line{font-family:\\00003" + ctx.debugInfo.lineNumber + "}}\n";
  1734. };
  1735. var Comment = /** @class */ (function (_super) {
  1736. __extends(Comment, _super);
  1737. function Comment(value, isLineComment, index, currentFileInfo) {
  1738. var _this = _super.call(this) || this;
  1739. _this.value = value;
  1740. _this.isLineComment = isLineComment;
  1741. _this._index = index;
  1742. _this._fileInfo = currentFileInfo;
  1743. _this.allowRoot = true;
  1744. return _this;
  1745. }
  1746. Comment.prototype.genCSS = function (context, output) {
  1747. if (this.debugInfo) {
  1748. output.add(debugInfo(context, this), this.fileInfo(), this.getIndex());
  1749. }
  1750. output.add(this.value);
  1751. };
  1752. Comment.prototype.isSilent = function (context) {
  1753. var isCompressed = context.compress && this.value[2] !== '!';
  1754. return this.isLineComment || isCompressed;
  1755. };
  1756. return Comment;
  1757. }(Node));
  1758. Comment.prototype.type = 'Comment';
  1759. var contexts = {};
  1760. var copyFromOriginal = function copyFromOriginal(original, destination, propertiesToCopy) {
  1761. if (!original) {
  1762. return;
  1763. }
  1764. for (var i_1 = 0; i_1 < propertiesToCopy.length; i_1++) {
  1765. if (original.hasOwnProperty(propertiesToCopy[i_1])) {
  1766. destination[propertiesToCopy[i_1]] = original[propertiesToCopy[i_1]];
  1767. }
  1768. }
  1769. };
  1770. /*
  1771. parse is used whilst parsing
  1772. */
  1773. var parseCopyProperties = [
  1774. // options
  1775. 'paths',
  1776. 'rewriteUrls',
  1777. 'rootpath',
  1778. 'strictImports',
  1779. 'insecure',
  1780. 'dumpLineNumbers',
  1781. 'compress',
  1782. 'syncImport',
  1783. 'chunkInput',
  1784. 'mime',
  1785. 'useFileCache',
  1786. // context
  1787. 'processImports',
  1788. // Used by the import manager to stop multiple import visitors being created.
  1789. 'pluginManager' // Used as the plugin manager for the session
  1790. ];
  1791. contexts.Parse = function (options) {
  1792. copyFromOriginal(options, this, parseCopyProperties);
  1793. if (typeof this.paths === 'string') {
  1794. this.paths = [this.paths];
  1795. }
  1796. };
  1797. var evalCopyProperties = [
  1798. 'paths',
  1799. 'compress',
  1800. 'math',
  1801. 'strictUnits',
  1802. 'sourceMap',
  1803. 'importMultiple',
  1804. 'urlArgs',
  1805. 'javascriptEnabled',
  1806. 'pluginManager',
  1807. 'importantScope',
  1808. 'rewriteUrls' // option - whether to adjust URL's to be relative
  1809. ];
  1810. function isPathRelative(path) {
  1811. return !/^(?:[a-z-]+:|\/|#)/i.test(path);
  1812. }
  1813. function isPathLocalRelative(path) {
  1814. return path.charAt(0) === '.';
  1815. }
  1816. contexts.Eval = /** @class */ (function () {
  1817. function Eval(options, frames) {
  1818. copyFromOriginal(options, this, evalCopyProperties);
  1819. if (typeof this.paths === 'string') {
  1820. this.paths = [this.paths];
  1821. }
  1822. this.frames = frames || [];
  1823. this.importantScope = this.importantScope || [];
  1824. this.inCalc = false;
  1825. this.mathOn = true;
  1826. }
  1827. Eval.prototype.enterCalc = function () {
  1828. if (!this.calcStack) {
  1829. this.calcStack = [];
  1830. }
  1831. this.calcStack.push(true);
  1832. this.inCalc = true;
  1833. };
  1834. Eval.prototype.exitCalc = function () {
  1835. this.calcStack.pop();
  1836. if (!this.calcStack) {
  1837. this.inCalc = false;
  1838. }
  1839. };
  1840. Eval.prototype.inParenthesis = function () {
  1841. if (!this.parensStack) {
  1842. this.parensStack = [];
  1843. }
  1844. this.parensStack.push(true);
  1845. };
  1846. Eval.prototype.outOfParenthesis = function () {
  1847. this.parensStack.pop();
  1848. };
  1849. Eval.prototype.isMathOn = function (op) {
  1850. if (!this.mathOn) {
  1851. return false;
  1852. }
  1853. if (op === '/' && this.math !== Math$1.ALWAYS && (!this.parensStack || !this.parensStack.length)) {
  1854. return false;
  1855. }
  1856. if (this.math > Math$1.PARENS_DIVISION) {
  1857. return this.parensStack && this.parensStack.length;
  1858. }
  1859. return true;
  1860. };
  1861. Eval.prototype.pathRequiresRewrite = function (path) {
  1862. var isRelative = this.rewriteUrls === RewriteUrls.LOCAL ? isPathLocalRelative : isPathRelative;
  1863. return isRelative(path);
  1864. };
  1865. Eval.prototype.rewritePath = function (path, rootpath) {
  1866. var newPath;
  1867. rootpath = rootpath || '';
  1868. newPath = this.normalizePath(rootpath + path);
  1869. // If a path was explicit relative and the rootpath was not an absolute path
  1870. // we must ensure that the new path is also explicit relative.
  1871. if (isPathLocalRelative(path) &&
  1872. isPathRelative(rootpath) &&
  1873. isPathLocalRelative(newPath) === false) {
  1874. newPath = "./" + newPath;
  1875. }
  1876. return newPath;
  1877. };
  1878. Eval.prototype.normalizePath = function (path) {
  1879. var segments = path.split('/').reverse();
  1880. var segment;
  1881. path = [];
  1882. while (segments.length !== 0) {
  1883. segment = segments.pop();
  1884. switch (segment) {
  1885. case '.':
  1886. break;
  1887. case '..':
  1888. if ((path.length === 0) || (path[path.length - 1] === '..')) {
  1889. path.push(segment);
  1890. }
  1891. else {
  1892. path.pop();
  1893. }
  1894. break;
  1895. default:
  1896. path.push(segment);
  1897. break;
  1898. }
  1899. }
  1900. return path.join('/');
  1901. };
  1902. return Eval;
  1903. }());
  1904. function makeRegistry(base) {
  1905. return {
  1906. _data: {},
  1907. add: function (name, func) {
  1908. // precautionary case conversion, as later querying of
  1909. // the registry by function-caller uses lower case as well.
  1910. name = name.toLowerCase();
  1911. if (this._data.hasOwnProperty(name)) ;
  1912. this._data[name] = func;
  1913. },
  1914. addMultiple: function (functions) {
  1915. var _this = this;
  1916. Object.keys(functions).forEach(function (name) {
  1917. _this.add(name, functions[name]);
  1918. });
  1919. },
  1920. get: function (name) {
  1921. return this._data[name] || (base && base.get(name));
  1922. },
  1923. getLocalFunctions: function () {
  1924. return this._data;
  1925. },
  1926. inherit: function () {
  1927. return makeRegistry(this);
  1928. },
  1929. create: function (base) {
  1930. return makeRegistry(base);
  1931. }
  1932. };
  1933. }
  1934. var functionRegistry = makeRegistry(null);
  1935. var defaultFunc = {
  1936. eval: function () {
  1937. var v = this.value_;
  1938. var e = this.error_;
  1939. if (e) {
  1940. throw e;
  1941. }
  1942. if (v != null) {
  1943. return v ? Keyword.True : Keyword.False;
  1944. }
  1945. },
  1946. value: function (v) {
  1947. this.value_ = v;
  1948. },
  1949. error: function (e) {
  1950. this.error_ = e;
  1951. },
  1952. reset: function () {
  1953. this.value_ = this.error_ = null;
  1954. }
  1955. };
  1956. var Ruleset = /** @class */ (function (_super) {
  1957. __extends(Ruleset, _super);
  1958. function Ruleset(selectors, rules, strictImports, visibilityInfo) {
  1959. var _this = _super.call(this) || this;
  1960. _this.selectors = selectors;
  1961. _this.rules = rules;
  1962. _this._lookups = {};
  1963. _this._variables = null;
  1964. _this._properties = null;
  1965. _this.strictImports = strictImports;
  1966. _this.copyVisibilityInfo(visibilityInfo);
  1967. _this.allowRoot = true;
  1968. _this.setParent(_this.selectors, _this);
  1969. _this.setParent(_this.rules, _this);
  1970. return _this;
  1971. }
  1972. Ruleset.prototype.isRulesetLike = function () {
  1973. return true;
  1974. };
  1975. Ruleset.prototype.accept = function (visitor) {
  1976. if (this.paths) {
  1977. this.paths = visitor.visitArray(this.paths, true);
  1978. }
  1979. else if (this.selectors) {
  1980. this.selectors = visitor.visitArray(this.selectors);
  1981. }
  1982. if (this.rules && this.rules.length) {
  1983. this.rules = visitor.visitArray(this.rules);
  1984. }
  1985. };
  1986. Ruleset.prototype.eval = function (context) {
  1987. var selectors;
  1988. var selCnt;
  1989. var selector;
  1990. var i;
  1991. var hasVariable;
  1992. var hasOnePassingSelector = false;
  1993. if (this.selectors && (selCnt = this.selectors.length)) {
  1994. selectors = new Array(selCnt);
  1995. defaultFunc.error({
  1996. type: 'Syntax',
  1997. message: 'it is currently only allowed in parametric mixin guards,'
  1998. });
  1999. for (i = 0; i < selCnt; i++) {
  2000. selector = this.selectors[i].eval(context);
  2001. for (var j = 0; j < selector.elements.length; j++) {
  2002. if (selector.elements[j].isVariable) {
  2003. hasVariable = true;
  2004. break;
  2005. }
  2006. }
  2007. selectors[i] = selector;
  2008. if (selector.evaldCondition) {
  2009. hasOnePassingSelector = true;
  2010. }
  2011. }
  2012. if (hasVariable) {
  2013. var toParseSelectors = new Array(selCnt);
  2014. for (i = 0; i < selCnt; i++) {
  2015. selector = selectors[i];
  2016. toParseSelectors[i] = selector.toCSS(context);
  2017. }
  2018. this.parse.parseNode(toParseSelectors.join(','), ["selectors"], selectors[0].getIndex(), selectors[0].fileInfo(), function (err, result) {
  2019. if (result) {
  2020. selectors = flattenArray(result);
  2021. }
  2022. });
  2023. }
  2024. defaultFunc.reset();
  2025. }
  2026. else {
  2027. hasOnePassingSelector = true;
  2028. }
  2029. var rules = this.rules ? copyArray(this.rules) : null;
  2030. var ruleset = new Ruleset(selectors, rules, this.strictImports, this.visibilityInfo());
  2031. var rule;
  2032. var subRule;
  2033. ruleset.originalRuleset = this;
  2034. ruleset.root = this.root;
  2035. ruleset.firstRoot = this.firstRoot;
  2036. ruleset.allowImports = this.allowImports;
  2037. if (this.debugInfo) {
  2038. ruleset.debugInfo = this.debugInfo;
  2039. }
  2040. if (!hasOnePassingSelector) {
  2041. rules.length = 0;
  2042. }
  2043. // inherit a function registry from the frames stack when possible;
  2044. // otherwise from the global registry
  2045. ruleset.functionRegistry = (function (frames) {
  2046. var i = 0;
  2047. var n = frames.length;
  2048. var found;
  2049. for (; i !== n; ++i) {
  2050. found = frames[i].functionRegistry;
  2051. if (found) {
  2052. return found;
  2053. }
  2054. }
  2055. return functionRegistry;
  2056. })(context.frames).inherit();
  2057. // push the current ruleset to the frames stack
  2058. var ctxFrames = context.frames;
  2059. ctxFrames.unshift(ruleset);
  2060. // currrent selectors
  2061. var ctxSelectors = context.selectors;
  2062. if (!ctxSelectors) {
  2063. context.selectors = ctxSelectors = [];
  2064. }
  2065. ctxSelectors.unshift(this.selectors);
  2066. // Evaluate imports
  2067. if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
  2068. ruleset.evalImports(context);
  2069. }
  2070. // Store the frames around mixin definitions,
  2071. // so they can be evaluated like closures when the time comes.
  2072. var rsRules = ruleset.rules;
  2073. for (i = 0; (rule = rsRules[i]); i++) {
  2074. if (rule.evalFirst) {
  2075. rsRules[i] = rule.eval(context);
  2076. }
  2077. }
  2078. var mediaBlockCount = (context.mediaBlocks && context.mediaBlocks.length) || 0;
  2079. // Evaluate mixin calls.
  2080. for (i = 0; (rule = rsRules[i]); i++) {
  2081. if (rule.type === 'MixinCall') {
  2082. /* jshint loopfunc:true */
  2083. rules = rule.eval(context).filter(function (r) {
  2084. if ((r instanceof Declaration) && r.variable) {
  2085. // do not pollute the scope if the variable is
  2086. // already there. consider returning false here
  2087. // but we need a way to "return" variable from mixins
  2088. return !(ruleset.variable(r.name));
  2089. }
  2090. return true;
  2091. });
  2092. rsRules.splice.apply(rsRules, [i, 1].concat(rules));
  2093. i += rules.length - 1;
  2094. ruleset.resetCache();
  2095. }
  2096. else if (rule.type === 'VariableCall') {
  2097. /* jshint loopfunc:true */
  2098. rules = rule.eval(context).rules.filter(function (r) {
  2099. if ((r instanceof Declaration) && r.variable) {
  2100. // do not pollute the scope at all
  2101. return false;
  2102. }
  2103. return true;
  2104. });
  2105. rsRules.splice.apply(rsRules, [i, 1].concat(rules));
  2106. i += rules.length - 1;
  2107. ruleset.resetCache();
  2108. }
  2109. }
  2110. // Evaluate everything else
  2111. for (i = 0; (rule = rsRules[i]); i++) {
  2112. if (!rule.evalFirst) {
  2113. rsRules[i] = rule = rule.eval ? rule.eval(context) : rule;
  2114. }
  2115. }
  2116. // Evaluate everything else
  2117. for (i = 0; (rule = rsRules[i]); i++) {
  2118. // for rulesets, check if it is a css guard and can be removed
  2119. if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) {
  2120. // check if it can be folded in (e.g. & where)
  2121. if (rule.selectors[0] && rule.selectors[0].isJustParentSelector()) {
  2122. rsRules.splice(i--, 1);
  2123. for (var j = 0; (subRule = rule.rules[j]); j++) {
  2124. if (subRule instanceof Node) {
  2125. subRule.copyVisibilityInfo(rule.visibilityInfo());
  2126. if (!(subRule instanceof Declaration) || !subRule.variable) {
  2127. rsRules.splice(++i, 0, subRule);
  2128. }
  2129. }
  2130. }
  2131. }
  2132. }
  2133. }
  2134. // Pop the stack
  2135. ctxFrames.shift();
  2136. ctxSelectors.shift();
  2137. if (context.mediaBlocks) {
  2138. for (i = mediaBlockCount; i < context.mediaBlocks.length; i++) {
  2139. context.mediaBlocks[i].bubbleSelectors(selectors);
  2140. }
  2141. }
  2142. return ruleset;
  2143. };
  2144. Ruleset.prototype.evalImports = function (context) {
  2145. var rules = this.rules;
  2146. var i;
  2147. var importRules;
  2148. if (!rules) {
  2149. return;
  2150. }
  2151. for (i = 0; i < rules.length; i++) {
  2152. if (rules[i].type === 'Import') {
  2153. importRules = rules[i].eval(context);
  2154. if (importRules && (importRules.length || importRules.length === 0)) {
  2155. rules.splice.apply(rules, [i, 1].concat(importRules));
  2156. i += importRules.length - 1;
  2157. }
  2158. else {
  2159. rules.splice(i, 1, importRules);
  2160. }
  2161. this.resetCache();
  2162. }
  2163. }
  2164. };
  2165. Ruleset.prototype.makeImportant = function () {
  2166. var result = new Ruleset(this.selectors, this.rules.map(function (r) {
  2167. if (r.makeImportant) {
  2168. return r.makeImportant();
  2169. }
  2170. else {
  2171. return r;
  2172. }
  2173. }), this.strictImports, this.visibilityInfo());
  2174. return result;
  2175. };
  2176. Ruleset.prototype.matchArgs = function (args) {
  2177. return !args || args.length === 0;
  2178. };
  2179. // lets you call a css selector with a guard
  2180. Ruleset.prototype.matchCondition = function (args, context) {
  2181. var lastSelector = this.selectors[this.selectors.length - 1];
  2182. if (!lastSelector.evaldCondition) {
  2183. return false;
  2184. }
  2185. if (lastSelector.condition &&
  2186. !lastSelector.condition.eval(new contexts.Eval(context, context.frames))) {
  2187. return false;
  2188. }
  2189. return true;
  2190. };
  2191. Ruleset.prototype.resetCache = function () {
  2192. this._rulesets = null;
  2193. this._variables = null;
  2194. this._properties = null;
  2195. this._lookups = {};
  2196. };
  2197. Ruleset.prototype.variables = function () {
  2198. if (!this._variables) {
  2199. this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) {
  2200. if (r instanceof Declaration && r.variable === true) {
  2201. hash[r.name] = r;
  2202. }
  2203. // when evaluating variables in an import statement, imports have not been eval'd
  2204. // so we need to go inside import statements.
  2205. // guard against root being a string (in the case of inlined less)
  2206. if (r.type === 'Import' && r.root && r.root.variables) {
  2207. var vars = r.root.variables();
  2208. for (var name_1 in vars) {
  2209. if (vars.hasOwnProperty(name_1)) {
  2210. hash[name_1] = r.root.variable(name_1);
  2211. }
  2212. }
  2213. }
  2214. return hash;
  2215. }, {});
  2216. }
  2217. return this._variables;
  2218. };
  2219. Ruleset.prototype.properties = function () {
  2220. if (!this._properties) {
  2221. this._properties = !this.rules ? {} : this.rules.reduce(function (hash, r) {
  2222. if (r instanceof Declaration && r.variable !== true) {
  2223. var name_2 = (r.name.length === 1) && (r.name[0] instanceof Keyword) ?
  2224. r.name[0].value : r.name;
  2225. // Properties don't overwrite as they can merge
  2226. if (!hash["$" + name_2]) {
  2227. hash["$" + name_2] = [r];
  2228. }
  2229. else {
  2230. hash["$" + name_2].push(r);
  2231. }
  2232. }
  2233. return hash;
  2234. }, {});
  2235. }
  2236. return this._properties;
  2237. };
  2238. Ruleset.prototype.variable = function (name) {
  2239. var decl = this.variables()[name];
  2240. if (decl) {
  2241. return this.parseValue(decl);
  2242. }
  2243. };
  2244. Ruleset.prototype.property = function (name) {
  2245. var decl = this.properties()[name];
  2246. if (decl) {
  2247. return this.parseValue(decl);
  2248. }
  2249. };
  2250. Ruleset.prototype.lastDeclaration = function () {
  2251. for (var i_1 = this.rules.length; i_1 > 0; i_1--) {
  2252. var decl = this.rules[i_1 - 1];
  2253. if (decl instanceof Declaration) {
  2254. return this.parseValue(decl);
  2255. }
  2256. }
  2257. };
  2258. Ruleset.prototype.parseValue = function (toParse) {
  2259. var self = this;
  2260. function transformDeclaration(decl) {
  2261. if (decl.value instanceof Anonymous && !decl.parsed) {
  2262. if (typeof decl.value.value === 'string') {
  2263. this.parse.parseNode(decl.value.value, ['value', 'important'], decl.value.getIndex(), decl.fileInfo(), function (err, result) {
  2264. if (err) {
  2265. decl.parsed = true;
  2266. }
  2267. if (result) {
  2268. decl.value = result[0];
  2269. decl.important = result[1] || '';
  2270. decl.parsed = true;
  2271. }
  2272. });
  2273. }
  2274. else {
  2275. decl.parsed = true;
  2276. }
  2277. return decl;
  2278. }
  2279. else {
  2280. return decl;
  2281. }
  2282. }
  2283. if (!Array.isArray(toParse)) {
  2284. return transformDeclaration.call(self, toParse);
  2285. }
  2286. else {
  2287. var nodes_1 = [];
  2288. toParse.forEach(function (n) {
  2289. nodes_1.push(transformDeclaration.call(self, n));
  2290. });
  2291. return nodes_1;
  2292. }
  2293. };
  2294. Ruleset.prototype.rulesets = function () {
  2295. if (!this.rules) {
  2296. return [];
  2297. }
  2298. var filtRules = [];
  2299. var rules = this.rules;
  2300. var i;
  2301. var rule;
  2302. for (i = 0; (rule = rules[i]); i++) {
  2303. if (rule.isRuleset) {
  2304. filtRules.push(rule);
  2305. }
  2306. }
  2307. return filtRules;
  2308. };
  2309. Ruleset.prototype.prependRule = function (rule) {
  2310. var rules = this.rules;
  2311. if (rules) {
  2312. rules.unshift(rule);
  2313. }
  2314. else {
  2315. this.rules = [rule];
  2316. }
  2317. this.setParent(rule, this);
  2318. };
  2319. Ruleset.prototype.find = function (selector, self, filter) {
  2320. if (self === void 0) { self = this; }
  2321. var rules = [];
  2322. var match;
  2323. var foundMixins;
  2324. var key = selector.toCSS();
  2325. if (key in this._lookups) {
  2326. return this._lookups[key];
  2327. }
  2328. this.rulesets().forEach(function (rule) {
  2329. if (rule !== self) {
  2330. for (var j = 0; j < rule.selectors.length; j++) {
  2331. match = selector.match(rule.selectors[j]);
  2332. if (match) {
  2333. if (selector.elements.length > match) {
  2334. if (!filter || filter(rule)) {
  2335. foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter);
  2336. for (var i_2 = 0; i_2 < foundMixins.length; ++i_2) {
  2337. foundMixins[i_2].path.push(rule);
  2338. }
  2339. Array.prototype.push.apply(rules, foundMixins);
  2340. }
  2341. }
  2342. else {
  2343. rules.push({ rule: rule, path: [] });
  2344. }
  2345. break;
  2346. }
  2347. }
  2348. }
  2349. });
  2350. this._lookups[key] = rules;
  2351. return rules;
  2352. };
  2353. Ruleset.prototype.genCSS = function (context, output) {
  2354. var i;
  2355. var j;
  2356. var charsetRuleNodes = [];
  2357. var ruleNodes = [];
  2358. var // Line number debugging
  2359. debugInfo$1;
  2360. var rule;
  2361. var path;
  2362. context.tabLevel = (context.tabLevel || 0);
  2363. if (!this.root) {
  2364. context.tabLevel++;
  2365. }
  2366. var tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(' ');
  2367. var tabSetStr = context.compress ? '' : Array(context.tabLevel).join(' ');
  2368. var sep;
  2369. var charsetNodeIndex = 0;
  2370. var importNodeIndex = 0;
  2371. for (i = 0; (rule = this.rules[i]); i++) {
  2372. if (rule instanceof Comment) {
  2373. if (importNodeIndex === i) {
  2374. importNodeIndex++;
  2375. }
  2376. ruleNodes.push(rule);
  2377. }
  2378. else if (rule.isCharset && rule.isCharset()) {
  2379. ruleNodes.splice(charsetNodeIndex, 0, rule);
  2380. charsetNodeIndex++;
  2381. importNodeIndex++;
  2382. }
  2383. else if (rule.type === 'Import') {
  2384. ruleNodes.splice(importNodeIndex, 0, rule);
  2385. importNodeIndex++;
  2386. }
  2387. else {
  2388. ruleNodes.push(rule);
  2389. }
  2390. }
  2391. ruleNodes = charsetRuleNodes.concat(ruleNodes);
  2392. // If this is the root node, we don't render
  2393. // a selector, or {}.
  2394. if (!this.root) {
  2395. debugInfo$1 = debugInfo(context, this, tabSetStr);
  2396. if (debugInfo$1) {
  2397. output.add(debugInfo$1);
  2398. output.add(tabSetStr);
  2399. }
  2400. var paths = this.paths;
  2401. var pathCnt = paths.length;
  2402. var pathSubCnt = void 0;
  2403. sep = context.compress ? ',' : (",\n" + tabSetStr);
  2404. for (i = 0; i < pathCnt; i++) {
  2405. path = paths[i];
  2406. if (!(pathSubCnt = path.length)) {
  2407. continue;
  2408. }
  2409. if (i > 0) {
  2410. output.add(sep);
  2411. }
  2412. context.firstSelector = true;
  2413. path[0].genCSS(context, output);
  2414. context.firstSelector = false;
  2415. for (j = 1; j < pathSubCnt; j++) {
  2416. path[j].genCSS(context, output);
  2417. }
  2418. }
  2419. output.add((context.compress ? '{' : ' {\n') + tabRuleStr);
  2420. }
  2421. // Compile rules and rulesets
  2422. for (i = 0; (rule = ruleNodes[i]); i++) {
  2423. if (i + 1 === ruleNodes.length) {
  2424. context.lastRule = true;
  2425. }
  2426. var currentLastRule = context.lastRule;
  2427. if (rule.isRulesetLike(rule)) {
  2428. context.lastRule = false;
  2429. }
  2430. if (rule.genCSS) {
  2431. rule.genCSS(context, output);
  2432. }
  2433. else if (rule.value) {
  2434. output.add(rule.value.toString());
  2435. }
  2436. context.lastRule = currentLastRule;
  2437. if (!context.lastRule && rule.isVisible()) {
  2438. output.add(context.compress ? '' : ("\n" + tabRuleStr));
  2439. }
  2440. else {
  2441. context.lastRule = false;
  2442. }
  2443. }
  2444. if (!this.root) {
  2445. output.add((context.compress ? '}' : "\n" + tabSetStr + "}"));
  2446. context.tabLevel--;
  2447. }
  2448. if (!output.isEmpty() && !context.compress && this.firstRoot) {
  2449. output.add('\n');
  2450. }
  2451. };
  2452. Ruleset.prototype.joinSelectors = function (paths, context, selectors) {
  2453. for (var s = 0; s < selectors.length; s++) {
  2454. this.joinSelector(paths, context, selectors[s]);
  2455. }
  2456. };
  2457. Ruleset.prototype.joinSelector = function (paths, context, selector) {
  2458. function createParenthesis(elementsToPak, originalElement) {
  2459. var replacementParen;
  2460. var j;
  2461. if (elementsToPak.length === 0) {
  2462. replacementParen = new Paren(elementsToPak[0]);
  2463. }
  2464. else {
  2465. var insideParent = new Array(elementsToPak.length);
  2466. for (j = 0; j < elementsToPak.length; j++) {
  2467. insideParent[j] = new Element(null, elementsToPak[j], originalElement.isVariable, originalElement._index, originalElement._fileInfo);
  2468. }
  2469. replacementParen = new Paren(new Selector(insideParent));
  2470. }
  2471. return replacementParen;
  2472. }
  2473. function createSelector(containedElement, originalElement) {
  2474. var element;
  2475. var selector;
  2476. element = new Element(null, containedElement, originalElement.isVariable, originalElement._index, originalElement._fileInfo);
  2477. selector = new Selector([element]);
  2478. return selector;
  2479. }
  2480. // joins selector path from `beginningPath` with selector path in `addPath`
  2481. // `replacedElement` contains element that is being replaced by `addPath`
  2482. // returns concatenated path
  2483. function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) {
  2484. var newSelectorPath;
  2485. var lastSelector;
  2486. var newJoinedSelector;
  2487. // our new selector path
  2488. newSelectorPath = [];
  2489. // construct the joined selector - if & is the first thing this will be empty,
  2490. // if not newJoinedSelector will be the last set of elements in the selector
  2491. if (beginningPath.length > 0) {
  2492. newSelectorPath = copyArray(beginningPath);
  2493. lastSelector = newSelectorPath.pop();
  2494. newJoinedSelector = originalSelector.createDerived(copyArray(lastSelector.elements));
  2495. }
  2496. else {
  2497. newJoinedSelector = originalSelector.createDerived([]);
  2498. }
  2499. if (addPath.length > 0) {
  2500. // /deep/ is a CSS4 selector - (removed, so should deprecate)
  2501. // that is valid without anything in front of it
  2502. // so if the & does not have a combinator that is "" or " " then
  2503. // and there is a combinator on the parent, then grab that.
  2504. // this also allows + a { & .b { .a & { ... though not sure why you would want to do that
  2505. var combinator = replacedElement.combinator;
  2506. var parentEl = addPath[0].elements[0];
  2507. if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) {
  2508. combinator = parentEl.combinator;
  2509. }
  2510. // join the elements so far with the first part of the parent
  2511. newJoinedSelector.elements.push(new Element(combinator, parentEl.value, replacedElement.isVariable, replacedElement._index, replacedElement._fileInfo));
  2512. newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1));
  2513. }
  2514. // now add the joined selector - but only if it is not empty
  2515. if (newJoinedSelector.elements.length !== 0) {
  2516. newSelectorPath.push(newJoinedSelector);
  2517. }
  2518. // put together the parent selectors after the join (e.g. the rest of the parent)
  2519. if (addPath.length > 1) {
  2520. var restOfPath = addPath.slice(1);
  2521. restOfPath = restOfPath.map(function (selector) { return selector.createDerived(selector.elements, []); });
  2522. newSelectorPath = newSelectorPath.concat(restOfPath);
  2523. }
  2524. return newSelectorPath;
  2525. }
  2526. // joins selector path from `beginningPath` with every selector path in `addPaths` array
  2527. // `replacedElement` contains element that is being replaced by `addPath`
  2528. // returns array with all concatenated paths
  2529. function addAllReplacementsIntoPath(beginningPath, addPaths, replacedElement, originalSelector, result) {
  2530. var j;
  2531. for (j = 0; j < beginningPath.length; j++) {
  2532. var newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector);
  2533. result.push(newSelectorPath);
  2534. }
  2535. return result;
  2536. }
  2537. function mergeElementsOnToSelectors(elements, selectors) {
  2538. var i;
  2539. var sel;
  2540. if (elements.length === 0) {
  2541. return;
  2542. }
  2543. if (selectors.length === 0) {
  2544. selectors.push([new Selector(elements)]);
  2545. return;
  2546. }
  2547. for (i = 0; (sel = selectors[i]); i++) {
  2548. // if the previous thing in sel is a parent this needs to join on to it
  2549. if (sel.length > 0) {
  2550. sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements));
  2551. }
  2552. else {
  2553. sel.push(new Selector(elements));
  2554. }
  2555. }
  2556. }
  2557. // replace all parent selectors inside `inSelector` by content of `context` array
  2558. // resulting selectors are returned inside `paths` array
  2559. // returns true if `inSelector` contained at least one parent selector
  2560. function replaceParentSelector(paths, context, inSelector) {
  2561. // The paths are [[Selector]]
  2562. // The first list is a list of comma separated selectors
  2563. // The inner list is a list of inheritance separated selectors
  2564. // e.g.
  2565. // .a, .b {
  2566. // .c {
  2567. // }
  2568. // }
  2569. // == [[.a] [.c]] [[.b] [.c]]
  2570. //
  2571. var i;
  2572. var j;
  2573. var k;
  2574. var currentElements;
  2575. var newSelectors;
  2576. var selectorsMultiplied;
  2577. var sel;
  2578. var el;
  2579. var hadParentSelector = false;
  2580. var length;
  2581. var lastSelector;
  2582. function findNestedSelector(element) {
  2583. var maybeSelector;
  2584. if (!(element.value instanceof Paren)) {
  2585. return null;
  2586. }
  2587. maybeSelector = element.value.value;
  2588. if (!(maybeSelector instanceof Selector)) {
  2589. return null;
  2590. }
  2591. return maybeSelector;
  2592. }
  2593. // the elements from the current selector so far
  2594. currentElements = [];
  2595. // the current list of new selectors to add to the path.
  2596. // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
  2597. // by the parents
  2598. newSelectors = [
  2599. []
  2600. ];
  2601. for (i = 0; (el = inSelector.elements[i]); i++) {
  2602. // non parent reference elements just get added
  2603. if (el.value !== '&') {
  2604. var nestedSelector = findNestedSelector(el);
  2605. if (nestedSelector != null) {
  2606. // merge the current list of non parent selector elements
  2607. // on to the current list of selectors to add
  2608. mergeElementsOnToSelectors(currentElements, newSelectors);
  2609. var nestedPaths = [];
  2610. var replaced = void 0;
  2611. var replacedNewSelectors = [];
  2612. replaced = replaceParentSelector(nestedPaths, context, nestedSelector);
  2613. hadParentSelector = hadParentSelector || replaced;
  2614. // the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors
  2615. for (k = 0; k < nestedPaths.length; k++) {
  2616. var replacementSelector = createSelector(createParenthesis(nestedPaths[k], el), el);
  2617. addAllReplacementsIntoPath(newSelectors, [replacementSelector], el, inSelector, replacedNewSelectors);
  2618. }
  2619. newSelectors = replacedNewSelectors;
  2620. currentElements = [];
  2621. }
  2622. else {
  2623. currentElements.push(el);
  2624. }
  2625. }
  2626. else {
  2627. hadParentSelector = true;
  2628. // the new list of selectors to add
  2629. selectorsMultiplied = [];
  2630. // merge the current list of non parent selector elements
  2631. // on to the current list of selectors to add
  2632. mergeElementsOnToSelectors(currentElements, newSelectors);
  2633. // loop through our current selectors
  2634. for (j = 0; j < newSelectors.length; j++) {
  2635. sel = newSelectors[j];
  2636. // if we don't have any parent paths, the & might be in a mixin so that it can be used
  2637. // whether there are parents or not
  2638. if (context.length === 0) {
  2639. // the combinator used on el should now be applied to the next element instead so that
  2640. // it is not lost
  2641. if (sel.length > 0) {
  2642. sel[0].elements.push(new Element(el.combinator, '', el.isVariable, el._index, el._fileInfo));
  2643. }
  2644. selectorsMultiplied.push(sel);
  2645. }
  2646. else {
  2647. // and the parent selectors
  2648. for (k = 0; k < context.length; k++) {
  2649. // We need to put the current selectors
  2650. // then join the last selector's elements on to the parents selectors
  2651. var newSelectorPath = addReplacementIntoPath(sel, context[k], el, inSelector);
  2652. // add that to our new set of selectors
  2653. selectorsMultiplied.push(newSelectorPath);
  2654. }
  2655. }
  2656. }
  2657. // our new selectors has been multiplied, so reset the state
  2658. newSelectors = selectorsMultiplied;
  2659. currentElements = [];
  2660. }
  2661. }
  2662. // if we have any elements left over (e.g. .a& .b == .b)
  2663. // add them on to all the current selectors
  2664. mergeElementsOnToSelectors(currentElements, newSelectors);
  2665. for (i = 0; i < newSelectors.length; i++) {
  2666. length = newSelectors[i].length;
  2667. if (length > 0) {
  2668. paths.push(newSelectors[i]);
  2669. lastSelector = newSelectors[i][length - 1];
  2670. newSelectors[i][length - 1] = lastSelector.createDerived(lastSelector.elements, inSelector.extendList);
  2671. }
  2672. }
  2673. return hadParentSelector;
  2674. }
  2675. function deriveSelector(visibilityInfo, deriveFrom) {
  2676. var newSelector = deriveFrom.createDerived(deriveFrom.elements, deriveFrom.extendList, deriveFrom.evaldCondition);
  2677. newSelector.copyVisibilityInfo(visibilityInfo);
  2678. return newSelector;
  2679. }
  2680. // joinSelector code follows
  2681. var i;
  2682. var newPaths;
  2683. var hadParentSelector;
  2684. newPaths = [];
  2685. hadParentSelector = replaceParentSelector(newPaths, context, selector);
  2686. if (!hadParentSelector) {
  2687. if (context.length > 0) {
  2688. newPaths = [];
  2689. for (i = 0; i < context.length; i++) {
  2690. var concatenated = context[i].map(deriveSelector.bind(this, selector.visibilityInfo()));
  2691. concatenated.push(selector);
  2692. newPaths.push(concatenated);
  2693. }
  2694. }
  2695. else {
  2696. newPaths = [[selector]];
  2697. }
  2698. }
  2699. for (i = 0; i < newPaths.length; i++) {
  2700. paths.push(newPaths[i]);
  2701. }
  2702. };
  2703. return Ruleset;
  2704. }(Node));
  2705. Ruleset.prototype.type = 'Ruleset';
  2706. Ruleset.prototype.isRuleset = true;
  2707. var AtRule = /** @class */ (function (_super) {
  2708. __extends(AtRule, _super);
  2709. function AtRule(name, value, rules, index, currentFileInfo, debugInfo, isRooted, visibilityInfo) {
  2710. var _this = _super.call(this) || this;
  2711. var i;
  2712. _this.name = name;
  2713. _this.value = (value instanceof Node) ? value : (value ? new Anonymous(value) : value);
  2714. if (rules) {
  2715. if (Array.isArray(rules)) {
  2716. _this.rules = rules;
  2717. }
  2718. else {
  2719. _this.rules = [rules];
  2720. _this.rules[0].selectors = (new Selector([], null, null, index, currentFileInfo)).createEmptySelectors();
  2721. }
  2722. for (i = 0; i < _this.rules.length; i++) {
  2723. _this.rules[i].allowImports = true;
  2724. }
  2725. _this.setParent(_this.rules, _this);
  2726. }
  2727. _this._index = index;
  2728. _this._fileInfo = currentFileInfo;
  2729. _this.debugInfo = debugInfo;
  2730. _this.isRooted = isRooted || false;
  2731. _this.copyVisibilityInfo(visibilityInfo);
  2732. _this.allowRoot = true;
  2733. return _this;
  2734. }
  2735. AtRule.prototype.accept = function (visitor) {
  2736. var value = this.value;
  2737. var rules = this.rules;
  2738. if (rules) {
  2739. this.rules = visitor.visitArray(rules);
  2740. }
  2741. if (value) {
  2742. this.value = visitor.visit(value);
  2743. }
  2744. };
  2745. AtRule.prototype.isRulesetLike = function () {
  2746. return this.rules || !this.isCharset();
  2747. };
  2748. AtRule.prototype.isCharset = function () {
  2749. return '@charset' === this.name;
  2750. };
  2751. AtRule.prototype.genCSS = function (context, output) {
  2752. var value = this.value;
  2753. var rules = this.rules;
  2754. output.add(this.name, this.fileInfo(), this.getIndex());
  2755. if (value) {
  2756. output.add(' ');
  2757. value.genCSS(context, output);
  2758. }
  2759. if (rules) {
  2760. this.outputRuleset(context, output, rules);
  2761. }
  2762. else {
  2763. output.add(';');
  2764. }
  2765. };
  2766. AtRule.prototype.eval = function (context) {
  2767. var mediaPathBackup;
  2768. var mediaBlocksBackup;
  2769. var value = this.value;
  2770. var rules = this.rules;
  2771. // media stored inside other atrule should not bubble over it
  2772. // backpup media bubbling information
  2773. mediaPathBackup = context.mediaPath;
  2774. mediaBlocksBackup = context.mediaBlocks;
  2775. // deleted media bubbling information
  2776. context.mediaPath = [];
  2777. context.mediaBlocks = [];
  2778. if (value) {
  2779. value = value.eval(context);
  2780. }
  2781. if (rules) {
  2782. // assuming that there is only one rule at this point - that is how parser constructs the rule
  2783. rules = [rules[0].eval(context)];
  2784. rules[0].root = true;
  2785. }
  2786. // restore media bubbling information
  2787. context.mediaPath = mediaPathBackup;
  2788. context.mediaBlocks = mediaBlocksBackup;
  2789. return new AtRule(this.name, value, rules, this.getIndex(), this.fileInfo(), this.debugInfo, this.isRooted, this.visibilityInfo());
  2790. };
  2791. AtRule.prototype.variable = function (name) {
  2792. if (this.rules) {
  2793. // assuming that there is only one rule at this point - that is how parser constructs the rule
  2794. return Ruleset.prototype.variable.call(this.rules[0], name);
  2795. }
  2796. };
  2797. AtRule.prototype.find = function () {
  2798. var args = [];
  2799. for (var _i = 0; _i < arguments.length; _i++) {
  2800. args[_i] = arguments[_i];
  2801. }
  2802. if (this.rules) {
  2803. // assuming that there is only one rule at this point - that is how parser constructs the rule
  2804. return Ruleset.prototype.find.apply(this.rules[0], args);
  2805. }
  2806. };
  2807. AtRule.prototype.rulesets = function () {
  2808. if (this.rules) {
  2809. // assuming that there is only one rule at this point - that is how parser constructs the rule
  2810. return Ruleset.prototype.rulesets.apply(this.rules[0]);
  2811. }
  2812. };
  2813. AtRule.prototype.outputRuleset = function (context, output, rules) {
  2814. var ruleCnt = rules.length;
  2815. var i;
  2816. context.tabLevel = (context.tabLevel | 0) + 1;
  2817. // Compressed
  2818. if (context.compress) {
  2819. output.add('{');
  2820. for (i = 0; i < ruleCnt; i++) {
  2821. rules[i].genCSS(context, output);
  2822. }
  2823. output.add('}');
  2824. context.tabLevel--;
  2825. return;
  2826. }
  2827. // Non-compressed
  2828. var tabSetStr = "\n" + Array(context.tabLevel).join(' ');
  2829. var tabRuleStr = tabSetStr + " ";
  2830. if (!ruleCnt) {
  2831. output.add(" {" + tabSetStr + "}");
  2832. }
  2833. else {
  2834. output.add(" {" + tabRuleStr);
  2835. rules[0].genCSS(context, output);
  2836. for (i = 1; i < ruleCnt; i++) {
  2837. output.add(tabRuleStr);
  2838. rules[i].genCSS(context, output);
  2839. }
  2840. output.add(tabSetStr + "}");
  2841. }
  2842. context.tabLevel--;
  2843. };
  2844. return AtRule;
  2845. }(Node));
  2846. AtRule.prototype.type = 'AtRule';
  2847. var DetachedRuleset = /** @class */ (function (_super) {
  2848. __extends(DetachedRuleset, _super);
  2849. function DetachedRuleset(ruleset, frames) {
  2850. var _this = _super.call(this) || this;
  2851. _this.ruleset = ruleset;
  2852. _this.frames = frames;
  2853. _this.setParent(_this.ruleset, _this);
  2854. return _this;
  2855. }
  2856. DetachedRuleset.prototype.accept = function (visitor) {
  2857. this.ruleset = visitor.visit(this.ruleset);
  2858. };
  2859. DetachedRuleset.prototype.eval = function (context) {
  2860. var frames = this.frames || copyArray(context.frames);
  2861. return new DetachedRuleset(this.ruleset, frames);
  2862. };
  2863. DetachedRuleset.prototype.callEval = function (context) {
  2864. return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context);
  2865. };
  2866. return DetachedRuleset;
  2867. }(Node));
  2868. DetachedRuleset.prototype.type = 'DetachedRuleset';
  2869. DetachedRuleset.prototype.evalFirst = true;
  2870. var Unit = /** @class */ (function (_super) {
  2871. __extends(Unit, _super);
  2872. function Unit(numerator, denominator, backupUnit) {
  2873. var _this = _super.call(this) || this;
  2874. _this.numerator = numerator ? copyArray(numerator).sort() : [];
  2875. _this.denominator = denominator ? copyArray(denominator).sort() : [];
  2876. if (backupUnit) {
  2877. _this.backupUnit = backupUnit;
  2878. }
  2879. else if (numerator && numerator.length) {
  2880. _this.backupUnit = numerator[0];
  2881. }
  2882. return _this;
  2883. }
  2884. Unit.prototype.clone = function () {
  2885. return new Unit(copyArray(this.numerator), copyArray(this.denominator), this.backupUnit);
  2886. };
  2887. Unit.prototype.genCSS = function (context, output) {
  2888. // Dimension checks the unit is singular and throws an error if in strict math mode.
  2889. var strictUnits = context && context.strictUnits;
  2890. if (this.numerator.length === 1) {
  2891. output.add(this.numerator[0]); // the ideal situation
  2892. }
  2893. else if (!strictUnits && this.backupUnit) {
  2894. output.add(this.backupUnit);
  2895. }
  2896. else if (!strictUnits && this.denominator.length) {
  2897. output.add(this.denominator[0]);
  2898. }
  2899. };
  2900. Unit.prototype.toString = function () {
  2901. var i;
  2902. var returnStr = this.numerator.join('*');
  2903. for (i = 0; i < this.denominator.length; i++) {
  2904. returnStr += "/" + this.denominator[i];
  2905. }
  2906. return returnStr;
  2907. };
  2908. Unit.prototype.compare = function (other) {
  2909. return this.is(other.toString()) ? 0 : undefined;
  2910. };
  2911. Unit.prototype.is = function (unitString) {
  2912. return this.toString().toUpperCase() === unitString.toUpperCase();
  2913. };
  2914. Unit.prototype.isLength = function () {
  2915. return RegExp('^(px|em|ex|ch|rem|in|cm|mm|pc|pt|ex|vw|vh|vmin|vmax)$', 'gi').test(this.toCSS());
  2916. };
  2917. Unit.prototype.isEmpty = function () {
  2918. return this.numerator.length === 0 && this.denominator.length === 0;
  2919. };
  2920. Unit.prototype.isSingular = function () {
  2921. return this.numerator.length <= 1 && this.denominator.length === 0;
  2922. };
  2923. Unit.prototype.map = function (callback) {
  2924. var i;
  2925. for (i = 0; i < this.numerator.length; i++) {
  2926. this.numerator[i] = callback(this.numerator[i], false);
  2927. }
  2928. for (i = 0; i < this.denominator.length; i++) {
  2929. this.denominator[i] = callback(this.denominator[i], true);
  2930. }
  2931. };
  2932. Unit.prototype.usedUnits = function () {
  2933. var group;
  2934. var result = {};
  2935. var mapUnit;
  2936. var groupName;
  2937. mapUnit = function (atomicUnit) {
  2938. /* jshint loopfunc:true */
  2939. if (group.hasOwnProperty(atomicUnit) && !result[groupName]) {
  2940. result[groupName] = atomicUnit;
  2941. }
  2942. return atomicUnit;
  2943. };
  2944. for (groupName in unitConversions) {
  2945. if (unitConversions.hasOwnProperty(groupName)) {
  2946. group = unitConversions[groupName];
  2947. this.map(mapUnit);
  2948. }
  2949. }
  2950. return result;
  2951. };
  2952. Unit.prototype.cancel = function () {
  2953. var counter = {};
  2954. var atomicUnit;
  2955. var i;
  2956. for (i = 0; i < this.numerator.length; i++) {
  2957. atomicUnit = this.numerator[i];
  2958. counter[atomicUnit] = (counter[atomicUnit] || 0) + 1;
  2959. }
  2960. for (i = 0; i < this.denominator.length; i++) {
  2961. atomicUnit = this.denominator[i];
  2962. counter[atomicUnit] = (counter[atomicUnit] || 0) - 1;
  2963. }
  2964. this.numerator = [];
  2965. this.denominator = [];
  2966. for (atomicUnit in counter) {
  2967. if (counter.hasOwnProperty(atomicUnit)) {
  2968. var count = counter[atomicUnit];
  2969. if (count > 0) {
  2970. for (i = 0; i < count; i++) {
  2971. this.numerator.push(atomicUnit);
  2972. }
  2973. }
  2974. else if (count < 0) {
  2975. for (i = 0; i < -count; i++) {
  2976. this.denominator.push(atomicUnit);
  2977. }
  2978. }
  2979. }
  2980. }
  2981. this.numerator.sort();
  2982. this.denominator.sort();
  2983. };
  2984. return Unit;
  2985. }(Node));
  2986. Unit.prototype.type = 'Unit';
  2987. //
  2988. // A number with a unit
  2989. //
  2990. var Dimension = /** @class */ (function (_super) {
  2991. __extends(Dimension, _super);
  2992. function Dimension(value, unit) {
  2993. var _this = _super.call(this) || this;
  2994. _this.value = parseFloat(value);
  2995. if (isNaN(_this.value)) {
  2996. throw new Error('Dimension is not a number.');
  2997. }
  2998. _this.unit = (unit && unit instanceof Unit) ? unit :
  2999. new Unit(unit ? [unit] : undefined);
  3000. _this.setParent(_this.unit, _this);
  3001. return _this;
  3002. }
  3003. Dimension.prototype.accept = function (visitor) {
  3004. this.unit = visitor.visit(this.unit);
  3005. };
  3006. Dimension.prototype.eval = function (context) {
  3007. return this;
  3008. };
  3009. Dimension.prototype.toColor = function () {
  3010. return new Color([this.value, this.value, this.value]);
  3011. };
  3012. Dimension.prototype.genCSS = function (context, output) {
  3013. if ((context && context.strictUnits) && !this.unit.isSingular()) {
  3014. throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: " + this.unit.toString());
  3015. }
  3016. var value = this.fround(context, this.value);
  3017. var strValue = String(value);
  3018. if (value !== 0 && value < 0.000001 && value > -0.000001) {
  3019. // would be output 1e-6 etc.
  3020. strValue = value.toFixed(20).replace(/0+$/, '');
  3021. }
  3022. if (context && context.compress) {
  3023. // Zero values doesn't need a unit
  3024. if (value === 0 && this.unit.isLength()) {
  3025. output.add(strValue);
  3026. return;
  3027. }
  3028. // Float values doesn't need a leading zero
  3029. if (value > 0 && value < 1) {
  3030. strValue = (strValue).substr(1);
  3031. }
  3032. }
  3033. output.add(strValue);
  3034. this.unit.genCSS(context, output);
  3035. };
  3036. // In an operation between two Dimensions,
  3037. // we default to the first Dimension's unit,
  3038. // so `1px + 2` will yield `3px`.
  3039. Dimension.prototype.operate = function (context, op, other) {
  3040. /* jshint noempty:false */
  3041. var value = this._operate(context, op, this.value, other.value);
  3042. var unit = this.unit.clone();
  3043. if (op === '+' || op === '-') {
  3044. if (unit.numerator.length === 0 && unit.denominator.length === 0) {
  3045. unit = other.unit.clone();
  3046. if (this.unit.backupUnit) {
  3047. unit.backupUnit = this.unit.backupUnit;
  3048. }
  3049. }
  3050. else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) ;
  3051. else {
  3052. other = other.convertTo(this.unit.usedUnits());
  3053. if (context.strictUnits && other.unit.toString() !== unit.toString()) {
  3054. throw new Error("Incompatible units. Change the units or use the unit function. " +
  3055. ("Bad units: '" + unit.toString() + "' and '" + other.unit.toString() + "'."));
  3056. }
  3057. value = this._operate(context, op, this.value, other.value);
  3058. }
  3059. }
  3060. else if (op === '*') {
  3061. unit.numerator = unit.numerator.concat(other.unit.numerator).sort();
  3062. unit.denominator = unit.denominator.concat(other.unit.denominator).sort();
  3063. unit.cancel();
  3064. }
  3065. else if (op === '/') {
  3066. unit.numerator = unit.numerator.concat(other.unit.denominator).sort();
  3067. unit.denominator = unit.denominator.concat(other.unit.numerator).sort();
  3068. unit.cancel();
  3069. }
  3070. return new Dimension(value, unit);
  3071. };
  3072. Dimension.prototype.compare = function (other) {
  3073. var a;
  3074. var b;
  3075. if (!(other instanceof Dimension)) {
  3076. return undefined;
  3077. }
  3078. if (this.unit.isEmpty() || other.unit.isEmpty()) {
  3079. a = this;
  3080. b = other;
  3081. }
  3082. else {
  3083. a = this.unify();
  3084. b = other.unify();
  3085. if (a.unit.compare(b.unit) !== 0) {
  3086. return undefined;
  3087. }
  3088. }
  3089. return Node.numericCompare(a.value, b.value);
  3090. };
  3091. Dimension.prototype.unify = function () {
  3092. return this.convertTo({ length: 'px', duration: 's', angle: 'rad' });
  3093. };
  3094. Dimension.prototype.convertTo = function (conversions) {
  3095. var value = this.value;
  3096. var unit = this.unit.clone();
  3097. var i;
  3098. var groupName;
  3099. var group;
  3100. var targetUnit;
  3101. var derivedConversions = {};
  3102. var applyUnit;
  3103. if (typeof conversions === 'string') {
  3104. for (i in unitConversions) {
  3105. if (unitConversions[i].hasOwnProperty(conversions)) {
  3106. derivedConversions = {};
  3107. derivedConversions[i] = conversions;
  3108. }
  3109. }
  3110. conversions = derivedConversions;
  3111. }
  3112. applyUnit = function (atomicUnit, denominator) {
  3113. /* jshint loopfunc:true */
  3114. if (group.hasOwnProperty(atomicUnit)) {
  3115. if (denominator) {
  3116. value = value / (group[atomicUnit] / group[targetUnit]);
  3117. }
  3118. else {
  3119. value = value * (group[atomicUnit] / group[targetUnit]);
  3120. }
  3121. return targetUnit;
  3122. }
  3123. return atomicUnit;
  3124. };
  3125. for (groupName in conversions) {
  3126. if (conversions.hasOwnProperty(groupName)) {
  3127. targetUnit = conversions[groupName];
  3128. group = unitConversions[groupName];
  3129. unit.map(applyUnit);
  3130. }
  3131. }
  3132. unit.cancel();
  3133. return new Dimension(value, unit);
  3134. };
  3135. return Dimension;
  3136. }(Node));
  3137. Dimension.prototype.type = 'Dimension';
  3138. var MATH$1 = Math$1;
  3139. var Operation = /** @class */ (function (_super) {
  3140. __extends(Operation, _super);
  3141. function Operation(op, operands, isSpaced) {
  3142. var _this = _super.call(this) || this;
  3143. _this.op = op.trim();
  3144. _this.operands = operands;
  3145. _this.isSpaced = isSpaced;
  3146. return _this;
  3147. }
  3148. Operation.prototype.accept = function (visitor) {
  3149. this.operands = visitor.visitArray(this.operands);
  3150. };
  3151. Operation.prototype.eval = function (context) {
  3152. var a = this.operands[0].eval(context);
  3153. var b = this.operands[1].eval(context);
  3154. var op;
  3155. if (context.isMathOn(this.op)) {
  3156. op = this.op === './' ? '/' : this.op;
  3157. if (a instanceof Dimension && b instanceof Color) {
  3158. a = a.toColor();
  3159. }
  3160. if (b instanceof Dimension && a instanceof Color) {
  3161. b = b.toColor();
  3162. }
  3163. if (!a.operate) {
  3164. if (a instanceof Operation && a.op === '/' && context.math === MATH$1.PARENS_DIVISION) {
  3165. return new Operation(this.op, [a, b], this.isSpaced);
  3166. }
  3167. throw { type: 'Operation',
  3168. message: 'Operation on an invalid type' };
  3169. }
  3170. return a.operate(context, op, b);
  3171. }
  3172. else {
  3173. return new Operation(this.op, [a, b], this.isSpaced);
  3174. }
  3175. };
  3176. Operation.prototype.genCSS = function (context, output) {
  3177. this.operands[0].genCSS(context, output);
  3178. if (this.isSpaced) {
  3179. output.add(' ');
  3180. }
  3181. output.add(this.op);
  3182. if (this.isSpaced) {
  3183. output.add(' ');
  3184. }
  3185. this.operands[1].genCSS(context, output);
  3186. };
  3187. return Operation;
  3188. }(Node));
  3189. Operation.prototype.type = 'Operation';
  3190. var MATH$2 = Math$1;
  3191. var Expression = /** @class */ (function (_super) {
  3192. __extends(Expression, _super);
  3193. function Expression(value, noSpacing) {
  3194. var _this = _super.call(this) || this;
  3195. _this.value = value;
  3196. _this.noSpacing = noSpacing;
  3197. if (!value) {
  3198. throw new Error('Expression requires an array parameter');
  3199. }
  3200. return _this;
  3201. }
  3202. Expression.prototype.accept = function (visitor) {
  3203. this.value = visitor.visitArray(this.value);
  3204. };
  3205. Expression.prototype.eval = function (context) {
  3206. var returnValue;
  3207. var mathOn = context.isMathOn();
  3208. var inParenthesis = this.parens &&
  3209. (context.math !== MATH$2.STRICT_LEGACY || !this.parensInOp);
  3210. var doubleParen = false;
  3211. if (inParenthesis) {
  3212. context.inParenthesis();
  3213. }
  3214. if (this.value.length > 1) {
  3215. returnValue = new Expression(this.value.map(function (e) {
  3216. if (!e.eval) {
  3217. return e;
  3218. }
  3219. return e.eval(context);
  3220. }), this.noSpacing);
  3221. }
  3222. else if (this.value.length === 1) {
  3223. if (this.value[0].parens && !this.value[0].parensInOp && !context.inCalc) {
  3224. doubleParen = true;
  3225. }
  3226. returnValue = this.value[0].eval(context);
  3227. }
  3228. else {
  3229. returnValue = this;
  3230. }
  3231. if (inParenthesis) {
  3232. context.outOfParenthesis();
  3233. }
  3234. if (this.parens && this.parensInOp && !mathOn && !doubleParen
  3235. && (!(returnValue instanceof Dimension))) {
  3236. returnValue = new Paren(returnValue);
  3237. }
  3238. return returnValue;
  3239. };
  3240. Expression.prototype.genCSS = function (context, output) {
  3241. for (var i_1 = 0; i_1 < this.value.length; i_1++) {
  3242. this.value[i_1].genCSS(context, output);
  3243. if (!this.noSpacing && i_1 + 1 < this.value.length) {
  3244. output.add(' ');
  3245. }
  3246. }
  3247. };
  3248. Expression.prototype.throwAwayComments = function () {
  3249. this.value = this.value.filter(function (v) { return !(v instanceof Comment); });
  3250. };
  3251. return Expression;
  3252. }(Node));
  3253. Expression.prototype.type = 'Expression';
  3254. var functionCaller = /** @class */ (function () {
  3255. function functionCaller(name, context, index, currentFileInfo) {
  3256. this.name = name.toLowerCase();
  3257. this.index = index;
  3258. this.context = context;
  3259. this.currentFileInfo = currentFileInfo;
  3260. this.func = context.frames[0].functionRegistry.get(this.name);
  3261. }
  3262. functionCaller.prototype.isValid = function () {
  3263. return Boolean(this.func);
  3264. };
  3265. functionCaller.prototype.call = function (args) {
  3266. // This code is terrible and should be replaced as per this issue...
  3267. // https://github.com/less/less.js/issues/2477
  3268. if (Array.isArray(args)) {
  3269. args = args.filter(function (item) {
  3270. if (item.type === 'Comment') {
  3271. return false;
  3272. }
  3273. return true;
  3274. })
  3275. .map(function (item) {
  3276. if (item.type === 'Expression') {
  3277. var subNodes = item.value.filter(function (item) {
  3278. if (item.type === 'Comment') {
  3279. return false;
  3280. }
  3281. return true;
  3282. });
  3283. if (subNodes.length === 1) {
  3284. return subNodes[0];
  3285. }
  3286. else {
  3287. return new Expression(subNodes);
  3288. }
  3289. }
  3290. return item;
  3291. });
  3292. }
  3293. return this.func.apply(this, args);
  3294. };
  3295. return functionCaller;
  3296. }());
  3297. //
  3298. // A function call node.
  3299. //
  3300. var Call = /** @class */ (function (_super) {
  3301. __extends(Call, _super);
  3302. function Call(name, args, index, currentFileInfo) {
  3303. var _this = _super.call(this) || this;
  3304. _this.name = name;
  3305. _this.args = args;
  3306. _this.calc = name === 'calc';
  3307. _this._index = index;
  3308. _this._fileInfo = currentFileInfo;
  3309. return _this;
  3310. }
  3311. Call.prototype.accept = function (visitor) {
  3312. if (this.args) {
  3313. this.args = visitor.visitArray(this.args);
  3314. }
  3315. };
  3316. //
  3317. // When evaluating a function call,
  3318. // we either find the function in the functionRegistry,
  3319. // in which case we call it, passing the evaluated arguments,
  3320. // if this returns null or we cannot find the function, we
  3321. // simply print it out as it appeared originally [2].
  3322. //
  3323. // The reason why we evaluate the arguments, is in the case where
  3324. // we try to pass a variable to a function, like: `saturate(@color)`.
  3325. // The function should receive the value, not the variable.
  3326. //
  3327. Call.prototype.eval = function (context) {
  3328. /**
  3329. * Turn off math for calc(), and switch back on for evaluating nested functions
  3330. */
  3331. var currentMathContext = context.mathOn;
  3332. context.mathOn = !this.calc;
  3333. if (this.calc || context.inCalc) {
  3334. context.enterCalc();
  3335. }
  3336. var args = this.args.map(function (a) { return a.eval(context); });
  3337. if (this.calc || context.inCalc) {
  3338. context.exitCalc();
  3339. }
  3340. context.mathOn = currentMathContext;
  3341. var result;
  3342. var funcCaller = new functionCaller(this.name, context, this.getIndex(), this.fileInfo());
  3343. if (funcCaller.isValid()) {
  3344. try {
  3345. result = funcCaller.call(args);
  3346. }
  3347. catch (e) {
  3348. throw {
  3349. type: e.type || 'Runtime',
  3350. message: "error evaluating function `" + this.name + "`" + (e.message ? ": " + e.message : ''),
  3351. index: this.getIndex(),
  3352. filename: this.fileInfo().filename,
  3353. line: e.lineNumber,
  3354. column: e.columnNumber
  3355. };
  3356. }
  3357. if (result !== null && result !== undefined) {
  3358. // Results that that are not nodes are cast as Anonymous nodes
  3359. // Falsy values or booleans are returned as empty nodes
  3360. if (!(result instanceof Node)) {
  3361. if (!result || result === true) {
  3362. result = new Anonymous(null);
  3363. }
  3364. else {
  3365. result = new Anonymous(result.toString());
  3366. }
  3367. }
  3368. result._index = this._index;
  3369. result._fileInfo = this._fileInfo;
  3370. return result;
  3371. }
  3372. }
  3373. return new Call(this.name, args, this.getIndex(), this.fileInfo());
  3374. };
  3375. Call.prototype.genCSS = function (context, output) {
  3376. output.add(this.name + "(", this.fileInfo(), this.getIndex());
  3377. for (var i_1 = 0; i_1 < this.args.length; i_1++) {
  3378. this.args[i_1].genCSS(context, output);
  3379. if (i_1 + 1 < this.args.length) {
  3380. output.add(', ');
  3381. }
  3382. }
  3383. output.add(')');
  3384. };
  3385. return Call;
  3386. }(Node));
  3387. Call.prototype.type = 'Call';
  3388. var Variable = /** @class */ (function (_super) {
  3389. __extends(Variable, _super);
  3390. function Variable(name, index, currentFileInfo) {
  3391. var _this = _super.call(this) || this;
  3392. _this.name = name;
  3393. _this._index = index;
  3394. _this._fileInfo = currentFileInfo;
  3395. return _this;
  3396. }
  3397. Variable.prototype.eval = function (context) {
  3398. var variable;
  3399. var name = this.name;
  3400. if (name.indexOf('@@') === 0) {
  3401. name = "@" + new Variable(name.slice(1), this.getIndex(), this.fileInfo()).eval(context).value;
  3402. }
  3403. if (this.evaluating) {
  3404. throw { type: 'Name',
  3405. message: "Recursive variable definition for " + name,
  3406. filename: this.fileInfo().filename,
  3407. index: this.getIndex() };
  3408. }
  3409. this.evaluating = true;
  3410. variable = this.find(context.frames, function (frame) {
  3411. var v = frame.variable(name);
  3412. if (v) {
  3413. if (v.important) {
  3414. var importantScope = context.importantScope[context.importantScope.length - 1];
  3415. importantScope.important = v.important;
  3416. }
  3417. // If in calc, wrap vars in a function call to cascade evaluate args first
  3418. if (context.inCalc) {
  3419. return (new Call('_SELF', [v.value])).eval(context);
  3420. }
  3421. else {
  3422. return v.value.eval(context);
  3423. }
  3424. }
  3425. });
  3426. if (variable) {
  3427. this.evaluating = false;
  3428. return variable;
  3429. }
  3430. else {
  3431. throw { type: 'Name',
  3432. message: "variable " + name + " is undefined",
  3433. filename: this.fileInfo().filename,
  3434. index: this.getIndex() };
  3435. }
  3436. };
  3437. Variable.prototype.find = function (obj, fun) {
  3438. for (var i_1 = 0, r = void 0; i_1 < obj.length; i_1++) {
  3439. r = fun.call(obj, obj[i_1]);
  3440. if (r) {
  3441. return r;
  3442. }
  3443. }
  3444. return null;
  3445. };
  3446. return Variable;
  3447. }(Node));
  3448. Variable.prototype.type = 'Variable';
  3449. var Property = /** @class */ (function (_super) {
  3450. __extends(Property, _super);
  3451. function Property(name, index, currentFileInfo) {
  3452. var _this = _super.call(this) || this;
  3453. _this.name = name;
  3454. _this._index = index;
  3455. _this._fileInfo = currentFileInfo;
  3456. return _this;
  3457. }
  3458. Property.prototype.eval = function (context) {
  3459. var property;
  3460. var name = this.name;
  3461. // TODO: shorten this reference
  3462. var mergeRules = context.pluginManager.less.visitors.ToCSSVisitor.prototype._mergeRules;
  3463. if (this.evaluating) {
  3464. throw { type: 'Name',
  3465. message: "Recursive property reference for " + name,
  3466. filename: this.fileInfo().filename,
  3467. index: this.getIndex() };
  3468. }
  3469. this.evaluating = true;
  3470. property = this.find(context.frames, function (frame) {
  3471. var v;
  3472. var vArr = frame.property(name);
  3473. if (vArr) {
  3474. for (var i_1 = 0; i_1 < vArr.length; i_1++) {
  3475. v = vArr[i_1];
  3476. vArr[i_1] = new Declaration(v.name, v.value, v.important, v.merge, v.index, v.currentFileInfo, v.inline, v.variable);
  3477. }
  3478. mergeRules(vArr);
  3479. v = vArr[vArr.length - 1];
  3480. if (v.important) {
  3481. var importantScope = context.importantScope[context.importantScope.length - 1];
  3482. importantScope.important = v.important;
  3483. }
  3484. v = v.value.eval(context);
  3485. return v;
  3486. }
  3487. });
  3488. if (property) {
  3489. this.evaluating = false;
  3490. return property;
  3491. }
  3492. else {
  3493. throw { type: 'Name',
  3494. message: "Property '" + name + "' is undefined",
  3495. filename: this.currentFileInfo.filename,
  3496. index: this.index };
  3497. }
  3498. };
  3499. Property.prototype.find = function (obj, fun) {
  3500. for (var i_2 = 0, r = void 0; i_2 < obj.length; i_2++) {
  3501. r = fun.call(obj, obj[i_2]);
  3502. if (r) {
  3503. return r;
  3504. }
  3505. }
  3506. return null;
  3507. };
  3508. return Property;
  3509. }(Node));
  3510. Property.prototype.type = 'Property';
  3511. var Attribute = /** @class */ (function (_super) {
  3512. __extends(Attribute, _super);
  3513. function Attribute(key, op, value) {
  3514. var _this = _super.call(this) || this;
  3515. _this.key = key;
  3516. _this.op = op;
  3517. _this.value = value;
  3518. return _this;
  3519. }
  3520. Attribute.prototype.eval = function (context) {
  3521. 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);
  3522. };
  3523. Attribute.prototype.genCSS = function (context, output) {
  3524. output.add(this.toCSS(context));
  3525. };
  3526. Attribute.prototype.toCSS = function (context) {
  3527. var value = this.key.toCSS ? this.key.toCSS(context) : this.key;
  3528. if (this.op) {
  3529. value += this.op;
  3530. value += (this.value.toCSS ? this.value.toCSS(context) : this.value);
  3531. }
  3532. return "[" + value + "]";
  3533. };
  3534. return Attribute;
  3535. }(Node));
  3536. Attribute.prototype.type = 'Attribute';
  3537. var Quoted = /** @class */ (function (_super) {
  3538. __extends(Quoted, _super);
  3539. function Quoted(str, content, escaped, index, currentFileInfo) {
  3540. var _this = _super.call(this) || this;
  3541. _this.escaped = (escaped == null) ? true : escaped;
  3542. _this.value = content || '';
  3543. _this.quote = str.charAt(0);
  3544. _this._index = index;
  3545. _this._fileInfo = currentFileInfo;
  3546. _this.variableRegex = /@\{([\w-]+)\}/g;
  3547. _this.propRegex = /\$\{([\w-]+)\}/g;
  3548. _this.allowRoot = escaped;
  3549. return _this;
  3550. }
  3551. Quoted.prototype.genCSS = function (context, output) {
  3552. if (!this.escaped) {
  3553. output.add(this.quote, this.fileInfo(), this.getIndex());
  3554. }
  3555. output.add(this.value);
  3556. if (!this.escaped) {
  3557. output.add(this.quote);
  3558. }
  3559. };
  3560. Quoted.prototype.containsVariables = function () {
  3561. return this.value.match(this.variableRegex);
  3562. };
  3563. Quoted.prototype.eval = function (context) {
  3564. var that = this;
  3565. var value = this.value;
  3566. var variableReplacement = function (_, name) {
  3567. var v = new Variable("@" + name, that.getIndex(), that.fileInfo()).eval(context, true);
  3568. return (v instanceof Quoted) ? v.value : v.toCSS();
  3569. };
  3570. var propertyReplacement = function (_, name) {
  3571. var v = new Property("$" + name, that.getIndex(), that.fileInfo()).eval(context, true);
  3572. return (v instanceof Quoted) ? v.value : v.toCSS();
  3573. };
  3574. function iterativeReplace(value, regexp, replacementFnc) {
  3575. var evaluatedValue = value;
  3576. do {
  3577. value = evaluatedValue.toString();
  3578. evaluatedValue = value.replace(regexp, replacementFnc);
  3579. } while (value !== evaluatedValue);
  3580. return evaluatedValue;
  3581. }
  3582. value = iterativeReplace(value, this.variableRegex, variableReplacement);
  3583. value = iterativeReplace(value, this.propRegex, propertyReplacement);
  3584. return new Quoted(this.quote + value + this.quote, value, this.escaped, this.getIndex(), this.fileInfo());
  3585. };
  3586. Quoted.prototype.compare = function (other) {
  3587. // when comparing quoted strings allow the quote to differ
  3588. if (other.type === 'Quoted' && !this.escaped && !other.escaped) {
  3589. return Node.numericCompare(this.value, other.value);
  3590. }
  3591. else {
  3592. return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;
  3593. }
  3594. };
  3595. return Quoted;
  3596. }(Node));
  3597. Quoted.prototype.type = 'Quoted';
  3598. var URL = /** @class */ (function (_super) {
  3599. __extends(URL, _super);
  3600. function URL(val, index, currentFileInfo, isEvald) {
  3601. var _this = _super.call(this) || this;
  3602. _this.value = val;
  3603. _this._index = index;
  3604. _this._fileInfo = currentFileInfo;
  3605. _this.isEvald = isEvald;
  3606. return _this;
  3607. }
  3608. URL.prototype.accept = function (visitor) {
  3609. this.value = visitor.visit(this.value);
  3610. };
  3611. URL.prototype.genCSS = function (context, output) {
  3612. output.add('url(');
  3613. this.value.genCSS(context, output);
  3614. output.add(')');
  3615. };
  3616. URL.prototype.eval = function (context) {
  3617. var val = this.value.eval(context);
  3618. var rootpath;
  3619. if (!this.isEvald) {
  3620. // Add the rootpath if the URL requires a rewrite
  3621. rootpath = this.fileInfo() && this.fileInfo().rootpath;
  3622. if (typeof rootpath === 'string' &&
  3623. typeof val.value === 'string' &&
  3624. context.pathRequiresRewrite(val.value)) {
  3625. if (!val.quote) {
  3626. rootpath = escapePath(rootpath);
  3627. }
  3628. val.value = context.rewritePath(val.value, rootpath);
  3629. }
  3630. else {
  3631. val.value = context.normalizePath(val.value);
  3632. }
  3633. // Add url args if enabled
  3634. if (context.urlArgs) {
  3635. if (!val.value.match(/^\s*data:/)) {
  3636. var delimiter = val.value.indexOf('?') === -1 ? '?' : '&';
  3637. var urlArgs = delimiter + context.urlArgs;
  3638. if (val.value.indexOf('#') !== -1) {
  3639. val.value = val.value.replace('#', urlArgs + "#");
  3640. }
  3641. else {
  3642. val.value += urlArgs;
  3643. }
  3644. }
  3645. }
  3646. }
  3647. return new URL(val, this.getIndex(), this.fileInfo(), true);
  3648. };
  3649. return URL;
  3650. }(Node));
  3651. URL.prototype.type = 'Url';
  3652. function escapePath(path) {
  3653. return path.replace(/[\(\)'"\s]/g, function (match) { return "\\" + match; });
  3654. }
  3655. var Media = /** @class */ (function (_super) {
  3656. __extends(Media, _super);
  3657. function Media(value, features, index, currentFileInfo, visibilityInfo) {
  3658. var _this = _super.call(this) || this;
  3659. _this._index = index;
  3660. _this._fileInfo = currentFileInfo;
  3661. var selectors = (new Selector([], null, null, _this._index, _this._fileInfo)).createEmptySelectors();
  3662. _this.features = new Value(features);
  3663. _this.rules = [new Ruleset(selectors, value)];
  3664. _this.rules[0].allowImports = true;
  3665. _this.copyVisibilityInfo(visibilityInfo);
  3666. _this.allowRoot = true;
  3667. _this.setParent(selectors, _this);
  3668. _this.setParent(_this.features, _this);
  3669. _this.setParent(_this.rules, _this);
  3670. return _this;
  3671. }
  3672. Media.prototype.isRulesetLike = function () {
  3673. return true;
  3674. };
  3675. Media.prototype.accept = function (visitor) {
  3676. if (this.features) {
  3677. this.features = visitor.visit(this.features);
  3678. }
  3679. if (this.rules) {
  3680. this.rules = visitor.visitArray(this.rules);
  3681. }
  3682. };
  3683. Media.prototype.genCSS = function (context, output) {
  3684. output.add('@media ', this._fileInfo, this._index);
  3685. this.features.genCSS(context, output);
  3686. this.outputRuleset(context, output, this.rules);
  3687. };
  3688. Media.prototype.eval = function (context) {
  3689. if (!context.mediaBlocks) {
  3690. context.mediaBlocks = [];
  3691. context.mediaPath = [];
  3692. }
  3693. var media = new Media(null, [], this._index, this._fileInfo, this.visibilityInfo());
  3694. if (this.debugInfo) {
  3695. this.rules[0].debugInfo = this.debugInfo;
  3696. media.debugInfo = this.debugInfo;
  3697. }
  3698. media.features = this.features.eval(context);
  3699. context.mediaPath.push(media);
  3700. context.mediaBlocks.push(media);
  3701. this.rules[0].functionRegistry = context.frames[0].functionRegistry.inherit();
  3702. context.frames.unshift(this.rules[0]);
  3703. media.rules = [this.rules[0].eval(context)];
  3704. context.frames.shift();
  3705. context.mediaPath.pop();
  3706. return context.mediaPath.length === 0 ? media.evalTop(context) :
  3707. media.evalNested(context);
  3708. };
  3709. Media.prototype.evalTop = function (context) {
  3710. var result = this;
  3711. // Render all dependent Media blocks.
  3712. if (context.mediaBlocks.length > 1) {
  3713. var selectors = (new Selector([], null, null, this.getIndex(), this.fileInfo())).createEmptySelectors();
  3714. result = new Ruleset(selectors, context.mediaBlocks);
  3715. result.multiMedia = true;
  3716. result.copyVisibilityInfo(this.visibilityInfo());
  3717. this.setParent(result, this);
  3718. }
  3719. delete context.mediaBlocks;
  3720. delete context.mediaPath;
  3721. return result;
  3722. };
  3723. Media.prototype.evalNested = function (context) {
  3724. var i;
  3725. var value;
  3726. var path = context.mediaPath.concat([this]);
  3727. // Extract the media-query conditions separated with `,` (OR).
  3728. for (i = 0; i < path.length; i++) {
  3729. value = path[i].features instanceof Value ?
  3730. path[i].features.value : path[i].features;
  3731. path[i] = Array.isArray(value) ? value : [value];
  3732. }
  3733. // Trace all permutations to generate the resulting media-query.
  3734. //
  3735. // (a, b and c) with nested (d, e) ->
  3736. // a and d
  3737. // a and e
  3738. // b and c and d
  3739. // b and c and e
  3740. this.features = new Value(this.permute(path).map(function (path) {
  3741. path = path.map(function (fragment) { return fragment.toCSS ? fragment : new Anonymous(fragment); });
  3742. for (i = path.length - 1; i > 0; i--) {
  3743. path.splice(i, 0, new Anonymous('and'));
  3744. }
  3745. return new Expression(path);
  3746. }));
  3747. this.setParent(this.features, this);
  3748. // Fake a tree-node that doesn't output anything.
  3749. return new Ruleset([], []);
  3750. };
  3751. Media.prototype.permute = function (arr) {
  3752. if (arr.length === 0) {
  3753. return [];
  3754. }
  3755. else if (arr.length === 1) {
  3756. return arr[0];
  3757. }
  3758. else {
  3759. var result = [];
  3760. var rest = this.permute(arr.slice(1));
  3761. for (var i_1 = 0; i_1 < rest.length; i_1++) {
  3762. for (var j = 0; j < arr[0].length; j++) {
  3763. result.push([arr[0][j]].concat(rest[i_1]));
  3764. }
  3765. }
  3766. return result;
  3767. }
  3768. };
  3769. Media.prototype.bubbleSelectors = function (selectors) {
  3770. if (!selectors) {
  3771. return;
  3772. }
  3773. this.rules = [new Ruleset(copyArray(selectors), [this.rules[0]])];
  3774. this.setParent(this.rules, this);
  3775. };
  3776. return Media;
  3777. }(AtRule));
  3778. Media.prototype.type = 'Media';
  3779. //
  3780. // CSS @import node
  3781. //
  3782. // The general strategy here is that we don't want to wait
  3783. // for the parsing to be completed, before we start importing
  3784. // the file. That's because in the context of a browser,
  3785. // most of the time will be spent waiting for the server to respond.
  3786. //
  3787. // On creation, we push the import path to our import queue, though
  3788. // `import,push`, we also pass it a callback, which it'll call once
  3789. // the file has been fetched, and parsed.
  3790. //
  3791. var Import = /** @class */ (function (_super) {
  3792. __extends(Import, _super);
  3793. function Import(path, features, options, index, currentFileInfo, visibilityInfo) {
  3794. var _this = _super.call(this) || this;
  3795. _this.options = options;
  3796. _this._index = index;
  3797. _this._fileInfo = currentFileInfo;
  3798. _this.path = path;
  3799. _this.features = features;
  3800. _this.allowRoot = true;
  3801. if (_this.options.less !== undefined || _this.options.inline) {
  3802. _this.css = !_this.options.less || _this.options.inline;
  3803. }
  3804. else {
  3805. var pathValue = _this.getPath();
  3806. if (pathValue && /[#\.\&\?]css([\?;].*)?$/.test(pathValue)) {
  3807. _this.css = true;
  3808. }
  3809. }
  3810. _this.copyVisibilityInfo(visibilityInfo);
  3811. _this.setParent(_this.features, _this);
  3812. _this.setParent(_this.path, _this);
  3813. return _this;
  3814. }
  3815. Import.prototype.accept = function (visitor) {
  3816. if (this.features) {
  3817. this.features = visitor.visit(this.features);
  3818. }
  3819. this.path = visitor.visit(this.path);
  3820. if (!this.options.isPlugin && !this.options.inline && this.root) {
  3821. this.root = visitor.visit(this.root);
  3822. }
  3823. };
  3824. Import.prototype.genCSS = function (context, output) {
  3825. if (this.css && this.path._fileInfo.reference === undefined) {
  3826. output.add('@import ', this._fileInfo, this._index);
  3827. this.path.genCSS(context, output);
  3828. if (this.features) {
  3829. output.add(' ');
  3830. this.features.genCSS(context, output);
  3831. }
  3832. output.add(';');
  3833. }
  3834. };
  3835. Import.prototype.getPath = function () {
  3836. return (this.path instanceof URL) ?
  3837. this.path.value.value : this.path.value;
  3838. };
  3839. Import.prototype.isVariableImport = function () {
  3840. var path = this.path;
  3841. if (path instanceof URL) {
  3842. path = path.value;
  3843. }
  3844. if (path instanceof Quoted) {
  3845. return path.containsVariables();
  3846. }
  3847. return true;
  3848. };
  3849. Import.prototype.evalForImport = function (context) {
  3850. var path = this.path;
  3851. if (path instanceof URL) {
  3852. path = path.value;
  3853. }
  3854. return new Import(path.eval(context), this.features, this.options, this._index, this._fileInfo, this.visibilityInfo());
  3855. };
  3856. Import.prototype.evalPath = function (context) {
  3857. var path = this.path.eval(context);
  3858. var fileInfo = this._fileInfo;
  3859. if (!(path instanceof URL)) {
  3860. // Add the rootpath if the URL requires a rewrite
  3861. var pathValue = path.value;
  3862. if (fileInfo &&
  3863. pathValue &&
  3864. context.pathRequiresRewrite(pathValue)) {
  3865. path.value = context.rewritePath(pathValue, fileInfo.rootpath);
  3866. }
  3867. else {
  3868. path.value = context.normalizePath(path.value);
  3869. }
  3870. }
  3871. return path;
  3872. };
  3873. Import.prototype.eval = function (context) {
  3874. var result = this.doEval(context);
  3875. if (this.options.reference || this.blocksVisibility()) {
  3876. if (result.length || result.length === 0) {
  3877. result.forEach(function (node) {
  3878. node.addVisibilityBlock();
  3879. });
  3880. }
  3881. else {
  3882. result.addVisibilityBlock();
  3883. }
  3884. }
  3885. return result;
  3886. };
  3887. Import.prototype.doEval = function (context) {
  3888. var ruleset;
  3889. var registry;
  3890. var features = this.features && this.features.eval(context);
  3891. if (this.options.isPlugin) {
  3892. if (this.root && this.root.eval) {
  3893. try {
  3894. this.root.eval(context);
  3895. }
  3896. catch (e) {
  3897. e.message = 'Plugin error during evaluation';
  3898. throw new LessError(e, this.root.imports, this.root.filename);
  3899. }
  3900. }
  3901. registry = context.frames[0] && context.frames[0].functionRegistry;
  3902. if (registry && this.root && this.root.functions) {
  3903. registry.addMultiple(this.root.functions);
  3904. }
  3905. return [];
  3906. }
  3907. if (this.skip) {
  3908. if (typeof this.skip === 'function') {
  3909. this.skip = this.skip();
  3910. }
  3911. if (this.skip) {
  3912. return [];
  3913. }
  3914. }
  3915. if (this.options.inline) {
  3916. var contents = new Anonymous(this.root, 0, {
  3917. filename: this.importedFilename,
  3918. reference: this.path._fileInfo && this.path._fileInfo.reference
  3919. }, true, true);
  3920. return this.features ? new Media([contents], this.features.value) : [contents];
  3921. }
  3922. else if (this.css) {
  3923. var newImport = new Import(this.evalPath(context), features, this.options, this._index);
  3924. if (!newImport.css && this.error) {
  3925. throw this.error;
  3926. }
  3927. return newImport;
  3928. }
  3929. else {
  3930. ruleset = new Ruleset(null, copyArray(this.root.rules));
  3931. ruleset.evalImports(context);
  3932. return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules;
  3933. }
  3934. };
  3935. return Import;
  3936. }(Node));
  3937. Import.prototype.type = 'Import';
  3938. var JsEvalNode = /** @class */ (function (_super) {
  3939. __extends(JsEvalNode, _super);
  3940. function JsEvalNode() {
  3941. return _super !== null && _super.apply(this, arguments) || this;
  3942. }
  3943. JsEvalNode.prototype.evaluateJavaScript = function (expression, context) {
  3944. var result;
  3945. var that = this;
  3946. var evalContext = {};
  3947. if (!context.javascriptEnabled) {
  3948. throw { message: 'Inline JavaScript is not enabled. Is it set in your options?',
  3949. filename: this.fileInfo().filename,
  3950. index: this.getIndex() };
  3951. }
  3952. expression = expression.replace(/@\{([\w-]+)\}/g, function (_, name) { return that.jsify(new Variable("@" + name, that.getIndex(), that.fileInfo()).eval(context)); });
  3953. try {
  3954. expression = new Function("return (" + expression + ")");
  3955. }
  3956. catch (e) {
  3957. throw { message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`",
  3958. filename: this.fileInfo().filename,
  3959. index: this.getIndex() };
  3960. }
  3961. var variables = context.frames[0].variables();
  3962. for (var k in variables) {
  3963. if (variables.hasOwnProperty(k)) {
  3964. /* jshint loopfunc:true */
  3965. evalContext[k.slice(1)] = {
  3966. value: variables[k].value,
  3967. toJS: function () {
  3968. return this.value.eval(context).toCSS();
  3969. }
  3970. };
  3971. }
  3972. }
  3973. try {
  3974. result = expression.call(evalContext);
  3975. }
  3976. catch (e) {
  3977. throw { message: "JavaScript evaluation error: '" + e.name + ": " + e.message.replace(/["]/g, '\'') + "'",
  3978. filename: this.fileInfo().filename,
  3979. index: this.getIndex() };
  3980. }
  3981. return result;
  3982. };
  3983. JsEvalNode.prototype.jsify = function (obj) {
  3984. if (Array.isArray(obj.value) && (obj.value.length > 1)) {
  3985. return "[" + obj.value.map(function (v) { return v.toCSS(); }).join(', ') + "]";
  3986. }
  3987. else {
  3988. return obj.toCSS();
  3989. }
  3990. };
  3991. return JsEvalNode;
  3992. }(Node));
  3993. var JavaScript = /** @class */ (function (_super) {
  3994. __extends(JavaScript, _super);
  3995. function JavaScript(string, escaped, index, currentFileInfo) {
  3996. var _this = _super.call(this) || this;
  3997. _this.escaped = escaped;
  3998. _this.expression = string;
  3999. _this._index = index;
  4000. _this._fileInfo = currentFileInfo;
  4001. return _this;
  4002. }
  4003. JavaScript.prototype.eval = function (context) {
  4004. var result = this.evaluateJavaScript(this.expression, context);
  4005. var type = typeof result;
  4006. if (type === 'number' && !isNaN(result)) {
  4007. return new Dimension(result);
  4008. }
  4009. else if (type === 'string') {
  4010. return new Quoted("\"" + result + "\"", result, this.escaped, this._index);
  4011. }
  4012. else if (Array.isArray(result)) {
  4013. return new Anonymous(result.join(', '));
  4014. }
  4015. else {
  4016. return new Anonymous(result);
  4017. }
  4018. };
  4019. return JavaScript;
  4020. }(JsEvalNode));
  4021. JavaScript.prototype.type = 'JavaScript';
  4022. var Assignment = /** @class */ (function (_super) {
  4023. __extends(Assignment, _super);
  4024. function Assignment(key, val) {
  4025. var _this = _super.call(this) || this;
  4026. _this.key = key;
  4027. _this.value = val;
  4028. return _this;
  4029. }
  4030. Assignment.prototype.accept = function (visitor) {
  4031. this.value = visitor.visit(this.value);
  4032. };
  4033. Assignment.prototype.eval = function (context) {
  4034. if (this.value.eval) {
  4035. return new Assignment(this.key, this.value.eval(context));
  4036. }
  4037. return this;
  4038. };
  4039. Assignment.prototype.genCSS = function (context, output) {
  4040. output.add(this.key + "=");
  4041. if (this.value.genCSS) {
  4042. this.value.genCSS(context, output);
  4043. }
  4044. else {
  4045. output.add(this.value);
  4046. }
  4047. };
  4048. return Assignment;
  4049. }(Node));
  4050. Assignment.prototype.type = 'Assignment';
  4051. var Condition = /** @class */ (function (_super) {
  4052. __extends(Condition, _super);
  4053. function Condition(op, l, r, i, negate) {
  4054. var _this = _super.call(this) || this;
  4055. _this.op = op.trim();
  4056. _this.lvalue = l;
  4057. _this.rvalue = r;
  4058. _this._index = i;
  4059. _this.negate = negate;
  4060. return _this;
  4061. }
  4062. Condition.prototype.accept = function (visitor) {
  4063. this.lvalue = visitor.visit(this.lvalue);
  4064. this.rvalue = visitor.visit(this.rvalue);
  4065. };
  4066. Condition.prototype.eval = function (context) {
  4067. var result = (function (op, a, b) {
  4068. switch (op) {
  4069. case 'and': return a && b;
  4070. case 'or': return a || b;
  4071. default:
  4072. switch (Node.compare(a, b)) {
  4073. case -1:
  4074. return op === '<' || op === '=<' || op === '<=';
  4075. case 0:
  4076. return op === '=' || op === '>=' || op === '=<' || op === '<=';
  4077. case 1:
  4078. return op === '>' || op === '>=';
  4079. default:
  4080. return false;
  4081. }
  4082. }
  4083. })(this.op, this.lvalue.eval(context), this.rvalue.eval(context));
  4084. return this.negate ? !result : result;
  4085. };
  4086. return Condition;
  4087. }(Node));
  4088. Condition.prototype.type = 'Condition';
  4089. var UnicodeDescriptor = /** @class */ (function (_super) {
  4090. __extends(UnicodeDescriptor, _super);
  4091. function UnicodeDescriptor(value) {
  4092. var _this = _super.call(this) || this;
  4093. _this.value = value;
  4094. return _this;
  4095. }
  4096. return UnicodeDescriptor;
  4097. }(Node));
  4098. UnicodeDescriptor.prototype.type = 'UnicodeDescriptor';
  4099. var Negative = /** @class */ (function (_super) {
  4100. __extends(Negative, _super);
  4101. function Negative(node) {
  4102. var _this = _super.call(this) || this;
  4103. _this.value = node;
  4104. return _this;
  4105. }
  4106. Negative.prototype.genCSS = function (context, output) {
  4107. output.add('-');
  4108. this.value.genCSS(context, output);
  4109. };
  4110. Negative.prototype.eval = function (context) {
  4111. if (context.isMathOn()) {
  4112. return (new Operation('*', [new Dimension(-1), this.value])).eval(context);
  4113. }
  4114. return new Negative(this.value.eval(context));
  4115. };
  4116. return Negative;
  4117. }(Node));
  4118. Negative.prototype.type = 'Negative';
  4119. var Extend = /** @class */ (function (_super) {
  4120. __extends(Extend, _super);
  4121. function Extend(selector, option, index, currentFileInfo, visibilityInfo) {
  4122. var _this = _super.call(this) || this;
  4123. _this.selector = selector;
  4124. _this.option = option;
  4125. _this.object_id = Extend.next_id++;
  4126. _this.parent_ids = [_this.object_id];
  4127. _this._index = index;
  4128. _this._fileInfo = currentFileInfo;
  4129. _this.copyVisibilityInfo(visibilityInfo);
  4130. _this.allowRoot = true;
  4131. switch (option) {
  4132. case 'all':
  4133. _this.allowBefore = true;
  4134. _this.allowAfter = true;
  4135. break;
  4136. default:
  4137. _this.allowBefore = false;
  4138. _this.allowAfter = false;
  4139. break;
  4140. }
  4141. _this.setParent(_this.selector, _this);
  4142. return _this;
  4143. }
  4144. Extend.prototype.accept = function (visitor) {
  4145. this.selector = visitor.visit(this.selector);
  4146. };
  4147. Extend.prototype.eval = function (context) {
  4148. return new Extend(this.selector.eval(context), this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo());
  4149. };
  4150. Extend.prototype.clone = function (context) {
  4151. return new Extend(this.selector, this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo());
  4152. };
  4153. // it concatenates (joins) all selectors in selector array
  4154. Extend.prototype.findSelfSelectors = function (selectors) {
  4155. var selfElements = [];
  4156. var i;
  4157. var selectorElements;
  4158. for (i = 0; i < selectors.length; i++) {
  4159. selectorElements = selectors[i].elements;
  4160. // duplicate the logic in genCSS function inside the selector node.
  4161. // future TODO - move both logics into the selector joiner visitor
  4162. if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === '') {
  4163. selectorElements[0].combinator.value = ' ';
  4164. }
  4165. selfElements = selfElements.concat(selectors[i].elements);
  4166. }
  4167. this.selfSelectors = [new Selector(selfElements)];
  4168. this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo());
  4169. };
  4170. return Extend;
  4171. }(Node));
  4172. Extend.next_id = 0;
  4173. Extend.prototype.type = 'Extend';
  4174. var VariableCall = /** @class */ (function (_super) {
  4175. __extends(VariableCall, _super);
  4176. function VariableCall(variable, index, currentFileInfo) {
  4177. var _this = _super.call(this) || this;
  4178. _this.variable = variable;
  4179. _this._index = index;
  4180. _this._fileInfo = currentFileInfo;
  4181. _this.allowRoot = true;
  4182. return _this;
  4183. }
  4184. VariableCall.prototype.eval = function (context) {
  4185. var rules;
  4186. var detachedRuleset = new Variable(this.variable, this.getIndex(), this.fileInfo()).eval(context);
  4187. var error = new LessError({ message: "Could not evaluate variable call " + this.variable });
  4188. if (!detachedRuleset.ruleset) {
  4189. if (detachedRuleset.rules) {
  4190. rules = detachedRuleset;
  4191. }
  4192. else if (Array.isArray(detachedRuleset)) {
  4193. rules = new Ruleset('', detachedRuleset);
  4194. }
  4195. else if (Array.isArray(detachedRuleset.value)) {
  4196. rules = new Ruleset('', detachedRuleset.value);
  4197. }
  4198. else {
  4199. throw error;
  4200. }
  4201. detachedRuleset = new DetachedRuleset(rules);
  4202. }
  4203. if (detachedRuleset.ruleset) {
  4204. return detachedRuleset.callEval(context);
  4205. }
  4206. throw error;
  4207. };
  4208. return VariableCall;
  4209. }(Node));
  4210. VariableCall.prototype.type = 'VariableCall';
  4211. var NamespaceValue = /** @class */ (function (_super) {
  4212. __extends(NamespaceValue, _super);
  4213. function NamespaceValue(ruleCall, lookups, index, fileInfo) {
  4214. var _this = _super.call(this) || this;
  4215. _this.value = ruleCall;
  4216. _this.lookups = lookups;
  4217. _this._index = index;
  4218. _this._fileInfo = fileInfo;
  4219. return _this;
  4220. }
  4221. NamespaceValue.prototype.eval = function (context) {
  4222. var i;
  4223. var name;
  4224. var rules = this.value.eval(context);
  4225. for (i = 0; i < this.lookups.length; i++) {
  4226. name = this.lookups[i];
  4227. /**
  4228. * Eval'd DRs return rulesets.
  4229. * Eval'd mixins return rules, so let's make a ruleset if we need it.
  4230. * We need to do this because of late parsing of values
  4231. */
  4232. if (Array.isArray(rules)) {
  4233. rules = new Ruleset([new Selector()], rules);
  4234. }
  4235. if (name === '') {
  4236. rules = rules.lastDeclaration();
  4237. }
  4238. else if (name.charAt(0) === '@') {
  4239. if (name.charAt(1) === '@') {
  4240. name = "@" + new Variable(name.substr(1)).eval(context).value;
  4241. }
  4242. if (rules.variables) {
  4243. rules = rules.variable(name);
  4244. }
  4245. if (!rules) {
  4246. throw { type: 'Name',
  4247. message: "variable " + name + " not found",
  4248. filename: this.fileInfo().filename,
  4249. index: this.getIndex() };
  4250. }
  4251. }
  4252. else {
  4253. if (name.substring(0, 2) === '$@') {
  4254. name = "$" + new Variable(name.substr(1)).eval(context).value;
  4255. }
  4256. else {
  4257. name = name.charAt(0) === '$' ? name : "$" + name;
  4258. }
  4259. if (rules.properties) {
  4260. rules = rules.property(name);
  4261. }
  4262. if (!rules) {
  4263. throw { type: 'Name',
  4264. message: "property \"" + name.substr(1) + "\" not found",
  4265. filename: this.fileInfo().filename,
  4266. index: this.getIndex() };
  4267. }
  4268. // Properties are an array of values, since a ruleset can have multiple props.
  4269. // We pick the last one (the "cascaded" value)
  4270. rules = rules[rules.length - 1];
  4271. }
  4272. if (rules.value) {
  4273. rules = rules.eval(context).value;
  4274. }
  4275. if (rules.ruleset) {
  4276. rules = rules.ruleset.eval(context);
  4277. }
  4278. }
  4279. return rules;
  4280. };
  4281. return NamespaceValue;
  4282. }(Node));
  4283. NamespaceValue.prototype.type = 'NamespaceValue';
  4284. var Definition = /** @class */ (function (_super) {
  4285. __extends(Definition, _super);
  4286. function Definition(name, params, rules, condition, variadic, frames, visibilityInfo) {
  4287. var _this = _super.call(this) || this;
  4288. _this.name = name || 'anonymous mixin';
  4289. _this.selectors = [new Selector([new Element(null, name, false, _this._index, _this._fileInfo)])];
  4290. _this.params = params;
  4291. _this.condition = condition;
  4292. _this.variadic = variadic;
  4293. _this.arity = params.length;
  4294. _this.rules = rules;
  4295. _this._lookups = {};
  4296. var optionalParameters = [];
  4297. _this.required = params.reduce(function (count, p) {
  4298. if (!p.name || (p.name && !p.value)) {
  4299. return count + 1;
  4300. }
  4301. else {
  4302. optionalParameters.push(p.name);
  4303. return count;
  4304. }
  4305. }, 0);
  4306. _this.optionalParameters = optionalParameters;
  4307. _this.frames = frames;
  4308. _this.copyVisibilityInfo(visibilityInfo);
  4309. _this.allowRoot = true;
  4310. return _this;
  4311. }
  4312. Definition.prototype.accept = function (visitor) {
  4313. if (this.params && this.params.length) {
  4314. this.params = visitor.visitArray(this.params);
  4315. }
  4316. this.rules = visitor.visitArray(this.rules);
  4317. if (this.condition) {
  4318. this.condition = visitor.visit(this.condition);
  4319. }
  4320. };
  4321. Definition.prototype.evalParams = function (context, mixinEnv, args, evaldArguments) {
  4322. /* jshint boss:true */
  4323. var frame = new Ruleset(null, null);
  4324. var varargs;
  4325. var arg;
  4326. var params = copyArray(this.params);
  4327. var i;
  4328. var j;
  4329. var val;
  4330. var name;
  4331. var isNamedFound;
  4332. var argIndex;
  4333. var argsLength = 0;
  4334. if (mixinEnv.frames && mixinEnv.frames[0] && mixinEnv.frames[0].functionRegistry) {
  4335. frame.functionRegistry = mixinEnv.frames[0].functionRegistry.inherit();
  4336. }
  4337. mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames));
  4338. if (args) {
  4339. args = copyArray(args);
  4340. argsLength = args.length;
  4341. for (i = 0; i < argsLength; i++) {
  4342. arg = args[i];
  4343. if (name = (arg && arg.name)) {
  4344. isNamedFound = false;
  4345. for (j = 0; j < params.length; j++) {
  4346. if (!evaldArguments[j] && name === params[j].name) {
  4347. evaldArguments[j] = arg.value.eval(context);
  4348. frame.prependRule(new Declaration(name, arg.value.eval(context)));
  4349. isNamedFound = true;
  4350. break;
  4351. }
  4352. }
  4353. if (isNamedFound) {
  4354. args.splice(i, 1);
  4355. i--;
  4356. continue;
  4357. }
  4358. else {
  4359. throw { type: 'Runtime', message: "Named argument for " + this.name + " " + args[i].name + " not found" };
  4360. }
  4361. }
  4362. }
  4363. }
  4364. argIndex = 0;
  4365. for (i = 0; i < params.length; i++) {
  4366. if (evaldArguments[i]) {
  4367. continue;
  4368. }
  4369. arg = args && args[argIndex];
  4370. if (name = params[i].name) {
  4371. if (params[i].variadic) {
  4372. varargs = [];
  4373. for (j = argIndex; j < argsLength; j++) {
  4374. varargs.push(args[j].value.eval(context));
  4375. }
  4376. frame.prependRule(new Declaration(name, new Expression(varargs).eval(context)));
  4377. }
  4378. else {
  4379. val = arg && arg.value;
  4380. if (val) {
  4381. // This was a mixin call, pass in a detached ruleset of it's eval'd rules
  4382. if (Array.isArray(val)) {
  4383. val = new DetachedRuleset(new Ruleset('', val));
  4384. }
  4385. else {
  4386. val = val.eval(context);
  4387. }
  4388. }
  4389. else if (params[i].value) {
  4390. val = params[i].value.eval(mixinEnv);
  4391. frame.resetCache();
  4392. }
  4393. else {
  4394. throw { type: 'Runtime', message: "wrong number of arguments for " + this.name + " (" + argsLength + " for " + this.arity + ")" };
  4395. }
  4396. frame.prependRule(new Declaration(name, val));
  4397. evaldArguments[i] = val;
  4398. }
  4399. }
  4400. if (params[i].variadic && args) {
  4401. for (j = argIndex; j < argsLength; j++) {
  4402. evaldArguments[j] = args[j].value.eval(context);
  4403. }
  4404. }
  4405. argIndex++;
  4406. }
  4407. return frame;
  4408. };
  4409. Definition.prototype.makeImportant = function () {
  4410. var rules = !this.rules ? this.rules : this.rules.map(function (r) {
  4411. if (r.makeImportant) {
  4412. return r.makeImportant(true);
  4413. }
  4414. else {
  4415. return r;
  4416. }
  4417. });
  4418. var result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames);
  4419. return result;
  4420. };
  4421. Definition.prototype.eval = function (context) {
  4422. return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || copyArray(context.frames));
  4423. };
  4424. Definition.prototype.evalCall = function (context, args, important) {
  4425. var _arguments = [];
  4426. var mixinFrames = this.frames ? this.frames.concat(context.frames) : context.frames;
  4427. var frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments);
  4428. var rules;
  4429. var ruleset;
  4430. frame.prependRule(new Declaration('@arguments', new Expression(_arguments).eval(context)));
  4431. rules = copyArray(this.rules);
  4432. ruleset = new Ruleset(null, rules);
  4433. ruleset.originalRuleset = this;
  4434. ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames)));
  4435. if (important) {
  4436. ruleset = ruleset.makeImportant();
  4437. }
  4438. return ruleset;
  4439. };
  4440. Definition.prototype.matchCondition = function (args, context) {
  4441. 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, [])]
  4442. .concat(this.frames || []) // the parent namespace/mixin frames
  4443. .concat(context.frames)))) { // the current environment frames
  4444. return false;
  4445. }
  4446. return true;
  4447. };
  4448. Definition.prototype.matchArgs = function (args, context) {
  4449. var allArgsCnt = (args && args.length) || 0;
  4450. var len;
  4451. var optionalParameters = this.optionalParameters;
  4452. var requiredArgsCnt = !args ? 0 : args.reduce(function (count, p) {
  4453. if (optionalParameters.indexOf(p.name) < 0) {
  4454. return count + 1;
  4455. }
  4456. else {
  4457. return count;
  4458. }
  4459. }, 0);
  4460. if (!this.variadic) {
  4461. if (requiredArgsCnt < this.required) {
  4462. return false;
  4463. }
  4464. if (allArgsCnt > this.params.length) {
  4465. return false;
  4466. }
  4467. }
  4468. else {
  4469. if (requiredArgsCnt < (this.required - 1)) {
  4470. return false;
  4471. }
  4472. }
  4473. // check patterns
  4474. len = Math.min(requiredArgsCnt, this.arity);
  4475. for (var i_1 = 0; i_1 < len; i_1++) {
  4476. if (!this.params[i_1].name && !this.params[i_1].variadic) {
  4477. if (args[i_1].value.eval(context).toCSS() != this.params[i_1].value.eval(context).toCSS()) {
  4478. return false;
  4479. }
  4480. }
  4481. }
  4482. return true;
  4483. };
  4484. return Definition;
  4485. }(Ruleset));
  4486. Definition.prototype.type = 'MixinDefinition';
  4487. Definition.prototype.evalFirst = true;
  4488. var MixinCall = /** @class */ (function (_super) {
  4489. __extends(MixinCall, _super);
  4490. function MixinCall(elements, args, index, currentFileInfo, important) {
  4491. var _this = _super.call(this) || this;
  4492. _this.selector = new Selector(elements);
  4493. _this.arguments = args || [];
  4494. _this._index = index;
  4495. _this._fileInfo = currentFileInfo;
  4496. _this.important = important;
  4497. _this.allowRoot = true;
  4498. _this.setParent(_this.selector, _this);
  4499. return _this;
  4500. }
  4501. MixinCall.prototype.accept = function (visitor) {
  4502. if (this.selector) {
  4503. this.selector = visitor.visit(this.selector);
  4504. }
  4505. if (this.arguments.length) {
  4506. this.arguments = visitor.visitArray(this.arguments);
  4507. }
  4508. };
  4509. MixinCall.prototype.eval = function (context) {
  4510. var mixins;
  4511. var mixin;
  4512. var mixinPath;
  4513. var args = [];
  4514. var arg;
  4515. var argValue;
  4516. var rules = [];
  4517. var match = false;
  4518. var i;
  4519. var m;
  4520. var f;
  4521. var isRecursive;
  4522. var isOneFound;
  4523. var candidates = [];
  4524. var candidate;
  4525. var conditionResult = [];
  4526. var defaultResult;
  4527. var defFalseEitherCase = -1;
  4528. var defNone = 0;
  4529. var defTrue = 1;
  4530. var defFalse = 2;
  4531. var count;
  4532. var originalRuleset;
  4533. var noArgumentsFilter;
  4534. this.selector = this.selector.eval(context);
  4535. function calcDefGroup(mixin, mixinPath) {
  4536. var f;
  4537. var p;
  4538. var namespace;
  4539. for (f = 0; f < 2; f++) {
  4540. conditionResult[f] = true;
  4541. defaultFunc.value(f);
  4542. for (p = 0; p < mixinPath.length && conditionResult[f]; p++) {
  4543. namespace = mixinPath[p];
  4544. if (namespace.matchCondition) {
  4545. conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context);
  4546. }
  4547. }
  4548. if (mixin.matchCondition) {
  4549. conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context);
  4550. }
  4551. }
  4552. if (conditionResult[0] || conditionResult[1]) {
  4553. if (conditionResult[0] != conditionResult[1]) {
  4554. return conditionResult[1] ?
  4555. defTrue : defFalse;
  4556. }
  4557. return defNone;
  4558. }
  4559. return defFalseEitherCase;
  4560. }
  4561. for (i = 0; i < this.arguments.length; i++) {
  4562. arg = this.arguments[i];
  4563. argValue = arg.value.eval(context);
  4564. if (arg.expand && Array.isArray(argValue.value)) {
  4565. argValue = argValue.value;
  4566. for (m = 0; m < argValue.length; m++) {
  4567. args.push({ value: argValue[m] });
  4568. }
  4569. }
  4570. else {
  4571. args.push({ name: arg.name, value: argValue });
  4572. }
  4573. }
  4574. noArgumentsFilter = function (rule) { return rule.matchArgs(null, context); };
  4575. for (i = 0; i < context.frames.length; i++) {
  4576. if ((mixins = context.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) {
  4577. isOneFound = true;
  4578. // To make `default()` function independent of definition order we have two "subpasses" here.
  4579. // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),
  4580. // and build candidate list with corresponding flags. Then, when we know all possible matches,
  4581. // we make a final decision.
  4582. for (m = 0; m < mixins.length; m++) {
  4583. mixin = mixins[m].rule;
  4584. mixinPath = mixins[m].path;
  4585. isRecursive = false;
  4586. for (f = 0; f < context.frames.length; f++) {
  4587. if ((!(mixin instanceof Definition)) && mixin === (context.frames[f].originalRuleset || context.frames[f])) {
  4588. isRecursive = true;
  4589. break;
  4590. }
  4591. }
  4592. if (isRecursive) {
  4593. continue;
  4594. }
  4595. if (mixin.matchArgs(args, context)) {
  4596. candidate = { mixin: mixin, group: calcDefGroup(mixin, mixinPath) };
  4597. if (candidate.group !== defFalseEitherCase) {
  4598. candidates.push(candidate);
  4599. }
  4600. match = true;
  4601. }
  4602. }
  4603. defaultFunc.reset();
  4604. count = [0, 0, 0];
  4605. for (m = 0; m < candidates.length; m++) {
  4606. count[candidates[m].group]++;
  4607. }
  4608. if (count[defNone] > 0) {
  4609. defaultResult = defFalse;
  4610. }
  4611. else {
  4612. defaultResult = defTrue;
  4613. if ((count[defTrue] + count[defFalse]) > 1) {
  4614. throw { type: 'Runtime',
  4615. message: "Ambiguous use of `default()` found when matching for `" + this.format(args) + "`",
  4616. index: this.getIndex(), filename: this.fileInfo().filename };
  4617. }
  4618. }
  4619. for (m = 0; m < candidates.length; m++) {
  4620. candidate = candidates[m].group;
  4621. if ((candidate === defNone) || (candidate === defaultResult)) {
  4622. try {
  4623. mixin = candidates[m].mixin;
  4624. if (!(mixin instanceof Definition)) {
  4625. originalRuleset = mixin.originalRuleset || mixin;
  4626. mixin = new Definition('', [], mixin.rules, null, false, null, originalRuleset.visibilityInfo());
  4627. mixin.originalRuleset = originalRuleset;
  4628. }
  4629. var newRules = mixin.evalCall(context, args, this.important).rules;
  4630. this._setVisibilityToReplacement(newRules);
  4631. Array.prototype.push.apply(rules, newRules);
  4632. }
  4633. catch (e) {
  4634. throw { message: e.message, index: this.getIndex(), filename: this.fileInfo().filename, stack: e.stack };
  4635. }
  4636. }
  4637. }
  4638. if (match) {
  4639. return rules;
  4640. }
  4641. }
  4642. }
  4643. if (isOneFound) {
  4644. throw { type: 'Runtime',
  4645. message: "No matching definition was found for `" + this.format(args) + "`",
  4646. index: this.getIndex(), filename: this.fileInfo().filename };
  4647. }
  4648. else {
  4649. throw { type: 'Name',
  4650. message: this.selector.toCSS().trim() + " is undefined",
  4651. index: this.getIndex(), filename: this.fileInfo().filename };
  4652. }
  4653. };
  4654. MixinCall.prototype._setVisibilityToReplacement = function (replacement) {
  4655. var i;
  4656. var rule;
  4657. if (this.blocksVisibility()) {
  4658. for (i = 0; i < replacement.length; i++) {
  4659. rule = replacement[i];
  4660. rule.addVisibilityBlock();
  4661. }
  4662. }
  4663. };
  4664. MixinCall.prototype.format = function (args) {
  4665. return this.selector.toCSS().trim() + "(" + (args ? args.map(function (a) {
  4666. var argValue = '';
  4667. if (a.name) {
  4668. argValue += a.name + ":";
  4669. }
  4670. if (a.value.toCSS) {
  4671. argValue += a.value.toCSS();
  4672. }
  4673. else {
  4674. argValue += '???';
  4675. }
  4676. return argValue;
  4677. }).join(', ') : '') + ")";
  4678. };
  4679. return MixinCall;
  4680. }(Node));
  4681. MixinCall.prototype.type = 'MixinCall';
  4682. var tree = {
  4683. Node: Node, Color: Color, AtRule: AtRule, DetachedRuleset: DetachedRuleset, Operation: Operation,
  4684. Dimension: Dimension, Unit: Unit, Keyword: Keyword, Variable: Variable, Property: Property,
  4685. Ruleset: Ruleset, Element: Element, Attribute: Attribute, Combinator: Combinator, Selector: Selector,
  4686. Quoted: Quoted, Expression: Expression, Declaration: Declaration, Call: Call, URL: URL, Import: Import,
  4687. Comment: Comment, Anonymous: Anonymous, Value: Value, JavaScript: JavaScript, Assignment: Assignment,
  4688. Condition: Condition, Paren: Paren, Media: Media, UnicodeDescriptor: UnicodeDescriptor, Negative: Negative,
  4689. Extend: Extend, VariableCall: VariableCall, NamespaceValue: NamespaceValue,
  4690. mixin: {
  4691. Call: MixinCall,
  4692. Definition: Definition
  4693. }
  4694. };
  4695. var logger = {
  4696. error: function (msg) {
  4697. this._fireEvent('error', msg);
  4698. },
  4699. warn: function (msg) {
  4700. this._fireEvent('warn', msg);
  4701. },
  4702. info: function (msg) {
  4703. this._fireEvent('info', msg);
  4704. },
  4705. debug: function (msg) {
  4706. this._fireEvent('debug', msg);
  4707. },
  4708. addListener: function (listener) {
  4709. this._listeners.push(listener);
  4710. },
  4711. removeListener: function (listener) {
  4712. for (var i_1 = 0; i_1 < this._listeners.length; i_1++) {
  4713. if (this._listeners[i_1] === listener) {
  4714. this._listeners.splice(i_1, 1);
  4715. return;
  4716. }
  4717. }
  4718. },
  4719. _fireEvent: function (type, msg) {
  4720. for (var i_2 = 0; i_2 < this._listeners.length; i_2++) {
  4721. var logFunction = this._listeners[i_2][type];
  4722. if (logFunction) {
  4723. logFunction(msg);
  4724. }
  4725. }
  4726. },
  4727. _listeners: []
  4728. };
  4729. /**
  4730. * @todo Document why this abstraction exists, and the relationship between
  4731. * environment, file managers, and plugin manager
  4732. */
  4733. var environment = /** @class */ (function () {
  4734. function environment(externalEnvironment, fileManagers) {
  4735. this.fileManagers = fileManagers || [];
  4736. externalEnvironment = externalEnvironment || {};
  4737. var optionalFunctions = ['encodeBase64', 'mimeLookup', 'charsetLookup', 'getSourceMapGenerator'];
  4738. var requiredFunctions = [];
  4739. var functions = requiredFunctions.concat(optionalFunctions);
  4740. for (var i_1 = 0; i_1 < functions.length; i_1++) {
  4741. var propName = functions[i_1];
  4742. var environmentFunc = externalEnvironment[propName];
  4743. if (environmentFunc) {
  4744. this[propName] = environmentFunc.bind(externalEnvironment);
  4745. }
  4746. else if (i_1 < requiredFunctions.length) {
  4747. this.warn("missing required function in environment - " + propName);
  4748. }
  4749. }
  4750. }
  4751. environment.prototype.getFileManager = function (filename, currentDirectory, options, environment, isSync) {
  4752. if (!filename) {
  4753. logger.warn('getFileManager called with no filename.. Please report this issue. continuing.');
  4754. }
  4755. if (currentDirectory == null) {
  4756. logger.warn('getFileManager called with null directory.. Please report this issue. continuing.');
  4757. }
  4758. var fileManagers = this.fileManagers;
  4759. if (options.pluginManager) {
  4760. fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers());
  4761. }
  4762. for (var i_2 = fileManagers.length - 1; i_2 >= 0; i_2--) {
  4763. var fileManager = fileManagers[i_2];
  4764. if (fileManager[isSync ? 'supportsSync' : 'supports'](filename, currentDirectory, options, environment)) {
  4765. return fileManager;
  4766. }
  4767. }
  4768. return null;
  4769. };
  4770. environment.prototype.addFileManager = function (fileManager) {
  4771. this.fileManagers.push(fileManager);
  4772. };
  4773. environment.prototype.clearFileManagers = function () {
  4774. this.fileManagers = [];
  4775. };
  4776. return environment;
  4777. }());
  4778. var AbstractFileManager = /** @class */ (function () {
  4779. function AbstractFileManager() {
  4780. }
  4781. AbstractFileManager.prototype.getPath = function (filename) {
  4782. var j = filename.lastIndexOf('?');
  4783. if (j > 0) {
  4784. filename = filename.slice(0, j);
  4785. }
  4786. j = filename.lastIndexOf('/');
  4787. if (j < 0) {
  4788. j = filename.lastIndexOf('\\');
  4789. }
  4790. if (j < 0) {
  4791. return '';
  4792. }
  4793. return filename.slice(0, j + 1);
  4794. };
  4795. AbstractFileManager.prototype.tryAppendExtension = function (path, ext) {
  4796. return /(\.[a-z]*$)|([\?;].*)$/.test(path) ? path : path + ext;
  4797. };
  4798. AbstractFileManager.prototype.tryAppendLessExtension = function (path) {
  4799. return this.tryAppendExtension(path, '.less');
  4800. };
  4801. AbstractFileManager.prototype.supportsSync = function () { return false; };
  4802. AbstractFileManager.prototype.alwaysMakePathsAbsolute = function () { return false; };
  4803. AbstractFileManager.prototype.isPathAbsolute = function (filename) {
  4804. return (/^(?:[a-z-]+:|\/|\\|#)/i).test(filename);
  4805. };
  4806. // TODO: pull out / replace?
  4807. AbstractFileManager.prototype.join = function (basePath, laterPath) {
  4808. if (!basePath) {
  4809. return laterPath;
  4810. }
  4811. return basePath + laterPath;
  4812. };
  4813. AbstractFileManager.prototype.pathDiff = function (url, baseUrl) {
  4814. // diff between two paths to create a relative path
  4815. var urlParts = this.extractUrlParts(url);
  4816. var baseUrlParts = this.extractUrlParts(baseUrl);
  4817. var i;
  4818. var max;
  4819. var urlDirectories;
  4820. var baseUrlDirectories;
  4821. var diff = '';
  4822. if (urlParts.hostPart !== baseUrlParts.hostPart) {
  4823. return '';
  4824. }
  4825. max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);
  4826. for (i = 0; i < max; i++) {
  4827. if (baseUrlParts.directories[i] !== urlParts.directories[i]) {
  4828. break;
  4829. }
  4830. }
  4831. baseUrlDirectories = baseUrlParts.directories.slice(i);
  4832. urlDirectories = urlParts.directories.slice(i);
  4833. for (i = 0; i < baseUrlDirectories.length - 1; i++) {
  4834. diff += '../';
  4835. }
  4836. for (i = 0; i < urlDirectories.length - 1; i++) {
  4837. diff += urlDirectories[i] + "/";
  4838. }
  4839. return diff;
  4840. };
  4841. // helper function, not part of API
  4842. AbstractFileManager.prototype.extractUrlParts = function (url, baseUrl) {
  4843. // urlParts[1] = protocol://hostname/ OR /
  4844. // urlParts[2] = / if path relative to host base
  4845. // urlParts[3] = directories
  4846. // urlParts[4] = filename
  4847. // urlParts[5] = parameters
  4848. var urlPartsRegex = /^((?:[a-z-]+:)?\/{2}(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i;
  4849. var urlParts = url.match(urlPartsRegex);
  4850. var returner = {};
  4851. var rawDirectories = [];
  4852. var directories = [];
  4853. var i;
  4854. var baseUrlParts;
  4855. if (!urlParts) {
  4856. throw new Error("Could not parse sheet href - '" + url + "'");
  4857. }
  4858. // Stylesheets in IE don't always return the full path
  4859. if (baseUrl && (!urlParts[1] || urlParts[2])) {
  4860. baseUrlParts = baseUrl.match(urlPartsRegex);
  4861. if (!baseUrlParts) {
  4862. throw new Error("Could not parse page url - '" + baseUrl + "'");
  4863. }
  4864. urlParts[1] = urlParts[1] || baseUrlParts[1] || '';
  4865. if (!urlParts[2]) {
  4866. urlParts[3] = baseUrlParts[3] + urlParts[3];
  4867. }
  4868. }
  4869. if (urlParts[3]) {
  4870. rawDirectories = urlParts[3].replace(/\\/g, '/').split('/');
  4871. // collapse '..' and skip '.'
  4872. for (i = 0; i < rawDirectories.length; i++) {
  4873. if (rawDirectories[i] === '..') {
  4874. directories.pop();
  4875. }
  4876. else if (rawDirectories[i] !== '.') {
  4877. directories.push(rawDirectories[i]);
  4878. }
  4879. }
  4880. }
  4881. returner.hostPart = urlParts[1];
  4882. returner.directories = directories;
  4883. returner.rawPath = (urlParts[1] || '') + rawDirectories.join('/');
  4884. returner.path = (urlParts[1] || '') + directories.join('/');
  4885. returner.filename = urlParts[4];
  4886. returner.fileUrl = returner.path + (urlParts[4] || '');
  4887. returner.url = returner.fileUrl + (urlParts[5] || '');
  4888. return returner;
  4889. };
  4890. return AbstractFileManager;
  4891. }());
  4892. var AbstractPluginLoader = /** @class */ (function () {
  4893. function AbstractPluginLoader() {
  4894. // Implemented by Node.js plugin loader
  4895. this.require = function () { return null; };
  4896. }
  4897. AbstractPluginLoader.prototype.evalPlugin = function (contents, context, imports, pluginOptions, fileInfo) {
  4898. var loader;
  4899. var registry;
  4900. var pluginObj;
  4901. var localModule;
  4902. var pluginManager;
  4903. var filename;
  4904. var result;
  4905. pluginManager = context.pluginManager;
  4906. if (fileInfo) {
  4907. if (typeof fileInfo === 'string') {
  4908. filename = fileInfo;
  4909. }
  4910. else {
  4911. filename = fileInfo.filename;
  4912. }
  4913. }
  4914. var shortname = (new this.less.FileManager()).extractUrlParts(filename).filename;
  4915. if (filename) {
  4916. pluginObj = pluginManager.get(filename);
  4917. if (pluginObj) {
  4918. result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
  4919. if (result) {
  4920. return result;
  4921. }
  4922. try {
  4923. if (pluginObj.use) {
  4924. pluginObj.use.call(this.context, pluginObj);
  4925. }
  4926. }
  4927. catch (e) {
  4928. e.message = e.message || 'Error during @plugin call';
  4929. return new LessError(e, imports, filename);
  4930. }
  4931. return pluginObj;
  4932. }
  4933. }
  4934. localModule = {
  4935. exports: {},
  4936. pluginManager: pluginManager,
  4937. fileInfo: fileInfo
  4938. };
  4939. registry = functionRegistry.create();
  4940. var registerPlugin = function (obj) {
  4941. pluginObj = obj;
  4942. };
  4943. try {
  4944. loader = new Function('module', 'require', 'registerPlugin', 'functions', 'tree', 'less', 'fileInfo', contents);
  4945. loader(localModule, this.require(filename), registerPlugin, registry, this.less.tree, this.less, fileInfo);
  4946. }
  4947. catch (e) {
  4948. return new LessError(e, imports, filename);
  4949. }
  4950. if (!pluginObj) {
  4951. pluginObj = localModule.exports;
  4952. }
  4953. pluginObj = this.validatePlugin(pluginObj, filename, shortname);
  4954. if (pluginObj instanceof LessError) {
  4955. return pluginObj;
  4956. }
  4957. if (pluginObj) {
  4958. pluginObj.imports = imports;
  4959. pluginObj.filename = filename;
  4960. // For < 3.x (or unspecified minVersion) - setOptions() before install()
  4961. if (!pluginObj.minVersion || this.compareVersion('3.0.0', pluginObj.minVersion) < 0) {
  4962. result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
  4963. if (result) {
  4964. return result;
  4965. }
  4966. }
  4967. // Run on first load
  4968. pluginManager.addPlugin(pluginObj, fileInfo.filename, registry);
  4969. pluginObj.functions = registry.getLocalFunctions();
  4970. // Need to call setOptions again because the pluginObj might have functions
  4971. result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
  4972. if (result) {
  4973. return result;
  4974. }
  4975. // Run every @plugin call
  4976. try {
  4977. if (pluginObj.use) {
  4978. pluginObj.use.call(this.context, pluginObj);
  4979. }
  4980. }
  4981. catch (e) {
  4982. e.message = e.message || 'Error during @plugin call';
  4983. return new LessError(e, imports, filename);
  4984. }
  4985. }
  4986. else {
  4987. return new LessError({ message: 'Not a valid plugin' }, imports, filename);
  4988. }
  4989. return pluginObj;
  4990. };
  4991. AbstractPluginLoader.prototype.trySetOptions = function (plugin, filename, name, options) {
  4992. if (options && !plugin.setOptions) {
  4993. return new LessError({
  4994. message: "Options have been provided but the plugin " + name + " does not support any options."
  4995. });
  4996. }
  4997. try {
  4998. plugin.setOptions && plugin.setOptions(options);
  4999. }
  5000. catch (e) {
  5001. return new LessError(e);
  5002. }
  5003. };
  5004. AbstractPluginLoader.prototype.validatePlugin = function (plugin, filename, name) {
  5005. if (plugin) {
  5006. // support plugins being a function
  5007. // so that the plugin can be more usable programmatically
  5008. if (typeof plugin === 'function') {
  5009. plugin = new plugin();
  5010. }
  5011. if (plugin.minVersion) {
  5012. if (this.compareVersion(plugin.minVersion, this.less.version) < 0) {
  5013. return new LessError({
  5014. message: "Plugin " + name + " requires version " + this.versionToString(plugin.minVersion)
  5015. });
  5016. }
  5017. }
  5018. return plugin;
  5019. }
  5020. return null;
  5021. };
  5022. AbstractPluginLoader.prototype.compareVersion = function (aVersion, bVersion) {
  5023. if (typeof aVersion === 'string') {
  5024. aVersion = aVersion.match(/^(\d+)\.?(\d+)?\.?(\d+)?/);
  5025. aVersion.shift();
  5026. }
  5027. for (var i_1 = 0; i_1 < aVersion.length; i_1++) {
  5028. if (aVersion[i_1] !== bVersion[i_1]) {
  5029. return parseInt(aVersion[i_1]) > parseInt(bVersion[i_1]) ? -1 : 1;
  5030. }
  5031. }
  5032. return 0;
  5033. };
  5034. AbstractPluginLoader.prototype.versionToString = function (version) {
  5035. var versionString = '';
  5036. for (var i_2 = 0; i_2 < version.length; i_2++) {
  5037. versionString += (versionString ? '.' : '') + version[i_2];
  5038. }
  5039. return versionString;
  5040. };
  5041. AbstractPluginLoader.prototype.printUsage = function (plugins) {
  5042. for (var i_3 = 0; i_3 < plugins.length; i_3++) {
  5043. var plugin = plugins[i_3];
  5044. if (plugin.printUsage) {
  5045. plugin.printUsage();
  5046. }
  5047. }
  5048. };
  5049. return AbstractPluginLoader;
  5050. }());
  5051. var _visitArgs = { visitDeeper: true };
  5052. var _hasIndexed = false;
  5053. function _noop(node) {
  5054. return node;
  5055. }
  5056. function indexNodeTypes(parent, ticker) {
  5057. // add .typeIndex to tree node types for lookup table
  5058. var key;
  5059. var child;
  5060. for (key in parent) {
  5061. /* eslint guard-for-in: 0 */
  5062. child = parent[key];
  5063. switch (typeof child) {
  5064. case 'function':
  5065. // ignore bound functions directly on tree which do not have a prototype
  5066. // or aren't nodes
  5067. if (child.prototype && child.prototype.type) {
  5068. child.prototype.typeIndex = ticker++;
  5069. }
  5070. break;
  5071. case 'object':
  5072. ticker = indexNodeTypes(child, ticker);
  5073. break;
  5074. }
  5075. }
  5076. return ticker;
  5077. }
  5078. var Visitor = /** @class */ (function () {
  5079. function Visitor(implementation) {
  5080. this._implementation = implementation;
  5081. this._visitInCache = {};
  5082. this._visitOutCache = {};
  5083. if (!_hasIndexed) {
  5084. indexNodeTypes(tree, 1);
  5085. _hasIndexed = true;
  5086. }
  5087. }
  5088. Visitor.prototype.visit = function (node) {
  5089. if (!node) {
  5090. return node;
  5091. }
  5092. var nodeTypeIndex = node.typeIndex;
  5093. if (!nodeTypeIndex) {
  5094. // MixinCall args aren't a node type?
  5095. if (node.value && node.value.typeIndex) {
  5096. this.visit(node.value);
  5097. }
  5098. return node;
  5099. }
  5100. var impl = this._implementation;
  5101. var func = this._visitInCache[nodeTypeIndex];
  5102. var funcOut = this._visitOutCache[nodeTypeIndex];
  5103. var visitArgs = _visitArgs;
  5104. var fnName;
  5105. visitArgs.visitDeeper = true;
  5106. if (!func) {
  5107. fnName = "visit" + node.type;
  5108. func = impl[fnName] || _noop;
  5109. funcOut = impl[fnName + "Out"] || _noop;
  5110. this._visitInCache[nodeTypeIndex] = func;
  5111. this._visitOutCache[nodeTypeIndex] = funcOut;
  5112. }
  5113. if (func !== _noop) {
  5114. var newNode = func.call(impl, node, visitArgs);
  5115. if (node && impl.isReplacing) {
  5116. node = newNode;
  5117. }
  5118. }
  5119. if (visitArgs.visitDeeper && node) {
  5120. if (node.length) {
  5121. for (var i = 0, cnt = node.length; i < cnt; i++) {
  5122. if (node[i].accept) {
  5123. node[i].accept(this);
  5124. }
  5125. }
  5126. }
  5127. else if (node.accept) {
  5128. node.accept(this);
  5129. }
  5130. }
  5131. if (funcOut != _noop) {
  5132. funcOut.call(impl, node);
  5133. }
  5134. return node;
  5135. };
  5136. Visitor.prototype.visitArray = function (nodes, nonReplacing) {
  5137. if (!nodes) {
  5138. return nodes;
  5139. }
  5140. var cnt = nodes.length;
  5141. var i;
  5142. // Non-replacing
  5143. if (nonReplacing || !this._implementation.isReplacing) {
  5144. for (i = 0; i < cnt; i++) {
  5145. this.visit(nodes[i]);
  5146. }
  5147. return nodes;
  5148. }
  5149. // Replacing
  5150. var out = [];
  5151. for (i = 0; i < cnt; i++) {
  5152. var evald = this.visit(nodes[i]);
  5153. if (evald === undefined) {
  5154. continue;
  5155. }
  5156. if (!evald.splice) {
  5157. out.push(evald);
  5158. }
  5159. else if (evald.length) {
  5160. this.flatten(evald, out);
  5161. }
  5162. }
  5163. return out;
  5164. };
  5165. Visitor.prototype.flatten = function (arr, out) {
  5166. if (!out) {
  5167. out = [];
  5168. }
  5169. var cnt;
  5170. var i;
  5171. var item;
  5172. var nestedCnt;
  5173. var j;
  5174. var nestedItem;
  5175. for (i = 0, cnt = arr.length; i < cnt; i++) {
  5176. item = arr[i];
  5177. if (item === undefined) {
  5178. continue;
  5179. }
  5180. if (!item.splice) {
  5181. out.push(item);
  5182. continue;
  5183. }
  5184. for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) {
  5185. nestedItem = item[j];
  5186. if (nestedItem === undefined) {
  5187. continue;
  5188. }
  5189. if (!nestedItem.splice) {
  5190. out.push(nestedItem);
  5191. }
  5192. else if (nestedItem.length) {
  5193. this.flatten(nestedItem, out);
  5194. }
  5195. }
  5196. }
  5197. return out;
  5198. };
  5199. return Visitor;
  5200. }());
  5201. var ImportSequencer = /** @class */ (function () {
  5202. function ImportSequencer(onSequencerEmpty) {
  5203. this.imports = [];
  5204. this.variableImports = [];
  5205. this._onSequencerEmpty = onSequencerEmpty;
  5206. this._currentDepth = 0;
  5207. }
  5208. ImportSequencer.prototype.addImport = function (callback) {
  5209. var importSequencer = this;
  5210. var importItem = {
  5211. callback: callback,
  5212. args: null,
  5213. isReady: false
  5214. };
  5215. this.imports.push(importItem);
  5216. return function () {
  5217. var args = [];
  5218. for (var _i = 0; _i < arguments.length; _i++) {
  5219. args[_i] = arguments[_i];
  5220. }
  5221. importItem.args = Array.prototype.slice.call(args, 0);
  5222. importItem.isReady = true;
  5223. importSequencer.tryRun();
  5224. };
  5225. };
  5226. ImportSequencer.prototype.addVariableImport = function (callback) {
  5227. this.variableImports.push(callback);
  5228. };
  5229. ImportSequencer.prototype.tryRun = function () {
  5230. this._currentDepth++;
  5231. try {
  5232. while (true) {
  5233. while (this.imports.length > 0) {
  5234. var importItem = this.imports[0];
  5235. if (!importItem.isReady) {
  5236. return;
  5237. }
  5238. this.imports = this.imports.slice(1);
  5239. importItem.callback.apply(null, importItem.args);
  5240. }
  5241. if (this.variableImports.length === 0) {
  5242. break;
  5243. }
  5244. var variableImport = this.variableImports[0];
  5245. this.variableImports = this.variableImports.slice(1);
  5246. variableImport();
  5247. }
  5248. }
  5249. finally {
  5250. this._currentDepth--;
  5251. }
  5252. if (this._currentDepth === 0 && this._onSequencerEmpty) {
  5253. this._onSequencerEmpty();
  5254. }
  5255. };
  5256. return ImportSequencer;
  5257. }());
  5258. var ImportVisitor = function (importer, finish) {
  5259. this._visitor = new Visitor(this);
  5260. this._importer = importer;
  5261. this._finish = finish;
  5262. this.context = new contexts.Eval();
  5263. this.importCount = 0;
  5264. this.onceFileDetectionMap = {};
  5265. this.recursionDetector = {};
  5266. this._sequencer = new ImportSequencer(this._onSequencerEmpty.bind(this));
  5267. };
  5268. ImportVisitor.prototype = {
  5269. isReplacing: false,
  5270. run: function (root) {
  5271. try {
  5272. // process the contents
  5273. this._visitor.visit(root);
  5274. }
  5275. catch (e) {
  5276. this.error = e;
  5277. }
  5278. this.isFinished = true;
  5279. this._sequencer.tryRun();
  5280. },
  5281. _onSequencerEmpty: function () {
  5282. if (!this.isFinished) {
  5283. return;
  5284. }
  5285. this._finish(this.error);
  5286. },
  5287. visitImport: function (importNode, visitArgs) {
  5288. var inlineCSS = importNode.options.inline;
  5289. if (!importNode.css || inlineCSS) {
  5290. var context = new contexts.Eval(this.context, copyArray(this.context.frames));
  5291. var importParent = context.frames[0];
  5292. this.importCount++;
  5293. if (importNode.isVariableImport()) {
  5294. this._sequencer.addVariableImport(this.processImportNode.bind(this, importNode, context, importParent));
  5295. }
  5296. else {
  5297. this.processImportNode(importNode, context, importParent);
  5298. }
  5299. }
  5300. visitArgs.visitDeeper = false;
  5301. },
  5302. processImportNode: function (importNode, context, importParent) {
  5303. var evaldImportNode;
  5304. var inlineCSS = importNode.options.inline;
  5305. try {
  5306. evaldImportNode = importNode.evalForImport(context);
  5307. }
  5308. catch (e) {
  5309. if (!e.filename) {
  5310. e.index = importNode.getIndex();
  5311. e.filename = importNode.fileInfo().filename;
  5312. }
  5313. // attempt to eval properly and treat as css
  5314. importNode.css = true;
  5315. // if that fails, this error will be thrown
  5316. importNode.error = e;
  5317. }
  5318. if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) {
  5319. if (evaldImportNode.options.multiple) {
  5320. context.importMultiple = true;
  5321. }
  5322. // try appending if we haven't determined if it is css or not
  5323. var tryAppendLessExtension = evaldImportNode.css === undefined;
  5324. for (var i_1 = 0; i_1 < importParent.rules.length; i_1++) {
  5325. if (importParent.rules[i_1] === importNode) {
  5326. importParent.rules[i_1] = evaldImportNode;
  5327. break;
  5328. }
  5329. }
  5330. var onImported = this.onImported.bind(this, evaldImportNode, context);
  5331. var sequencedOnImported = this._sequencer.addImport(onImported);
  5332. this._importer.push(evaldImportNode.getPath(), tryAppendLessExtension, evaldImportNode.fileInfo(), evaldImportNode.options, sequencedOnImported);
  5333. }
  5334. else {
  5335. this.importCount--;
  5336. if (this.isFinished) {
  5337. this._sequencer.tryRun();
  5338. }
  5339. }
  5340. },
  5341. onImported: function (importNode, context, e, root, importedAtRoot, fullPath) {
  5342. if (e) {
  5343. if (!e.filename) {
  5344. e.index = importNode.getIndex();
  5345. e.filename = importNode.fileInfo().filename;
  5346. }
  5347. this.error = e;
  5348. }
  5349. var importVisitor = this;
  5350. var inlineCSS = importNode.options.inline;
  5351. var isPlugin = importNode.options.isPlugin;
  5352. var isOptional = importNode.options.optional;
  5353. var duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector;
  5354. if (!context.importMultiple) {
  5355. if (duplicateImport) {
  5356. importNode.skip = true;
  5357. }
  5358. else {
  5359. importNode.skip = function () {
  5360. if (fullPath in importVisitor.onceFileDetectionMap) {
  5361. return true;
  5362. }
  5363. importVisitor.onceFileDetectionMap[fullPath] = true;
  5364. return false;
  5365. };
  5366. }
  5367. }
  5368. if (!fullPath && isOptional) {
  5369. importNode.skip = true;
  5370. }
  5371. if (root) {
  5372. importNode.root = root;
  5373. importNode.importedFilename = fullPath;
  5374. if (!inlineCSS && !isPlugin && (context.importMultiple || !duplicateImport)) {
  5375. importVisitor.recursionDetector[fullPath] = true;
  5376. var oldContext = this.context;
  5377. this.context = context;
  5378. try {
  5379. this._visitor.visit(root);
  5380. }
  5381. catch (e) {
  5382. this.error = e;
  5383. }
  5384. this.context = oldContext;
  5385. }
  5386. }
  5387. importVisitor.importCount--;
  5388. if (importVisitor.isFinished) {
  5389. importVisitor._sequencer.tryRun();
  5390. }
  5391. },
  5392. visitDeclaration: function (declNode, visitArgs) {
  5393. if (declNode.value.type === 'DetachedRuleset') {
  5394. this.context.frames.unshift(declNode);
  5395. }
  5396. else {
  5397. visitArgs.visitDeeper = false;
  5398. }
  5399. },
  5400. visitDeclarationOut: function (declNode) {
  5401. if (declNode.value.type === 'DetachedRuleset') {
  5402. this.context.frames.shift();
  5403. }
  5404. },
  5405. visitAtRule: function (atRuleNode, visitArgs) {
  5406. this.context.frames.unshift(atRuleNode);
  5407. },
  5408. visitAtRuleOut: function (atRuleNode) {
  5409. this.context.frames.shift();
  5410. },
  5411. visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {
  5412. this.context.frames.unshift(mixinDefinitionNode);
  5413. },
  5414. visitMixinDefinitionOut: function (mixinDefinitionNode) {
  5415. this.context.frames.shift();
  5416. },
  5417. visitRuleset: function (rulesetNode, visitArgs) {
  5418. this.context.frames.unshift(rulesetNode);
  5419. },
  5420. visitRulesetOut: function (rulesetNode) {
  5421. this.context.frames.shift();
  5422. },
  5423. visitMedia: function (mediaNode, visitArgs) {
  5424. this.context.frames.unshift(mediaNode.rules[0]);
  5425. },
  5426. visitMediaOut: function (mediaNode) {
  5427. this.context.frames.shift();
  5428. }
  5429. };
  5430. var SetTreeVisibilityVisitor = /** @class */ (function () {
  5431. function SetTreeVisibilityVisitor(visible) {
  5432. this.visible = visible;
  5433. }
  5434. SetTreeVisibilityVisitor.prototype.run = function (root) {
  5435. this.visit(root);
  5436. };
  5437. SetTreeVisibilityVisitor.prototype.visitArray = function (nodes) {
  5438. if (!nodes) {
  5439. return nodes;
  5440. }
  5441. var cnt = nodes.length;
  5442. var i;
  5443. for (i = 0; i < cnt; i++) {
  5444. this.visit(nodes[i]);
  5445. }
  5446. return nodes;
  5447. };
  5448. SetTreeVisibilityVisitor.prototype.visit = function (node) {
  5449. if (!node) {
  5450. return node;
  5451. }
  5452. if (node.constructor === Array) {
  5453. return this.visitArray(node);
  5454. }
  5455. if (!node.blocksVisibility || node.blocksVisibility()) {
  5456. return node;
  5457. }
  5458. if (this.visible) {
  5459. node.ensureVisibility();
  5460. }
  5461. else {
  5462. node.ensureInvisibility();
  5463. }
  5464. node.accept(this);
  5465. return node;
  5466. };
  5467. return SetTreeVisibilityVisitor;
  5468. }());
  5469. /* jshint loopfunc:true */
  5470. var ExtendFinderVisitor = /** @class */ (function () {
  5471. function ExtendFinderVisitor() {
  5472. this._visitor = new Visitor(this);
  5473. this.contexts = [];
  5474. this.allExtendsStack = [[]];
  5475. }
  5476. ExtendFinderVisitor.prototype.run = function (root) {
  5477. root = this._visitor.visit(root);
  5478. root.allExtends = this.allExtendsStack[0];
  5479. return root;
  5480. };
  5481. ExtendFinderVisitor.prototype.visitDeclaration = function (declNode, visitArgs) {
  5482. visitArgs.visitDeeper = false;
  5483. };
  5484. ExtendFinderVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) {
  5485. visitArgs.visitDeeper = false;
  5486. };
  5487. ExtendFinderVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) {
  5488. if (rulesetNode.root) {
  5489. return;
  5490. }
  5491. var i;
  5492. var j;
  5493. var extend;
  5494. var allSelectorsExtendList = [];
  5495. var extendList;
  5496. // get &:extend(.a); rules which apply to all selectors in this ruleset
  5497. var rules = rulesetNode.rules;
  5498. var ruleCnt = rules ? rules.length : 0;
  5499. for (i = 0; i < ruleCnt; i++) {
  5500. if (rulesetNode.rules[i] instanceof tree.Extend) {
  5501. allSelectorsExtendList.push(rules[i]);
  5502. rulesetNode.extendOnEveryPath = true;
  5503. }
  5504. }
  5505. // now find every selector and apply the extends that apply to all extends
  5506. // and the ones which apply to an individual extend
  5507. var paths = rulesetNode.paths;
  5508. for (i = 0; i < paths.length; i++) {
  5509. var selectorPath = paths[i];
  5510. var selector = selectorPath[selectorPath.length - 1];
  5511. var selExtendList = selector.extendList;
  5512. extendList = selExtendList ? copyArray(selExtendList).concat(allSelectorsExtendList)
  5513. : allSelectorsExtendList;
  5514. if (extendList) {
  5515. extendList = extendList.map(function (allSelectorsExtend) { return allSelectorsExtend.clone(); });
  5516. }
  5517. for (j = 0; j < extendList.length; j++) {
  5518. this.foundExtends = true;
  5519. extend = extendList[j];
  5520. extend.findSelfSelectors(selectorPath);
  5521. extend.ruleset = rulesetNode;
  5522. if (j === 0) {
  5523. extend.firstExtendOnThisSelectorPath = true;
  5524. }
  5525. this.allExtendsStack[this.allExtendsStack.length - 1].push(extend);
  5526. }
  5527. }
  5528. this.contexts.push(rulesetNode.selectors);
  5529. };
  5530. ExtendFinderVisitor.prototype.visitRulesetOut = function (rulesetNode) {
  5531. if (!rulesetNode.root) {
  5532. this.contexts.length = this.contexts.length - 1;
  5533. }
  5534. };
  5535. ExtendFinderVisitor.prototype.visitMedia = function (mediaNode, visitArgs) {
  5536. mediaNode.allExtends = [];
  5537. this.allExtendsStack.push(mediaNode.allExtends);
  5538. };
  5539. ExtendFinderVisitor.prototype.visitMediaOut = function (mediaNode) {
  5540. this.allExtendsStack.length = this.allExtendsStack.length - 1;
  5541. };
  5542. ExtendFinderVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) {
  5543. atRuleNode.allExtends = [];
  5544. this.allExtendsStack.push(atRuleNode.allExtends);
  5545. };
  5546. ExtendFinderVisitor.prototype.visitAtRuleOut = function (atRuleNode) {
  5547. this.allExtendsStack.length = this.allExtendsStack.length - 1;
  5548. };
  5549. return ExtendFinderVisitor;
  5550. }());
  5551. var ProcessExtendsVisitor = /** @class */ (function () {
  5552. function ProcessExtendsVisitor() {
  5553. this._visitor = new Visitor(this);
  5554. }
  5555. ProcessExtendsVisitor.prototype.run = function (root) {
  5556. var extendFinder = new ExtendFinderVisitor();
  5557. this.extendIndices = {};
  5558. extendFinder.run(root);
  5559. if (!extendFinder.foundExtends) {
  5560. return root;
  5561. }
  5562. root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends));
  5563. this.allExtendsStack = [root.allExtends];
  5564. var newRoot = this._visitor.visit(root);
  5565. this.checkExtendsForNonMatched(root.allExtends);
  5566. return newRoot;
  5567. };
  5568. ProcessExtendsVisitor.prototype.checkExtendsForNonMatched = function (extendList) {
  5569. var indices = this.extendIndices;
  5570. extendList.filter(function (extend) { return !extend.hasFoundMatches && extend.parent_ids.length == 1; }).forEach(function (extend) {
  5571. var selector = '_unknown_';
  5572. try {
  5573. selector = extend.selector.toCSS({});
  5574. }
  5575. catch (_) { }
  5576. if (!indices[extend.index + " " + selector]) {
  5577. indices[extend.index + " " + selector] = true;
  5578. logger.warn("extend '" + selector + "' has no matches");
  5579. }
  5580. });
  5581. };
  5582. ProcessExtendsVisitor.prototype.doExtendChaining = function (extendsList, extendsListTarget, iterationCount) {
  5583. //
  5584. // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering
  5585. // and pasting the selector we would do normally, but we are also adding an extend with the same target selector
  5586. // this means this new extend can then go and alter other extends
  5587. //
  5588. // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors
  5589. // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already
  5590. // processed if we look at each selector at a time, as is done in visitRuleset
  5591. var extendIndex;
  5592. var targetExtendIndex;
  5593. var matches;
  5594. var extendsToAdd = [];
  5595. var newSelector;
  5596. var extendVisitor = this;
  5597. var selectorPath;
  5598. var extend;
  5599. var targetExtend;
  5600. var newExtend;
  5601. iterationCount = iterationCount || 0;
  5602. // loop through comparing every extend with every target extend.
  5603. // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place
  5604. // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one
  5605. // and the second is the target.
  5606. // the separation into two lists allows us to process a subset of chains with a bigger set, as is the
  5607. // case when processing media queries
  5608. for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) {
  5609. for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) {
  5610. extend = extendsList[extendIndex];
  5611. targetExtend = extendsListTarget[targetExtendIndex];
  5612. // look for circular references
  5613. if (extend.parent_ids.indexOf(targetExtend.object_id) >= 0) {
  5614. continue;
  5615. }
  5616. // find a match in the target extends self selector (the bit before :extend)
  5617. selectorPath = [targetExtend.selfSelectors[0]];
  5618. matches = extendVisitor.findMatch(extend, selectorPath);
  5619. if (matches.length) {
  5620. extend.hasFoundMatches = true;
  5621. // we found a match, so for each self selector..
  5622. extend.selfSelectors.forEach(function (selfSelector) {
  5623. var info = targetExtend.visibilityInfo();
  5624. // process the extend as usual
  5625. newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector, extend.isVisible());
  5626. // but now we create a new extend from it
  5627. newExtend = new (tree.Extend)(targetExtend.selector, targetExtend.option, 0, targetExtend.fileInfo(), info);
  5628. newExtend.selfSelectors = newSelector;
  5629. // add the extend onto the list of extends for that selector
  5630. newSelector[newSelector.length - 1].extendList = [newExtend];
  5631. // record that we need to add it.
  5632. extendsToAdd.push(newExtend);
  5633. newExtend.ruleset = targetExtend.ruleset;
  5634. // remember its parents for circular references
  5635. newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids);
  5636. // only process the selector once.. if we have :extend(.a,.b) then multiple
  5637. // extends will look at the same selector path, so when extending
  5638. // we know that any others will be duplicates in terms of what is added to the css
  5639. if (targetExtend.firstExtendOnThisSelectorPath) {
  5640. newExtend.firstExtendOnThisSelectorPath = true;
  5641. targetExtend.ruleset.paths.push(newSelector);
  5642. }
  5643. });
  5644. }
  5645. }
  5646. }
  5647. if (extendsToAdd.length) {
  5648. // try to detect circular references to stop a stack overflow.
  5649. // may no longer be needed.
  5650. this.extendChainCount++;
  5651. if (iterationCount > 100) {
  5652. var selectorOne = '{unable to calculate}';
  5653. var selectorTwo = '{unable to calculate}';
  5654. try {
  5655. selectorOne = extendsToAdd[0].selfSelectors[0].toCSS();
  5656. selectorTwo = extendsToAdd[0].selector.toCSS();
  5657. }
  5658. catch (e) { }
  5659. throw { message: "extend circular reference detected. One of the circular extends is currently:" + selectorOne + ":extend(" + selectorTwo + ")" };
  5660. }
  5661. // now process the new extends on the existing rules so that we can handle a extending b extending c extending
  5662. // d extending e...
  5663. return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount + 1));
  5664. }
  5665. else {
  5666. return extendsToAdd;
  5667. }
  5668. };
  5669. ProcessExtendsVisitor.prototype.visitDeclaration = function (ruleNode, visitArgs) {
  5670. visitArgs.visitDeeper = false;
  5671. };
  5672. ProcessExtendsVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) {
  5673. visitArgs.visitDeeper = false;
  5674. };
  5675. ProcessExtendsVisitor.prototype.visitSelector = function (selectorNode, visitArgs) {
  5676. visitArgs.visitDeeper = false;
  5677. };
  5678. ProcessExtendsVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) {
  5679. if (rulesetNode.root) {
  5680. return;
  5681. }
  5682. var matches;
  5683. var pathIndex;
  5684. var extendIndex;
  5685. var allExtends = this.allExtendsStack[this.allExtendsStack.length - 1];
  5686. var selectorsToAdd = [];
  5687. var extendVisitor = this;
  5688. var selectorPath;
  5689. // look at each selector path in the ruleset, find any extend matches and then copy, find and replace
  5690. for (extendIndex = 0; extendIndex < allExtends.length; extendIndex++) {
  5691. for (pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) {
  5692. selectorPath = rulesetNode.paths[pathIndex];
  5693. // extending extends happens initially, before the main pass
  5694. if (rulesetNode.extendOnEveryPath) {
  5695. continue;
  5696. }
  5697. var extendList = selectorPath[selectorPath.length - 1].extendList;
  5698. if (extendList && extendList.length) {
  5699. continue;
  5700. }
  5701. matches = this.findMatch(allExtends[extendIndex], selectorPath);
  5702. if (matches.length) {
  5703. allExtends[extendIndex].hasFoundMatches = true;
  5704. allExtends[extendIndex].selfSelectors.forEach(function (selfSelector) {
  5705. var extendedSelectors;
  5706. extendedSelectors = extendVisitor.extendSelector(matches, selectorPath, selfSelector, allExtends[extendIndex].isVisible());
  5707. selectorsToAdd.push(extendedSelectors);
  5708. });
  5709. }
  5710. }
  5711. }
  5712. rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd);
  5713. };
  5714. ProcessExtendsVisitor.prototype.findMatch = function (extend, haystackSelectorPath) {
  5715. //
  5716. // look through the haystack selector path to try and find the needle - extend.selector
  5717. // returns an array of selector matches that can then be replaced
  5718. //
  5719. var haystackSelectorIndex;
  5720. var hackstackSelector;
  5721. var hackstackElementIndex;
  5722. var haystackElement;
  5723. var targetCombinator;
  5724. var i;
  5725. var extendVisitor = this;
  5726. var needleElements = extend.selector.elements;
  5727. var potentialMatches = [];
  5728. var potentialMatch;
  5729. var matches = [];
  5730. // loop through the haystack elements
  5731. for (haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) {
  5732. hackstackSelector = haystackSelectorPath[haystackSelectorIndex];
  5733. for (hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) {
  5734. haystackElement = hackstackSelector.elements[hackstackElementIndex];
  5735. // if we allow elements before our match we can add a potential match every time. otherwise only at the first element.
  5736. if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) {
  5737. potentialMatches.push({ pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0,
  5738. initialCombinator: haystackElement.combinator });
  5739. }
  5740. for (i = 0; i < potentialMatches.length; i++) {
  5741. potentialMatch = potentialMatches[i];
  5742. // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't
  5743. // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to
  5744. // work out what the resulting combinator will be
  5745. targetCombinator = haystackElement.combinator.value;
  5746. if (targetCombinator === '' && hackstackElementIndex === 0) {
  5747. targetCombinator = ' ';
  5748. }
  5749. // if we don't match, null our match to indicate failure
  5750. if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) ||
  5751. (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) {
  5752. potentialMatch = null;
  5753. }
  5754. else {
  5755. potentialMatch.matched++;
  5756. }
  5757. // if we are still valid and have finished, test whether we have elements after and whether these are allowed
  5758. if (potentialMatch) {
  5759. potentialMatch.finished = potentialMatch.matched === needleElements.length;
  5760. if (potentialMatch.finished &&
  5761. (!extend.allowAfter &&
  5762. (hackstackElementIndex + 1 < hackstackSelector.elements.length || haystackSelectorIndex + 1 < haystackSelectorPath.length))) {
  5763. potentialMatch = null;
  5764. }
  5765. }
  5766. // if null we remove, if not, we are still valid, so either push as a valid match or continue
  5767. if (potentialMatch) {
  5768. if (potentialMatch.finished) {
  5769. potentialMatch.length = needleElements.length;
  5770. potentialMatch.endPathIndex = haystackSelectorIndex;
  5771. potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match
  5772. potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again
  5773. matches.push(potentialMatch);
  5774. }
  5775. }
  5776. else {
  5777. potentialMatches.splice(i, 1);
  5778. i--;
  5779. }
  5780. }
  5781. }
  5782. }
  5783. return matches;
  5784. };
  5785. ProcessExtendsVisitor.prototype.isElementValuesEqual = function (elementValue1, elementValue2) {
  5786. if (typeof elementValue1 === 'string' || typeof elementValue2 === 'string') {
  5787. return elementValue1 === elementValue2;
  5788. }
  5789. if (elementValue1 instanceof tree.Attribute) {
  5790. if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) {
  5791. return false;
  5792. }
  5793. if (!elementValue1.value || !elementValue2.value) {
  5794. if (elementValue1.value || elementValue2.value) {
  5795. return false;
  5796. }
  5797. return true;
  5798. }
  5799. elementValue1 = elementValue1.value.value || elementValue1.value;
  5800. elementValue2 = elementValue2.value.value || elementValue2.value;
  5801. return elementValue1 === elementValue2;
  5802. }
  5803. elementValue1 = elementValue1.value;
  5804. elementValue2 = elementValue2.value;
  5805. if (elementValue1 instanceof tree.Selector) {
  5806. if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) {
  5807. return false;
  5808. }
  5809. for (var i_1 = 0; i_1 < elementValue1.elements.length; i_1++) {
  5810. if (elementValue1.elements[i_1].combinator.value !== elementValue2.elements[i_1].combinator.value) {
  5811. if (i_1 !== 0 || (elementValue1.elements[i_1].combinator.value || ' ') !== (elementValue2.elements[i_1].combinator.value || ' ')) {
  5812. return false;
  5813. }
  5814. }
  5815. if (!this.isElementValuesEqual(elementValue1.elements[i_1].value, elementValue2.elements[i_1].value)) {
  5816. return false;
  5817. }
  5818. }
  5819. return true;
  5820. }
  5821. return false;
  5822. };
  5823. ProcessExtendsVisitor.prototype.extendSelector = function (matches, selectorPath, replacementSelector, isVisible) {
  5824. // for a set of matches, replace each match with the replacement selector
  5825. var currentSelectorPathIndex = 0;
  5826. var currentSelectorPathElementIndex = 0;
  5827. var path = [];
  5828. var matchIndex;
  5829. var selector;
  5830. var firstElement;
  5831. var match;
  5832. var newElements;
  5833. for (matchIndex = 0; matchIndex < matches.length; matchIndex++) {
  5834. match = matches[matchIndex];
  5835. selector = selectorPath[match.pathIndex];
  5836. firstElement = new tree.Element(match.initialCombinator, replacementSelector.elements[0].value, replacementSelector.elements[0].isVariable, replacementSelector.elements[0].getIndex(), replacementSelector.elements[0].fileInfo());
  5837. if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) {
  5838. path[path.length - 1].elements = path[path.length - 1]
  5839. .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));
  5840. currentSelectorPathElementIndex = 0;
  5841. currentSelectorPathIndex++;
  5842. }
  5843. newElements = selector.elements
  5844. .slice(currentSelectorPathElementIndex, match.index)
  5845. .concat([firstElement])
  5846. .concat(replacementSelector.elements.slice(1));
  5847. if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) {
  5848. path[path.length - 1].elements =
  5849. path[path.length - 1].elements.concat(newElements);
  5850. }
  5851. else {
  5852. path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex));
  5853. path.push(new tree.Selector(newElements));
  5854. }
  5855. currentSelectorPathIndex = match.endPathIndex;
  5856. currentSelectorPathElementIndex = match.endPathElementIndex;
  5857. if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) {
  5858. currentSelectorPathElementIndex = 0;
  5859. currentSelectorPathIndex++;
  5860. }
  5861. }
  5862. if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) {
  5863. path[path.length - 1].elements = path[path.length - 1]
  5864. .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));
  5865. currentSelectorPathIndex++;
  5866. }
  5867. path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length));
  5868. path = path.map(function (currentValue) {
  5869. // we can re-use elements here, because the visibility property matters only for selectors
  5870. var derived = currentValue.createDerived(currentValue.elements);
  5871. if (isVisible) {
  5872. derived.ensureVisibility();
  5873. }
  5874. else {
  5875. derived.ensureInvisibility();
  5876. }
  5877. return derived;
  5878. });
  5879. return path;
  5880. };
  5881. ProcessExtendsVisitor.prototype.visitMedia = function (mediaNode, visitArgs) {
  5882. var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]);
  5883. newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends));
  5884. this.allExtendsStack.push(newAllExtends);
  5885. };
  5886. ProcessExtendsVisitor.prototype.visitMediaOut = function (mediaNode) {
  5887. var lastIndex = this.allExtendsStack.length - 1;
  5888. this.allExtendsStack.length = lastIndex;
  5889. };
  5890. ProcessExtendsVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) {
  5891. var newAllExtends = atRuleNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]);
  5892. newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, atRuleNode.allExtends));
  5893. this.allExtendsStack.push(newAllExtends);
  5894. };
  5895. ProcessExtendsVisitor.prototype.visitAtRuleOut = function (atRuleNode) {
  5896. var lastIndex = this.allExtendsStack.length - 1;
  5897. this.allExtendsStack.length = lastIndex;
  5898. };
  5899. return ProcessExtendsVisitor;
  5900. }());
  5901. var JoinSelectorVisitor = /** @class */ (function () {
  5902. function JoinSelectorVisitor() {
  5903. this.contexts = [[]];
  5904. this._visitor = new Visitor(this);
  5905. }
  5906. JoinSelectorVisitor.prototype.run = function (root) {
  5907. return this._visitor.visit(root);
  5908. };
  5909. JoinSelectorVisitor.prototype.visitDeclaration = function (declNode, visitArgs) {
  5910. visitArgs.visitDeeper = false;
  5911. };
  5912. JoinSelectorVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) {
  5913. visitArgs.visitDeeper = false;
  5914. };
  5915. JoinSelectorVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) {
  5916. var context = this.contexts[this.contexts.length - 1];
  5917. var paths = [];
  5918. var selectors;
  5919. this.contexts.push(paths);
  5920. if (!rulesetNode.root) {
  5921. selectors = rulesetNode.selectors;
  5922. if (selectors) {
  5923. selectors = selectors.filter(function (selector) { return selector.getIsOutput(); });
  5924. rulesetNode.selectors = selectors.length ? selectors : (selectors = null);
  5925. if (selectors) {
  5926. rulesetNode.joinSelectors(paths, context, selectors);
  5927. }
  5928. }
  5929. if (!selectors) {
  5930. rulesetNode.rules = null;
  5931. }
  5932. rulesetNode.paths = paths;
  5933. }
  5934. };
  5935. JoinSelectorVisitor.prototype.visitRulesetOut = function (rulesetNode) {
  5936. this.contexts.length = this.contexts.length - 1;
  5937. };
  5938. JoinSelectorVisitor.prototype.visitMedia = function (mediaNode, visitArgs) {
  5939. var context = this.contexts[this.contexts.length - 1];
  5940. mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia);
  5941. };
  5942. JoinSelectorVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) {
  5943. var context = this.contexts[this.contexts.length - 1];
  5944. if (atRuleNode.rules && atRuleNode.rules.length) {
  5945. atRuleNode.rules[0].root = (atRuleNode.isRooted || context.length === 0 || null);
  5946. }
  5947. };
  5948. return JoinSelectorVisitor;
  5949. }());
  5950. var CSSVisitorUtils = /** @class */ (function () {
  5951. function CSSVisitorUtils(context) {
  5952. this._visitor = new Visitor(this);
  5953. this._context = context;
  5954. }
  5955. CSSVisitorUtils.prototype.containsSilentNonBlockedChild = function (bodyRules) {
  5956. var rule;
  5957. if (!bodyRules) {
  5958. return false;
  5959. }
  5960. for (var r = 0; r < bodyRules.length; r++) {
  5961. rule = bodyRules[r];
  5962. if (rule.isSilent && rule.isSilent(this._context) && !rule.blocksVisibility()) {
  5963. // the atrule contains something that was referenced (likely by extend)
  5964. // therefore it needs to be shown in output too
  5965. return true;
  5966. }
  5967. }
  5968. return false;
  5969. };
  5970. CSSVisitorUtils.prototype.keepOnlyVisibleChilds = function (owner) {
  5971. if (owner && owner.rules) {
  5972. owner.rules = owner.rules.filter(function (thing) { return thing.isVisible(); });
  5973. }
  5974. };
  5975. CSSVisitorUtils.prototype.isEmpty = function (owner) {
  5976. return (owner && owner.rules)
  5977. ? (owner.rules.length === 0) : true;
  5978. };
  5979. CSSVisitorUtils.prototype.hasVisibleSelector = function (rulesetNode) {
  5980. return (rulesetNode && rulesetNode.paths)
  5981. ? (rulesetNode.paths.length > 0) : false;
  5982. };
  5983. CSSVisitorUtils.prototype.resolveVisibility = function (node, originalRules) {
  5984. if (!node.blocksVisibility()) {
  5985. if (this.isEmpty(node) && !this.containsSilentNonBlockedChild(originalRules)) {
  5986. return;
  5987. }
  5988. return node;
  5989. }
  5990. var compiledRulesBody = node.rules[0];
  5991. this.keepOnlyVisibleChilds(compiledRulesBody);
  5992. if (this.isEmpty(compiledRulesBody)) {
  5993. return;
  5994. }
  5995. node.ensureVisibility();
  5996. node.removeVisibilityBlock();
  5997. return node;
  5998. };
  5999. CSSVisitorUtils.prototype.isVisibleRuleset = function (rulesetNode) {
  6000. if (rulesetNode.firstRoot) {
  6001. return true;
  6002. }
  6003. if (this.isEmpty(rulesetNode)) {
  6004. return false;
  6005. }
  6006. if (!rulesetNode.root && !this.hasVisibleSelector(rulesetNode)) {
  6007. return false;
  6008. }
  6009. return true;
  6010. };
  6011. return CSSVisitorUtils;
  6012. }());
  6013. var ToCSSVisitor = function (context) {
  6014. this._visitor = new Visitor(this);
  6015. this._context = context;
  6016. this.utils = new CSSVisitorUtils(context);
  6017. };
  6018. ToCSSVisitor.prototype = {
  6019. isReplacing: true,
  6020. run: function (root) {
  6021. return this._visitor.visit(root);
  6022. },
  6023. visitDeclaration: function (declNode, visitArgs) {
  6024. if (declNode.blocksVisibility() || declNode.variable) {
  6025. return;
  6026. }
  6027. return declNode;
  6028. },
  6029. visitMixinDefinition: function (mixinNode, visitArgs) {
  6030. // mixin definitions do not get eval'd - this means they keep state
  6031. // so we have to clear that state here so it isn't used if toCSS is called twice
  6032. mixinNode.frames = [];
  6033. },
  6034. visitExtend: function (extendNode, visitArgs) {
  6035. },
  6036. visitComment: function (commentNode, visitArgs) {
  6037. if (commentNode.blocksVisibility() || commentNode.isSilent(this._context)) {
  6038. return;
  6039. }
  6040. return commentNode;
  6041. },
  6042. visitMedia: function (mediaNode, visitArgs) {
  6043. var originalRules = mediaNode.rules[0].rules;
  6044. mediaNode.accept(this._visitor);
  6045. visitArgs.visitDeeper = false;
  6046. return this.utils.resolveVisibility(mediaNode, originalRules);
  6047. },
  6048. visitImport: function (importNode, visitArgs) {
  6049. if (importNode.blocksVisibility()) {
  6050. return;
  6051. }
  6052. return importNode;
  6053. },
  6054. visitAtRule: function (atRuleNode, visitArgs) {
  6055. if (atRuleNode.rules && atRuleNode.rules.length) {
  6056. return this.visitAtRuleWithBody(atRuleNode, visitArgs);
  6057. }
  6058. else {
  6059. return this.visitAtRuleWithoutBody(atRuleNode, visitArgs);
  6060. }
  6061. },
  6062. visitAnonymous: function (anonymousNode, visitArgs) {
  6063. if (!anonymousNode.blocksVisibility()) {
  6064. anonymousNode.accept(this._visitor);
  6065. return anonymousNode;
  6066. }
  6067. },
  6068. visitAtRuleWithBody: function (atRuleNode, visitArgs) {
  6069. // if there is only one nested ruleset and that one has no path, then it is
  6070. // just fake ruleset
  6071. function hasFakeRuleset(atRuleNode) {
  6072. var bodyRules = atRuleNode.rules;
  6073. return bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0);
  6074. }
  6075. function getBodyRules(atRuleNode) {
  6076. var nodeRules = atRuleNode.rules;
  6077. if (hasFakeRuleset(atRuleNode)) {
  6078. return nodeRules[0].rules;
  6079. }
  6080. return nodeRules;
  6081. }
  6082. // it is still true that it is only one ruleset in array
  6083. // this is last such moment
  6084. // process childs
  6085. var originalRules = getBodyRules(atRuleNode);
  6086. atRuleNode.accept(this._visitor);
  6087. visitArgs.visitDeeper = false;
  6088. if (!this.utils.isEmpty(atRuleNode)) {
  6089. this._mergeRules(atRuleNode.rules[0].rules);
  6090. }
  6091. return this.utils.resolveVisibility(atRuleNode, originalRules);
  6092. },
  6093. visitAtRuleWithoutBody: function (atRuleNode, visitArgs) {
  6094. if (atRuleNode.blocksVisibility()) {
  6095. return;
  6096. }
  6097. if (atRuleNode.name === '@charset') {
  6098. // Only output the debug info together with subsequent @charset definitions
  6099. // a comment (or @media statement) before the actual @charset atrule would
  6100. // be considered illegal css as it has to be on the first line
  6101. if (this.charset) {
  6102. if (atRuleNode.debugInfo) {
  6103. var comment = new tree.Comment("/* " + atRuleNode.toCSS(this._context).replace(/\n/g, '') + " */\n");
  6104. comment.debugInfo = atRuleNode.debugInfo;
  6105. return this._visitor.visit(comment);
  6106. }
  6107. return;
  6108. }
  6109. this.charset = true;
  6110. }
  6111. return atRuleNode;
  6112. },
  6113. checkValidNodes: function (rules, isRoot) {
  6114. if (!rules) {
  6115. return;
  6116. }
  6117. for (var i_1 = 0; i_1 < rules.length; i_1++) {
  6118. var ruleNode = rules[i_1];
  6119. if (isRoot && ruleNode instanceof tree.Declaration && !ruleNode.variable) {
  6120. throw { message: 'Properties must be inside selector blocks. They cannot be in the root',
  6121. index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename };
  6122. }
  6123. if (ruleNode instanceof tree.Call) {
  6124. throw { message: "Function '" + ruleNode.name + "' is undefined",
  6125. index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename };
  6126. }
  6127. if (ruleNode.type && !ruleNode.allowRoot) {
  6128. throw { message: ruleNode.type + " node returned by a function is not valid here",
  6129. index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename };
  6130. }
  6131. }
  6132. },
  6133. visitRuleset: function (rulesetNode, visitArgs) {
  6134. // at this point rulesets are nested into each other
  6135. var rule;
  6136. var rulesets = [];
  6137. this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot);
  6138. if (!rulesetNode.root) {
  6139. // remove invisible paths
  6140. this._compileRulesetPaths(rulesetNode);
  6141. // remove rulesets from this ruleset body and compile them separately
  6142. var nodeRules = rulesetNode.rules;
  6143. var nodeRuleCnt = nodeRules ? nodeRules.length : 0;
  6144. for (var i_2 = 0; i_2 < nodeRuleCnt;) {
  6145. rule = nodeRules[i_2];
  6146. if (rule && rule.rules) {
  6147. // visit because we are moving them out from being a child
  6148. rulesets.push(this._visitor.visit(rule));
  6149. nodeRules.splice(i_2, 1);
  6150. nodeRuleCnt--;
  6151. continue;
  6152. }
  6153. i_2++;
  6154. }
  6155. // accept the visitor to remove rules and refactor itself
  6156. // then we can decide nogw whether we want it or not
  6157. // compile body
  6158. if (nodeRuleCnt > 0) {
  6159. rulesetNode.accept(this._visitor);
  6160. }
  6161. else {
  6162. rulesetNode.rules = null;
  6163. }
  6164. visitArgs.visitDeeper = false;
  6165. }
  6166. else { // if (! rulesetNode.root) {
  6167. rulesetNode.accept(this._visitor);
  6168. visitArgs.visitDeeper = false;
  6169. }
  6170. if (rulesetNode.rules) {
  6171. this._mergeRules(rulesetNode.rules);
  6172. this._removeDuplicateRules(rulesetNode.rules);
  6173. }
  6174. // now decide whether we keep the ruleset
  6175. if (this.utils.isVisibleRuleset(rulesetNode)) {
  6176. rulesetNode.ensureVisibility();
  6177. rulesets.splice(0, 0, rulesetNode);
  6178. }
  6179. if (rulesets.length === 1) {
  6180. return rulesets[0];
  6181. }
  6182. return rulesets;
  6183. },
  6184. _compileRulesetPaths: function (rulesetNode) {
  6185. if (rulesetNode.paths) {
  6186. rulesetNode.paths = rulesetNode.paths
  6187. .filter(function (p) {
  6188. var i;
  6189. if (p[0].elements[0].combinator.value === ' ') {
  6190. p[0].elements[0].combinator = new (tree.Combinator)('');
  6191. }
  6192. for (i = 0; i < p.length; i++) {
  6193. if (p[i].isVisible() && p[i].getIsOutput()) {
  6194. return true;
  6195. }
  6196. }
  6197. return false;
  6198. });
  6199. }
  6200. },
  6201. _removeDuplicateRules: function (rules) {
  6202. if (!rules) {
  6203. return;
  6204. }
  6205. // remove duplicates
  6206. var ruleCache = {};
  6207. var ruleList;
  6208. var rule;
  6209. var i;
  6210. for (i = rules.length - 1; i >= 0; i--) {
  6211. rule = rules[i];
  6212. if (rule instanceof tree.Declaration) {
  6213. if (!ruleCache[rule.name]) {
  6214. ruleCache[rule.name] = rule;
  6215. }
  6216. else {
  6217. ruleList = ruleCache[rule.name];
  6218. if (ruleList instanceof tree.Declaration) {
  6219. ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._context)];
  6220. }
  6221. var ruleCSS = rule.toCSS(this._context);
  6222. if (ruleList.indexOf(ruleCSS) !== -1) {
  6223. rules.splice(i, 1);
  6224. }
  6225. else {
  6226. ruleList.push(ruleCSS);
  6227. }
  6228. }
  6229. }
  6230. }
  6231. },
  6232. _mergeRules: function (rules) {
  6233. if (!rules) {
  6234. return;
  6235. }
  6236. var groups = {};
  6237. var groupsArr = [];
  6238. for (var i_3 = 0; i_3 < rules.length; i_3++) {
  6239. var rule = rules[i_3];
  6240. if (rule.merge) {
  6241. var key = rule.name;
  6242. groups[key] ? rules.splice(i_3--, 1) :
  6243. groupsArr.push(groups[key] = []);
  6244. groups[key].push(rule);
  6245. }
  6246. }
  6247. groupsArr.forEach(function (group) {
  6248. if (group.length > 0) {
  6249. var result_1 = group[0];
  6250. var space_1 = [];
  6251. var comma_1 = [new tree.Expression(space_1)];
  6252. group.forEach(function (rule) {
  6253. if ((rule.merge === '+') && (space_1.length > 0)) {
  6254. comma_1.push(new tree.Expression(space_1 = []));
  6255. }
  6256. space_1.push(rule.value);
  6257. result_1.important = result_1.important || rule.important;
  6258. });
  6259. result_1.value = new tree.Value(comma_1);
  6260. }
  6261. });
  6262. }
  6263. };
  6264. var visitors = {
  6265. Visitor: Visitor,
  6266. ImportVisitor: ImportVisitor,
  6267. MarkVisibleSelectorsVisitor: SetTreeVisibilityVisitor,
  6268. ExtendVisitor: ProcessExtendsVisitor,
  6269. JoinSelectorVisitor: JoinSelectorVisitor,
  6270. ToCSSVisitor: ToCSSVisitor
  6271. };
  6272. // Split the input into chunks.
  6273. var chunker = (function (input, fail) {
  6274. var len = input.length;
  6275. var level = 0;
  6276. var parenLevel = 0;
  6277. var lastOpening;
  6278. var lastOpeningParen;
  6279. var lastMultiComment;
  6280. var lastMultiCommentEndBrace;
  6281. var chunks = [];
  6282. var emitFrom = 0;
  6283. var chunkerCurrentIndex;
  6284. var currentChunkStartIndex;
  6285. var cc;
  6286. var cc2;
  6287. var matched;
  6288. function emitChunk(force) {
  6289. var len = chunkerCurrentIndex - emitFrom;
  6290. if (((len < 512) && !force) || !len) {
  6291. return;
  6292. }
  6293. chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1));
  6294. emitFrom = chunkerCurrentIndex + 1;
  6295. }
  6296. for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
  6297. cc = input.charCodeAt(chunkerCurrentIndex);
  6298. if (((cc >= 97) && (cc <= 122)) || (cc < 34)) {
  6299. // a-z or whitespace
  6300. continue;
  6301. }
  6302. switch (cc) {
  6303. case 40: // (
  6304. parenLevel++;
  6305. lastOpeningParen = chunkerCurrentIndex;
  6306. continue;
  6307. case 41: // )
  6308. if (--parenLevel < 0) {
  6309. return fail('missing opening `(`', chunkerCurrentIndex);
  6310. }
  6311. continue;
  6312. case 59: // ;
  6313. if (!parenLevel) {
  6314. emitChunk();
  6315. }
  6316. continue;
  6317. case 123: // {
  6318. level++;
  6319. lastOpening = chunkerCurrentIndex;
  6320. continue;
  6321. case 125: // }
  6322. if (--level < 0) {
  6323. return fail('missing opening `{`', chunkerCurrentIndex);
  6324. }
  6325. if (!level && !parenLevel) {
  6326. emitChunk();
  6327. }
  6328. continue;
  6329. case 92: // \
  6330. if (chunkerCurrentIndex < len - 1) {
  6331. chunkerCurrentIndex++;
  6332. continue;
  6333. }
  6334. return fail('unescaped `\\`', chunkerCurrentIndex);
  6335. case 34:
  6336. case 39:
  6337. case 96: // ", ' and `
  6338. matched = 0;
  6339. currentChunkStartIndex = chunkerCurrentIndex;
  6340. for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
  6341. cc2 = input.charCodeAt(chunkerCurrentIndex);
  6342. if (cc2 > 96) {
  6343. continue;
  6344. }
  6345. if (cc2 == cc) {
  6346. matched = 1;
  6347. break;
  6348. }
  6349. if (cc2 == 92) { // \
  6350. if (chunkerCurrentIndex == len - 1) {
  6351. return fail('unescaped `\\`', chunkerCurrentIndex);
  6352. }
  6353. chunkerCurrentIndex++;
  6354. }
  6355. }
  6356. if (matched) {
  6357. continue;
  6358. }
  6359. return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex);
  6360. case 47: // /, check for comment
  6361. if (parenLevel || (chunkerCurrentIndex == len - 1)) {
  6362. continue;
  6363. }
  6364. cc2 = input.charCodeAt(chunkerCurrentIndex + 1);
  6365. if (cc2 == 47) {
  6366. // //, find lnfeed
  6367. for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
  6368. cc2 = input.charCodeAt(chunkerCurrentIndex);
  6369. if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) {
  6370. break;
  6371. }
  6372. }
  6373. }
  6374. else if (cc2 == 42) {
  6375. // /*, find */
  6376. lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex;
  6377. for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) {
  6378. cc2 = input.charCodeAt(chunkerCurrentIndex);
  6379. if (cc2 == 125) {
  6380. lastMultiCommentEndBrace = chunkerCurrentIndex;
  6381. }
  6382. if (cc2 != 42) {
  6383. continue;
  6384. }
  6385. if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) {
  6386. break;
  6387. }
  6388. }
  6389. if (chunkerCurrentIndex == len - 1) {
  6390. return fail('missing closing `*/`', currentChunkStartIndex);
  6391. }
  6392. chunkerCurrentIndex++;
  6393. }
  6394. continue;
  6395. case 42: // *, check for unmatched */
  6396. if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) {
  6397. return fail('unmatched `/*`', chunkerCurrentIndex);
  6398. }
  6399. continue;
  6400. }
  6401. }
  6402. if (level !== 0) {
  6403. if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) {
  6404. return fail('missing closing `}` or `*/`', lastOpening);
  6405. }
  6406. else {
  6407. return fail('missing closing `}`', lastOpening);
  6408. }
  6409. }
  6410. else if (parenLevel !== 0) {
  6411. return fail('missing closing `)`', lastOpeningParen);
  6412. }
  6413. emitChunk(true);
  6414. return chunks;
  6415. });
  6416. var getParserInput = (function () {
  6417. var // Less input string
  6418. input;
  6419. var // current chunk
  6420. j;
  6421. var // holds state for backtracking
  6422. saveStack = [];
  6423. var // furthest index the parser has gone to
  6424. furthest;
  6425. var // if this is furthest we got to, this is the probably cause
  6426. furthestPossibleErrorMessage;
  6427. var // chunkified input
  6428. chunks;
  6429. var // current chunk
  6430. current;
  6431. var // index of current chunk, in `input`
  6432. currentPos;
  6433. var parserInput = {};
  6434. var CHARCODE_SPACE = 32;
  6435. var CHARCODE_TAB = 9;
  6436. var CHARCODE_LF = 10;
  6437. var CHARCODE_CR = 13;
  6438. var CHARCODE_PLUS = 43;
  6439. var CHARCODE_COMMA = 44;
  6440. var CHARCODE_FORWARD_SLASH = 47;
  6441. var CHARCODE_9 = 57;
  6442. function skipWhitespace(length) {
  6443. var oldi = parserInput.i;
  6444. var oldj = j;
  6445. var curr = parserInput.i - currentPos;
  6446. var endIndex = parserInput.i + current.length - curr;
  6447. var mem = (parserInput.i += length);
  6448. var inp = input;
  6449. var c;
  6450. var nextChar;
  6451. var comment;
  6452. for (; parserInput.i < endIndex; parserInput.i++) {
  6453. c = inp.charCodeAt(parserInput.i);
  6454. if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) {
  6455. nextChar = inp.charAt(parserInput.i + 1);
  6456. if (nextChar === '/') {
  6457. comment = { index: parserInput.i, isLineComment: true };
  6458. var nextNewLine = inp.indexOf('\n', parserInput.i + 2);
  6459. if (nextNewLine < 0) {
  6460. nextNewLine = endIndex;
  6461. }
  6462. parserInput.i = nextNewLine;
  6463. comment.text = inp.substr(comment.index, parserInput.i - comment.index);
  6464. parserInput.commentStore.push(comment);
  6465. continue;
  6466. }
  6467. else if (nextChar === '*') {
  6468. var nextStarSlash = inp.indexOf('*/', parserInput.i + 2);
  6469. if (nextStarSlash >= 0) {
  6470. comment = {
  6471. index: parserInput.i,
  6472. text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i),
  6473. isLineComment: false
  6474. };
  6475. parserInput.i += comment.text.length - 1;
  6476. parserInput.commentStore.push(comment);
  6477. continue;
  6478. }
  6479. }
  6480. break;
  6481. }
  6482. if ((c !== CHARCODE_SPACE) && (c !== CHARCODE_LF) && (c !== CHARCODE_TAB) && (c !== CHARCODE_CR)) {
  6483. break;
  6484. }
  6485. }
  6486. current = current.slice(length + parserInput.i - mem + curr);
  6487. currentPos = parserInput.i;
  6488. if (!current.length) {
  6489. if (j < chunks.length - 1) {
  6490. current = chunks[++j];
  6491. skipWhitespace(0); // skip space at the beginning of a chunk
  6492. return true; // things changed
  6493. }
  6494. parserInput.finished = true;
  6495. }
  6496. return oldi !== parserInput.i || oldj !== j;
  6497. }
  6498. parserInput.save = function () {
  6499. currentPos = parserInput.i;
  6500. saveStack.push({ current: current, i: parserInput.i, j: j });
  6501. };
  6502. parserInput.restore = function (possibleErrorMessage) {
  6503. if (parserInput.i > furthest || (parserInput.i === furthest && possibleErrorMessage && !furthestPossibleErrorMessage)) {
  6504. furthest = parserInput.i;
  6505. furthestPossibleErrorMessage = possibleErrorMessage;
  6506. }
  6507. var state = saveStack.pop();
  6508. current = state.current;
  6509. currentPos = parserInput.i = state.i;
  6510. j = state.j;
  6511. };
  6512. parserInput.forget = function () {
  6513. saveStack.pop();
  6514. };
  6515. parserInput.isWhitespace = function (offset) {
  6516. var pos = parserInput.i + (offset || 0);
  6517. var code = input.charCodeAt(pos);
  6518. return (code === CHARCODE_SPACE || code === CHARCODE_CR || code === CHARCODE_TAB || code === CHARCODE_LF);
  6519. };
  6520. // Specialization of $(tok)
  6521. parserInput.$re = function (tok) {
  6522. if (parserInput.i > currentPos) {
  6523. current = current.slice(parserInput.i - currentPos);
  6524. currentPos = parserInput.i;
  6525. }
  6526. var m = tok.exec(current);
  6527. if (!m) {
  6528. return null;
  6529. }
  6530. skipWhitespace(m[0].length);
  6531. if (typeof m === 'string') {
  6532. return m;
  6533. }
  6534. return m.length === 1 ? m[0] : m;
  6535. };
  6536. parserInput.$char = function (tok) {
  6537. if (input.charAt(parserInput.i) !== tok) {
  6538. return null;
  6539. }
  6540. skipWhitespace(1);
  6541. return tok;
  6542. };
  6543. parserInput.$str = function (tok) {
  6544. var tokLength = tok.length;
  6545. // https://jsperf.com/string-startswith/21
  6546. for (var i_1 = 0; i_1 < tokLength; i_1++) {
  6547. if (input.charAt(parserInput.i + i_1) !== tok.charAt(i_1)) {
  6548. return null;
  6549. }
  6550. }
  6551. skipWhitespace(tokLength);
  6552. return tok;
  6553. };
  6554. parserInput.$quoted = function (loc) {
  6555. var pos = loc || parserInput.i;
  6556. var startChar = input.charAt(pos);
  6557. if (startChar !== '\'' && startChar !== '"') {
  6558. return;
  6559. }
  6560. var length = input.length;
  6561. var currentPosition = pos;
  6562. for (var i_2 = 1; i_2 + currentPosition < length; i_2++) {
  6563. var nextChar = input.charAt(i_2 + currentPosition);
  6564. switch (nextChar) {
  6565. case '\\':
  6566. i_2++;
  6567. continue;
  6568. case '\r':
  6569. case '\n':
  6570. break;
  6571. case startChar:
  6572. var str = input.substr(currentPosition, i_2 + 1);
  6573. if (!loc && loc !== 0) {
  6574. skipWhitespace(i_2 + 1);
  6575. return str;
  6576. }
  6577. return [startChar, str];
  6578. }
  6579. }
  6580. return null;
  6581. };
  6582. /**
  6583. * Permissive parsing. Ignores everything except matching {} [] () and quotes
  6584. * until matching token (outside of blocks)
  6585. */
  6586. parserInput.$parseUntil = function (tok) {
  6587. var quote = '';
  6588. var returnVal = null;
  6589. var inComment = false;
  6590. var blockDepth = 0;
  6591. var blockStack = [];
  6592. var parseGroups = [];
  6593. var length = input.length;
  6594. var startPos = parserInput.i;
  6595. var lastPos = parserInput.i;
  6596. var i = parserInput.i;
  6597. var loop = true;
  6598. var testChar;
  6599. if (typeof tok === 'string') {
  6600. testChar = function (char) { return char === tok; };
  6601. }
  6602. else {
  6603. testChar = function (char) { return tok.test(char); };
  6604. }
  6605. do {
  6606. var nextChar = input.charAt(i);
  6607. if (blockDepth === 0 && testChar(nextChar)) {
  6608. returnVal = input.substr(lastPos, i - lastPos);
  6609. if (returnVal) {
  6610. parseGroups.push(returnVal);
  6611. }
  6612. else {
  6613. parseGroups.push(' ');
  6614. }
  6615. returnVal = parseGroups;
  6616. skipWhitespace(i - startPos);
  6617. loop = false;
  6618. }
  6619. else {
  6620. if (inComment) {
  6621. if (nextChar === '*' &&
  6622. input.charAt(i + 1) === '/') {
  6623. i++;
  6624. blockDepth--;
  6625. inComment = false;
  6626. }
  6627. i++;
  6628. continue;
  6629. }
  6630. switch (nextChar) {
  6631. case '\\':
  6632. i++;
  6633. nextChar = input.charAt(i);
  6634. parseGroups.push(input.substr(lastPos, i - lastPos + 1));
  6635. lastPos = i + 1;
  6636. break;
  6637. case '/':
  6638. if (input.charAt(i + 1) === '*') {
  6639. i++;
  6640. inComment = true;
  6641. blockDepth++;
  6642. }
  6643. break;
  6644. case '\'':
  6645. case '"':
  6646. quote = parserInput.$quoted(i);
  6647. if (quote) {
  6648. parseGroups.push(input.substr(lastPos, i - lastPos), quote);
  6649. i += quote[1].length - 1;
  6650. lastPos = i + 1;
  6651. }
  6652. else {
  6653. skipWhitespace(i - startPos);
  6654. returnVal = nextChar;
  6655. loop = false;
  6656. }
  6657. break;
  6658. case '{':
  6659. blockStack.push('}');
  6660. blockDepth++;
  6661. break;
  6662. case '(':
  6663. blockStack.push(')');
  6664. blockDepth++;
  6665. break;
  6666. case '[':
  6667. blockStack.push(']');
  6668. blockDepth++;
  6669. break;
  6670. case '}':
  6671. case ')':
  6672. case ']':
  6673. var expected = blockStack.pop();
  6674. if (nextChar === expected) {
  6675. blockDepth--;
  6676. }
  6677. else {
  6678. // move the parser to the error and return expected
  6679. skipWhitespace(i - startPos);
  6680. returnVal = expected;
  6681. loop = false;
  6682. }
  6683. }
  6684. i++;
  6685. if (i > length) {
  6686. loop = false;
  6687. }
  6688. }
  6689. } while (loop);
  6690. return returnVal ? returnVal : null;
  6691. };
  6692. parserInput.autoCommentAbsorb = true;
  6693. parserInput.commentStore = [];
  6694. parserInput.finished = false;
  6695. // Same as $(), but don't change the state of the parser,
  6696. // just return the match.
  6697. parserInput.peek = function (tok) {
  6698. if (typeof tok === 'string') {
  6699. // https://jsperf.com/string-startswith/21
  6700. for (var i_3 = 0; i_3 < tok.length; i_3++) {
  6701. if (input.charAt(parserInput.i + i_3) !== tok.charAt(i_3)) {
  6702. return false;
  6703. }
  6704. }
  6705. return true;
  6706. }
  6707. else {
  6708. return tok.test(current);
  6709. }
  6710. };
  6711. // Specialization of peek()
  6712. // TODO remove or change some currentChar calls to peekChar
  6713. parserInput.peekChar = function (tok) { return input.charAt(parserInput.i) === tok; };
  6714. parserInput.currentChar = function () { return input.charAt(parserInput.i); };
  6715. parserInput.prevChar = function () { return input.charAt(parserInput.i - 1); };
  6716. parserInput.getInput = function () { return input; };
  6717. parserInput.peekNotNumeric = function () {
  6718. var c = input.charCodeAt(parserInput.i);
  6719. // Is the first char of the dimension 0-9, '.', '+' or '-'
  6720. return (c > CHARCODE_9 || c < CHARCODE_PLUS) || c === CHARCODE_FORWARD_SLASH || c === CHARCODE_COMMA;
  6721. };
  6722. parserInput.start = function (str, chunkInput, failFunction) {
  6723. input = str;
  6724. parserInput.i = j = currentPos = furthest = 0;
  6725. // chunking apparently makes things quicker (but my tests indicate
  6726. // it might actually make things slower in node at least)
  6727. // and it is a non-perfect parse - it can't recognise
  6728. // unquoted urls, meaning it can't distinguish comments
  6729. // meaning comments with quotes or {}() in them get 'counted'
  6730. // and then lead to parse errors.
  6731. // In addition if the chunking chunks in the wrong place we might
  6732. // not be able to parse a parser statement in one go
  6733. // this is officially deprecated but can be switched on via an option
  6734. // in the case it causes too much performance issues.
  6735. if (chunkInput) {
  6736. chunks = chunker(str, failFunction);
  6737. }
  6738. else {
  6739. chunks = [str];
  6740. }
  6741. current = chunks[0];
  6742. skipWhitespace(0);
  6743. };
  6744. parserInput.end = function () {
  6745. var message;
  6746. var isFinished = parserInput.i >= input.length;
  6747. if (parserInput.i < furthest) {
  6748. message = furthestPossibleErrorMessage;
  6749. parserInput.i = furthest;
  6750. }
  6751. return {
  6752. isFinished: isFinished,
  6753. furthest: parserInput.i,
  6754. furthestPossibleErrorMessage: message,
  6755. furthestReachedEnd: parserInput.i >= input.length - 1,
  6756. furthestChar: input[parserInput.i]
  6757. };
  6758. };
  6759. return parserInput;
  6760. });
  6761. //
  6762. // less.js - parser
  6763. //
  6764. // A relatively straight-forward predictive parser.
  6765. // There is no tokenization/lexing stage, the input is parsed
  6766. // in one sweep.
  6767. //
  6768. // To make the parser fast enough to run in the browser, several
  6769. // optimization had to be made:
  6770. //
  6771. // - Matching and slicing on a huge input is often cause of slowdowns.
  6772. // The solution is to chunkify the input into smaller strings.
  6773. // The chunks are stored in the `chunks` var,
  6774. // `j` holds the current chunk index, and `currentPos` holds
  6775. // the index of the current chunk in relation to `input`.
  6776. // This gives us an almost 4x speed-up.
  6777. //
  6778. // - In many cases, we don't need to match individual tokens;
  6779. // for example, if a value doesn't hold any variables, operations
  6780. // or dynamic references, the parser can effectively 'skip' it,
  6781. // treating it as a literal.
  6782. // An example would be '1px solid #000' - which evaluates to itself,
  6783. // we don't need to know what the individual components are.
  6784. // The drawback, of course is that you don't get the benefits of
  6785. // syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
  6786. // and a smaller speed-up in the code-gen.
  6787. //
  6788. //
  6789. // Token matching is done with the `$` function, which either takes
  6790. // a terminal string or regexp, or a non-terminal function to call.
  6791. // It also takes care of moving all the indices forwards.
  6792. //
  6793. var Parser = function Parser(context, imports, fileInfo) {
  6794. var parsers;
  6795. var parserInput = getParserInput();
  6796. function error(msg, type) {
  6797. throw new LessError({
  6798. index: parserInput.i,
  6799. filename: fileInfo.filename,
  6800. type: type || 'Syntax',
  6801. message: msg
  6802. }, imports);
  6803. }
  6804. function expect(arg, msg) {
  6805. // some older browsers return typeof 'function' for RegExp
  6806. var result = (arg instanceof Function) ? arg.call(parsers) : parserInput.$re(arg);
  6807. if (result) {
  6808. return result;
  6809. }
  6810. error(msg || (typeof arg === 'string'
  6811. ? "expected '" + arg + "' got '" + parserInput.currentChar() + "'"
  6812. : 'unexpected token'));
  6813. }
  6814. // Specialization of expect()
  6815. function expectChar(arg, msg) {
  6816. if (parserInput.$char(arg)) {
  6817. return arg;
  6818. }
  6819. error(msg || "expected '" + arg + "' got '" + parserInput.currentChar() + "'");
  6820. }
  6821. function getDebugInfo(index) {
  6822. var filename = fileInfo.filename;
  6823. return {
  6824. lineNumber: getLocation(index, parserInput.getInput()).line + 1,
  6825. fileName: filename
  6826. };
  6827. }
  6828. /**
  6829. * Used after initial parsing to create nodes on the fly
  6830. *
  6831. * @param {String} str - string to parse
  6832. * @param {Array} parseList - array of parsers to run input through e.g. ["value", "important"]
  6833. * @param {Number} currentIndex - start number to begin indexing
  6834. * @param {Object} fileInfo - fileInfo to attach to created nodes
  6835. */
  6836. function parseNode(str, parseList, currentIndex, fileInfo, callback) {
  6837. var result;
  6838. var returnNodes = [];
  6839. var parser = parserInput;
  6840. try {
  6841. parser.start(str, false, function fail(msg, index) {
  6842. callback({
  6843. message: msg,
  6844. index: index + currentIndex
  6845. });
  6846. });
  6847. for (var x = 0, p = void 0, i_1; (p = parseList[x]); x++) {
  6848. i_1 = parser.i;
  6849. result = parsers[p]();
  6850. if (result) {
  6851. try {
  6852. result._index = i_1 + currentIndex;
  6853. result._fileInfo = fileInfo;
  6854. }
  6855. catch (e) { }
  6856. returnNodes.push(result);
  6857. }
  6858. else {
  6859. returnNodes.push(null);
  6860. }
  6861. }
  6862. var endInfo = parser.end();
  6863. if (endInfo.isFinished) {
  6864. callback(null, returnNodes);
  6865. }
  6866. else {
  6867. callback(true, null);
  6868. }
  6869. }
  6870. catch (e) {
  6871. throw new LessError({
  6872. index: e.index + currentIndex,
  6873. message: e.message
  6874. }, imports, fileInfo.filename);
  6875. }
  6876. }
  6877. //
  6878. // The Parser
  6879. //
  6880. return {
  6881. parserInput: parserInput,
  6882. imports: imports,
  6883. fileInfo: fileInfo,
  6884. parseNode: parseNode,
  6885. //
  6886. // Parse an input string into an abstract syntax tree,
  6887. // @param str A string containing 'less' markup
  6888. // @param callback call `callback` when done.
  6889. // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply
  6890. //
  6891. parse: function (str, callback, additionalData) {
  6892. var root;
  6893. var error = null;
  6894. var globalVars;
  6895. var modifyVars;
  6896. var ignored;
  6897. var preText = '';
  6898. globalVars = (additionalData && additionalData.globalVars) ? Parser.serializeVars(additionalData.globalVars) + "\n" : '';
  6899. modifyVars = (additionalData && additionalData.modifyVars) ? "\n" + Parser.serializeVars(additionalData.modifyVars) : '';
  6900. if (context.pluginManager) {
  6901. var preProcessors = context.pluginManager.getPreProcessors();
  6902. for (var i_2 = 0; i_2 < preProcessors.length; i_2++) {
  6903. str = preProcessors[i_2].process(str, { context: context, imports: imports, fileInfo: fileInfo });
  6904. }
  6905. }
  6906. if (globalVars || (additionalData && additionalData.banner)) {
  6907. preText = ((additionalData && additionalData.banner) ? additionalData.banner : '') + globalVars;
  6908. ignored = imports.contentsIgnoredChars;
  6909. ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0;
  6910. ignored[fileInfo.filename] += preText.length;
  6911. }
  6912. str = str.replace(/\r\n?/g, '\n');
  6913. // Remove potential UTF Byte Order Mark
  6914. str = preText + str.replace(/^\uFEFF/, '') + modifyVars;
  6915. imports.contents[fileInfo.filename] = str;
  6916. // Start with the primary rule.
  6917. // The whole syntax tree is held under a Ruleset node,
  6918. // with the `root` property set to true, so no `{}` are
  6919. // output. The callback is called when the input is parsed.
  6920. try {
  6921. parserInput.start(str, context.chunkInput, function fail(msg, index) {
  6922. throw new LessError({
  6923. index: index,
  6924. type: 'Parse',
  6925. message: msg,
  6926. filename: fileInfo.filename
  6927. }, imports);
  6928. });
  6929. tree.Node.prototype.parse = this;
  6930. root = new tree.Ruleset(null, this.parsers.primary());
  6931. tree.Node.prototype.rootNode = root;
  6932. root.root = true;
  6933. root.firstRoot = true;
  6934. root.functionRegistry = functionRegistry.inherit();
  6935. }
  6936. catch (e) {
  6937. return callback(new LessError(e, imports, fileInfo.filename));
  6938. }
  6939. // If `i` is smaller than the `input.length - 1`,
  6940. // it means the parser wasn't able to parse the whole
  6941. // string, so we've got a parsing error.
  6942. //
  6943. // We try to extract a \n delimited string,
  6944. // showing the line where the parse error occurred.
  6945. // We split it up into two parts (the part which parsed,
  6946. // and the part which didn't), so we can color them differently.
  6947. var endInfo = parserInput.end();
  6948. if (!endInfo.isFinished) {
  6949. var message = endInfo.furthestPossibleErrorMessage;
  6950. if (!message) {
  6951. message = 'Unrecognised input';
  6952. if (endInfo.furthestChar === '}') {
  6953. message += '. Possibly missing opening \'{\'';
  6954. }
  6955. else if (endInfo.furthestChar === ')') {
  6956. message += '. Possibly missing opening \'(\'';
  6957. }
  6958. else if (endInfo.furthestReachedEnd) {
  6959. message += '. Possibly missing something';
  6960. }
  6961. }
  6962. error = new LessError({
  6963. type: 'Parse',
  6964. message: message,
  6965. index: endInfo.furthest,
  6966. filename: fileInfo.filename
  6967. }, imports);
  6968. }
  6969. var finish = function (e) {
  6970. e = error || e || imports.error;
  6971. if (e) {
  6972. if (!(e instanceof LessError)) {
  6973. e = new LessError(e, imports, fileInfo.filename);
  6974. }
  6975. return callback(e);
  6976. }
  6977. else {
  6978. return callback(null, root);
  6979. }
  6980. };
  6981. if (context.processImports !== false) {
  6982. new visitors.ImportVisitor(imports, finish)
  6983. .run(root);
  6984. }
  6985. else {
  6986. return finish();
  6987. }
  6988. },
  6989. //
  6990. // Here in, the parsing rules/functions
  6991. //
  6992. // The basic structure of the syntax tree generated is as follows:
  6993. //
  6994. // Ruleset -> Declaration -> Value -> Expression -> Entity
  6995. //
  6996. // Here's some Less code:
  6997. //
  6998. // .class {
  6999. // color: #fff;
  7000. // border: 1px solid #000;
  7001. // width: @w + 4px;
  7002. // > .child {...}
  7003. // }
  7004. //
  7005. // And here's what the parse tree might look like:
  7006. //
  7007. // Ruleset (Selector '.class', [
  7008. // Declaration ("color", Value ([Expression [Color #fff]]))
  7009. // Declaration ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
  7010. // Declaration ("width", Value ([Expression [Operation " + " [Variable "@w"][Dimension 4px]]]))
  7011. // Ruleset (Selector [Element '>', '.child'], [...])
  7012. // ])
  7013. //
  7014. // In general, most rules will try to parse a token with the `$re()` function, and if the return
  7015. // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
  7016. // first, before parsing, that's when we use `peek()`.
  7017. //
  7018. parsers: parsers = {
  7019. //
  7020. // The `primary` rule is the *entry* and *exit* point of the parser.
  7021. // The rules here can appear at any level of the parse tree.
  7022. //
  7023. // The recursive nature of the grammar is an interplay between the `block`
  7024. // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
  7025. // as represented by this simplified grammar:
  7026. //
  7027. // primary → (ruleset | declaration)+
  7028. // ruleset → selector+ block
  7029. // block → '{' primary '}'
  7030. //
  7031. // Only at one point is the primary rule not called from the
  7032. // block rule: at the root level.
  7033. //
  7034. primary: function () {
  7035. var mixin = this.mixin;
  7036. var root = [];
  7037. var node;
  7038. while (true) {
  7039. while (true) {
  7040. node = this.comment();
  7041. if (!node) {
  7042. break;
  7043. }
  7044. root.push(node);
  7045. }
  7046. // always process comments before deciding if finished
  7047. if (parserInput.finished) {
  7048. break;
  7049. }
  7050. if (parserInput.peek('}')) {
  7051. break;
  7052. }
  7053. node = this.extendRule();
  7054. if (node) {
  7055. root = root.concat(node);
  7056. continue;
  7057. }
  7058. node = mixin.definition() || this.declaration() || mixin.call(false, false) ||
  7059. this.ruleset() || this.variableCall() || this.entities.call() || this.atrule();
  7060. if (node) {
  7061. root.push(node);
  7062. }
  7063. else {
  7064. var foundSemiColon = false;
  7065. while (parserInput.$char(';')) {
  7066. foundSemiColon = true;
  7067. }
  7068. if (!foundSemiColon) {
  7069. break;
  7070. }
  7071. }
  7072. }
  7073. return root;
  7074. },
  7075. // comments are collected by the main parsing mechanism and then assigned to nodes
  7076. // where the current structure allows it
  7077. comment: function () {
  7078. if (parserInput.commentStore.length) {
  7079. var comment = parserInput.commentStore.shift();
  7080. return new (tree.Comment)(comment.text, comment.isLineComment, comment.index, fileInfo);
  7081. }
  7082. },
  7083. //
  7084. // Entities are tokens which can be found inside an Expression
  7085. //
  7086. entities: {
  7087. mixinLookup: function () {
  7088. return parsers.mixin.call(true, true);
  7089. },
  7090. //
  7091. // A string, which supports escaping " and '
  7092. //
  7093. // "milky way" 'he\'s the one!'
  7094. //
  7095. quoted: function (forceEscaped) {
  7096. var str;
  7097. var index = parserInput.i;
  7098. var isEscaped = false;
  7099. parserInput.save();
  7100. if (parserInput.$char('~')) {
  7101. isEscaped = true;
  7102. }
  7103. else if (forceEscaped) {
  7104. parserInput.restore();
  7105. return;
  7106. }
  7107. str = parserInput.$quoted();
  7108. if (!str) {
  7109. parserInput.restore();
  7110. return;
  7111. }
  7112. parserInput.forget();
  7113. return new (tree.Quoted)(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index, fileInfo);
  7114. },
  7115. //
  7116. // A catch-all word, such as:
  7117. //
  7118. // black border-collapse
  7119. //
  7120. keyword: function () {
  7121. var k = parserInput.$char('%') || parserInput.$re(/^\[?(?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+\]?/);
  7122. if (k) {
  7123. return tree.Color.fromKeyword(k) || new (tree.Keyword)(k);
  7124. }
  7125. },
  7126. //
  7127. // A function call
  7128. //
  7129. // rgb(255, 0, 255)
  7130. //
  7131. // The arguments are parsed with the `entities.arguments` parser.
  7132. //
  7133. call: function () {
  7134. var name;
  7135. var args;
  7136. var func;
  7137. var index = parserInput.i;
  7138. // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18
  7139. if (parserInput.peek(/^url\(/i)) {
  7140. return;
  7141. }
  7142. parserInput.save();
  7143. name = parserInput.$re(/^([\w-]+|%|progid:[\w\.]+)\(/);
  7144. if (!name) {
  7145. parserInput.forget();
  7146. return;
  7147. }
  7148. name = name[1];
  7149. func = this.customFuncCall(name);
  7150. if (func) {
  7151. args = func.parse();
  7152. if (args && func.stop) {
  7153. parserInput.forget();
  7154. return args;
  7155. }
  7156. }
  7157. args = this.arguments(args);
  7158. if (!parserInput.$char(')')) {
  7159. parserInput.restore('Could not parse call arguments or missing \')\'');
  7160. return;
  7161. }
  7162. parserInput.forget();
  7163. return new (tree.Call)(name, args, index, fileInfo);
  7164. },
  7165. //
  7166. // Parsing rules for functions with non-standard args, e.g.:
  7167. //
  7168. // boolean(not(2 > 1))
  7169. //
  7170. // This is a quick prototype, to be modified/improved when
  7171. // more custom-parsed funcs come (e.g. `selector(...)`)
  7172. //
  7173. customFuncCall: function (name) {
  7174. /* Ideally the table is to be moved out of here for faster perf.,
  7175. but it's quite tricky since it relies on all these `parsers`
  7176. and `expect` available only here */
  7177. return {
  7178. alpha: f(parsers.ieAlpha, true),
  7179. boolean: f(condition),
  7180. 'if': f(condition)
  7181. }[name.toLowerCase()];
  7182. function f(parse, stop) {
  7183. return {
  7184. parse: parse,
  7185. stop: stop // when true - stop after parse() and return its result,
  7186. // otherwise continue for plain args
  7187. };
  7188. }
  7189. function condition() {
  7190. return [expect(parsers.condition, 'expected condition')];
  7191. }
  7192. },
  7193. arguments: function (prevArgs) {
  7194. var argsComma = prevArgs || [];
  7195. var argsSemiColon = [];
  7196. var isSemiColonSeparated;
  7197. var value;
  7198. parserInput.save();
  7199. while (true) {
  7200. if (prevArgs) {
  7201. prevArgs = false;
  7202. }
  7203. else {
  7204. value = parsers.detachedRuleset() || this.assignment() || parsers.expression();
  7205. if (!value) {
  7206. break;
  7207. }
  7208. if (value.value && value.value.length == 1) {
  7209. value = value.value[0];
  7210. }
  7211. argsComma.push(value);
  7212. }
  7213. if (parserInput.$char(',')) {
  7214. continue;
  7215. }
  7216. if (parserInput.$char(';') || isSemiColonSeparated) {
  7217. isSemiColonSeparated = true;
  7218. value = (argsComma.length < 1) ? argsComma[0]
  7219. : new tree.Value(argsComma);
  7220. argsSemiColon.push(value);
  7221. argsComma = [];
  7222. }
  7223. }
  7224. parserInput.forget();
  7225. return isSemiColonSeparated ? argsSemiColon : argsComma;
  7226. },
  7227. literal: function () {
  7228. return this.dimension() ||
  7229. this.color() ||
  7230. this.quoted() ||
  7231. this.unicodeDescriptor();
  7232. },
  7233. // Assignments are argument entities for calls.
  7234. // They are present in ie filter properties as shown below.
  7235. //
  7236. // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
  7237. //
  7238. assignment: function () {
  7239. var key;
  7240. var value;
  7241. parserInput.save();
  7242. key = parserInput.$re(/^\w+(?=\s?=)/i);
  7243. if (!key) {
  7244. parserInput.restore();
  7245. return;
  7246. }
  7247. if (!parserInput.$char('=')) {
  7248. parserInput.restore();
  7249. return;
  7250. }
  7251. value = parsers.entity();
  7252. if (value) {
  7253. parserInput.forget();
  7254. return new (tree.Assignment)(key, value);
  7255. }
  7256. else {
  7257. parserInput.restore();
  7258. }
  7259. },
  7260. //
  7261. // Parse url() tokens
  7262. //
  7263. // We use a specific rule for urls, because they don't really behave like
  7264. // standard function calls. The difference is that the argument doesn't have
  7265. // to be enclosed within a string, so it can't be parsed as an Expression.
  7266. //
  7267. url: function () {
  7268. var value;
  7269. var index = parserInput.i;
  7270. parserInput.autoCommentAbsorb = false;
  7271. if (!parserInput.$str('url(')) {
  7272. parserInput.autoCommentAbsorb = true;
  7273. return;
  7274. }
  7275. value = this.quoted() || this.variable() || this.property() ||
  7276. parserInput.$re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || '';
  7277. parserInput.autoCommentAbsorb = true;
  7278. expectChar(')');
  7279. return new (tree.URL)((value.value != null ||
  7280. value instanceof tree.Variable ||
  7281. value instanceof tree.Property) ?
  7282. value : new (tree.Anonymous)(value, index), index, fileInfo);
  7283. },
  7284. //
  7285. // A Variable entity, such as `@fink`, in
  7286. //
  7287. // width: @fink + 2px
  7288. //
  7289. // We use a different parser for variable definitions,
  7290. // see `parsers.variable`.
  7291. //
  7292. variable: function () {
  7293. var ch;
  7294. var name;
  7295. var index = parserInput.i;
  7296. parserInput.save();
  7297. if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^@@?[\w-]+/))) {
  7298. ch = parserInput.currentChar();
  7299. if (ch === '(' || ch === '[' && !parserInput.prevChar().match(/^\s/)) {
  7300. // this may be a VariableCall lookup
  7301. var result = parsers.variableCall(name);
  7302. if (result) {
  7303. parserInput.forget();
  7304. return result;
  7305. }
  7306. }
  7307. parserInput.forget();
  7308. return new (tree.Variable)(name, index, fileInfo);
  7309. }
  7310. parserInput.restore();
  7311. },
  7312. // A variable entity using the protective {} e.g. @{var}
  7313. variableCurly: function () {
  7314. var curly;
  7315. var index = parserInput.i;
  7316. if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\{([\w-]+)\}/))) {
  7317. return new (tree.Variable)("@" + curly[1], index, fileInfo);
  7318. }
  7319. },
  7320. //
  7321. // A Property accessor, such as `$color`, in
  7322. //
  7323. // background-color: $color
  7324. //
  7325. property: function () {
  7326. var name;
  7327. var index = parserInput.i;
  7328. if (parserInput.currentChar() === '$' && (name = parserInput.$re(/^\$[\w-]+/))) {
  7329. return new (tree.Property)(name, index, fileInfo);
  7330. }
  7331. },
  7332. // A property entity useing the protective {} e.g. ${prop}
  7333. propertyCurly: function () {
  7334. var curly;
  7335. var index = parserInput.i;
  7336. if (parserInput.currentChar() === '$' && (curly = parserInput.$re(/^\$\{([\w-]+)\}/))) {
  7337. return new (tree.Property)("$" + curly[1], index, fileInfo);
  7338. }
  7339. },
  7340. //
  7341. // A Hexadecimal color
  7342. //
  7343. // #4F3C2F
  7344. //
  7345. // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
  7346. //
  7347. color: function () {
  7348. var rgb;
  7349. parserInput.save();
  7350. if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\w.#\[])?/))) {
  7351. if (!rgb[2]) {
  7352. parserInput.forget();
  7353. return new (tree.Color)(rgb[1], undefined, rgb[0]);
  7354. }
  7355. }
  7356. parserInput.restore();
  7357. },
  7358. colorKeyword: function () {
  7359. parserInput.save();
  7360. var autoCommentAbsorb = parserInput.autoCommentAbsorb;
  7361. parserInput.autoCommentAbsorb = false;
  7362. var k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/);
  7363. parserInput.autoCommentAbsorb = autoCommentAbsorb;
  7364. if (!k) {
  7365. parserInput.forget();
  7366. return;
  7367. }
  7368. parserInput.restore();
  7369. var color = tree.Color.fromKeyword(k);
  7370. if (color) {
  7371. parserInput.$str(k);
  7372. return color;
  7373. }
  7374. },
  7375. //
  7376. // A Dimension, that is, a number and a unit
  7377. //
  7378. // 0.5em 95%
  7379. //
  7380. dimension: function () {
  7381. if (parserInput.peekNotNumeric()) {
  7382. return;
  7383. }
  7384. var value = parserInput.$re(/^([+-]?\d*\.?\d+)(%|[a-z_]+)?/i);
  7385. if (value) {
  7386. return new (tree.Dimension)(value[1], value[2]);
  7387. }
  7388. },
  7389. //
  7390. // A unicode descriptor, as is used in unicode-range
  7391. //
  7392. // U+0?? or U+00A1-00A9
  7393. //
  7394. unicodeDescriptor: function () {
  7395. var ud;
  7396. ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/);
  7397. if (ud) {
  7398. return new (tree.UnicodeDescriptor)(ud[0]);
  7399. }
  7400. },
  7401. //
  7402. // JavaScript code to be evaluated
  7403. //
  7404. // `window.location.href`
  7405. //
  7406. javascript: function () {
  7407. var js;
  7408. var index = parserInput.i;
  7409. parserInput.save();
  7410. var escape = parserInput.$char('~');
  7411. var jsQuote = parserInput.$char('`');
  7412. if (!jsQuote) {
  7413. parserInput.restore();
  7414. return;
  7415. }
  7416. js = parserInput.$re(/^[^`]*`/);
  7417. if (js) {
  7418. parserInput.forget();
  7419. return new (tree.JavaScript)(js.substr(0, js.length - 1), Boolean(escape), index, fileInfo);
  7420. }
  7421. parserInput.restore('invalid javascript definition');
  7422. }
  7423. },
  7424. //
  7425. // The variable part of a variable definition. Used in the `rule` parser
  7426. //
  7427. // @fink:
  7428. //
  7429. variable: function () {
  7430. var name;
  7431. if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\s*:/))) {
  7432. return name[1];
  7433. }
  7434. },
  7435. //
  7436. // Call a variable value to retrieve a detached ruleset
  7437. // or a value from a detached ruleset's rules.
  7438. //
  7439. // @fink();
  7440. // @fink;
  7441. // color: @fink[@color];
  7442. //
  7443. variableCall: function (parsedName) {
  7444. var lookups;
  7445. var i = parserInput.i;
  7446. var inValue = !!parsedName;
  7447. var name = parsedName;
  7448. parserInput.save();
  7449. if (name || (parserInput.currentChar() === '@'
  7450. && (name = parserInput.$re(/^(@[\w-]+)(\(\s*\))?/)))) {
  7451. lookups = this.mixin.ruleLookups();
  7452. if (!lookups && ((inValue && parserInput.$str('()') !== '()') || (name[2] !== '()'))) {
  7453. parserInput.restore('Missing \'[...]\' lookup in variable call');
  7454. return;
  7455. }
  7456. if (!inValue) {
  7457. name = name[1];
  7458. }
  7459. var call = new tree.VariableCall(name, i, fileInfo);
  7460. if (!inValue && parsers.end()) {
  7461. parserInput.forget();
  7462. return call;
  7463. }
  7464. else {
  7465. parserInput.forget();
  7466. return new tree.NamespaceValue(call, lookups, i, fileInfo);
  7467. }
  7468. }
  7469. parserInput.restore();
  7470. },
  7471. //
  7472. // extend syntax - used to extend selectors
  7473. //
  7474. extend: function (isRule) {
  7475. var elements;
  7476. var e;
  7477. var index = parserInput.i;
  7478. var option;
  7479. var extendList;
  7480. var extend;
  7481. if (!parserInput.$str(isRule ? '&:extend(' : ':extend(')) {
  7482. return;
  7483. }
  7484. do {
  7485. option = null;
  7486. elements = null;
  7487. while (!(option = parserInput.$re(/^(all)(?=\s*(\)|,))/))) {
  7488. e = this.element();
  7489. if (!e) {
  7490. break;
  7491. }
  7492. if (elements) {
  7493. elements.push(e);
  7494. }
  7495. else {
  7496. elements = [e];
  7497. }
  7498. }
  7499. option = option && option[1];
  7500. if (!elements) {
  7501. error('Missing target selector for :extend().');
  7502. }
  7503. extend = new (tree.Extend)(new (tree.Selector)(elements), option, index, fileInfo);
  7504. if (extendList) {
  7505. extendList.push(extend);
  7506. }
  7507. else {
  7508. extendList = [extend];
  7509. }
  7510. } while (parserInput.$char(','));
  7511. expect(/^\)/);
  7512. if (isRule) {
  7513. expect(/^;/);
  7514. }
  7515. return extendList;
  7516. },
  7517. //
  7518. // extendRule - used in a rule to extend all the parent selectors
  7519. //
  7520. extendRule: function () {
  7521. return this.extend(true);
  7522. },
  7523. //
  7524. // Mixins
  7525. //
  7526. mixin: {
  7527. //
  7528. // A Mixin call, with an optional argument list
  7529. //
  7530. // #mixins > .square(#fff);
  7531. // #mixins.square(#fff);
  7532. // .rounded(4px, black);
  7533. // .button;
  7534. //
  7535. // We can lookup / return a value using the lookup syntax:
  7536. //
  7537. // color: #mixin.square(#fff)[@color];
  7538. //
  7539. // The `while` loop is there because mixins can be
  7540. // namespaced, but we only support the child and descendant
  7541. // selector for now.
  7542. //
  7543. call: function (inValue, getLookup) {
  7544. var s = parserInput.currentChar();
  7545. var important = false;
  7546. var lookups;
  7547. var index = parserInput.i;
  7548. var elements;
  7549. var args;
  7550. var hasParens;
  7551. if (s !== '.' && s !== '#') {
  7552. return;
  7553. }
  7554. parserInput.save(); // stop us absorbing part of an invalid selector
  7555. elements = this.elements();
  7556. if (elements) {
  7557. if (parserInput.$char('(')) {
  7558. args = this.args(true).args;
  7559. expectChar(')');
  7560. hasParens = true;
  7561. }
  7562. if (getLookup !== false) {
  7563. lookups = this.ruleLookups();
  7564. }
  7565. if (getLookup === true && !lookups) {
  7566. parserInput.restore();
  7567. return;
  7568. }
  7569. if (inValue && !lookups && !hasParens) {
  7570. // This isn't a valid in-value mixin call
  7571. parserInput.restore();
  7572. return;
  7573. }
  7574. if (!inValue && parsers.important()) {
  7575. important = true;
  7576. }
  7577. if (inValue || parsers.end()) {
  7578. parserInput.forget();
  7579. var mixin = new (tree.mixin.Call)(elements, args, index, fileInfo, !lookups && important);
  7580. if (lookups) {
  7581. return new tree.NamespaceValue(mixin, lookups);
  7582. }
  7583. else {
  7584. return mixin;
  7585. }
  7586. }
  7587. }
  7588. parserInput.restore();
  7589. },
  7590. /**
  7591. * Matching elements for mixins
  7592. * (Start with . or # and can have > )
  7593. */
  7594. elements: function () {
  7595. var elements;
  7596. var e;
  7597. var c;
  7598. var elem;
  7599. var elemIndex;
  7600. var re = /^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/;
  7601. while (true) {
  7602. elemIndex = parserInput.i;
  7603. e = parserInput.$re(re);
  7604. if (!e) {
  7605. break;
  7606. }
  7607. elem = new (tree.Element)(c, e, false, elemIndex, fileInfo);
  7608. if (elements) {
  7609. elements.push(elem);
  7610. }
  7611. else {
  7612. elements = [elem];
  7613. }
  7614. c = parserInput.$char('>');
  7615. }
  7616. return elements;
  7617. },
  7618. args: function (isCall) {
  7619. var entities = parsers.entities;
  7620. var returner = { args: null, variadic: false };
  7621. var expressions = [];
  7622. var argsSemiColon = [];
  7623. var argsComma = [];
  7624. var isSemiColonSeparated;
  7625. var expressionContainsNamed;
  7626. var name;
  7627. var nameLoop;
  7628. var value;
  7629. var arg;
  7630. var expand;
  7631. var hasSep = true;
  7632. parserInput.save();
  7633. while (true) {
  7634. if (isCall) {
  7635. arg = parsers.detachedRuleset() || parsers.expression();
  7636. }
  7637. else {
  7638. parserInput.commentStore.length = 0;
  7639. if (parserInput.$str('...')) {
  7640. returner.variadic = true;
  7641. if (parserInput.$char(';') && !isSemiColonSeparated) {
  7642. isSemiColonSeparated = true;
  7643. }
  7644. (isSemiColonSeparated ? argsSemiColon : argsComma)
  7645. .push({ variadic: true });
  7646. break;
  7647. }
  7648. arg = entities.variable() || entities.property() || entities.literal() || entities.keyword() || this.call(true);
  7649. }
  7650. if (!arg || !hasSep) {
  7651. break;
  7652. }
  7653. nameLoop = null;
  7654. if (arg.throwAwayComments) {
  7655. arg.throwAwayComments();
  7656. }
  7657. value = arg;
  7658. var val = null;
  7659. if (isCall) {
  7660. // Variable
  7661. if (arg.value && arg.value.length == 1) {
  7662. val = arg.value[0];
  7663. }
  7664. }
  7665. else {
  7666. val = arg;
  7667. }
  7668. if (val && (val instanceof tree.Variable || val instanceof tree.Property)) {
  7669. if (parserInput.$char(':')) {
  7670. if (expressions.length > 0) {
  7671. if (isSemiColonSeparated) {
  7672. error('Cannot mix ; and , as delimiter types');
  7673. }
  7674. expressionContainsNamed = true;
  7675. }
  7676. value = parsers.detachedRuleset() || parsers.expression();
  7677. if (!value) {
  7678. if (isCall) {
  7679. error('could not understand value for named argument');
  7680. }
  7681. else {
  7682. parserInput.restore();
  7683. returner.args = [];
  7684. return returner;
  7685. }
  7686. }
  7687. nameLoop = (name = val.name);
  7688. }
  7689. else if (parserInput.$str('...')) {
  7690. if (!isCall) {
  7691. returner.variadic = true;
  7692. if (parserInput.$char(';') && !isSemiColonSeparated) {
  7693. isSemiColonSeparated = true;
  7694. }
  7695. (isSemiColonSeparated ? argsSemiColon : argsComma)
  7696. .push({ name: arg.name, variadic: true });
  7697. break;
  7698. }
  7699. else {
  7700. expand = true;
  7701. }
  7702. }
  7703. else if (!isCall) {
  7704. name = nameLoop = val.name;
  7705. value = null;
  7706. }
  7707. }
  7708. if (value) {
  7709. expressions.push(value);
  7710. }
  7711. argsComma.push({ name: nameLoop, value: value, expand: expand });
  7712. if (parserInput.$char(',')) {
  7713. hasSep = true;
  7714. continue;
  7715. }
  7716. hasSep = parserInput.$char(';') === ';';
  7717. if (hasSep || isSemiColonSeparated) {
  7718. if (expressionContainsNamed) {
  7719. error('Cannot mix ; and , as delimiter types');
  7720. }
  7721. isSemiColonSeparated = true;
  7722. if (expressions.length > 1) {
  7723. value = new (tree.Value)(expressions);
  7724. }
  7725. argsSemiColon.push({ name: name, value: value, expand: expand });
  7726. name = null;
  7727. expressions = [];
  7728. expressionContainsNamed = false;
  7729. }
  7730. }
  7731. parserInput.forget();
  7732. returner.args = isSemiColonSeparated ? argsSemiColon : argsComma;
  7733. return returner;
  7734. },
  7735. //
  7736. // A Mixin definition, with a list of parameters
  7737. //
  7738. // .rounded (@radius: 2px, @color) {
  7739. // ...
  7740. // }
  7741. //
  7742. // Until we have a finer grained state-machine, we have to
  7743. // do a look-ahead, to make sure we don't have a mixin call.
  7744. // See the `rule` function for more information.
  7745. //
  7746. // We start by matching `.rounded (`, and then proceed on to
  7747. // the argument list, which has optional default values.
  7748. // We store the parameters in `params`, with a `value` key,
  7749. // if there is a value, such as in the case of `@radius`.
  7750. //
  7751. // Once we've got our params list, and a closing `)`, we parse
  7752. // the `{...}` block.
  7753. //
  7754. definition: function () {
  7755. var name;
  7756. var params = [];
  7757. var match;
  7758. var ruleset;
  7759. var cond;
  7760. var variadic = false;
  7761. if ((parserInput.currentChar() !== '.' && parserInput.currentChar() !== '#') ||
  7762. parserInput.peek(/^[^{]*\}/)) {
  7763. return;
  7764. }
  7765. parserInput.save();
  7766. match = parserInput.$re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/);
  7767. if (match) {
  7768. name = match[1];
  7769. var argInfo = this.args(false);
  7770. params = argInfo.args;
  7771. variadic = argInfo.variadic;
  7772. // .mixincall("@{a}");
  7773. // looks a bit like a mixin definition..
  7774. // also
  7775. // .mixincall(@a: {rule: set;});
  7776. // so we have to be nice and restore
  7777. if (!parserInput.$char(')')) {
  7778. parserInput.restore('Missing closing \')\'');
  7779. return;
  7780. }
  7781. parserInput.commentStore.length = 0;
  7782. if (parserInput.$str('when')) { // Guard
  7783. cond = expect(parsers.conditions, 'expected condition');
  7784. }
  7785. ruleset = parsers.block();
  7786. if (ruleset) {
  7787. parserInput.forget();
  7788. return new (tree.mixin.Definition)(name, params, ruleset, cond, variadic);
  7789. }
  7790. else {
  7791. parserInput.restore();
  7792. }
  7793. }
  7794. else {
  7795. parserInput.restore();
  7796. }
  7797. },
  7798. ruleLookups: function () {
  7799. var rule;
  7800. var lookups = [];
  7801. if (parserInput.currentChar() !== '[') {
  7802. return;
  7803. }
  7804. while (true) {
  7805. parserInput.save();
  7806. rule = this.lookupValue();
  7807. if (!rule && rule !== '') {
  7808. parserInput.restore();
  7809. break;
  7810. }
  7811. lookups.push(rule);
  7812. parserInput.forget();
  7813. }
  7814. if (lookups.length > 0) {
  7815. return lookups;
  7816. }
  7817. },
  7818. lookupValue: function () {
  7819. parserInput.save();
  7820. if (!parserInput.$char('[')) {
  7821. parserInput.restore();
  7822. return;
  7823. }
  7824. var name = parserInput.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/);
  7825. if (!parserInput.$char(']')) {
  7826. parserInput.restore();
  7827. return;
  7828. }
  7829. if (name || name === '') {
  7830. parserInput.forget();
  7831. return name;
  7832. }
  7833. parserInput.restore();
  7834. }
  7835. },
  7836. //
  7837. // Entities are the smallest recognized token,
  7838. // and can be found inside a rule's value.
  7839. //
  7840. entity: function () {
  7841. var entities = this.entities;
  7842. return this.comment() || entities.literal() || entities.variable() || entities.url() ||
  7843. entities.property() || entities.call() || entities.keyword() || this.mixin.call(true) ||
  7844. entities.javascript();
  7845. },
  7846. //
  7847. // A Declaration terminator. Note that we use `peek()` to check for '}',
  7848. // because the `block` rule will be expecting it, but we still need to make sure
  7849. // it's there, if ';' was omitted.
  7850. //
  7851. end: function () {
  7852. return parserInput.$char(';') || parserInput.peek('}');
  7853. },
  7854. //
  7855. // IE's alpha function
  7856. //
  7857. // alpha(opacity=88)
  7858. //
  7859. ieAlpha: function () {
  7860. var value;
  7861. // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18
  7862. if (!parserInput.$re(/^opacity=/i)) {
  7863. return;
  7864. }
  7865. value = parserInput.$re(/^\d+/);
  7866. if (!value) {
  7867. value = expect(parsers.entities.variable, 'Could not parse alpha');
  7868. value = "@{" + value.name.slice(1) + "}";
  7869. }
  7870. expectChar(')');
  7871. return new tree.Quoted('', "alpha(opacity=" + value + ")");
  7872. },
  7873. //
  7874. // A Selector Element
  7875. //
  7876. // div
  7877. // + h1
  7878. // #socks
  7879. // input[type="text"]
  7880. //
  7881. // Elements are the building blocks for Selectors,
  7882. // they are made out of a `Combinator` (see combinator rule),
  7883. // and an element name, such as a tag a class, or `*`.
  7884. //
  7885. element: function () {
  7886. var e;
  7887. var c;
  7888. var v;
  7889. var index = parserInput.i;
  7890. c = this.combinator();
  7891. e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) ||
  7892. parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
  7893. parserInput.$char('*') || parserInput.$char('&') || this.attribute() ||
  7894. parserInput.$re(/^\([^&()@]+\)/) || parserInput.$re(/^[\.#:](?=@)/) ||
  7895. this.entities.variableCurly();
  7896. if (!e) {
  7897. parserInput.save();
  7898. if (parserInput.$char('(')) {
  7899. if ((v = this.selector(false)) && parserInput.$char(')')) {
  7900. e = new (tree.Paren)(v);
  7901. parserInput.forget();
  7902. }
  7903. else {
  7904. parserInput.restore('Missing closing \')\'');
  7905. }
  7906. }
  7907. else {
  7908. parserInput.forget();
  7909. }
  7910. }
  7911. if (e) {
  7912. return new (tree.Element)(c, e, e instanceof tree.Variable, index, fileInfo);
  7913. }
  7914. },
  7915. //
  7916. // Combinators combine elements together, in a Selector.
  7917. //
  7918. // Because our parser isn't white-space sensitive, special care
  7919. // has to be taken, when parsing the descendant combinator, ` `,
  7920. // as it's an empty space. We have to check the previous character
  7921. // in the input, to see if it's a ` ` character. More info on how
  7922. // we deal with this in *combinator.js*.
  7923. //
  7924. combinator: function () {
  7925. var c = parserInput.currentChar();
  7926. if (c === '/') {
  7927. parserInput.save();
  7928. var slashedCombinator = parserInput.$re(/^\/[a-z]+\//i);
  7929. if (slashedCombinator) {
  7930. parserInput.forget();
  7931. return new (tree.Combinator)(slashedCombinator);
  7932. }
  7933. parserInput.restore();
  7934. }
  7935. if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') {
  7936. parserInput.i++;
  7937. if (c === '^' && parserInput.currentChar() === '^') {
  7938. c = '^^';
  7939. parserInput.i++;
  7940. }
  7941. while (parserInput.isWhitespace()) {
  7942. parserInput.i++;
  7943. }
  7944. return new (tree.Combinator)(c);
  7945. }
  7946. else if (parserInput.isWhitespace(-1)) {
  7947. return new (tree.Combinator)(' ');
  7948. }
  7949. else {
  7950. return new (tree.Combinator)(null);
  7951. }
  7952. },
  7953. //
  7954. // A CSS Selector
  7955. // with less extensions e.g. the ability to extend and guard
  7956. //
  7957. // .class > div + h1
  7958. // li a:hover
  7959. //
  7960. // Selectors are made out of one or more Elements, see above.
  7961. //
  7962. selector: function (isLess) {
  7963. var index = parserInput.i;
  7964. var elements;
  7965. var extendList;
  7966. var c;
  7967. var e;
  7968. var allExtends;
  7969. var when;
  7970. var condition;
  7971. isLess = isLess !== false;
  7972. while ((isLess && (extendList = this.extend())) || (isLess && (when = parserInput.$str('when'))) || (e = this.element())) {
  7973. if (when) {
  7974. condition = expect(this.conditions, 'expected condition');
  7975. }
  7976. else if (condition) {
  7977. error('CSS guard can only be used at the end of selector');
  7978. }
  7979. else if (extendList) {
  7980. if (allExtends) {
  7981. allExtends = allExtends.concat(extendList);
  7982. }
  7983. else {
  7984. allExtends = extendList;
  7985. }
  7986. }
  7987. else {
  7988. if (allExtends) {
  7989. error('Extend can only be used at the end of selector');
  7990. }
  7991. c = parserInput.currentChar();
  7992. if (elements) {
  7993. elements.push(e);
  7994. }
  7995. else {
  7996. elements = [e];
  7997. }
  7998. e = null;
  7999. }
  8000. if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') {
  8001. break;
  8002. }
  8003. }
  8004. if (elements) {
  8005. return new (tree.Selector)(elements, allExtends, condition, index, fileInfo);
  8006. }
  8007. if (allExtends) {
  8008. error('Extend must be used to extend a selector, it cannot be used on its own');
  8009. }
  8010. },
  8011. selectors: function () {
  8012. var s;
  8013. var selectors;
  8014. while (true) {
  8015. s = this.selector();
  8016. if (!s) {
  8017. break;
  8018. }
  8019. if (selectors) {
  8020. selectors.push(s);
  8021. }
  8022. else {
  8023. selectors = [s];
  8024. }
  8025. parserInput.commentStore.length = 0;
  8026. if (s.condition && selectors.length > 1) {
  8027. error("Guards are only currently allowed on a single selector.");
  8028. }
  8029. if (!parserInput.$char(',')) {
  8030. break;
  8031. }
  8032. if (s.condition) {
  8033. error("Guards are only currently allowed on a single selector.");
  8034. }
  8035. parserInput.commentStore.length = 0;
  8036. }
  8037. return selectors;
  8038. },
  8039. attribute: function () {
  8040. if (!parserInput.$char('[')) {
  8041. return;
  8042. }
  8043. var entities = this.entities;
  8044. var key;
  8045. var val;
  8046. var op;
  8047. if (!(key = entities.variableCurly())) {
  8048. key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/);
  8049. }
  8050. op = parserInput.$re(/^[|~*$^]?=/);
  8051. if (op) {
  8052. val = entities.quoted() || parserInput.$re(/^[0-9]+%/) || parserInput.$re(/^[\w-]+/) || entities.variableCurly();
  8053. }
  8054. expectChar(']');
  8055. return new (tree.Attribute)(key, op, val);
  8056. },
  8057. //
  8058. // The `block` rule is used by `ruleset` and `mixin.definition`.
  8059. // It's a wrapper around the `primary` rule, with added `{}`.
  8060. //
  8061. block: function () {
  8062. var content;
  8063. if (parserInput.$char('{') && (content = this.primary()) && parserInput.$char('}')) {
  8064. return content;
  8065. }
  8066. },
  8067. blockRuleset: function () {
  8068. var block = this.block();
  8069. if (block) {
  8070. block = new tree.Ruleset(null, block);
  8071. }
  8072. return block;
  8073. },
  8074. detachedRuleset: function () {
  8075. var argInfo;
  8076. var params;
  8077. var variadic;
  8078. parserInput.save();
  8079. if (parserInput.$re(/^[.#]\(/)) {
  8080. /**
  8081. * DR args currently only implemented for each() function, and not
  8082. * yet settable as `@dr: #(@arg) {}`
  8083. * This should be done when DRs are merged with mixins.
  8084. * See: https://github.com/less/less-meta/issues/16
  8085. */
  8086. argInfo = this.mixin.args(false);
  8087. params = argInfo.args;
  8088. variadic = argInfo.variadic;
  8089. if (!parserInput.$char(')')) {
  8090. parserInput.restore();
  8091. return;
  8092. }
  8093. }
  8094. var blockRuleset = this.blockRuleset();
  8095. if (blockRuleset) {
  8096. parserInput.forget();
  8097. if (params) {
  8098. return new tree.mixin.Definition(null, params, blockRuleset, null, variadic);
  8099. }
  8100. return new tree.DetachedRuleset(blockRuleset);
  8101. }
  8102. parserInput.restore();
  8103. },
  8104. //
  8105. // div, .class, body > p {...}
  8106. //
  8107. ruleset: function () {
  8108. var selectors;
  8109. var rules;
  8110. var debugInfo;
  8111. parserInput.save();
  8112. if (context.dumpLineNumbers) {
  8113. debugInfo = getDebugInfo(parserInput.i);
  8114. }
  8115. selectors = this.selectors();
  8116. if (selectors && (rules = this.block())) {
  8117. parserInput.forget();
  8118. var ruleset = new (tree.Ruleset)(selectors, rules, context.strictImports);
  8119. if (context.dumpLineNumbers) {
  8120. ruleset.debugInfo = debugInfo;
  8121. }
  8122. return ruleset;
  8123. }
  8124. else {
  8125. parserInput.restore();
  8126. }
  8127. },
  8128. declaration: function () {
  8129. var name;
  8130. var value;
  8131. var index = parserInput.i;
  8132. var hasDR;
  8133. var c = parserInput.currentChar();
  8134. var important;
  8135. var merge;
  8136. var isVariable;
  8137. if (c === '.' || c === '#' || c === '&' || c === ':') {
  8138. return;
  8139. }
  8140. parserInput.save();
  8141. name = this.variable() || this.ruleProperty();
  8142. if (name) {
  8143. isVariable = typeof name === 'string';
  8144. if (isVariable) {
  8145. value = this.detachedRuleset();
  8146. if (value) {
  8147. hasDR = true;
  8148. }
  8149. }
  8150. parserInput.commentStore.length = 0;
  8151. if (!value) {
  8152. // a name returned by this.ruleProperty() is always an array of the form:
  8153. // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"]
  8154. // where each item is a tree.Keyword or tree.Variable
  8155. merge = !isVariable && name.length > 1 && name.pop().value;
  8156. // Custom property values get permissive parsing
  8157. if (name[0].value && name[0].value.slice(0, 2) === '--') {
  8158. value = this.permissiveValue();
  8159. }
  8160. // Try to store values as anonymous
  8161. // If we need the value later we'll re-parse it in ruleset.parseValue
  8162. else {
  8163. value = this.anonymousValue();
  8164. }
  8165. if (value) {
  8166. parserInput.forget();
  8167. // anonymous values absorb the end ';' which is required for them to work
  8168. return new (tree.Declaration)(name, value, false, merge, index, fileInfo);
  8169. }
  8170. if (!value) {
  8171. value = this.value();
  8172. }
  8173. if (value) {
  8174. important = this.important();
  8175. }
  8176. else if (isVariable) {
  8177. // As a last resort, try permissiveValue
  8178. value = this.permissiveValue();
  8179. }
  8180. }
  8181. if (value && (this.end() || hasDR)) {
  8182. parserInput.forget();
  8183. return new (tree.Declaration)(name, value, important, merge, index, fileInfo);
  8184. }
  8185. else {
  8186. parserInput.restore();
  8187. }
  8188. }
  8189. else {
  8190. parserInput.restore();
  8191. }
  8192. },
  8193. anonymousValue: function () {
  8194. var index = parserInput.i;
  8195. var match = parserInput.$re(/^([^.#@\$+\/'"*`(;{}-]*);/);
  8196. if (match) {
  8197. return new (tree.Anonymous)(match[1], index);
  8198. }
  8199. },
  8200. /**
  8201. * Used for custom properties, at-rules, and variables (as fallback)
  8202. * Parses almost anything inside of {} [] () "" blocks
  8203. * until it reaches outer-most tokens.
  8204. *
  8205. * First, it will try to parse comments and entities to reach
  8206. * the end. This is mostly like the Expression parser except no
  8207. * math is allowed.
  8208. */
  8209. permissiveValue: function (untilTokens) {
  8210. var i;
  8211. var e;
  8212. var done;
  8213. var value;
  8214. var tok = untilTokens || ';';
  8215. var index = parserInput.i;
  8216. var result = [];
  8217. function testCurrentChar() {
  8218. var char = parserInput.currentChar();
  8219. if (typeof tok === 'string') {
  8220. return char === tok;
  8221. }
  8222. else {
  8223. return tok.test(char);
  8224. }
  8225. }
  8226. if (testCurrentChar()) {
  8227. return;
  8228. }
  8229. value = [];
  8230. do {
  8231. e = this.comment();
  8232. if (e) {
  8233. value.push(e);
  8234. continue;
  8235. }
  8236. e = this.entity();
  8237. if (e) {
  8238. value.push(e);
  8239. }
  8240. } while (e);
  8241. done = testCurrentChar();
  8242. if (value.length > 0) {
  8243. value = new (tree.Expression)(value);
  8244. if (done) {
  8245. return value;
  8246. }
  8247. else {
  8248. result.push(value);
  8249. }
  8250. // Preserve space before $parseUntil as it will not
  8251. if (parserInput.prevChar() === ' ') {
  8252. result.push(new tree.Anonymous(' ', index));
  8253. }
  8254. }
  8255. parserInput.save();
  8256. value = parserInput.$parseUntil(tok);
  8257. if (value) {
  8258. if (typeof value === 'string') {
  8259. error("Expected '" + value + "'", 'Parse');
  8260. }
  8261. if (value.length === 1 && value[0] === ' ') {
  8262. parserInput.forget();
  8263. return new tree.Anonymous('', index);
  8264. }
  8265. var item = void 0;
  8266. for (i = 0; i < value.length; i++) {
  8267. item = value[i];
  8268. if (Array.isArray(item)) {
  8269. // Treat actual quotes as normal quoted values
  8270. result.push(new tree.Quoted(item[0], item[1], true, index, fileInfo));
  8271. }
  8272. else {
  8273. if (i === value.length - 1) {
  8274. item = item.trim();
  8275. }
  8276. // Treat like quoted values, but replace vars like unquoted expressions
  8277. var quote = new tree.Quoted('\'', item, true, index, fileInfo);
  8278. quote.variableRegex = /@([\w-]+)/g;
  8279. quote.propRegex = /\$([\w-]+)/g;
  8280. result.push(quote);
  8281. }
  8282. }
  8283. parserInput.forget();
  8284. return new tree.Expression(result, true);
  8285. }
  8286. parserInput.restore();
  8287. },
  8288. //
  8289. // An @import atrule
  8290. //
  8291. // @import "lib";
  8292. //
  8293. // Depending on our environment, importing is done differently:
  8294. // In the browser, it's an XHR request, in Node, it would be a
  8295. // file-system operation. The function used for importing is
  8296. // stored in `import`, which we pass to the Import constructor.
  8297. //
  8298. 'import': function () {
  8299. var path;
  8300. var features;
  8301. var index = parserInput.i;
  8302. var dir = parserInput.$re(/^@import?\s+/);
  8303. if (dir) {
  8304. var options_1 = (dir ? this.importOptions() : null) || {};
  8305. if ((path = this.entities.quoted() || this.entities.url())) {
  8306. features = this.mediaFeatures();
  8307. if (!parserInput.$char(';')) {
  8308. parserInput.i = index;
  8309. error('missing semi-colon or unrecognised media features on import');
  8310. }
  8311. features = features && new (tree.Value)(features);
  8312. return new (tree.Import)(path, features, options_1, index, fileInfo);
  8313. }
  8314. else {
  8315. parserInput.i = index;
  8316. error('malformed import statement');
  8317. }
  8318. }
  8319. },
  8320. importOptions: function () {
  8321. var o;
  8322. var options = {};
  8323. var optionName;
  8324. var value;
  8325. // list of options, surrounded by parens
  8326. if (!parserInput.$char('(')) {
  8327. return null;
  8328. }
  8329. do {
  8330. o = this.importOption();
  8331. if (o) {
  8332. optionName = o;
  8333. value = true;
  8334. switch (optionName) {
  8335. case 'css':
  8336. optionName = 'less';
  8337. value = false;
  8338. break;
  8339. case 'once':
  8340. optionName = 'multiple';
  8341. value = false;
  8342. break;
  8343. }
  8344. options[optionName] = value;
  8345. if (!parserInput.$char(',')) {
  8346. break;
  8347. }
  8348. }
  8349. } while (o);
  8350. expectChar(')');
  8351. return options;
  8352. },
  8353. importOption: function () {
  8354. var opt = parserInput.$re(/^(less|css|multiple|once|inline|reference|optional)/);
  8355. if (opt) {
  8356. return opt[1];
  8357. }
  8358. },
  8359. mediaFeature: function () {
  8360. var entities = this.entities;
  8361. var nodes = [];
  8362. var e;
  8363. var p;
  8364. parserInput.save();
  8365. do {
  8366. e = entities.keyword() || entities.variable() || entities.mixinLookup();
  8367. if (e) {
  8368. nodes.push(e);
  8369. }
  8370. else if (parserInput.$char('(')) {
  8371. p = this.property();
  8372. e = this.value();
  8373. if (parserInput.$char(')')) {
  8374. if (p && e) {
  8375. nodes.push(new (tree.Paren)(new (tree.Declaration)(p, e, null, null, parserInput.i, fileInfo, true)));
  8376. }
  8377. else if (e) {
  8378. nodes.push(new (tree.Paren)(e));
  8379. }
  8380. else {
  8381. error('badly formed media feature definition');
  8382. }
  8383. }
  8384. else {
  8385. error('Missing closing \')\'', 'Parse');
  8386. }
  8387. }
  8388. } while (e);
  8389. parserInput.forget();
  8390. if (nodes.length > 0) {
  8391. return new (tree.Expression)(nodes);
  8392. }
  8393. },
  8394. mediaFeatures: function () {
  8395. var entities = this.entities;
  8396. var features = [];
  8397. var e;
  8398. do {
  8399. e = this.mediaFeature();
  8400. if (e) {
  8401. features.push(e);
  8402. if (!parserInput.$char(',')) {
  8403. break;
  8404. }
  8405. }
  8406. else {
  8407. e = entities.variable() || entities.mixinLookup();
  8408. if (e) {
  8409. features.push(e);
  8410. if (!parserInput.$char(',')) {
  8411. break;
  8412. }
  8413. }
  8414. }
  8415. } while (e);
  8416. return features.length > 0 ? features : null;
  8417. },
  8418. media: function () {
  8419. var features;
  8420. var rules;
  8421. var media;
  8422. var debugInfo;
  8423. var index = parserInput.i;
  8424. if (context.dumpLineNumbers) {
  8425. debugInfo = getDebugInfo(index);
  8426. }
  8427. parserInput.save();
  8428. if (parserInput.$str('@media')) {
  8429. features = this.mediaFeatures();
  8430. rules = this.block();
  8431. if (!rules) {
  8432. error('media definitions require block statements after any features');
  8433. }
  8434. parserInput.forget();
  8435. media = new (tree.Media)(rules, features, index, fileInfo);
  8436. if (context.dumpLineNumbers) {
  8437. media.debugInfo = debugInfo;
  8438. }
  8439. return media;
  8440. }
  8441. parserInput.restore();
  8442. },
  8443. //
  8444. // A @plugin directive, used to import plugins dynamically.
  8445. //
  8446. // @plugin (args) "lib";
  8447. //
  8448. plugin: function () {
  8449. var path;
  8450. var args;
  8451. var options;
  8452. var index = parserInput.i;
  8453. var dir = parserInput.$re(/^@plugin?\s+/);
  8454. if (dir) {
  8455. args = this.pluginArgs();
  8456. if (args) {
  8457. options = {
  8458. pluginArgs: args,
  8459. isPlugin: true
  8460. };
  8461. }
  8462. else {
  8463. options = { isPlugin: true };
  8464. }
  8465. if ((path = this.entities.quoted() || this.entities.url())) {
  8466. if (!parserInput.$char(';')) {
  8467. parserInput.i = index;
  8468. error('missing semi-colon on @plugin');
  8469. }
  8470. return new (tree.Import)(path, null, options, index, fileInfo);
  8471. }
  8472. else {
  8473. parserInput.i = index;
  8474. error('malformed @plugin statement');
  8475. }
  8476. }
  8477. },
  8478. pluginArgs: function () {
  8479. // list of options, surrounded by parens
  8480. parserInput.save();
  8481. if (!parserInput.$char('(')) {
  8482. parserInput.restore();
  8483. return null;
  8484. }
  8485. var args = parserInput.$re(/^\s*([^\);]+)\)\s*/);
  8486. if (args[1]) {
  8487. parserInput.forget();
  8488. return args[1].trim();
  8489. }
  8490. else {
  8491. parserInput.restore();
  8492. return null;
  8493. }
  8494. },
  8495. //
  8496. // A CSS AtRule
  8497. //
  8498. // @charset "utf-8";
  8499. //
  8500. atrule: function () {
  8501. var index = parserInput.i;
  8502. var name;
  8503. var value;
  8504. var rules;
  8505. var nonVendorSpecificName;
  8506. var hasIdentifier;
  8507. var hasExpression;
  8508. var hasUnknown;
  8509. var hasBlock = true;
  8510. var isRooted = true;
  8511. if (parserInput.currentChar() !== '@') {
  8512. return;
  8513. }
  8514. value = this['import']() || this.plugin() || this.media();
  8515. if (value) {
  8516. return value;
  8517. }
  8518. parserInput.save();
  8519. name = parserInput.$re(/^@[a-z-]+/);
  8520. if (!name) {
  8521. return;
  8522. }
  8523. nonVendorSpecificName = name;
  8524. if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {
  8525. nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1);
  8526. }
  8527. switch (nonVendorSpecificName) {
  8528. case '@charset':
  8529. hasIdentifier = true;
  8530. hasBlock = false;
  8531. break;
  8532. case '@namespace':
  8533. hasExpression = true;
  8534. hasBlock = false;
  8535. break;
  8536. case '@keyframes':
  8537. case '@counter-style':
  8538. hasIdentifier = true;
  8539. break;
  8540. case '@document':
  8541. case '@supports':
  8542. hasUnknown = true;
  8543. isRooted = false;
  8544. break;
  8545. default:
  8546. hasUnknown = true;
  8547. break;
  8548. }
  8549. parserInput.commentStore.length = 0;
  8550. if (hasIdentifier) {
  8551. value = this.entity();
  8552. if (!value) {
  8553. error("expected " + name + " identifier");
  8554. }
  8555. }
  8556. else if (hasExpression) {
  8557. value = this.expression();
  8558. if (!value) {
  8559. error("expected " + name + " expression");
  8560. }
  8561. }
  8562. else if (hasUnknown) {
  8563. value = this.permissiveValue(/^[{;]/);
  8564. hasBlock = (parserInput.currentChar() === '{');
  8565. if (!value) {
  8566. if (!hasBlock && parserInput.currentChar() !== ';') {
  8567. error(name + " rule is missing block or ending semi-colon");
  8568. }
  8569. }
  8570. else if (!value.value) {
  8571. value = null;
  8572. }
  8573. }
  8574. if (hasBlock) {
  8575. rules = this.blockRuleset();
  8576. }
  8577. if (rules || (!hasBlock && value && parserInput.$char(';'))) {
  8578. parserInput.forget();
  8579. return new (tree.AtRule)(name, value, rules, index, fileInfo, context.dumpLineNumbers ? getDebugInfo(index) : null, isRooted);
  8580. }
  8581. parserInput.restore('at-rule options not recognised');
  8582. },
  8583. //
  8584. // A Value is a comma-delimited list of Expressions
  8585. //
  8586. // font-family: Baskerville, Georgia, serif;
  8587. //
  8588. // In a Rule, a Value represents everything after the `:`,
  8589. // and before the `;`.
  8590. //
  8591. value: function () {
  8592. var e;
  8593. var expressions = [];
  8594. var index = parserInput.i;
  8595. do {
  8596. e = this.expression();
  8597. if (e) {
  8598. expressions.push(e);
  8599. if (!parserInput.$char(',')) {
  8600. break;
  8601. }
  8602. }
  8603. } while (e);
  8604. if (expressions.length > 0) {
  8605. return new (tree.Value)(expressions, index);
  8606. }
  8607. },
  8608. important: function () {
  8609. if (parserInput.currentChar() === '!') {
  8610. return parserInput.$re(/^! *important/);
  8611. }
  8612. },
  8613. sub: function () {
  8614. var a;
  8615. var e;
  8616. parserInput.save();
  8617. if (parserInput.$char('(')) {
  8618. a = this.addition();
  8619. if (a && parserInput.$char(')')) {
  8620. parserInput.forget();
  8621. e = new (tree.Expression)([a]);
  8622. e.parens = true;
  8623. return e;
  8624. }
  8625. parserInput.restore('Expected \')\'');
  8626. return;
  8627. }
  8628. parserInput.restore();
  8629. },
  8630. multiplication: function () {
  8631. var m;
  8632. var a;
  8633. var op;
  8634. var operation;
  8635. var isSpaced;
  8636. m = this.operand();
  8637. if (m) {
  8638. isSpaced = parserInput.isWhitespace(-1);
  8639. while (true) {
  8640. if (parserInput.peek(/^\/[*\/]/)) {
  8641. break;
  8642. }
  8643. parserInput.save();
  8644. op = parserInput.$char('/') || parserInput.$char('*') || parserInput.$str('./');
  8645. if (!op) {
  8646. parserInput.forget();
  8647. break;
  8648. }
  8649. a = this.operand();
  8650. if (!a) {
  8651. parserInput.restore();
  8652. break;
  8653. }
  8654. parserInput.forget();
  8655. m.parensInOp = true;
  8656. a.parensInOp = true;
  8657. operation = new (tree.Operation)(op, [operation || m, a], isSpaced);
  8658. isSpaced = parserInput.isWhitespace(-1);
  8659. }
  8660. return operation || m;
  8661. }
  8662. },
  8663. addition: function () {
  8664. var m;
  8665. var a;
  8666. var op;
  8667. var operation;
  8668. var isSpaced;
  8669. m = this.multiplication();
  8670. if (m) {
  8671. isSpaced = parserInput.isWhitespace(-1);
  8672. while (true) {
  8673. op = parserInput.$re(/^[-+]\s+/) || (!isSpaced && (parserInput.$char('+') || parserInput.$char('-')));
  8674. if (!op) {
  8675. break;
  8676. }
  8677. a = this.multiplication();
  8678. if (!a) {
  8679. break;
  8680. }
  8681. m.parensInOp = true;
  8682. a.parensInOp = true;
  8683. operation = new (tree.Operation)(op, [operation || m, a], isSpaced);
  8684. isSpaced = parserInput.isWhitespace(-1);
  8685. }
  8686. return operation || m;
  8687. }
  8688. },
  8689. conditions: function () {
  8690. var a;
  8691. var b;
  8692. var index = parserInput.i;
  8693. var condition;
  8694. a = this.condition(true);
  8695. if (a) {
  8696. while (true) {
  8697. if (!parserInput.peek(/^,\s*(not\s*)?\(/) || !parserInput.$char(',')) {
  8698. break;
  8699. }
  8700. b = this.condition(true);
  8701. if (!b) {
  8702. break;
  8703. }
  8704. condition = new (tree.Condition)('or', condition || a, b, index);
  8705. }
  8706. return condition || a;
  8707. }
  8708. },
  8709. condition: function (needsParens) {
  8710. var result;
  8711. var logical;
  8712. var next;
  8713. function or() {
  8714. return parserInput.$str('or');
  8715. }
  8716. result = this.conditionAnd(needsParens);
  8717. if (!result) {
  8718. return;
  8719. }
  8720. logical = or();
  8721. if (logical) {
  8722. next = this.condition(needsParens);
  8723. if (next) {
  8724. result = new (tree.Condition)(logical, result, next);
  8725. }
  8726. else {
  8727. return;
  8728. }
  8729. }
  8730. return result;
  8731. },
  8732. conditionAnd: function (needsParens) {
  8733. var result;
  8734. var logical;
  8735. var next;
  8736. var self = this;
  8737. function insideCondition() {
  8738. var cond = self.negatedCondition(needsParens) || self.parenthesisCondition(needsParens);
  8739. if (!cond && !needsParens) {
  8740. return self.atomicCondition(needsParens);
  8741. }
  8742. return cond;
  8743. }
  8744. function and() {
  8745. return parserInput.$str('and');
  8746. }
  8747. result = insideCondition();
  8748. if (!result) {
  8749. return;
  8750. }
  8751. logical = and();
  8752. if (logical) {
  8753. next = this.conditionAnd(needsParens);
  8754. if (next) {
  8755. result = new (tree.Condition)(logical, result, next);
  8756. }
  8757. else {
  8758. return;
  8759. }
  8760. }
  8761. return result;
  8762. },
  8763. negatedCondition: function (needsParens) {
  8764. if (parserInput.$str('not')) {
  8765. var result = this.parenthesisCondition(needsParens);
  8766. if (result) {
  8767. result.negate = !result.negate;
  8768. }
  8769. return result;
  8770. }
  8771. },
  8772. parenthesisCondition: function (needsParens) {
  8773. function tryConditionFollowedByParenthesis(me) {
  8774. var body;
  8775. parserInput.save();
  8776. body = me.condition(needsParens);
  8777. if (!body) {
  8778. parserInput.restore();
  8779. return;
  8780. }
  8781. if (!parserInput.$char(')')) {
  8782. parserInput.restore();
  8783. return;
  8784. }
  8785. parserInput.forget();
  8786. return body;
  8787. }
  8788. var body;
  8789. parserInput.save();
  8790. if (!parserInput.$str('(')) {
  8791. parserInput.restore();
  8792. return;
  8793. }
  8794. body = tryConditionFollowedByParenthesis(this);
  8795. if (body) {
  8796. parserInput.forget();
  8797. return body;
  8798. }
  8799. body = this.atomicCondition(needsParens);
  8800. if (!body) {
  8801. parserInput.restore();
  8802. return;
  8803. }
  8804. if (!parserInput.$char(')')) {
  8805. parserInput.restore("expected ')' got '" + parserInput.currentChar() + "'");
  8806. return;
  8807. }
  8808. parserInput.forget();
  8809. return body;
  8810. },
  8811. atomicCondition: function (needsParens) {
  8812. var entities = this.entities;
  8813. var index = parserInput.i;
  8814. var a;
  8815. var b;
  8816. var c;
  8817. var op;
  8818. function cond() {
  8819. return this.addition() || entities.keyword() || entities.quoted() || entities.mixinLookup();
  8820. }
  8821. cond = cond.bind(this);
  8822. a = cond();
  8823. if (a) {
  8824. if (parserInput.$char('>')) {
  8825. if (parserInput.$char('=')) {
  8826. op = '>=';
  8827. }
  8828. else {
  8829. op = '>';
  8830. }
  8831. }
  8832. else if (parserInput.$char('<')) {
  8833. if (parserInput.$char('=')) {
  8834. op = '<=';
  8835. }
  8836. else {
  8837. op = '<';
  8838. }
  8839. }
  8840. else if (parserInput.$char('=')) {
  8841. if (parserInput.$char('>')) {
  8842. op = '=>';
  8843. }
  8844. else if (parserInput.$char('<')) {
  8845. op = '=<';
  8846. }
  8847. else {
  8848. op = '=';
  8849. }
  8850. }
  8851. if (op) {
  8852. b = cond();
  8853. if (b) {
  8854. c = new (tree.Condition)(op, a, b, index, false);
  8855. }
  8856. else {
  8857. error('expected expression');
  8858. }
  8859. }
  8860. else {
  8861. c = new (tree.Condition)('=', a, new (tree.Keyword)('true'), index, false);
  8862. }
  8863. return c;
  8864. }
  8865. },
  8866. //
  8867. // An operand is anything that can be part of an operation,
  8868. // such as a Color, or a Variable
  8869. //
  8870. operand: function () {
  8871. var entities = this.entities;
  8872. var negate;
  8873. if (parserInput.peek(/^-[@\$\(]/)) {
  8874. negate = parserInput.$char('-');
  8875. }
  8876. var o = this.sub() || entities.dimension() ||
  8877. entities.color() || entities.variable() ||
  8878. entities.property() || entities.call() ||
  8879. entities.quoted(true) || entities.colorKeyword() ||
  8880. entities.mixinLookup();
  8881. if (negate) {
  8882. o.parensInOp = true;
  8883. o = new (tree.Negative)(o);
  8884. }
  8885. return o;
  8886. },
  8887. //
  8888. // Expressions either represent mathematical operations,
  8889. // or white-space delimited Entities.
  8890. //
  8891. // 1px solid black
  8892. // @var * 2
  8893. //
  8894. expression: function () {
  8895. var entities = [];
  8896. var e;
  8897. var delim;
  8898. var index = parserInput.i;
  8899. do {
  8900. e = this.comment();
  8901. if (e) {
  8902. entities.push(e);
  8903. continue;
  8904. }
  8905. e = this.addition() || this.entity();
  8906. if (e) {
  8907. entities.push(e);
  8908. // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here
  8909. if (!parserInput.peek(/^\/[\/*]/)) {
  8910. delim = parserInput.$char('/');
  8911. if (delim) {
  8912. entities.push(new (tree.Anonymous)(delim, index));
  8913. }
  8914. }
  8915. }
  8916. } while (e);
  8917. if (entities.length > 0) {
  8918. return new (tree.Expression)(entities);
  8919. }
  8920. },
  8921. property: function () {
  8922. var name = parserInput.$re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/);
  8923. if (name) {
  8924. return name[1];
  8925. }
  8926. },
  8927. ruleProperty: function () {
  8928. var name = [];
  8929. var index = [];
  8930. var s;
  8931. var k;
  8932. parserInput.save();
  8933. var simpleProperty = parserInput.$re(/^([_a-zA-Z0-9-]+)\s*:/);
  8934. if (simpleProperty) {
  8935. name = [new (tree.Keyword)(simpleProperty[1])];
  8936. parserInput.forget();
  8937. return name;
  8938. }
  8939. function match(re) {
  8940. var i = parserInput.i;
  8941. var chunk = parserInput.$re(re);
  8942. if (chunk) {
  8943. index.push(i);
  8944. return name.push(chunk[1]);
  8945. }
  8946. }
  8947. match(/^(\*?)/);
  8948. while (true) {
  8949. if (!match(/^((?:[\w-]+)|(?:[@\$]\{[\w-]+\}))/)) {
  8950. break;
  8951. }
  8952. }
  8953. if ((name.length > 1) && match(/^((?:\+_|\+)?)\s*:/)) {
  8954. parserInput.forget();
  8955. // at last, we have the complete match now. move forward,
  8956. // convert name particles to tree objects and return:
  8957. if (name[0] === '') {
  8958. name.shift();
  8959. index.shift();
  8960. }
  8961. for (k = 0; k < name.length; k++) {
  8962. s = name[k];
  8963. name[k] = (s.charAt(0) !== '@' && s.charAt(0) !== '$') ?
  8964. new (tree.Keyword)(s) :
  8965. (s.charAt(0) === '@' ?
  8966. new (tree.Variable)("@" + s.slice(2, -1), index[k], fileInfo) :
  8967. new (tree.Property)("$" + s.slice(2, -1), index[k], fileInfo));
  8968. }
  8969. return name;
  8970. }
  8971. parserInput.restore();
  8972. }
  8973. }
  8974. };
  8975. };
  8976. Parser.serializeVars = function (vars) {
  8977. var s = '';
  8978. for (var name_1 in vars) {
  8979. if (Object.hasOwnProperty.call(vars, name_1)) {
  8980. var value = vars[name_1];
  8981. s += ((name_1[0] === '@') ? '' : '@') + name_1 + ": " + value + ((String(value).slice(-1) === ';') ? '' : ';');
  8982. }
  8983. }
  8984. return s;
  8985. };
  8986. function boolean(condition) {
  8987. return condition ? Keyword.True : Keyword.False;
  8988. }
  8989. function If(condition, trueValue, falseValue) {
  8990. return condition ? trueValue
  8991. : (falseValue || new Anonymous);
  8992. }
  8993. var boolean$1 = { boolean: boolean, 'if': If };
  8994. var colorFunctions;
  8995. function clamp$1(val) {
  8996. return Math.min(1, Math.max(0, val));
  8997. }
  8998. function hsla(origColor, hsl) {
  8999. var color = colorFunctions.hsla(hsl.h, hsl.s, hsl.l, hsl.a);
  9000. if (color) {
  9001. if (origColor.value &&
  9002. /^(rgb|hsl)/.test(origColor.value)) {
  9003. color.value = origColor.value;
  9004. }
  9005. else {
  9006. color.value = 'rgb';
  9007. }
  9008. return color;
  9009. }
  9010. }
  9011. function toHSL(color) {
  9012. if (color.toHSL) {
  9013. return color.toHSL();
  9014. }
  9015. else {
  9016. throw new Error('Argument cannot be evaluated to a color');
  9017. }
  9018. }
  9019. function toHSV(color) {
  9020. if (color.toHSV) {
  9021. return color.toHSV();
  9022. }
  9023. else {
  9024. throw new Error('Argument cannot be evaluated to a color');
  9025. }
  9026. }
  9027. function number(n) {
  9028. if (n instanceof Dimension) {
  9029. return parseFloat(n.unit.is('%') ? n.value / 100 : n.value);
  9030. }
  9031. else if (typeof n === 'number') {
  9032. return n;
  9033. }
  9034. else {
  9035. throw {
  9036. type: 'Argument',
  9037. message: 'color functions take numbers as parameters'
  9038. };
  9039. }
  9040. }
  9041. function scaled(n, size) {
  9042. if (n instanceof Dimension && n.unit.is('%')) {
  9043. return parseFloat(n.value * size / 100);
  9044. }
  9045. else {
  9046. return number(n);
  9047. }
  9048. }
  9049. colorFunctions = {
  9050. rgb: function (r, g, b) {
  9051. var color = colorFunctions.rgba(r, g, b, 1.0);
  9052. if (color) {
  9053. color.value = 'rgb';
  9054. return color;
  9055. }
  9056. },
  9057. rgba: function (r, g, b, a) {
  9058. try {
  9059. if (r instanceof Color) {
  9060. if (g) {
  9061. a = number(g);
  9062. }
  9063. else {
  9064. a = r.alpha;
  9065. }
  9066. return new Color(r.rgb, a, 'rgba');
  9067. }
  9068. var rgb = [r, g, b].map(function (c) { return scaled(c, 255); });
  9069. a = number(a);
  9070. return new Color(rgb, a, 'rgba');
  9071. }
  9072. catch (e) { }
  9073. },
  9074. hsl: function (h, s, l) {
  9075. var color = colorFunctions.hsla(h, s, l, 1.0);
  9076. if (color) {
  9077. color.value = 'hsl';
  9078. return color;
  9079. }
  9080. },
  9081. hsla: function (h, s, l, a) {
  9082. try {
  9083. if (h instanceof Color) {
  9084. if (s) {
  9085. a = number(s);
  9086. }
  9087. else {
  9088. a = h.alpha;
  9089. }
  9090. return new Color(h.rgb, a, 'hsla');
  9091. }
  9092. var m1_1;
  9093. var m2_1;
  9094. function hue(h) {
  9095. h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
  9096. if (h * 6 < 1) {
  9097. return m1_1 + (m2_1 - m1_1) * h * 6;
  9098. }
  9099. else if (h * 2 < 1) {
  9100. return m2_1;
  9101. }
  9102. else if (h * 3 < 2) {
  9103. return m1_1 + (m2_1 - m1_1) * (2 / 3 - h) * 6;
  9104. }
  9105. else {
  9106. return m1_1;
  9107. }
  9108. }
  9109. h = (number(h) % 360) / 360;
  9110. s = clamp$1(number(s));
  9111. l = clamp$1(number(l));
  9112. a = clamp$1(number(a));
  9113. m2_1 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
  9114. m1_1 = l * 2 - m2_1;
  9115. var rgb = [
  9116. hue(h + 1 / 3) * 255,
  9117. hue(h) * 255,
  9118. hue(h - 1 / 3) * 255
  9119. ];
  9120. a = number(a);
  9121. return new Color(rgb, a, 'hsla');
  9122. }
  9123. catch (e) { }
  9124. },
  9125. hsv: function (h, s, v) {
  9126. return colorFunctions.hsva(h, s, v, 1.0);
  9127. },
  9128. hsva: function (h, s, v, a) {
  9129. h = ((number(h) % 360) / 360) * 360;
  9130. s = number(s);
  9131. v = number(v);
  9132. a = number(a);
  9133. var i;
  9134. var f;
  9135. i = Math.floor((h / 60) % 6);
  9136. f = (h / 60) - i;
  9137. var vs = [v,
  9138. v * (1 - s),
  9139. v * (1 - f * s),
  9140. v * (1 - (1 - f) * s)];
  9141. var perm = [[0, 3, 1],
  9142. [2, 0, 1],
  9143. [1, 0, 3],
  9144. [1, 2, 0],
  9145. [3, 1, 0],
  9146. [0, 1, 2]];
  9147. return colorFunctions.rgba(vs[perm[i][0]] * 255, vs[perm[i][1]] * 255, vs[perm[i][2]] * 255, a);
  9148. },
  9149. hue: function (color) {
  9150. return new Dimension(toHSL(color).h);
  9151. },
  9152. saturation: function (color) {
  9153. return new Dimension(toHSL(color).s * 100, '%');
  9154. },
  9155. lightness: function (color) {
  9156. return new Dimension(toHSL(color).l * 100, '%');
  9157. },
  9158. hsvhue: function (color) {
  9159. return new Dimension(toHSV(color).h);
  9160. },
  9161. hsvsaturation: function (color) {
  9162. return new Dimension(toHSV(color).s * 100, '%');
  9163. },
  9164. hsvvalue: function (color) {
  9165. return new Dimension(toHSV(color).v * 100, '%');
  9166. },
  9167. red: function (color) {
  9168. return new Dimension(color.rgb[0]);
  9169. },
  9170. green: function (color) {
  9171. return new Dimension(color.rgb[1]);
  9172. },
  9173. blue: function (color) {
  9174. return new Dimension(color.rgb[2]);
  9175. },
  9176. alpha: function (color) {
  9177. return new Dimension(toHSL(color).a);
  9178. },
  9179. luma: function (color) {
  9180. return new Dimension(color.luma() * color.alpha * 100, '%');
  9181. },
  9182. luminance: function (color) {
  9183. var luminance = (0.2126 * color.rgb[0] / 255) +
  9184. (0.7152 * color.rgb[1] / 255) +
  9185. (0.0722 * color.rgb[2] / 255);
  9186. return new Dimension(luminance * color.alpha * 100, '%');
  9187. },
  9188. saturate: function (color, amount, method) {
  9189. // filter: saturate(3.2);
  9190. // should be kept as is, so check for color
  9191. if (!color.rgb) {
  9192. return null;
  9193. }
  9194. var hsl = toHSL(color);
  9195. if (typeof method !== 'undefined' && method.value === 'relative') {
  9196. hsl.s += hsl.s * amount.value / 100;
  9197. }
  9198. else {
  9199. hsl.s += amount.value / 100;
  9200. }
  9201. hsl.s = clamp$1(hsl.s);
  9202. return hsla(color, hsl);
  9203. },
  9204. desaturate: function (color, amount, method) {
  9205. var hsl = toHSL(color);
  9206. if (typeof method !== 'undefined' && method.value === 'relative') {
  9207. hsl.s -= hsl.s * amount.value / 100;
  9208. }
  9209. else {
  9210. hsl.s -= amount.value / 100;
  9211. }
  9212. hsl.s = clamp$1(hsl.s);
  9213. return hsla(color, hsl);
  9214. },
  9215. lighten: function (color, amount, method) {
  9216. var hsl = toHSL(color);
  9217. if (typeof method !== 'undefined' && method.value === 'relative') {
  9218. hsl.l += hsl.l * amount.value / 100;
  9219. }
  9220. else {
  9221. hsl.l += amount.value / 100;
  9222. }
  9223. hsl.l = clamp$1(hsl.l);
  9224. return hsla(color, hsl);
  9225. },
  9226. darken: function (color, amount, method) {
  9227. var hsl = toHSL(color);
  9228. if (typeof method !== 'undefined' && method.value === 'relative') {
  9229. hsl.l -= hsl.l * amount.value / 100;
  9230. }
  9231. else {
  9232. hsl.l -= amount.value / 100;
  9233. }
  9234. hsl.l = clamp$1(hsl.l);
  9235. return hsla(color, hsl);
  9236. },
  9237. fadein: function (color, amount, method) {
  9238. var hsl = toHSL(color);
  9239. if (typeof method !== 'undefined' && method.value === 'relative') {
  9240. hsl.a += hsl.a * amount.value / 100;
  9241. }
  9242. else {
  9243. hsl.a += amount.value / 100;
  9244. }
  9245. hsl.a = clamp$1(hsl.a);
  9246. return hsla(color, hsl);
  9247. },
  9248. fadeout: function (color, amount, method) {
  9249. var hsl = toHSL(color);
  9250. if (typeof method !== 'undefined' && method.value === 'relative') {
  9251. hsl.a -= hsl.a * amount.value / 100;
  9252. }
  9253. else {
  9254. hsl.a -= amount.value / 100;
  9255. }
  9256. hsl.a = clamp$1(hsl.a);
  9257. return hsla(color, hsl);
  9258. },
  9259. fade: function (color, amount) {
  9260. var hsl = toHSL(color);
  9261. hsl.a = amount.value / 100;
  9262. hsl.a = clamp$1(hsl.a);
  9263. return hsla(color, hsl);
  9264. },
  9265. spin: function (color, amount) {
  9266. var hsl = toHSL(color);
  9267. var hue = (hsl.h + amount.value) % 360;
  9268. hsl.h = hue < 0 ? 360 + hue : hue;
  9269. return hsla(color, hsl);
  9270. },
  9271. //
  9272. // Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein
  9273. // http://sass-lang.com
  9274. //
  9275. mix: function (color1, color2, weight) {
  9276. if (!weight) {
  9277. weight = new Dimension(50);
  9278. }
  9279. var p = weight.value / 100.0;
  9280. var w = p * 2 - 1;
  9281. var a = toHSL(color1).a - toHSL(color2).a;
  9282. var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
  9283. var w2 = 1 - w1;
  9284. var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
  9285. color1.rgb[1] * w1 + color2.rgb[1] * w2,
  9286. color1.rgb[2] * w1 + color2.rgb[2] * w2];
  9287. var alpha = color1.alpha * p + color2.alpha * (1 - p);
  9288. return new Color(rgb, alpha);
  9289. },
  9290. greyscale: function (color) {
  9291. return colorFunctions.desaturate(color, new Dimension(100));
  9292. },
  9293. contrast: function (color, dark, light, threshold) {
  9294. // filter: contrast(3.2);
  9295. // should be kept as is, so check for color
  9296. if (!color.rgb) {
  9297. return null;
  9298. }
  9299. if (typeof light === 'undefined') {
  9300. light = colorFunctions.rgba(255, 255, 255, 1.0);
  9301. }
  9302. if (typeof dark === 'undefined') {
  9303. dark = colorFunctions.rgba(0, 0, 0, 1.0);
  9304. }
  9305. // Figure out which is actually light and dark:
  9306. if (dark.luma() > light.luma()) {
  9307. var t = light;
  9308. light = dark;
  9309. dark = t;
  9310. }
  9311. if (typeof threshold === 'undefined') {
  9312. threshold = 0.43;
  9313. }
  9314. else {
  9315. threshold = number(threshold);
  9316. }
  9317. if (color.luma() < threshold) {
  9318. return light;
  9319. }
  9320. else {
  9321. return dark;
  9322. }
  9323. },
  9324. // Changes made in 2.7.0 - Reverted in 3.0.0
  9325. // contrast: function (color, color1, color2, threshold) {
  9326. // // Return which of `color1` and `color2` has the greatest contrast with `color`
  9327. // // according to the standard WCAG contrast ratio calculation.
  9328. // // http://www.w3.org/TR/WCAG20/#contrast-ratiodef
  9329. // // The threshold param is no longer used, in line with SASS.
  9330. // // filter: contrast(3.2);
  9331. // // should be kept as is, so check for color
  9332. // if (!color.rgb) {
  9333. // return null;
  9334. // }
  9335. // if (typeof color1 === 'undefined') {
  9336. // color1 = colorFunctions.rgba(0, 0, 0, 1.0);
  9337. // }
  9338. // if (typeof color2 === 'undefined') {
  9339. // color2 = colorFunctions.rgba(255, 255, 255, 1.0);
  9340. // }
  9341. // var contrast1, contrast2;
  9342. // var luma = color.luma();
  9343. // var luma1 = color1.luma();
  9344. // var luma2 = color2.luma();
  9345. // // Calculate contrast ratios for each color
  9346. // if (luma > luma1) {
  9347. // contrast1 = (luma + 0.05) / (luma1 + 0.05);
  9348. // } else {
  9349. // contrast1 = (luma1 + 0.05) / (luma + 0.05);
  9350. // }
  9351. // if (luma > luma2) {
  9352. // contrast2 = (luma + 0.05) / (luma2 + 0.05);
  9353. // } else {
  9354. // contrast2 = (luma2 + 0.05) / (luma + 0.05);
  9355. // }
  9356. // if (contrast1 > contrast2) {
  9357. // return color1;
  9358. // } else {
  9359. // return color2;
  9360. // }
  9361. // },
  9362. argb: function (color) {
  9363. return new Anonymous(color.toARGB());
  9364. },
  9365. color: function (c) {
  9366. if ((c instanceof Quoted) &&
  9367. (/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})$/i.test(c.value))) {
  9368. var val = c.value.slice(1);
  9369. return new Color(val, undefined, "#" + val);
  9370. }
  9371. if ((c instanceof Color) || (c = Color.fromKeyword(c.value))) {
  9372. c.value = undefined;
  9373. return c;
  9374. }
  9375. throw {
  9376. type: 'Argument',
  9377. message: 'argument must be a color keyword or 3|4|6|8 digit hex e.g. #FFF'
  9378. };
  9379. },
  9380. tint: function (color, amount) {
  9381. return colorFunctions.mix(colorFunctions.rgb(255, 255, 255), color, amount);
  9382. },
  9383. shade: function (color, amount) {
  9384. return colorFunctions.mix(colorFunctions.rgb(0, 0, 0), color, amount);
  9385. }
  9386. };
  9387. var color = colorFunctions;
  9388. // Color Blending
  9389. // ref: http://www.w3.org/TR/compositing-1
  9390. function colorBlend(mode, color1, color2) {
  9391. var ab = color1.alpha; // result
  9392. var // backdrop
  9393. cb;
  9394. var as = color2.alpha;
  9395. var // source
  9396. cs;
  9397. var ar;
  9398. var cr;
  9399. var r = [];
  9400. ar = as + ab * (1 - as);
  9401. for (var i_1 = 0; i_1 < 3; i_1++) {
  9402. cb = color1.rgb[i_1] / 255;
  9403. cs = color2.rgb[i_1] / 255;
  9404. cr = mode(cb, cs);
  9405. if (ar) {
  9406. cr = (as * cs + ab * (cb -
  9407. as * (cb + cs - cr))) / ar;
  9408. }
  9409. r[i_1] = cr * 255;
  9410. }
  9411. return new Color(r, ar);
  9412. }
  9413. var colorBlendModeFunctions = {
  9414. multiply: function (cb, cs) {
  9415. return cb * cs;
  9416. },
  9417. screen: function (cb, cs) {
  9418. return cb + cs - cb * cs;
  9419. },
  9420. overlay: function (cb, cs) {
  9421. cb *= 2;
  9422. return (cb <= 1) ?
  9423. colorBlendModeFunctions.multiply(cb, cs) :
  9424. colorBlendModeFunctions.screen(cb - 1, cs);
  9425. },
  9426. softlight: function (cb, cs) {
  9427. var d = 1;
  9428. var e = cb;
  9429. if (cs > 0.5) {
  9430. e = 1;
  9431. d = (cb > 0.25) ? Math.sqrt(cb)
  9432. : ((16 * cb - 12) * cb + 4) * cb;
  9433. }
  9434. return cb - (1 - 2 * cs) * e * (d - cb);
  9435. },
  9436. hardlight: function (cb, cs) {
  9437. return colorBlendModeFunctions.overlay(cs, cb);
  9438. },
  9439. difference: function (cb, cs) {
  9440. return Math.abs(cb - cs);
  9441. },
  9442. exclusion: function (cb, cs) {
  9443. return cb + cs - 2 * cb * cs;
  9444. },
  9445. // non-w3c functions:
  9446. average: function (cb, cs) {
  9447. return (cb + cs) / 2;
  9448. },
  9449. negation: function (cb, cs) {
  9450. return 1 - Math.abs(cb + cs - 1);
  9451. }
  9452. };
  9453. for (var f in colorBlendModeFunctions) {
  9454. if (colorBlendModeFunctions.hasOwnProperty(f)) {
  9455. colorBlend[f] = colorBlend.bind(null, colorBlendModeFunctions[f]);
  9456. }
  9457. }
  9458. var dataUri = (function (environment) {
  9459. var fallback = function (functionThis, node) { return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context); };
  9460. return { 'data-uri': function (mimetypeNode, filePathNode) {
  9461. if (!filePathNode) {
  9462. filePathNode = mimetypeNode;
  9463. mimetypeNode = null;
  9464. }
  9465. var mimetype = mimetypeNode && mimetypeNode.value;
  9466. var filePath = filePathNode.value;
  9467. var currentFileInfo = this.currentFileInfo;
  9468. var currentDirectory = currentFileInfo.rewriteUrls ?
  9469. currentFileInfo.currentDirectory : currentFileInfo.entryPath;
  9470. var fragmentStart = filePath.indexOf('#');
  9471. var fragment = '';
  9472. if (fragmentStart !== -1) {
  9473. fragment = filePath.slice(fragmentStart);
  9474. filePath = filePath.slice(0, fragmentStart);
  9475. }
  9476. var context = clone(this.context);
  9477. context.rawBuffer = true;
  9478. var fileManager = environment.getFileManager(filePath, currentDirectory, context, environment, true);
  9479. if (!fileManager) {
  9480. return fallback(this, filePathNode);
  9481. }
  9482. var useBase64 = false;
  9483. // detect the mimetype if not given
  9484. if (!mimetypeNode) {
  9485. mimetype = environment.mimeLookup(filePath);
  9486. if (mimetype === 'image/svg+xml') {
  9487. useBase64 = false;
  9488. }
  9489. else {
  9490. // use base 64 unless it's an ASCII or UTF-8 format
  9491. var charset = environment.charsetLookup(mimetype);
  9492. useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0;
  9493. }
  9494. if (useBase64) {
  9495. mimetype += ';base64';
  9496. }
  9497. }
  9498. else {
  9499. useBase64 = /;base64$/.test(mimetype);
  9500. }
  9501. var fileSync = fileManager.loadFileSync(filePath, currentDirectory, context, environment);
  9502. if (!fileSync.contents) {
  9503. logger.warn("Skipped data-uri embedding of " + filePath + " because file not found");
  9504. return fallback(this, filePathNode || mimetypeNode);
  9505. }
  9506. var buf = fileSync.contents;
  9507. if (useBase64 && !environment.encodeBase64) {
  9508. return fallback(this, filePathNode);
  9509. }
  9510. buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf);
  9511. var uri = "data:" + mimetype + "," + buf + fragment;
  9512. return new URL(new Quoted("\"" + uri + "\"", uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);
  9513. } };
  9514. });
  9515. var getItemsFromNode = function (node) {
  9516. // handle non-array values as an array of length 1
  9517. // return 'undefined' if index is invalid
  9518. var items = Array.isArray(node.value) ?
  9519. node.value : Array(node);
  9520. return items;
  9521. };
  9522. var list = {
  9523. _SELF: function (n) {
  9524. return n;
  9525. },
  9526. extract: function (values, index) {
  9527. // (1-based index)
  9528. index = index.value - 1;
  9529. return getItemsFromNode(values)[index];
  9530. },
  9531. length: function (values) {
  9532. return new Dimension(getItemsFromNode(values).length);
  9533. },
  9534. /**
  9535. * Creates a Less list of incremental values.
  9536. * Modeled after Lodash's range function, also exists natively in PHP
  9537. *
  9538. * @param {Dimension} [start=1]
  9539. * @param {Dimension} end - e.g. 10 or 10px - unit is added to output
  9540. * @param {Dimension} [step=1]
  9541. */
  9542. range: function (start, end, step) {
  9543. var from;
  9544. var to;
  9545. var stepValue = 1;
  9546. var list = [];
  9547. if (end) {
  9548. to = end;
  9549. from = start.value;
  9550. if (step) {
  9551. stepValue = step.value;
  9552. }
  9553. }
  9554. else {
  9555. from = 1;
  9556. to = start;
  9557. }
  9558. for (var i_1 = from; i_1 <= to.value; i_1 += stepValue) {
  9559. list.push(new Dimension(i_1, to.unit));
  9560. }
  9561. return new Expression(list);
  9562. },
  9563. each: function (list, rs) {
  9564. var rules = [];
  9565. var newRules;
  9566. var iterator;
  9567. if (list.value && !(list instanceof Quoted)) {
  9568. if (Array.isArray(list.value)) {
  9569. iterator = list.value;
  9570. }
  9571. else {
  9572. iterator = [list.value];
  9573. }
  9574. }
  9575. else if (list.ruleset) {
  9576. iterator = list.ruleset.rules;
  9577. }
  9578. else if (list.rules) {
  9579. iterator = list.rules;
  9580. }
  9581. else if (Array.isArray(list)) {
  9582. iterator = list;
  9583. }
  9584. else {
  9585. iterator = [list];
  9586. }
  9587. var valueName = '@value';
  9588. var keyName = '@key';
  9589. var indexName = '@index';
  9590. if (rs.params) {
  9591. valueName = rs.params[0] && rs.params[0].name;
  9592. keyName = rs.params[1] && rs.params[1].name;
  9593. indexName = rs.params[2] && rs.params[2].name;
  9594. rs = rs.rules;
  9595. }
  9596. else {
  9597. rs = rs.ruleset;
  9598. }
  9599. for (var i_2 = 0; i_2 < iterator.length; i_2++) {
  9600. var key = void 0;
  9601. var value = void 0;
  9602. var item = iterator[i_2];
  9603. if (item instanceof Declaration) {
  9604. key = typeof item.name === 'string' ? item.name : item.name[0].value;
  9605. value = item.value;
  9606. }
  9607. else {
  9608. key = new Dimension(i_2 + 1);
  9609. value = item;
  9610. }
  9611. if (item instanceof Comment) {
  9612. continue;
  9613. }
  9614. newRules = rs.rules.slice(0);
  9615. if (valueName) {
  9616. newRules.push(new Declaration(valueName, value, false, false, this.index, this.currentFileInfo));
  9617. }
  9618. if (indexName) {
  9619. newRules.push(new Declaration(indexName, new Dimension(i_2 + 1), false, false, this.index, this.currentFileInfo));
  9620. }
  9621. if (keyName) {
  9622. newRules.push(new Declaration(keyName, key, false, false, this.index, this.currentFileInfo));
  9623. }
  9624. rules.push(new Ruleset([new (Selector)([new Element("", '&')])], newRules, rs.strictImports, rs.visibilityInfo()));
  9625. }
  9626. return new Ruleset([new (Selector)([new Element("", '&')])], rules, rs.strictImports, rs.visibilityInfo()).eval(this.context);
  9627. }
  9628. };
  9629. var MathHelper = function (fn, unit, n) {
  9630. if (!(n instanceof Dimension)) {
  9631. throw { type: 'Argument', message: 'argument must be a number' };
  9632. }
  9633. if (unit == null) {
  9634. unit = n.unit;
  9635. }
  9636. else {
  9637. n = n.unify();
  9638. }
  9639. return new Dimension(fn(parseFloat(n.value)), unit);
  9640. };
  9641. var mathFunctions = {
  9642. // name, unit
  9643. ceil: null,
  9644. floor: null,
  9645. sqrt: null,
  9646. abs: null,
  9647. tan: '',
  9648. sin: '',
  9649. cos: '',
  9650. atan: 'rad',
  9651. asin: 'rad',
  9652. acos: 'rad'
  9653. };
  9654. for (var f$1 in mathFunctions) {
  9655. if (mathFunctions.hasOwnProperty(f$1)) {
  9656. mathFunctions[f$1] = MathHelper.bind(null, Math[f$1], mathFunctions[f$1]);
  9657. }
  9658. }
  9659. mathFunctions.round = function (n, f) {
  9660. var fraction = typeof f === 'undefined' ? 0 : f.value;
  9661. return MathHelper(function (num) { return num.toFixed(fraction); }, null, n);
  9662. };
  9663. var minMax = function (isMin, args) {
  9664. args = Array.prototype.slice.call(args);
  9665. switch (args.length) {
  9666. case 0: throw { type: 'Argument', message: 'one or more arguments required' };
  9667. }
  9668. var i; // key is the unit.toString() for unified Dimension values,
  9669. var j;
  9670. var current;
  9671. var currentUnified;
  9672. var referenceUnified;
  9673. var unit;
  9674. var unitStatic;
  9675. var unitClone;
  9676. var // elems only contains original argument values.
  9677. order = [];
  9678. var values = {};
  9679. // value is the index into the order array.
  9680. for (i = 0; i < args.length; i++) {
  9681. current = args[i];
  9682. if (!(current instanceof Dimension)) {
  9683. if (Array.isArray(args[i].value)) {
  9684. Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value));
  9685. }
  9686. continue;
  9687. }
  9688. currentUnified = current.unit.toString() === '' && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify();
  9689. unit = currentUnified.unit.toString() === '' && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString();
  9690. unitStatic = unit !== '' && unitStatic === undefined || unit !== '' && order[0].unify().unit.toString() === '' ? unit : unitStatic;
  9691. unitClone = unit !== '' && unitClone === undefined ? current.unit.toString() : unitClone;
  9692. j = values[''] !== undefined && unit !== '' && unit === unitStatic ? values[''] : values[unit];
  9693. if (j === undefined) {
  9694. if (unitStatic !== undefined && unit !== unitStatic) {
  9695. throw { type: 'Argument', message: 'incompatible types' };
  9696. }
  9697. values[unit] = order.length;
  9698. order.push(current);
  9699. continue;
  9700. }
  9701. referenceUnified = order[j].unit.toString() === '' && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify();
  9702. if (isMin && currentUnified.value < referenceUnified.value ||
  9703. !isMin && currentUnified.value > referenceUnified.value) {
  9704. order[j] = current;
  9705. }
  9706. }
  9707. if (order.length == 1) {
  9708. return order[0];
  9709. }
  9710. args = order.map(function (a) { return a.toCSS(this.context); }).join(this.context.compress ? ',' : ', ');
  9711. return new Anonymous((isMin ? 'min' : 'max') + "(" + args + ")");
  9712. };
  9713. var number$1 = {
  9714. min: function () {
  9715. var args = [];
  9716. for (var _i = 0; _i < arguments.length; _i++) {
  9717. args[_i] = arguments[_i];
  9718. }
  9719. return minMax(true, args);
  9720. },
  9721. max: function () {
  9722. var args = [];
  9723. for (var _i = 0; _i < arguments.length; _i++) {
  9724. args[_i] = arguments[_i];
  9725. }
  9726. return minMax(false, args);
  9727. },
  9728. convert: function (val, unit) {
  9729. return val.convertTo(unit.value);
  9730. },
  9731. pi: function () {
  9732. return new Dimension(Math.PI);
  9733. },
  9734. mod: function (a, b) {
  9735. return new Dimension(a.value % b.value, a.unit);
  9736. },
  9737. pow: function (x, y) {
  9738. if (typeof x === 'number' && typeof y === 'number') {
  9739. x = new Dimension(x);
  9740. y = new Dimension(y);
  9741. }
  9742. else if (!(x instanceof Dimension) || !(y instanceof Dimension)) {
  9743. throw { type: 'Argument', message: 'arguments must be numbers' };
  9744. }
  9745. return new Dimension(Math.pow(x.value, y.value), x.unit);
  9746. },
  9747. percentage: function (n) {
  9748. var result = MathHelper(function (num) { return num * 100; }, '%', n);
  9749. return result;
  9750. }
  9751. };
  9752. var string = {
  9753. e: function (str) {
  9754. return new Quoted('"', str instanceof JavaScript ? str.evaluated : str.value, true);
  9755. },
  9756. escape: function (str) {
  9757. return new Anonymous(encodeURI(str.value).replace(/=/g, '%3D').replace(/:/g, '%3A').replace(/#/g, '%23').replace(/;/g, '%3B')
  9758. .replace(/\(/g, '%28').replace(/\)/g, '%29'));
  9759. },
  9760. replace: function (string, pattern, replacement, flags) {
  9761. var result = string.value;
  9762. replacement = (replacement.type === 'Quoted') ?
  9763. replacement.value : replacement.toCSS();
  9764. result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement);
  9765. return new Quoted(string.quote || '', result, string.escaped);
  9766. },
  9767. '%': function (string /* arg, arg, ... */) {
  9768. var args = Array.prototype.slice.call(arguments, 1);
  9769. var result = string.value;
  9770. var _loop_1 = function (i_1) {
  9771. /* jshint loopfunc:true */
  9772. result = result.replace(/%[sda]/i, function (token) {
  9773. var value = ((args[i_1].type === 'Quoted') &&
  9774. token.match(/s/i)) ? args[i_1].value : args[i_1].toCSS();
  9775. return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
  9776. });
  9777. };
  9778. for (var i_1 = 0; i_1 < args.length; i_1++) {
  9779. _loop_1(i_1);
  9780. }
  9781. result = result.replace(/%%/g, '%');
  9782. return new Quoted(string.quote || '', result, string.escaped);
  9783. }
  9784. };
  9785. var svg = (function (environment) {
  9786. return { 'svg-gradient': function (direction) {
  9787. var stops;
  9788. var gradientDirectionSvg;
  9789. var gradientType = 'linear';
  9790. var rectangleDimension = 'x="0" y="0" width="1" height="1"';
  9791. var renderEnv = { compress: false };
  9792. var returner;
  9793. var directionValue = direction.toCSS(renderEnv);
  9794. var i;
  9795. var color;
  9796. var position;
  9797. var positionValue;
  9798. var alpha;
  9799. function throwArgumentDescriptor() {
  9800. throw { type: 'Argument',
  9801. message: 'svg-gradient expects direction, start_color [start_position], [color position,]...,' +
  9802. ' end_color [end_position] or direction, color list' };
  9803. }
  9804. if (arguments.length == 2) {
  9805. if (arguments[1].value.length < 2) {
  9806. throwArgumentDescriptor();
  9807. }
  9808. stops = arguments[1].value;
  9809. }
  9810. else if (arguments.length < 3) {
  9811. throwArgumentDescriptor();
  9812. }
  9813. else {
  9814. stops = Array.prototype.slice.call(arguments, 1);
  9815. }
  9816. switch (directionValue) {
  9817. case 'to bottom':
  9818. gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"';
  9819. break;
  9820. case 'to right':
  9821. gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"';
  9822. break;
  9823. case 'to bottom right':
  9824. gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"';
  9825. break;
  9826. case 'to top right':
  9827. gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"';
  9828. break;
  9829. case 'ellipse':
  9830. case 'ellipse at center':
  9831. gradientType = 'radial';
  9832. gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"';
  9833. rectangleDimension = 'x="-50" y="-50" width="101" height="101"';
  9834. break;
  9835. default:
  9836. throw { type: 'Argument', message: 'svg-gradient direction must be \'to bottom\', \'to right\',' +
  9837. ' \'to bottom right\', \'to top right\' or \'ellipse at center\'' };
  9838. }
  9839. returner = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1 1\"><" + gradientType + "Gradient id=\"g\" " + gradientDirectionSvg + ">";
  9840. for (i = 0; i < stops.length; i += 1) {
  9841. if (stops[i] instanceof Expression) {
  9842. color = stops[i].value[0];
  9843. position = stops[i].value[1];
  9844. }
  9845. else {
  9846. color = stops[i];
  9847. position = undefined;
  9848. }
  9849. if (!(color instanceof Color) || (!((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension))) {
  9850. throwArgumentDescriptor();
  9851. }
  9852. positionValue = position ? position.toCSS(renderEnv) : i === 0 ? '0%' : '100%';
  9853. alpha = color.alpha;
  9854. returner += "<stop offset=\"" + positionValue + "\" stop-color=\"" + color.toRGB() + "\"" + (alpha < 1 ? " stop-opacity=\"" + alpha + "\"" : '') + "/>";
  9855. }
  9856. returner += "</" + gradientType + "Gradient><rect " + rectangleDimension + " fill=\"url(#g)\" /></svg>";
  9857. returner = encodeURIComponent(returner);
  9858. returner = "data:image/svg+xml," + returner;
  9859. return new URL(new Quoted("'" + returner + "'", returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);
  9860. } };
  9861. });
  9862. var isa = function (n, Type) { return (n instanceof Type) ? Keyword.True : Keyword.False; };
  9863. var isunit = function (n, unit) {
  9864. if (unit === undefined) {
  9865. throw { type: 'Argument', message: 'missing the required second argument to isunit.' };
  9866. }
  9867. unit = typeof unit.value === 'string' ? unit.value : unit;
  9868. if (typeof unit !== 'string') {
  9869. throw { type: 'Argument', message: 'Second argument to isunit should be a unit or a string.' };
  9870. }
  9871. return (n instanceof Dimension) && n.unit.is(unit) ? Keyword.True : Keyword.False;
  9872. };
  9873. var types = {
  9874. isruleset: function (n) {
  9875. return isa(n, DetachedRuleset);
  9876. },
  9877. iscolor: function (n) {
  9878. return isa(n, Color);
  9879. },
  9880. isnumber: function (n) {
  9881. return isa(n, Dimension);
  9882. },
  9883. isstring: function (n) {
  9884. return isa(n, Quoted);
  9885. },
  9886. iskeyword: function (n) {
  9887. return isa(n, Keyword);
  9888. },
  9889. isurl: function (n) {
  9890. return isa(n, URL);
  9891. },
  9892. ispixel: function (n) {
  9893. return isunit(n, 'px');
  9894. },
  9895. ispercentage: function (n) {
  9896. return isunit(n, '%');
  9897. },
  9898. isem: function (n) {
  9899. return isunit(n, 'em');
  9900. },
  9901. isunit: isunit,
  9902. unit: function (val, unit) {
  9903. if (!(val instanceof Dimension)) {
  9904. throw { type: 'Argument',
  9905. message: "the first argument to unit must be a number" + (val instanceof Operation ? '. Have you forgotten parenthesis?' : '') };
  9906. }
  9907. if (unit) {
  9908. if (unit instanceof Keyword) {
  9909. unit = unit.value;
  9910. }
  9911. else {
  9912. unit = unit.toCSS();
  9913. }
  9914. }
  9915. else {
  9916. unit = '';
  9917. }
  9918. return new Dimension(val.value, unit);
  9919. },
  9920. 'get-unit': function (n) {
  9921. return new Anonymous(n.unit);
  9922. }
  9923. };
  9924. var Functions = (function (environment) {
  9925. var functions = { functionRegistry: functionRegistry, functionCaller: functionCaller };
  9926. // register functions
  9927. functionRegistry.addMultiple(boolean$1);
  9928. functionRegistry.add('default', defaultFunc.eval.bind(defaultFunc));
  9929. functionRegistry.addMultiple(color);
  9930. functionRegistry.addMultiple(colorBlend);
  9931. functionRegistry.addMultiple(dataUri(environment));
  9932. functionRegistry.addMultiple(list);
  9933. functionRegistry.addMultiple(mathFunctions);
  9934. functionRegistry.addMultiple(number$1);
  9935. functionRegistry.addMultiple(string);
  9936. functionRegistry.addMultiple(svg());
  9937. functionRegistry.addMultiple(types);
  9938. return functions;
  9939. });
  9940. var sourceMapOutput = (function (environment) {
  9941. var SourceMapOutput = /** @class */ (function () {
  9942. function SourceMapOutput(options) {
  9943. this._css = [];
  9944. this._rootNode = options.rootNode;
  9945. this._contentsMap = options.contentsMap;
  9946. this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap;
  9947. if (options.sourceMapFilename) {
  9948. this._sourceMapFilename = options.sourceMapFilename.replace(/\\/g, '/');
  9949. }
  9950. this._outputFilename = options.outputFilename;
  9951. this.sourceMapURL = options.sourceMapURL;
  9952. if (options.sourceMapBasepath) {
  9953. this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/');
  9954. }
  9955. if (options.sourceMapRootpath) {
  9956. this._sourceMapRootpath = options.sourceMapRootpath.replace(/\\/g, '/');
  9957. if (this._sourceMapRootpath.charAt(this._sourceMapRootpath.length - 1) !== '/') {
  9958. this._sourceMapRootpath += '/';
  9959. }
  9960. }
  9961. else {
  9962. this._sourceMapRootpath = '';
  9963. }
  9964. this._outputSourceFiles = options.outputSourceFiles;
  9965. this._sourceMapGeneratorConstructor = environment.getSourceMapGenerator();
  9966. this._lineNumber = 0;
  9967. this._column = 0;
  9968. }
  9969. SourceMapOutput.prototype.removeBasepath = function (path) {
  9970. if (this._sourceMapBasepath && path.indexOf(this._sourceMapBasepath) === 0) {
  9971. path = path.substring(this._sourceMapBasepath.length);
  9972. if (path.charAt(0) === '\\' || path.charAt(0) === '/') {
  9973. path = path.substring(1);
  9974. }
  9975. }
  9976. return path;
  9977. };
  9978. SourceMapOutput.prototype.normalizeFilename = function (filename) {
  9979. filename = filename.replace(/\\/g, '/');
  9980. filename = this.removeBasepath(filename);
  9981. return (this._sourceMapRootpath || '') + filename;
  9982. };
  9983. SourceMapOutput.prototype.add = function (chunk, fileInfo, index, mapLines) {
  9984. // ignore adding empty strings
  9985. if (!chunk) {
  9986. return;
  9987. }
  9988. var lines;
  9989. var sourceLines;
  9990. var columns;
  9991. var sourceColumns;
  9992. var i;
  9993. if (fileInfo && fileInfo.filename) {
  9994. var inputSource = this._contentsMap[fileInfo.filename];
  9995. // remove vars/banner added to the top of the file
  9996. if (this._contentsIgnoredCharsMap[fileInfo.filename]) {
  9997. // adjust the index
  9998. index -= this._contentsIgnoredCharsMap[fileInfo.filename];
  9999. if (index < 0) {
  10000. index = 0;
  10001. }
  10002. // adjust the source
  10003. inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]);
  10004. }
  10005. // ignore empty content
  10006. if (inputSource === undefined) {
  10007. return;
  10008. }
  10009. inputSource = inputSource.substring(0, index);
  10010. sourceLines = inputSource.split('\n');
  10011. sourceColumns = sourceLines[sourceLines.length - 1];
  10012. }
  10013. lines = chunk.split('\n');
  10014. columns = lines[lines.length - 1];
  10015. if (fileInfo && fileInfo.filename) {
  10016. if (!mapLines) {
  10017. this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column },
  10018. original: { line: sourceLines.length, column: sourceColumns.length },
  10019. source: this.normalizeFilename(fileInfo.filename) });
  10020. }
  10021. else {
  10022. for (i = 0; i < lines.length; i++) {
  10023. this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0 },
  10024. original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0 },
  10025. source: this.normalizeFilename(fileInfo.filename) });
  10026. }
  10027. }
  10028. }
  10029. if (lines.length === 1) {
  10030. this._column += columns.length;
  10031. }
  10032. else {
  10033. this._lineNumber += lines.length - 1;
  10034. this._column = columns.length;
  10035. }
  10036. this._css.push(chunk);
  10037. };
  10038. SourceMapOutput.prototype.isEmpty = function () {
  10039. return this._css.length === 0;
  10040. };
  10041. SourceMapOutput.prototype.toCSS = function (context) {
  10042. this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null });
  10043. if (this._outputSourceFiles) {
  10044. for (var filename in this._contentsMap) {
  10045. if (this._contentsMap.hasOwnProperty(filename)) {
  10046. var source = this._contentsMap[filename];
  10047. if (this._contentsIgnoredCharsMap[filename]) {
  10048. source = source.slice(this._contentsIgnoredCharsMap[filename]);
  10049. }
  10050. this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source);
  10051. }
  10052. }
  10053. }
  10054. this._rootNode.genCSS(context, this);
  10055. if (this._css.length > 0) {
  10056. var sourceMapURL = void 0;
  10057. var sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON());
  10058. if (this.sourceMapURL) {
  10059. sourceMapURL = this.sourceMapURL;
  10060. }
  10061. else if (this._sourceMapFilename) {
  10062. sourceMapURL = this._sourceMapFilename;
  10063. }
  10064. this.sourceMapURL = sourceMapURL;
  10065. this.sourceMap = sourceMapContent;
  10066. }
  10067. return this._css.join('');
  10068. };
  10069. return SourceMapOutput;
  10070. }());
  10071. return SourceMapOutput;
  10072. });
  10073. var sourceMapBuilder = (function (SourceMapOutput, environment) {
  10074. var SourceMapBuilder = /** @class */ (function () {
  10075. function SourceMapBuilder(options) {
  10076. this.options = options;
  10077. }
  10078. SourceMapBuilder.prototype.toCSS = function (rootNode, options, imports) {
  10079. var sourceMapOutput = new SourceMapOutput({
  10080. contentsIgnoredCharsMap: imports.contentsIgnoredChars,
  10081. rootNode: rootNode,
  10082. contentsMap: imports.contents,
  10083. sourceMapFilename: this.options.sourceMapFilename,
  10084. sourceMapURL: this.options.sourceMapURL,
  10085. outputFilename: this.options.sourceMapOutputFilename,
  10086. sourceMapBasepath: this.options.sourceMapBasepath,
  10087. sourceMapRootpath: this.options.sourceMapRootpath,
  10088. outputSourceFiles: this.options.outputSourceFiles,
  10089. sourceMapGenerator: this.options.sourceMapGenerator,
  10090. sourceMapFileInline: this.options.sourceMapFileInline
  10091. });
  10092. var css = sourceMapOutput.toCSS(options);
  10093. this.sourceMap = sourceMapOutput.sourceMap;
  10094. this.sourceMapURL = sourceMapOutput.sourceMapURL;
  10095. if (this.options.sourceMapInputFilename) {
  10096. this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename);
  10097. }
  10098. if (this.options.sourceMapBasepath !== undefined && this.sourceMapURL !== undefined) {
  10099. this.sourceMapURL = sourceMapOutput.removeBasepath(this.sourceMapURL);
  10100. }
  10101. return css + this.getCSSAppendage();
  10102. };
  10103. SourceMapBuilder.prototype.getCSSAppendage = function () {
  10104. var sourceMapURL = this.sourceMapURL;
  10105. if (this.options.sourceMapFileInline) {
  10106. if (this.sourceMap === undefined) {
  10107. return '';
  10108. }
  10109. sourceMapURL = "data:application/json;base64," + environment.encodeBase64(this.sourceMap);
  10110. }
  10111. if (sourceMapURL) {
  10112. return "/*# sourceMappingURL=" + sourceMapURL + " */";
  10113. }
  10114. return '';
  10115. };
  10116. SourceMapBuilder.prototype.getExternalSourceMap = function () {
  10117. return this.sourceMap;
  10118. };
  10119. SourceMapBuilder.prototype.setExternalSourceMap = function (sourceMap) {
  10120. this.sourceMap = sourceMap;
  10121. };
  10122. SourceMapBuilder.prototype.isInline = function () {
  10123. return this.options.sourceMapFileInline;
  10124. };
  10125. SourceMapBuilder.prototype.getSourceMapURL = function () {
  10126. return this.sourceMapURL;
  10127. };
  10128. SourceMapBuilder.prototype.getOutputFilename = function () {
  10129. return this.options.sourceMapOutputFilename;
  10130. };
  10131. SourceMapBuilder.prototype.getInputFilename = function () {
  10132. return this.sourceMapInputFilename;
  10133. };
  10134. return SourceMapBuilder;
  10135. }());
  10136. return SourceMapBuilder;
  10137. });
  10138. var transformTree = (function (root, options) {
  10139. if (options === void 0) { options = {}; }
  10140. var evaldRoot;
  10141. var variables = options.variables;
  10142. var evalEnv = new contexts.Eval(options);
  10143. //
  10144. // Allows setting variables with a hash, so:
  10145. //
  10146. // `{ color: new tree.Color('#f01') }` will become:
  10147. //
  10148. // new tree.Declaration('@color',
  10149. // new tree.Value([
  10150. // new tree.Expression([
  10151. // new tree.Color('#f01')
  10152. // ])
  10153. // ])
  10154. // )
  10155. //
  10156. if (typeof variables === 'object' && !Array.isArray(variables)) {
  10157. variables = Object.keys(variables).map(function (k) {
  10158. var value = variables[k];
  10159. if (!(value instanceof tree.Value)) {
  10160. if (!(value instanceof tree.Expression)) {
  10161. value = new tree.Expression([value]);
  10162. }
  10163. value = new tree.Value([value]);
  10164. }
  10165. return new tree.Declaration("@" + k, value, false, null, 0);
  10166. });
  10167. evalEnv.frames = [new tree.Ruleset(null, variables)];
  10168. }
  10169. var visitors$1 = [
  10170. new visitors.JoinSelectorVisitor(),
  10171. new visitors.MarkVisibleSelectorsVisitor(true),
  10172. new visitors.ExtendVisitor(),
  10173. new visitors.ToCSSVisitor({ compress: Boolean(options.compress) })
  10174. ];
  10175. var preEvalVisitors = [];
  10176. var v;
  10177. var visitorIterator;
  10178. /**
  10179. * first() / get() allows visitors to be added while visiting
  10180. *
  10181. * @todo Add scoping for visitors just like functions for @plugin; right now they're global
  10182. */
  10183. if (options.pluginManager) {
  10184. visitorIterator = options.pluginManager.visitor();
  10185. for (var i = 0; i < 2; i++) {
  10186. visitorIterator.first();
  10187. while ((v = visitorIterator.get())) {
  10188. if (v.isPreEvalVisitor) {
  10189. if (i === 0 || preEvalVisitors.indexOf(v) === -1) {
  10190. preEvalVisitors.push(v);
  10191. v.run(root);
  10192. }
  10193. }
  10194. else {
  10195. if (i === 0 || visitors$1.indexOf(v) === -1) {
  10196. if (v.isPreVisitor) {
  10197. visitors$1.unshift(v);
  10198. }
  10199. else {
  10200. visitors$1.push(v);
  10201. }
  10202. }
  10203. }
  10204. }
  10205. }
  10206. }
  10207. evaldRoot = root.eval(evalEnv);
  10208. for (var i = 0; i < visitors$1.length; i++) {
  10209. visitors$1[i].run(evaldRoot);
  10210. }
  10211. // Run any remaining visitors added after eval pass
  10212. if (options.pluginManager) {
  10213. visitorIterator.first();
  10214. while ((v = visitorIterator.get())) {
  10215. if (visitors$1.indexOf(v) === -1 && preEvalVisitors.indexOf(v) === -1) {
  10216. v.run(evaldRoot);
  10217. }
  10218. }
  10219. }
  10220. return evaldRoot;
  10221. });
  10222. var parseTree = (function (SourceMapBuilder) {
  10223. var ParseTree = /** @class */ (function () {
  10224. function ParseTree(root, imports) {
  10225. this.root = root;
  10226. this.imports = imports;
  10227. }
  10228. ParseTree.prototype.toCSS = function (options) {
  10229. var evaldRoot;
  10230. var result = {};
  10231. var sourceMapBuilder;
  10232. try {
  10233. evaldRoot = transformTree(this.root, options);
  10234. }
  10235. catch (e) {
  10236. throw new LessError(e, this.imports);
  10237. }
  10238. try {
  10239. var compress = Boolean(options.compress);
  10240. if (compress) {
  10241. logger.warn('The compress option has been deprecated. ' +
  10242. 'We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.');
  10243. }
  10244. var toCSSOptions = {
  10245. compress: compress,
  10246. dumpLineNumbers: options.dumpLineNumbers,
  10247. strictUnits: Boolean(options.strictUnits),
  10248. numPrecision: 8
  10249. };
  10250. if (options.sourceMap) {
  10251. sourceMapBuilder = new SourceMapBuilder(options.sourceMap);
  10252. result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports);
  10253. }
  10254. else {
  10255. result.css = evaldRoot.toCSS(toCSSOptions);
  10256. }
  10257. }
  10258. catch (e) {
  10259. throw new LessError(e, this.imports);
  10260. }
  10261. if (options.pluginManager) {
  10262. var postProcessors = options.pluginManager.getPostProcessors();
  10263. for (var i_1 = 0; i_1 < postProcessors.length; i_1++) {
  10264. result.css = postProcessors[i_1].process(result.css, { sourceMap: sourceMapBuilder, options: options, imports: this.imports });
  10265. }
  10266. }
  10267. if (options.sourceMap) {
  10268. result.map = sourceMapBuilder.getExternalSourceMap();
  10269. }
  10270. result.imports = [];
  10271. for (var file_1 in this.imports.files) {
  10272. if (this.imports.files.hasOwnProperty(file_1) && file_1 !== this.imports.rootFilename) {
  10273. result.imports.push(file_1);
  10274. }
  10275. }
  10276. return result;
  10277. };
  10278. return ParseTree;
  10279. }());
  10280. return ParseTree;
  10281. });
  10282. var importManager = (function (environment) {
  10283. // FileInfo = {
  10284. // 'rewriteUrls' - option - whether to adjust URL's to be relative
  10285. // 'filename' - full resolved filename of current file
  10286. // 'rootpath' - path to append to normal URLs for this node
  10287. // 'currentDirectory' - path to the current file, absolute
  10288. // 'rootFilename' - filename of the base file
  10289. // 'entryPath' - absolute path to the entry file
  10290. // 'reference' - whether the file should not be output and only output parts that are referenced
  10291. var ImportManager = /** @class */ (function () {
  10292. function ImportManager(less, context, rootFileInfo) {
  10293. this.less = less;
  10294. this.rootFilename = rootFileInfo.filename;
  10295. this.paths = context.paths || []; // Search paths, when importing
  10296. this.contents = {}; // map - filename to contents of all the files
  10297. this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore
  10298. this.mime = context.mime;
  10299. this.error = null;
  10300. this.context = context;
  10301. // Deprecated? Unused outside of here, could be useful.
  10302. this.queue = []; // Files which haven't been imported yet
  10303. this.files = {}; // Holds the imported parse trees.
  10304. }
  10305. /**
  10306. * Add an import to be imported
  10307. * @param path - the raw path
  10308. * @param tryAppendExtension - whether to try appending a file extension (.less or .js if the path has no extension)
  10309. * @param currentFileInfo - the current file info (used for instance to work out relative paths)
  10310. * @param importOptions - import options
  10311. * @param callback - callback for when it is imported
  10312. */
  10313. ImportManager.prototype.push = function (path, tryAppendExtension, currentFileInfo, importOptions, callback) {
  10314. var importManager = this;
  10315. var pluginLoader = this.context.pluginManager.Loader;
  10316. this.queue.push(path);
  10317. var fileParsedFunc = function (e, root, fullPath) {
  10318. importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue
  10319. var importedEqualsRoot = fullPath === importManager.rootFilename;
  10320. if (importOptions.optional && e) {
  10321. callback(null, { rules: [] }, false, null);
  10322. logger.info("The file " + fullPath + " was skipped because it was not found and the import was marked optional.");
  10323. }
  10324. else {
  10325. // Inline imports aren't cached here.
  10326. // If we start to cache them, please make sure they won't conflict with non-inline imports of the
  10327. // same name as they used to do before this comment and the condition below have been added.
  10328. if (!importManager.files[fullPath] && !importOptions.inline) {
  10329. importManager.files[fullPath] = { root: root, options: importOptions };
  10330. }
  10331. if (e && !importManager.error) {
  10332. importManager.error = e;
  10333. }
  10334. callback(e, root, importedEqualsRoot, fullPath);
  10335. }
  10336. };
  10337. var newFileInfo = {
  10338. rewriteUrls: this.context.rewriteUrls,
  10339. entryPath: currentFileInfo.entryPath,
  10340. rootpath: currentFileInfo.rootpath,
  10341. rootFilename: currentFileInfo.rootFilename
  10342. };
  10343. var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment);
  10344. if (!fileManager) {
  10345. fileParsedFunc({ message: "Could not find a file-manager for " + path });
  10346. return;
  10347. }
  10348. var loadFileCallback = function (loadedFile) {
  10349. var plugin;
  10350. var resolvedFilename = loadedFile.filename;
  10351. var contents = loadedFile.contents.replace(/^\uFEFF/, '');
  10352. // Pass on an updated rootpath if path of imported file is relative and file
  10353. // is in a (sub|sup) directory
  10354. //
  10355. // Examples:
  10356. // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/',
  10357. // then rootpath should become 'less/module/nav/'
  10358. // - If path of imported file is '../mixins.less' and rootpath is 'less/',
  10359. // then rootpath should become 'less/../'
  10360. newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename);
  10361. if (newFileInfo.rewriteUrls) {
  10362. newFileInfo.rootpath = fileManager.join((importManager.context.rootpath || ''), fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath));
  10363. if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) {
  10364. newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath);
  10365. }
  10366. }
  10367. newFileInfo.filename = resolvedFilename;
  10368. var newEnv = new contexts.Parse(importManager.context);
  10369. newEnv.processImports = false;
  10370. importManager.contents[resolvedFilename] = contents;
  10371. if (currentFileInfo.reference || importOptions.reference) {
  10372. newFileInfo.reference = true;
  10373. }
  10374. if (importOptions.isPlugin) {
  10375. plugin = pluginLoader.evalPlugin(contents, newEnv, importManager, importOptions.pluginArgs, newFileInfo);
  10376. if (plugin instanceof LessError) {
  10377. fileParsedFunc(plugin, null, resolvedFilename);
  10378. }
  10379. else {
  10380. fileParsedFunc(null, plugin, resolvedFilename);
  10381. }
  10382. }
  10383. else if (importOptions.inline) {
  10384. fileParsedFunc(null, contents, resolvedFilename);
  10385. }
  10386. else {
  10387. // import (multiple) parse trees apparently get altered and can't be cached.
  10388. // TODO: investigate why this is
  10389. if (importManager.files[resolvedFilename]
  10390. && !importManager.files[resolvedFilename].options.multiple
  10391. && !importOptions.multiple) {
  10392. fileParsedFunc(null, importManager.files[resolvedFilename].root, resolvedFilename);
  10393. }
  10394. else {
  10395. new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) {
  10396. fileParsedFunc(e, root, resolvedFilename);
  10397. });
  10398. }
  10399. }
  10400. };
  10401. var promise;
  10402. var context = clone(this.context);
  10403. if (tryAppendExtension) {
  10404. context.ext = importOptions.isPlugin ? '.js' : '.less';
  10405. }
  10406. if (importOptions.isPlugin) {
  10407. context.mime = 'application/javascript';
  10408. promise = pluginLoader.loadPlugin(path, currentFileInfo.currentDirectory, context, environment, fileManager);
  10409. }
  10410. else {
  10411. promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, context, environment, function (err, loadedFile) {
  10412. if (err) {
  10413. fileParsedFunc(err);
  10414. }
  10415. else {
  10416. loadFileCallback(loadedFile);
  10417. }
  10418. });
  10419. }
  10420. if (promise) {
  10421. promise.then(loadFileCallback, fileParsedFunc);
  10422. }
  10423. };
  10424. return ImportManager;
  10425. }());
  10426. return ImportManager;
  10427. });
  10428. var Render = (function (environment, ParseTree, ImportManager) {
  10429. var render = function (input, options, callback) {
  10430. if (typeof options === 'function') {
  10431. callback = options;
  10432. options = copyOptions(this.options, {});
  10433. }
  10434. else {
  10435. options = copyOptions(this.options, options || {});
  10436. }
  10437. if (!callback) {
  10438. var self_1 = this;
  10439. return new Promise(function (resolve, reject) {
  10440. render.call(self_1, input, options, function (err, output) {
  10441. if (err) {
  10442. reject(err);
  10443. }
  10444. else {
  10445. resolve(output);
  10446. }
  10447. });
  10448. });
  10449. }
  10450. else {
  10451. this.parse(input, options, function (err, root, imports, options) {
  10452. if (err) {
  10453. return callback(err);
  10454. }
  10455. var result;
  10456. try {
  10457. var parseTree = new ParseTree(root, imports);
  10458. result = parseTree.toCSS(options);
  10459. }
  10460. catch (err) {
  10461. return callback(err);
  10462. }
  10463. callback(null, result);
  10464. });
  10465. }
  10466. };
  10467. return render;
  10468. });
  10469. /**
  10470. * Plugin Manager
  10471. */
  10472. var PluginManager = /** @class */ (function () {
  10473. function PluginManager(less) {
  10474. this.less = less;
  10475. this.visitors = [];
  10476. this.preProcessors = [];
  10477. this.postProcessors = [];
  10478. this.installedPlugins = [];
  10479. this.fileManagers = [];
  10480. this.iterator = -1;
  10481. this.pluginCache = {};
  10482. this.Loader = new less.PluginLoader(less);
  10483. }
  10484. /**
  10485. * Adds all the plugins in the array
  10486. * @param {Array} plugins
  10487. */
  10488. PluginManager.prototype.addPlugins = function (plugins) {
  10489. if (plugins) {
  10490. for (var i_1 = 0; i_1 < plugins.length; i_1++) {
  10491. this.addPlugin(plugins[i_1]);
  10492. }
  10493. }
  10494. };
  10495. /**
  10496. *
  10497. * @param plugin
  10498. * @param {String} filename
  10499. */
  10500. PluginManager.prototype.addPlugin = function (plugin, filename, functionRegistry) {
  10501. this.installedPlugins.push(plugin);
  10502. if (filename) {
  10503. this.pluginCache[filename] = plugin;
  10504. }
  10505. if (plugin.install) {
  10506. plugin.install(this.less, this, functionRegistry || this.less.functions.functionRegistry);
  10507. }
  10508. };
  10509. /**
  10510. *
  10511. * @param filename
  10512. */
  10513. PluginManager.prototype.get = function (filename) {
  10514. return this.pluginCache[filename];
  10515. };
  10516. /**
  10517. * Adds a visitor. The visitor object has options on itself to determine
  10518. * when it should run.
  10519. * @param visitor
  10520. */
  10521. PluginManager.prototype.addVisitor = function (visitor) {
  10522. this.visitors.push(visitor);
  10523. };
  10524. /**
  10525. * Adds a pre processor object
  10526. * @param {object} preProcessor
  10527. * @param {number} priority - guidelines 1 = before import, 1000 = import, 2000 = after import
  10528. */
  10529. PluginManager.prototype.addPreProcessor = function (preProcessor, priority) {
  10530. var indexToInsertAt;
  10531. for (indexToInsertAt = 0; indexToInsertAt < this.preProcessors.length; indexToInsertAt++) {
  10532. if (this.preProcessors[indexToInsertAt].priority >= priority) {
  10533. break;
  10534. }
  10535. }
  10536. this.preProcessors.splice(indexToInsertAt, 0, { preProcessor: preProcessor, priority: priority });
  10537. };
  10538. /**
  10539. * Adds a post processor object
  10540. * @param {object} postProcessor
  10541. * @param {number} priority - guidelines 1 = before compression, 1000 = compression, 2000 = after compression
  10542. */
  10543. PluginManager.prototype.addPostProcessor = function (postProcessor, priority) {
  10544. var indexToInsertAt;
  10545. for (indexToInsertAt = 0; indexToInsertAt < this.postProcessors.length; indexToInsertAt++) {
  10546. if (this.postProcessors[indexToInsertAt].priority >= priority) {
  10547. break;
  10548. }
  10549. }
  10550. this.postProcessors.splice(indexToInsertAt, 0, { postProcessor: postProcessor, priority: priority });
  10551. };
  10552. /**
  10553. *
  10554. * @param manager
  10555. */
  10556. PluginManager.prototype.addFileManager = function (manager) {
  10557. this.fileManagers.push(manager);
  10558. };
  10559. /**
  10560. *
  10561. * @returns {Array}
  10562. * @private
  10563. */
  10564. PluginManager.prototype.getPreProcessors = function () {
  10565. var preProcessors = [];
  10566. for (var i_2 = 0; i_2 < this.preProcessors.length; i_2++) {
  10567. preProcessors.push(this.preProcessors[i_2].preProcessor);
  10568. }
  10569. return preProcessors;
  10570. };
  10571. /**
  10572. *
  10573. * @returns {Array}
  10574. * @private
  10575. */
  10576. PluginManager.prototype.getPostProcessors = function () {
  10577. var postProcessors = [];
  10578. for (var i_3 = 0; i_3 < this.postProcessors.length; i_3++) {
  10579. postProcessors.push(this.postProcessors[i_3].postProcessor);
  10580. }
  10581. return postProcessors;
  10582. };
  10583. /**
  10584. *
  10585. * @returns {Array}
  10586. * @private
  10587. */
  10588. PluginManager.prototype.getVisitors = function () {
  10589. return this.visitors;
  10590. };
  10591. PluginManager.prototype.visitor = function () {
  10592. var self = this;
  10593. return {
  10594. first: function () {
  10595. self.iterator = -1;
  10596. return self.visitors[self.iterator];
  10597. },
  10598. get: function () {
  10599. self.iterator += 1;
  10600. return self.visitors[self.iterator];
  10601. }
  10602. };
  10603. };
  10604. /**
  10605. *
  10606. * @returns {Array}
  10607. * @private
  10608. */
  10609. PluginManager.prototype.getFileManagers = function () {
  10610. return this.fileManagers;
  10611. };
  10612. return PluginManager;
  10613. }());
  10614. var pm;
  10615. function PluginManagerFactory(less, newFactory) {
  10616. if (newFactory || !pm) {
  10617. pm = new PluginManager(less);
  10618. }
  10619. return pm;
  10620. }
  10621. var Parse = (function (environment, ParseTree, ImportManager) {
  10622. var parse = function (input, options, callback) {
  10623. if (typeof options === 'function') {
  10624. callback = options;
  10625. options = copyOptions(this.options, {});
  10626. }
  10627. else {
  10628. options = copyOptions(this.options, options || {});
  10629. }
  10630. if (!callback) {
  10631. var self_1 = this;
  10632. return new Promise(function (resolve, reject) {
  10633. parse.call(self_1, input, options, function (err, output) {
  10634. if (err) {
  10635. reject(err);
  10636. }
  10637. else {
  10638. resolve(output);
  10639. }
  10640. });
  10641. });
  10642. }
  10643. else {
  10644. var context_1;
  10645. var rootFileInfo = void 0;
  10646. var pluginManager_1 = new PluginManagerFactory(this, !options.reUsePluginManager);
  10647. options.pluginManager = pluginManager_1;
  10648. context_1 = new contexts.Parse(options);
  10649. if (options.rootFileInfo) {
  10650. rootFileInfo = options.rootFileInfo;
  10651. }
  10652. else {
  10653. var filename = options.filename || 'input';
  10654. var entryPath = filename.replace(/[^\/\\]*$/, '');
  10655. rootFileInfo = {
  10656. filename: filename,
  10657. rewriteUrls: context_1.rewriteUrls,
  10658. rootpath: context_1.rootpath || '',
  10659. currentDirectory: entryPath,
  10660. entryPath: entryPath,
  10661. rootFilename: filename
  10662. };
  10663. // add in a missing trailing slash
  10664. if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== '/') {
  10665. rootFileInfo.rootpath += '/';
  10666. }
  10667. }
  10668. var imports_1 = new ImportManager(this, context_1, rootFileInfo);
  10669. this.importManager = imports_1;
  10670. // TODO: allow the plugins to be just a list of paths or names
  10671. // Do an async plugin queue like lessc
  10672. if (options.plugins) {
  10673. options.plugins.forEach(function (plugin) {
  10674. var evalResult;
  10675. var contents;
  10676. if (plugin.fileContent) {
  10677. contents = plugin.fileContent.replace(/^\uFEFF/, '');
  10678. evalResult = pluginManager_1.Loader.evalPlugin(contents, context_1, imports_1, plugin.options, plugin.filename);
  10679. if (evalResult instanceof LessError) {
  10680. return callback(evalResult);
  10681. }
  10682. }
  10683. else {
  10684. pluginManager_1.addPlugin(plugin);
  10685. }
  10686. });
  10687. }
  10688. new Parser(context_1, imports_1, rootFileInfo)
  10689. .parse(input, function (e, root) {
  10690. if (e) {
  10691. return callback(e);
  10692. }
  10693. callback(null, root, imports_1, options);
  10694. }, options);
  10695. }
  10696. };
  10697. return parse;
  10698. });
  10699. var lessRoot = (function (environment$1, fileManagers) {
  10700. /**
  10701. * @todo
  10702. * This original code could be improved quite a bit.
  10703. * Many classes / modules currently add side-effects / mutations to passed in objects,
  10704. * which makes it hard to refactor and reason about.
  10705. */
  10706. environment$1 = new environment(environment$1, fileManagers);
  10707. var SourceMapOutput = sourceMapOutput(environment$1);
  10708. var SourceMapBuilder = sourceMapBuilder(SourceMapOutput, environment$1);
  10709. var ParseTree = parseTree(SourceMapBuilder);
  10710. var ImportManager = importManager(environment$1);
  10711. var render = Render(environment$1, ParseTree);
  10712. var parse = Parse(environment$1, ParseTree, ImportManager);
  10713. var functions = Functions(environment$1);
  10714. /**
  10715. * @todo
  10716. * This root properties / methods need to be organized.
  10717. * It's not clear what should / must be public and why.
  10718. */
  10719. var initial = {
  10720. version: [3, 11, 1],
  10721. data: data,
  10722. tree: tree,
  10723. Environment: environment,
  10724. AbstractFileManager: AbstractFileManager,
  10725. AbstractPluginLoader: AbstractPluginLoader,
  10726. environment: environment$1,
  10727. visitors: visitors,
  10728. Parser: Parser,
  10729. functions: functions,
  10730. contexts: contexts,
  10731. SourceMapOutput: SourceMapOutput,
  10732. SourceMapBuilder: SourceMapBuilder,
  10733. ParseTree: ParseTree,
  10734. ImportManager: ImportManager,
  10735. render: render,
  10736. parse: parse,
  10737. LessError: LessError,
  10738. transformTree: transformTree,
  10739. utils: utils,
  10740. PluginManager: PluginManagerFactory,
  10741. logger: logger
  10742. };
  10743. // Create a public API
  10744. var ctor = function (t) { return function () {
  10745. var args = [];
  10746. for (var _i = 0; _i < arguments.length; _i++) {
  10747. args[_i] = arguments[_i];
  10748. }
  10749. return new (t.bind.apply(t, __spreadArrays([void 0], args)))();
  10750. }; };
  10751. var t;
  10752. var api = Object.create(initial);
  10753. for (var n in initial.tree) {
  10754. /* eslint guard-for-in: 0 */
  10755. t = initial.tree[n];
  10756. if (typeof t === 'function') {
  10757. api[n.toLowerCase()] = ctor(t);
  10758. }
  10759. else {
  10760. api[n] = Object.create(null);
  10761. for (var o in t) {
  10762. /* eslint guard-for-in: 0 */
  10763. api[n][o.toLowerCase()] = ctor(t[o]);
  10764. }
  10765. }
  10766. }
  10767. return api;
  10768. });
  10769. /* global window, XMLHttpRequest */
  10770. var options;
  10771. var logger$1;
  10772. var fileCache = {};
  10773. // TODOS - move log somewhere. pathDiff and doing something similar in node. use pathDiff in the other browser file for the initial load
  10774. var FileManager = /** @class */ (function (_super) {
  10775. __extends(FileManager, _super);
  10776. function FileManager() {
  10777. return _super !== null && _super.apply(this, arguments) || this;
  10778. }
  10779. FileManager.prototype.alwaysMakePathsAbsolute = function () {
  10780. return true;
  10781. };
  10782. FileManager.prototype.join = function (basePath, laterPath) {
  10783. if (!basePath) {
  10784. return laterPath;
  10785. }
  10786. return this.extractUrlParts(laterPath, basePath).path;
  10787. };
  10788. FileManager.prototype.doXHR = function (url, type, callback, errback) {
  10789. var xhr = new XMLHttpRequest();
  10790. var async = options.isFileProtocol ? options.fileAsync : true;
  10791. if (typeof xhr.overrideMimeType === 'function') {
  10792. xhr.overrideMimeType('text/css');
  10793. }
  10794. logger$1.debug("XHR: Getting '" + url + "'");
  10795. xhr.open('GET', url, async);
  10796. xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
  10797. xhr.send(null);
  10798. function handleResponse(xhr, callback, errback) {
  10799. if (xhr.status >= 200 && xhr.status < 300) {
  10800. callback(xhr.responseText, xhr.getResponseHeader('Last-Modified'));
  10801. }
  10802. else if (typeof errback === 'function') {
  10803. errback(xhr.status, url);
  10804. }
  10805. }
  10806. if (options.isFileProtocol && !options.fileAsync) {
  10807. if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
  10808. callback(xhr.responseText);
  10809. }
  10810. else {
  10811. errback(xhr.status, url);
  10812. }
  10813. }
  10814. else if (async) {
  10815. xhr.onreadystatechange = function () {
  10816. if (xhr.readyState == 4) {
  10817. handleResponse(xhr, callback, errback);
  10818. }
  10819. };
  10820. }
  10821. else {
  10822. handleResponse(xhr, callback, errback);
  10823. }
  10824. };
  10825. FileManager.prototype.supports = function () {
  10826. return true;
  10827. };
  10828. FileManager.prototype.clearFileCache = function () {
  10829. fileCache = {};
  10830. };
  10831. FileManager.prototype.loadFile = function (filename, currentDirectory, options, environment) {
  10832. // TODO: Add prefix support like less-node?
  10833. // What about multiple paths?
  10834. if (currentDirectory && !this.isPathAbsolute(filename)) {
  10835. filename = currentDirectory + filename;
  10836. }
  10837. filename = options.ext ? this.tryAppendExtension(filename, options.ext) : filename;
  10838. options = options || {};
  10839. // sheet may be set to the stylesheet for the initial load or a collection of properties including
  10840. // some context variables for imports
  10841. var hrefParts = this.extractUrlParts(filename, window.location.href);
  10842. var href = hrefParts.url;
  10843. var self = this;
  10844. return new Promise(function (resolve, reject) {
  10845. if (options.useFileCache && fileCache[href]) {
  10846. try {
  10847. var lessText_1 = fileCache[href];
  10848. return resolve({ contents: lessText_1, filename: href, webInfo: { lastModified: new Date() } });
  10849. }
  10850. catch (e) {
  10851. return reject({ filename: href, message: "Error loading file " + href + " error was " + e.message });
  10852. }
  10853. }
  10854. self.doXHR(href, options.mime, function doXHRCallback(data, lastModified) {
  10855. // per file cache
  10856. fileCache[href] = data;
  10857. // Use remote copy (re-parse)
  10858. resolve({ contents: data, filename: href, webInfo: { lastModified: lastModified } });
  10859. }, function doXHRError(status, url) {
  10860. reject({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")", href: href });
  10861. });
  10862. });
  10863. };
  10864. return FileManager;
  10865. }(AbstractFileManager));
  10866. var FM = (function (opts, log) {
  10867. options = opts;
  10868. logger$1 = log;
  10869. return FileManager;
  10870. });
  10871. // TODO: Add tests for browser @plugin
  10872. /**
  10873. * Browser Plugin Loader
  10874. */
  10875. var PluginLoader = /** @class */ (function (_super) {
  10876. __extends(PluginLoader, _super);
  10877. function PluginLoader(less) {
  10878. var _this = _super.call(this) || this;
  10879. _this.less = less;
  10880. return _this;
  10881. // Should we shim this.require for browser? Probably not?
  10882. }
  10883. PluginLoader.prototype.loadPlugin = function (filename, basePath, context, environment, fileManager) {
  10884. return new Promise(function (fulfill, reject) {
  10885. fileManager.loadFile(filename, basePath, context, environment)
  10886. .then(fulfill).catch(reject);
  10887. });
  10888. };
  10889. return PluginLoader;
  10890. }(AbstractPluginLoader));
  10891. var LogListener = (function (less, options) {
  10892. var logLevel_debug = 4;
  10893. var logLevel_info = 3;
  10894. var logLevel_warn = 2;
  10895. var logLevel_error = 1;
  10896. // The amount of logging in the javascript console.
  10897. // 3 - Debug, information and errors
  10898. // 2 - Information and errors
  10899. // 1 - Errors
  10900. // 0 - None
  10901. // Defaults to 2
  10902. options.logLevel = typeof options.logLevel !== 'undefined' ? options.logLevel : (options.env === 'development' ? logLevel_info : logLevel_error);
  10903. if (!options.loggers) {
  10904. options.loggers = [{
  10905. debug: function (msg) {
  10906. if (options.logLevel >= logLevel_debug) {
  10907. console.log(msg);
  10908. }
  10909. },
  10910. info: function (msg) {
  10911. if (options.logLevel >= logLevel_info) {
  10912. console.log(msg);
  10913. }
  10914. },
  10915. warn: function (msg) {
  10916. if (options.logLevel >= logLevel_warn) {
  10917. console.warn(msg);
  10918. }
  10919. },
  10920. error: function (msg) {
  10921. if (options.logLevel >= logLevel_error) {
  10922. console.error(msg);
  10923. }
  10924. }
  10925. }];
  10926. }
  10927. for (var i_1 = 0; i_1 < options.loggers.length; i_1++) {
  10928. less.logger.addListener(options.loggers[i_1]);
  10929. }
  10930. });
  10931. var ErrorReporting = (function (window, less, options) {
  10932. function errorHTML(e, rootHref) {
  10933. var id = "less-error-message:" + extractId(rootHref || '');
  10934. var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
  10935. var elem = window.document.createElement('div');
  10936. var timer;
  10937. var content;
  10938. var errors = [];
  10939. var filename = e.filename || rootHref;
  10940. var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1];
  10941. elem.id = id;
  10942. elem.className = 'less-error-message';
  10943. content = "<h3>" + (e.type || 'Syntax') + "Error: " + (e.message || 'There is an error in your .less file') +
  10944. ("</h3><p>in <a href=\"" + filename + "\">" + filenameNoPath + "</a> ");
  10945. var errorline = function (e, i, classname) {
  10946. if (e.extract[i] !== undefined) {
  10947. errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
  10948. .replace(/\{class\}/, classname)
  10949. .replace(/\{content\}/, e.extract[i]));
  10950. }
  10951. };
  10952. if (e.line) {
  10953. errorline(e, 0, '');
  10954. errorline(e, 1, 'line');
  10955. errorline(e, 2, '');
  10956. content += "on line " + e.line + ", column " + (e.column + 1) + ":</p><ul>" + errors.join('') + "</ul>";
  10957. }
  10958. if (e.stack && (e.extract || options.logLevel >= 4)) {
  10959. content += "<br/>Stack Trace</br />" + e.stack.split('\n').slice(1).join('<br/>');
  10960. }
  10961. elem.innerHTML = content;
  10962. // CSS for error messages
  10963. browser.createCSS(window.document, [
  10964. '.less-error-message ul, .less-error-message li {',
  10965. 'list-style-type: none;',
  10966. 'margin-right: 15px;',
  10967. 'padding: 4px 0;',
  10968. 'margin: 0;',
  10969. '}',
  10970. '.less-error-message label {',
  10971. 'font-size: 12px;',
  10972. 'margin-right: 15px;',
  10973. 'padding: 4px 0;',
  10974. 'color: #cc7777;',
  10975. '}',
  10976. '.less-error-message pre {',
  10977. 'color: #dd6666;',
  10978. 'padding: 4px 0;',
  10979. 'margin: 0;',
  10980. 'display: inline-block;',
  10981. '}',
  10982. '.less-error-message pre.line {',
  10983. 'color: #ff0000;',
  10984. '}',
  10985. '.less-error-message h3 {',
  10986. 'font-size: 20px;',
  10987. 'font-weight: bold;',
  10988. 'padding: 15px 0 5px 0;',
  10989. 'margin: 0;',
  10990. '}',
  10991. '.less-error-message a {',
  10992. 'color: #10a',
  10993. '}',
  10994. '.less-error-message .error {',
  10995. 'color: red;',
  10996. 'font-weight: bold;',
  10997. 'padding-bottom: 2px;',
  10998. 'border-bottom: 1px dashed red;',
  10999. '}'
  11000. ].join('\n'), { title: 'error-message' });
  11001. elem.style.cssText = [
  11002. 'font-family: Arial, sans-serif',
  11003. 'border: 1px solid #e00',
  11004. 'background-color: #eee',
  11005. 'border-radius: 5px',
  11006. '-webkit-border-radius: 5px',
  11007. '-moz-border-radius: 5px',
  11008. 'color: #e00',
  11009. 'padding: 15px',
  11010. 'margin-bottom: 15px'
  11011. ].join(';');
  11012. if (options.env === 'development') {
  11013. timer = setInterval(function () {
  11014. var document = window.document;
  11015. var body = document.body;
  11016. if (body) {
  11017. if (document.getElementById(id)) {
  11018. body.replaceChild(elem, document.getElementById(id));
  11019. }
  11020. else {
  11021. body.insertBefore(elem, body.firstChild);
  11022. }
  11023. clearInterval(timer);
  11024. }
  11025. }, 10);
  11026. }
  11027. }
  11028. function removeErrorHTML(path) {
  11029. var node = window.document.getElementById("less-error-message:" + extractId(path));
  11030. if (node) {
  11031. node.parentNode.removeChild(node);
  11032. }
  11033. }
  11034. function removeError(path) {
  11035. if (!options.errorReporting || options.errorReporting === 'html') {
  11036. removeErrorHTML(path);
  11037. }
  11038. else if (options.errorReporting === 'console') ;
  11039. else if (typeof options.errorReporting === 'function') {
  11040. options.errorReporting('remove', path);
  11041. }
  11042. }
  11043. function errorConsole(e, rootHref) {
  11044. var template = '{line} {content}';
  11045. var filename = e.filename || rootHref;
  11046. var errors = [];
  11047. var content = (e.type || 'Syntax') + "Error: " + (e.message || 'There is an error in your .less file') + " in " + filename;
  11048. var errorline = function (e, i, classname) {
  11049. if (e.extract[i] !== undefined) {
  11050. errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
  11051. .replace(/\{class\}/, classname)
  11052. .replace(/\{content\}/, e.extract[i]));
  11053. }
  11054. };
  11055. if (e.line) {
  11056. errorline(e, 0, '');
  11057. errorline(e, 1, 'line');
  11058. errorline(e, 2, '');
  11059. content += " on line " + e.line + ", column " + (e.column + 1) + ":\n" + errors.join('\n');
  11060. }
  11061. if (e.stack && (e.extract || options.logLevel >= 4)) {
  11062. content += "\nStack Trace\n" + e.stack;
  11063. }
  11064. less.logger.error(content);
  11065. }
  11066. function error(e, rootHref) {
  11067. if (!options.errorReporting || options.errorReporting === 'html') {
  11068. errorHTML(e, rootHref);
  11069. }
  11070. else if (options.errorReporting === 'console') {
  11071. errorConsole(e, rootHref);
  11072. }
  11073. else if (typeof options.errorReporting === 'function') {
  11074. options.errorReporting('add', e, rootHref);
  11075. }
  11076. }
  11077. return {
  11078. add: error,
  11079. remove: removeError
  11080. };
  11081. });
  11082. // Cache system is a bit outdated and could do with work
  11083. var Cache = (function (window, options, logger) {
  11084. var cache = null;
  11085. if (options.env !== 'development') {
  11086. try {
  11087. cache = (typeof window.localStorage === 'undefined') ? null : window.localStorage;
  11088. }
  11089. catch (_) { }
  11090. }
  11091. return {
  11092. setCSS: function (path, lastModified, modifyVars, styles) {
  11093. if (cache) {
  11094. logger.info("saving " + path + " to cache.");
  11095. try {
  11096. cache.setItem(path, styles);
  11097. cache.setItem(path + ":timestamp", lastModified);
  11098. if (modifyVars) {
  11099. cache.setItem(path + ":vars", JSON.stringify(modifyVars));
  11100. }
  11101. }
  11102. catch (e) {
  11103. // TODO - could do with adding more robust error handling
  11104. logger.error("failed to save \"" + path + "\" to local storage for caching.");
  11105. }
  11106. }
  11107. },
  11108. getCSS: function (path, webInfo, modifyVars) {
  11109. var css = cache && cache.getItem(path);
  11110. var timestamp = cache && cache.getItem(path + ":timestamp");
  11111. var vars = cache && cache.getItem(path + ":vars");
  11112. modifyVars = modifyVars || {};
  11113. vars = vars || "{}"; // if not set, treat as the JSON representation of an empty object
  11114. if (timestamp && webInfo.lastModified &&
  11115. (new Date(webInfo.lastModified).valueOf() ===
  11116. new Date(timestamp).valueOf()) &&
  11117. JSON.stringify(modifyVars) === vars) {
  11118. // Use local copy
  11119. return css;
  11120. }
  11121. }
  11122. };
  11123. });
  11124. var ImageSize = (function () {
  11125. function imageSize() {
  11126. throw {
  11127. type: 'Runtime',
  11128. message: 'Image size functions are not supported in browser version of less'
  11129. };
  11130. }
  11131. var imageFunctions = {
  11132. 'image-size': function (filePathNode) {
  11133. imageSize();
  11134. return -1;
  11135. },
  11136. 'image-width': function (filePathNode) {
  11137. imageSize();
  11138. return -1;
  11139. },
  11140. 'image-height': function (filePathNode) {
  11141. imageSize();
  11142. return -1;
  11143. }
  11144. };
  11145. functionRegistry.addMultiple(imageFunctions);
  11146. });
  11147. //
  11148. var root = (function (window, options) {
  11149. var document = window.document;
  11150. var less = lessRoot();
  11151. less.options = options;
  11152. var environment = less.environment;
  11153. var FileManager = FM(options, less.logger);
  11154. var fileManager = new FileManager();
  11155. environment.addFileManager(fileManager);
  11156. less.FileManager = FileManager;
  11157. less.PluginLoader = PluginLoader;
  11158. LogListener(less, options);
  11159. var errors = ErrorReporting(window, less, options);
  11160. var cache = less.cache = options.cache || Cache(window, options, less.logger);
  11161. ImageSize(less.environment);
  11162. // Setup user functions - Deprecate?
  11163. if (options.functions) {
  11164. less.functions.functionRegistry.addMultiple(options.functions);
  11165. }
  11166. var typePattern = /^text\/(x-)?less$/;
  11167. function clone(obj) {
  11168. var cloned = {};
  11169. for (var prop in obj) {
  11170. if (obj.hasOwnProperty(prop)) {
  11171. cloned[prop] = obj[prop];
  11172. }
  11173. }
  11174. return cloned;
  11175. }
  11176. // only really needed for phantom
  11177. function bind(func, thisArg) {
  11178. var curryArgs = Array.prototype.slice.call(arguments, 2);
  11179. return function () {
  11180. var args = curryArgs.concat(Array.prototype.slice.call(arguments, 0));
  11181. return func.apply(thisArg, args);
  11182. };
  11183. }
  11184. function loadStyles(modifyVars) {
  11185. var styles = document.getElementsByTagName('style');
  11186. var style;
  11187. for (var i_1 = 0; i_1 < styles.length; i_1++) {
  11188. style = styles[i_1];
  11189. if (style.type.match(typePattern)) {
  11190. var instanceOptions = clone(options);
  11191. instanceOptions.modifyVars = modifyVars;
  11192. var lessText_1 = style.innerHTML || '';
  11193. instanceOptions.filename = document.location.href.replace(/#.*$/, '');
  11194. /* jshint loopfunc:true */
  11195. // use closure to store current style
  11196. less.render(lessText_1, instanceOptions, bind(function (style, e, result) {
  11197. if (e) {
  11198. errors.add(e, 'inline');
  11199. }
  11200. else {
  11201. style.type = 'text/css';
  11202. if (style.styleSheet) {
  11203. style.styleSheet.cssText = result.css;
  11204. }
  11205. else {
  11206. style.innerHTML = result.css;
  11207. }
  11208. }
  11209. }, null, style));
  11210. }
  11211. }
  11212. }
  11213. function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) {
  11214. var instanceOptions = clone(options);
  11215. addDataAttr(instanceOptions, sheet);
  11216. instanceOptions.mime = sheet.type;
  11217. if (modifyVars) {
  11218. instanceOptions.modifyVars = modifyVars;
  11219. }
  11220. function loadInitialFileCallback(loadedFile) {
  11221. var data = loadedFile.contents;
  11222. var path = loadedFile.filename;
  11223. var webInfo = loadedFile.webInfo;
  11224. var newFileInfo = {
  11225. currentDirectory: fileManager.getPath(path),
  11226. filename: path,
  11227. rootFilename: path,
  11228. rewriteUrls: instanceOptions.rewriteUrls
  11229. };
  11230. newFileInfo.entryPath = newFileInfo.currentDirectory;
  11231. newFileInfo.rootpath = instanceOptions.rootpath || newFileInfo.currentDirectory;
  11232. if (webInfo) {
  11233. webInfo.remaining = remaining;
  11234. var css = cache.getCSS(path, webInfo, instanceOptions.modifyVars);
  11235. if (!reload && css) {
  11236. webInfo.local = true;
  11237. callback(null, css, data, sheet, webInfo, path);
  11238. return;
  11239. }
  11240. }
  11241. // TODO add tests around how this behaves when reloading
  11242. errors.remove(path);
  11243. instanceOptions.rootFileInfo = newFileInfo;
  11244. less.render(data, instanceOptions, function (e, result) {
  11245. if (e) {
  11246. e.href = path;
  11247. callback(e);
  11248. }
  11249. else {
  11250. cache.setCSS(sheet.href, webInfo.lastModified, instanceOptions.modifyVars, result.css);
  11251. callback(null, result.css, data, sheet, webInfo, path);
  11252. }
  11253. });
  11254. }
  11255. fileManager.loadFile(sheet.href, null, instanceOptions, environment)
  11256. .then(function (loadedFile) {
  11257. loadInitialFileCallback(loadedFile);
  11258. }).catch(function (err) {
  11259. console.log(err);
  11260. callback(err);
  11261. });
  11262. }
  11263. function loadStyleSheets(callback, reload, modifyVars) {
  11264. for (var i_2 = 0; i_2 < less.sheets.length; i_2++) {
  11265. loadStyleSheet(less.sheets[i_2], callback, reload, less.sheets.length - (i_2 + 1), modifyVars);
  11266. }
  11267. }
  11268. function initRunningMode() {
  11269. if (less.env === 'development') {
  11270. less.watchTimer = setInterval(function () {
  11271. if (less.watchMode) {
  11272. fileManager.clearFileCache();
  11273. loadStyleSheets(function (e, css, _, sheet, webInfo) {
  11274. if (e) {
  11275. errors.add(e, e.href || sheet.href);
  11276. }
  11277. else if (css) {
  11278. browser.createCSS(window.document, css, sheet);
  11279. }
  11280. });
  11281. }
  11282. }, options.poll);
  11283. }
  11284. }
  11285. //
  11286. // Watch mode
  11287. //
  11288. less.watch = function () {
  11289. if (!less.watchMode) {
  11290. less.env = 'development';
  11291. initRunningMode();
  11292. }
  11293. this.watchMode = true;
  11294. return true;
  11295. };
  11296. less.unwatch = function () { clearInterval(less.watchTimer); this.watchMode = false; return false; };
  11297. //
  11298. // Synchronously get all <link> tags with the 'rel' attribute set to
  11299. // "stylesheet/less".
  11300. //
  11301. less.registerStylesheetsImmediately = function () {
  11302. var links = document.getElementsByTagName('link');
  11303. less.sheets = [];
  11304. for (var i_3 = 0; i_3 < links.length; i_3++) {
  11305. if (links[i_3].rel === 'stylesheet/less' || (links[i_3].rel.match(/stylesheet/) &&
  11306. (links[i_3].type.match(typePattern)))) {
  11307. less.sheets.push(links[i_3]);
  11308. }
  11309. }
  11310. };
  11311. //
  11312. // Asynchronously get all <link> tags with the 'rel' attribute set to
  11313. // "stylesheet/less", returning a Promise.
  11314. //
  11315. less.registerStylesheets = function () { return new Promise(function (resolve, reject) {
  11316. less.registerStylesheetsImmediately();
  11317. resolve();
  11318. }); };
  11319. //
  11320. // With this function, it's possible to alter variables and re-render
  11321. // CSS without reloading less-files
  11322. //
  11323. less.modifyVars = function (record) { return less.refresh(true, record, false); };
  11324. less.refresh = function (reload, modifyVars, clearFileCache) {
  11325. if ((reload || clearFileCache) && clearFileCache !== false) {
  11326. fileManager.clearFileCache();
  11327. }
  11328. return new Promise(function (resolve, reject) {
  11329. var startTime;
  11330. var endTime;
  11331. var totalMilliseconds;
  11332. var remainingSheets;
  11333. startTime = endTime = new Date();
  11334. // Set counter for remaining unprocessed sheets
  11335. remainingSheets = less.sheets.length;
  11336. if (remainingSheets === 0) {
  11337. endTime = new Date();
  11338. totalMilliseconds = endTime - startTime;
  11339. less.logger.info('Less has finished and no sheets were loaded.');
  11340. resolve({
  11341. startTime: startTime,
  11342. endTime: endTime,
  11343. totalMilliseconds: totalMilliseconds,
  11344. sheets: less.sheets.length
  11345. });
  11346. }
  11347. else {
  11348. // Relies on less.sheets array, callback seems to be guaranteed to be called for every element of the array
  11349. loadStyleSheets(function (e, css, _, sheet, webInfo) {
  11350. if (e) {
  11351. errors.add(e, e.href || sheet.href);
  11352. reject(e);
  11353. return;
  11354. }
  11355. if (webInfo.local) {
  11356. less.logger.info("Loading " + sheet.href + " from cache.");
  11357. }
  11358. else {
  11359. less.logger.info("Rendered " + sheet.href + " successfully.");
  11360. }
  11361. browser.createCSS(window.document, css, sheet);
  11362. less.logger.info("CSS for " + sheet.href + " generated in " + (new Date() - endTime) + "ms");
  11363. // Count completed sheet
  11364. remainingSheets--;
  11365. // Check if the last remaining sheet was processed and then call the promise
  11366. if (remainingSheets === 0) {
  11367. totalMilliseconds = new Date() - startTime;
  11368. less.logger.info("Less has finished. CSS generated in " + totalMilliseconds + "ms");
  11369. resolve({
  11370. startTime: startTime,
  11371. endTime: endTime,
  11372. totalMilliseconds: totalMilliseconds,
  11373. sheets: less.sheets.length
  11374. });
  11375. }
  11376. endTime = new Date();
  11377. }, reload, modifyVars);
  11378. }
  11379. loadStyles(modifyVars);
  11380. });
  11381. };
  11382. less.refreshStyles = loadStyles;
  11383. return less;
  11384. });
  11385. /**
  11386. * Kicks off less and compiles any stylesheets
  11387. * used in the browser distributed version of less
  11388. * to kick-start less using the browser api
  11389. */
  11390. var options$1 = defaultOptions();
  11391. if (window.less) {
  11392. for (var key in window.less) {
  11393. if (window.less.hasOwnProperty(key)) {
  11394. options$1[key] = window.less[key];
  11395. }
  11396. }
  11397. }
  11398. addDefaultOptions(window, options$1);
  11399. options$1.plugins = options$1.plugins || [];
  11400. if (window.LESS_PLUGINS) {
  11401. options$1.plugins = options$1.plugins.concat(window.LESS_PLUGINS);
  11402. }
  11403. var less = root(window, options$1);
  11404. window.less = less;
  11405. var css;
  11406. var head;
  11407. var style;
  11408. // Always restore page visibility
  11409. function resolveOrReject(data) {
  11410. if (data.filename) {
  11411. console.warn(data);
  11412. }
  11413. if (!options$1.async) {
  11414. head.removeChild(style);
  11415. }
  11416. }
  11417. if (options$1.onReady) {
  11418. if (/!watch/.test(window.location.hash)) {
  11419. less.watch();
  11420. }
  11421. // Simulate synchronous stylesheet loading by hiding page rendering
  11422. if (!options$1.async) {
  11423. css = 'body { display: none !important }';
  11424. head = document.head || document.getElementsByTagName('head')[0];
  11425. style = document.createElement('style');
  11426. style.type = 'text/css';
  11427. if (style.styleSheet) {
  11428. style.styleSheet.cssText = css;
  11429. }
  11430. else {
  11431. style.appendChild(document.createTextNode(css));
  11432. }
  11433. head.appendChild(style);
  11434. }
  11435. less.registerStylesheetsImmediately();
  11436. less.pageLoadFinished = less.refresh(less.env === 'development').then(resolveOrReject, resolveOrReject);
  11437. }
  11438. return less;
  11439. })));