| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235342363423734238342393424034241342423424334244342453424634247342483424934250342513425234253342543425534256342573425834259342603426134262342633426434265342663426734268342693427034271342723427334274342753427634277342783427934280342813428234283342843428534286342873428834289342903429134292342933429434295342963429734298342993430034301343023430334304343053430634307343083430934310343113431234313343143431534316343173431834319343203432134322343233432434325343263432734328343293433034331343323433334334343353433634337343383433934340343413434234343343443434534346343473434834349343503435134352343533435434355343563435734358343593436034361343623436334364343653436634367343683436934370343713437234373343743437534376343773437834379343803438134382343833438434385343863438734388343893439034391343923439334394343953439634397343983439934400344013440234403344043440534406344073440834409344103441134412344133441434415344163441734418344193442034421344223442334424344253442634427344283442934430344313443234433344343443534436344373443834439344403444134442344433444434445344463444734448344493445034451344523445334454344553445634457344583445934460344613446234463344643446534466344673446834469344703447134472344733447434475344763447734478344793448034481344823448334484344853448634487344883448934490344913449234493344943449534496344973449834499345003450134502345033450434505345063450734508345093451034511345123451334514345153451634517345183451934520345213452234523345243452534526345273452834529345303453134532345333453434535345363453734538345393454034541345423454334544345453454634547345483454934550345513455234553345543455534556345573455834559345603456134562345633456434565345663456734568345693457034571345723457334574345753457634577345783457934580345813458234583345843458534586345873458834589345903459134592345933459434595345963459734598345993460034601346023460334604346053460634607346083460934610346113461234613346143461534616346173461834619346203462134622346233462434625346263462734628346293463034631346323463334634346353463634637346383463934640346413464234643346443464534646346473464834649346503465134652346533465434655346563465734658346593466034661346623466334664346653466634667346683466934670346713467234673346743467534676346773467834679346803468134682346833468434685346863468734688346893469034691346923469334694346953469634697346983469934700347013470234703347043470534706347073470834709347103471134712347133471434715347163471734718347193472034721347223472334724347253472634727347283472934730347313473234733347343473534736347373473834739347403474134742347433474434745347463474734748347493475034751347523475334754347553475634757347583475934760347613476234763347643476534766347673476834769347703477134772347733477434775347763477734778347793478034781347823478334784347853478634787347883478934790347913479234793347943479534796347973479834799348003480134802348033480434805348063480734808348093481034811348123481334814348153481634817348183481934820348213482234823348243482534826348273482834829348303483134832348333483434835348363483734838348393484034841348423484334844348453484634847348483484934850348513485234853348543485534856348573485834859348603486134862348633486434865348663486734868348693487034871348723487334874348753487634877348783487934880348813488234883348843488534886348873488834889348903489134892348933489434895348963489734898348993490034901349023490334904349053490634907349083490934910349113491234913349143491534916349173491834919349203492134922349233492434925349263492734928349293493034931349323493334934349353493634937349383493934940349413494234943349443494534946349473494834949349503495134952349533495434955349563495734958349593496034961349623496334964349653496634967349683496934970349713497234973349743497534976349773497834979349803498134982349833498434985349863498734988349893499034991349923499334994349953499634997349983499935000350013500235003350043500535006350073500835009350103501135012350133501435015350163501735018350193502035021350223502335024350253502635027350283502935030350313503235033350343503535036350373503835039350403504135042350433504435045350463504735048 |
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@jridgewell/source-map')) :
- typeof define === 'function' && define.amd ? define(['exports', '@jridgewell/source-map'], factory) :
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Terser = {}, global.sourceMap));
- })(this, (function (exports, sourceMap) { 'use strict';
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- function characters(str) {
- return str.split("");
- }
- function member(name, array) {
- return array.includes(name);
- }
- class DefaultsError extends Error {
- constructor(msg, defs) {
- super();
- this.name = "DefaultsError";
- this.message = msg;
- this.defs = defs;
- }
- }
- function defaults(args, defs, croak) {
- if (args === true) {
- args = {};
- } else if (args != null && typeof args === "object") {
- args = {...args};
- }
- const ret = args || {};
- if (croak) for (const i in ret) if (HOP(ret, i) && !HOP(defs, i)) {
- throw new DefaultsError("`" + i + "` is not a supported option", defs);
- }
- for (const i in defs) if (HOP(defs, i)) {
- if (!args || !HOP(args, i)) {
- ret[i] = defs[i];
- } else if (i === "ecma" || i === "builtins_ecma") {
- let ecma = args[i] | 0;
- if (ecma > 5 && ecma < 2015) ecma += 2009;
- ret[i] = ecma;
- } else {
- ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
- }
- }
- return ret;
- }
- function noop() {}
- function return_false() { return false; }
- function return_true() { return true; }
- function return_this() { return this; }
- function return_null() { return null; }
- var MAP = (function() {
- function MAP(a, tw, allow_splicing = true) {
- const new_a = [];
- for (let i = 0; i < a.length; ++i) {
- let item = a[i];
- let ret = item.transform(tw, allow_splicing);
- if (ret instanceof AST_Node) {
- new_a.push(ret);
- } else if (ret instanceof Splice) {
- new_a.push(...ret.v);
- }
- }
- return new_a;
- }
- MAP.splice = function(val) { return new Splice(val); };
- MAP.skip = {};
- function Splice(val) { this.v = val; }
- return MAP;
- })();
- function make_node(ctor, orig, props) {
- if (!props) props = {};
- if (orig) {
- if (!props.start) props.start = orig.start;
- if (!props.end) props.end = orig.end;
- }
- return new ctor(props);
- }
- /** Makes a `void 0` expression. Use instead of AST_Undefined which may conflict
- * with an existing variable called `undefined` */
- function make_void_0(orig) {
- return make_node(AST_UnaryPrefix, orig, {
- operator: "void",
- expression: make_node(AST_Number, orig, { value: 0 })
- });
- }
- function push_uniq(array, el) {
- if (!array.includes(el))
- array.push(el);
- }
- function string_template(text, props) {
- return text.replace(/{(.+?)}/g, function(str, p) {
- return props && props[p];
- });
- }
- function remove(array, el) {
- for (var i = array.length; --i >= 0;) {
- if (array[i] === el) array.splice(i, 1);
- }
- }
- function mergeSort(array, cmp) {
- if (array.length < 2) return array.slice();
- function merge(a, b) {
- var r = [], ai = 0, bi = 0, i = 0;
- while (ai < a.length && bi < b.length) {
- cmp(a[ai], b[bi]) <= 0
- ? r[i++] = a[ai++]
- : r[i++] = b[bi++];
- }
- if (ai < a.length) r.push.apply(r, a.slice(ai));
- if (bi < b.length) r.push.apply(r, b.slice(bi));
- return r;
- }
- function _ms(a) {
- if (a.length <= 1)
- return a;
- var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m);
- left = _ms(left);
- right = _ms(right);
- return merge(left, right);
- }
- return _ms(array);
- }
- function makePredicate(words) {
- if (!Array.isArray(words)) words = words.split(" ");
- return new Set(words.sort());
- }
- function map_add(map, key, value) {
- if (map.has(key)) {
- map.get(key).push(value);
- } else {
- map.set(key, [ value ]);
- }
- }
- function map_from_object(obj) {
- var map = new Map();
- for (var key in obj) {
- if (HOP(obj, key) && key.charAt(0) === "$") {
- map.set(key.substr(1), obj[key]);
- }
- }
- return map;
- }
- function map_to_object(map) {
- var obj = Object.create(null);
- map.forEach(function (value, key) {
- obj["$" + key] = value;
- });
- return obj;
- }
- function HOP(obj, prop) {
- return Object.prototype.hasOwnProperty.call(obj, prop);
- }
- function keep_name(keep_setting, name) {
- return keep_setting === true
- || (keep_setting instanceof RegExp && keep_setting.test(name));
- }
- var lineTerminatorEscape = {
- "\0": "0",
- "\n": "n",
- "\r": "r",
- "\u2028": "u2028",
- "\u2029": "u2029",
- };
- function regexp_source_fix(source) {
- // V8 does not escape line terminators in regexp patterns in node 12
- // We'll also remove literal \0
- return source.replace(/[\0\n\r\u2028\u2029]/g, function (match, offset) {
- var escaped = source[offset - 1] == "\\"
- && (source[offset - 2] != "\\"
- || /(?:^|[^\\])(?:\\{2})*$/.test(source.slice(0, offset - 1)));
- return (escaped ? "" : "\\") + lineTerminatorEscape[match];
- });
- }
- // Subset of regexps that is not going to cause regexp based DDOS
- // https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- const re_safe_regexp = /^[\\/|\0\s\w^$.[\]()]*$/;
- /** Check if the regexp is safe for Terser to create without risking a RegExp DOS */
- const regexp_is_safe = (source) => re_safe_regexp.test(source);
- const all_flags = "dgimsuyv";
- function sort_regexp_flags(flags) {
- const existing_flags = new Set(flags.split(""));
- let out = "";
- for (const flag of all_flags) {
- if (existing_flags.has(flag)) {
- out += flag;
- existing_flags.delete(flag);
- }
- }
- if (existing_flags.size) {
- // Flags Terser doesn't know about
- existing_flags.forEach(flag => { out += flag; });
- }
- return out;
- }
- function has_annotation(node, annotation) {
- return node._annotations & annotation;
- }
- function set_annotation(node, annotation) {
- node._annotations |= annotation;
- }
- function clear_annotation(node, annotation) {
- node._annotations &= ~annotation;
- }
- // surrogate safe regexps adapted from https://github.com/mathiasbynens/unicode-8.0.0/tree/89b412d8a71ecca9ed593d9e9fa073ab64acfebe/Binary_Property
- /** Used for checking if a string is an identifier during output.
- * We don't use \p{ID_Start} and \p{ID_Continue} because that's a moving target
- * and Terser's output should run on old browsers.
- */
- var UNICODE_NARROW = {
- ID_Start: /[$A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]/,
- ID_Continue: /(?:[$0-9A-Z_a-z\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF])+/,
- };
- /** For detecting and bounding identifiers in source text. Broader than
- * UNICODE_NARROW depending on the JS runtime's unicode version */
- var UNICODE_BROAD = UNICODE_NARROW;
- try {
- UNICODE_BROAD = {
- // https://262.ecma-international.org/13.0/#prod-IdentifierStartChar
- // $, _, ID_Start
- ID_Start: new RegExp("[_$\\p{ID_Start}]", "u"),
- // https://262.ecma-international.org/13.0/#prod-IdentifierPartChar
- // $, zero-width-joiner, zero-width-non-joiner, ID_Continue
- ID_Continue: new RegExp("[$\\u200C\\u200D\\p{ID_Continue}]+", "u"),
- };
- } catch(e) {
- // Could not use modern JS \p{...}.
- }
- const BASIC_IDENT = /^[a-z_$][a-z0-9_$]*$/i;
- function is_basic_identifier_string(str) {
- return BASIC_IDENT.test(str);
- }
- function get_full_char(str, pos) {
- if (is_surrogate_pair_head(str.charCodeAt(pos))) {
- if (is_surrogate_pair_tail(str.charCodeAt(pos + 1))) {
- return str.charAt(pos) + str.charAt(pos + 1);
- }
- } else if (is_surrogate_pair_tail(str.charCodeAt(pos))) {
- if (is_surrogate_pair_head(str.charCodeAt(pos - 1))) {
- return str.charAt(pos - 1) + str.charAt(pos);
- }
- }
- return str.charAt(pos);
- }
- function get_full_char_code(str, pos) {
- // https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates
- const char_code = str.charCodeAt(pos);
- if (is_surrogate_pair_head(char_code)) {
- return 0x10000 + (char_code - 0xd800 << 10) + str.charCodeAt(pos + 1) - 0xdc00;
- }
- return char_code;
- }
- function get_full_char_length(str) {
- var surrogates = 0;
- for (var i = 0; i < str.length; i++) {
- if (is_surrogate_pair_head(str.charCodeAt(i)) && is_surrogate_pair_tail(str.charCodeAt(i + 1))) {
- surrogates++;
- i++;
- }
- }
- return str.length - surrogates;
- }
- function from_char_code(code) {
- // Based on https://github.com/mathiasbynens/String.fromCodePoint/blob/master/fromcodepoint.js
- if (code > 0xFFFF) {
- code -= 0x10000;
- return (String.fromCharCode((code >> 10) + 0xD800) +
- String.fromCharCode((code % 0x400) + 0xDC00));
- }
- return String.fromCharCode(code);
- }
- function is_surrogate_pair_head(code) {
- return code >= 0xd800 && code <= 0xdbff;
- }
- function is_surrogate_pair_tail(code) {
- return code >= 0xdc00 && code <= 0xdfff;
- }
- function is_identifier_start(ch) {
- return UNICODE_NARROW.ID_Start.test(ch);
- }
- function is_identifier_char(ch) {
- return UNICODE_NARROW.ID_Continue.test(ch);
- }
- /** supports a "wider" range of identifiers -- as unicode evolves, new characters are accepted */
- function is_identifier_start_broad(ch) {
- return UNICODE_BROAD.ID_Start.test(ch);
- }
- /** supports a "wider" range of identifiers -- as unicode evolves, new characters are accepted */
- function is_identifier_char_broad(ch) {
- return UNICODE_BROAD.ID_Continue.test(ch);
- }
- function is_identifier_string(str, allow_surrogates) {
- if (BASIC_IDENT.test(str)) {
- return true;
- }
- if (!allow_surrogates && /[\ud800-\udfff]/.test(str)) {
- return false;
- }
- var match = UNICODE_NARROW.ID_Start.exec(str);
- if (!match || match.index !== 0) {
- return false;
- }
- str = str.slice(match[0].length);
- if (!str) {
- return true;
- }
- match = UNICODE_NARROW.ID_Continue.exec(str);
- return !!match && match[0].length === str.length;
- }
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Parser based on parse-js (http://marijn.haverbeke.nl/parse-js/).
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- var LATEST_RAW = ""; // Only used for numbers and template strings
- var TEMPLATE_RAWS = new Map(); // Raw template strings
- var KEYWORDS = "break case catch class const continue debugger default delete do else export extends finally for function if in instanceof let new return switch throw try typeof var void while with";
- var KEYWORDS_ATOM = "false null true";
- var RESERVED_WORDS = "enum import super this " + KEYWORDS_ATOM + " " + KEYWORDS;
- var ALL_RESERVED_WORDS = "implements interface package private protected public static " + RESERVED_WORDS;
- var KEYWORDS_BEFORE_EXPRESSION = "return new delete throw else case yield await";
- KEYWORDS = makePredicate(KEYWORDS);
- RESERVED_WORDS = makePredicate(RESERVED_WORDS);
- KEYWORDS_BEFORE_EXPRESSION = makePredicate(KEYWORDS_BEFORE_EXPRESSION);
- KEYWORDS_ATOM = makePredicate(KEYWORDS_ATOM);
- ALL_RESERVED_WORDS = makePredicate(ALL_RESERVED_WORDS);
- var OPERATOR_CHARS = makePredicate(characters("+-*&%=<>!?|~^"));
- var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i;
- var RE_OCT_NUMBER = /^0[0-7]+$/;
- var RE_ES6_OCT_NUMBER = /^0o[0-7]+$/i;
- var RE_BIN_NUMBER = /^0b[01]+$/i;
- var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i;
- var RE_BIG_INT = /^(0[xob])?[0-9a-f]+n$/i;
- var RE_KEYWORD_RELATIONAL_OPERATORS = /in(?:stanceof)?/y;
- var OPERATORS = makePredicate([
- "in",
- "instanceof",
- "typeof",
- "new",
- "void",
- "delete",
- "++",
- "--",
- "+",
- "-",
- "!",
- "~",
- "&",
- "|",
- "^",
- "*",
- "**",
- "/",
- "%",
- ">>",
- "<<",
- ">>>",
- "<",
- ">",
- "<=",
- ">=",
- "==",
- "===",
- "!=",
- "!==",
- "?",
- "=",
- "+=",
- "-=",
- "||=",
- "&&=",
- "??=",
- "/=",
- "*=",
- "**=",
- "%=",
- ">>=",
- "<<=",
- ">>>=",
- "|=",
- "^=",
- "&=",
- "&&",
- "??",
- "||",
- ]);
- var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000\uFEFF"));
- var NEWLINE_CHARS = makePredicate(characters("\n\r\u2028\u2029"));
- var PUNC_AFTER_EXPRESSION = makePredicate(characters(";]),:"));
- var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:"));
- var PUNC_CHARS = makePredicate(characters("[]{}(),;:"));
- /* -----[ Tokenizer ]----- */
- function is_digit(code) {
- return code >= 48 && code <= 57;
- }
- function parse_js_number(num, allow_e = true) {
- if (!allow_e && num.includes("e")) {
- return NaN;
- }
- if (RE_HEX_NUMBER.test(num)) {
- return parseInt(num.substr(2), 16);
- } else if (RE_OCT_NUMBER.test(num)) {
- return parseInt(num.substr(1), 8);
- } else if (RE_ES6_OCT_NUMBER.test(num)) {
- return parseInt(num.substr(2), 8);
- } else if (RE_BIN_NUMBER.test(num)) {
- return parseInt(num.substr(2), 2);
- } else if (RE_DEC_NUMBER.test(num)) {
- return parseFloat(num);
- } else {
- var val = parseFloat(num);
- if (val == num) return val;
- }
- }
- class JS_Parse_Error extends Error {
- constructor(message, filename, line, col, pos) {
- super();
- this.name = "SyntaxError";
- this.message = message;
- this.filename = filename;
- this.line = line;
- this.col = col;
- this.pos = pos;
- }
- }
- function js_error(message, filename, line, col, pos) {
- throw new JS_Parse_Error(message, filename, line, col, pos);
- }
- function is_token(token, type, val) {
- return token.type == type && (val == null || token.value == val);
- }
- var EX_EOF = {};
- function tokenizer($TEXT, filename, html5_comments, shebang) {
- var S = {
- text : $TEXT,
- filename : filename,
- pos : 0,
- tokpos : 0,
- line : 1,
- tokline : 0,
- col : 0,
- tokcol : 0,
- newline_before : false,
- regex_allowed : false,
- brace_counter : 0,
- template_braces : [],
- comments_before : [],
- directives : {},
- directive_stack : []
- };
- function peek() { return get_full_char(S.text, S.pos); }
- // Used because parsing ?. involves a lookahead for a digit
- function is_option_chain_op() {
- const must_be_dot = S.text.charCodeAt(S.pos + 1) === 46;
- if (!must_be_dot) return false;
- const cannot_be_digit = S.text.charCodeAt(S.pos + 2);
- return cannot_be_digit < 48 || cannot_be_digit > 57;
- }
- function next(signal_eof, in_string) {
- var ch = get_full_char(S.text, S.pos++);
- if (signal_eof && !ch)
- throw EX_EOF;
- if (NEWLINE_CHARS.has(ch)) {
- S.newline_before = S.newline_before || !in_string;
- ++S.line;
- S.col = 0;
- if (ch == "\r" && peek() == "\n") {
- // treat a \r\n sequence as a single \n
- ++S.pos;
- ch = "\n";
- }
- } else {
- if (ch.length > 1) {
- ++S.pos;
- ++S.col;
- }
- ++S.col;
- }
- return ch;
- }
- function forward(i) {
- while (i--) next();
- }
- function looking_at(str) {
- return S.text.substr(S.pos, str.length) == str;
- }
- function find_eol() {
- var text = S.text;
- for (var i = S.pos, n = S.text.length; i < n; ++i) {
- var ch = text[i];
- if (NEWLINE_CHARS.has(ch))
- return i;
- }
- return -1;
- }
- function find(what, signal_eof) {
- var pos = S.text.indexOf(what, S.pos);
- if (signal_eof && pos == -1) throw EX_EOF;
- return pos;
- }
- function start_token() {
- S.tokline = S.line;
- S.tokcol = S.col;
- S.tokpos = S.pos;
- }
- var prev_was_dot = false;
- var previous_token = null;
- function token(type, value, is_comment) {
- S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX.has(value)) ||
- (type == "keyword" && KEYWORDS_BEFORE_EXPRESSION.has(value)) ||
- (type == "punc" && PUNC_BEFORE_EXPRESSION.has(value))) ||
- (type == "arrow");
- if (type == "punc" && (value == "." || value == "?.")) {
- prev_was_dot = true;
- } else if (!is_comment) {
- prev_was_dot = false;
- }
- const line = S.tokline;
- const col = S.tokcol;
- const pos = S.tokpos;
- const nlb = S.newline_before;
- const file = filename;
- let comments_before = [];
- let comments_after = [];
- if (!is_comment) {
- comments_before = S.comments_before;
- comments_after = S.comments_before = [];
- }
- S.newline_before = false;
- const tok = new AST_Token(type, value, line, col, pos, nlb, comments_before, comments_after, file);
- if (!is_comment) previous_token = tok;
- return tok;
- }
- function skip_whitespace() {
- while (WHITESPACE_CHARS.has(peek()))
- next();
- }
- function peek_next_token_start_or_newline() {
- var pos = S.pos;
- for (var in_multiline_comment = false; pos < S.text.length; ) {
- var ch = get_full_char(S.text, pos);
- if (NEWLINE_CHARS.has(ch)) {
- return { char: ch, pos: pos };
- } else if (in_multiline_comment) {
- if (ch == "*" && get_full_char(S.text, pos + 1) == "/") {
- pos += 2;
- in_multiline_comment = false;
- } else {
- pos++;
- }
- } else if (!WHITESPACE_CHARS.has(ch)) {
- if (ch == "/") {
- var next_ch = get_full_char(S.text, pos + 1);
- if (next_ch == "/") {
- pos = find_eol();
- return { char: get_full_char(S.text, pos), pos: pos };
- } else if (next_ch == "*") {
- in_multiline_comment = true;
- pos += 2;
- continue;
- }
- }
- return { char: ch, pos: pos };
- } else {
- pos++;
- }
- }
- return { char: null, pos: pos };
- }
- function ch_starts_binding_identifier(ch, pos) {
- if (ch == "\\") {
- return true;
- } else if (is_identifier_start_broad(ch)) {
- RE_KEYWORD_RELATIONAL_OPERATORS.lastIndex = pos;
- if (RE_KEYWORD_RELATIONAL_OPERATORS.test(S.text)) {
- var after = get_full_char(S.text, RE_KEYWORD_RELATIONAL_OPERATORS.lastIndex);
- if (!is_identifier_char_broad(after) && after != "\\") {
- // "in" or "instanceof" are keywords, not binding identifiers
- return false;
- }
- }
- return true;
- }
- return false;
- }
- function read_while(pred) {
- var ret = "", ch, i = 0;
- while ((ch = peek()) && pred(ch, i++))
- ret += next();
- return ret;
- }
- function parse_error(err) {
- js_error(err, filename, S.tokline, S.tokcol, S.tokpos);
- }
- function read_num(prefix) {
- var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".", is_big_int = false, numeric_separator = false;
- var num = read_while(function(ch, i) {
- if (is_big_int) return false;
- var code = ch.charCodeAt(0);
- switch (code) {
- case 95: // _
- return (numeric_separator = true);
- case 98: case 66: // bB
- return (has_x = true); // Can occur in hex sequence, don't return false yet
- case 111: case 79: // oO
- case 120: case 88: // xX
- return has_x ? false : (has_x = true);
- case 101: case 69: // eE
- return has_x ? true : has_e ? false : (has_e = after_e = true);
- case 45: // -
- return after_e || (i == 0 && !prefix);
- case 43: // +
- return after_e;
- case (after_e = false, 46): // .
- return (!has_dot && !has_x && !has_e) ? (has_dot = true) : false;
- case 110: // n
- is_big_int = true;
- return true;
- }
- return (
- code >= 48 && code <= 57 // 0-9
- || code >= 97 && code <= 102 // a-f
- || code >= 65 && code <= 70 // A-F
- );
- });
- if (prefix) num = prefix + num;
- LATEST_RAW = num;
- if (RE_OCT_NUMBER.test(num) && next_token.has_directive("use strict")) {
- parse_error("Legacy octal literals are not allowed in strict mode");
- }
- if (numeric_separator) {
- if (num.endsWith("_")) {
- parse_error("Numeric separators are not allowed at the end of numeric literals");
- } else if (num.includes("__")) {
- parse_error("Only one underscore is allowed as numeric separator");
- }
- num = num.replace(/_/g, "");
- }
- if (is_big_int) {
- const without_n = num.slice(0, -1);
- const allow_e = RE_HEX_NUMBER.test(without_n);
- const valid = parse_js_number(without_n, allow_e);
- if (!has_dot && RE_BIG_INT.test(num) && !isNaN(valid))
- return token("big_int", without_n);
- parse_error("Invalid or unexpected token");
- }
- var valid = parse_js_number(num);
- if (!isNaN(valid)) {
- return token("num", valid);
- } else {
- parse_error("Invalid syntax: " + num);
- }
- }
- function is_octal(ch) {
- return ch >= "0" && ch <= "7";
- }
- function read_escaped_char(in_string, strict_hex, template_string) {
- var ch = next(true, in_string);
- switch (ch.charCodeAt(0)) {
- case 110 : return "\n";
- case 114 : return "\r";
- case 116 : return "\t";
- case 98 : return "\b";
- case 118 : return "\u000b"; // \v
- case 102 : return "\f";
- case 120 : return String.fromCharCode(hex_bytes(2, strict_hex)); // \x
- case 117 : // \u
- if (peek() == "{") {
- next(true);
- if (peek() === "}")
- parse_error("Expecting hex-character between {}");
- while (peek() == "0") next(true); // No significance
- var result, length = find("}", true) - S.pos;
- // Avoid 32 bit integer overflow (1 << 32 === 1)
- // We know first character isn't 0 and thus out of range anyway
- if (length > 6 || (result = hex_bytes(length, strict_hex)) > 0x10FFFF) {
- parse_error("Unicode reference out of bounds");
- }
- next(true);
- return from_char_code(result);
- }
- return String.fromCharCode(hex_bytes(4, strict_hex));
- case 10 : return ""; // newline
- case 13 : // \r
- if (peek() == "\n") { // DOS newline
- next(true, in_string);
- return "";
- }
- }
- if (is_octal(ch)) {
- if (template_string && strict_hex) {
- const represents_null_character = ch === "0" && !is_octal(peek());
- if (!represents_null_character) {
- parse_error("Octal escape sequences are not allowed in template strings");
- }
- }
- return read_octal_escape_sequence(ch, strict_hex);
- }
- return ch;
- }
- function read_octal_escape_sequence(ch, strict_octal) {
- // Read
- var p = peek();
- if (p >= "0" && p <= "7") {
- ch += next(true);
- if (ch[0] <= "3" && (p = peek()) >= "0" && p <= "7")
- ch += next(true);
- }
- // Parse
- if (ch === "0") return "\0";
- if (ch.length > 0 && next_token.has_directive("use strict") && strict_octal)
- parse_error("Legacy octal escape sequences are not allowed in strict mode");
- return String.fromCharCode(parseInt(ch, 8));
- }
- function hex_bytes(n, strict_hex) {
- var num = 0;
- for (; n > 0; --n) {
- if (!strict_hex && isNaN(parseInt(peek(), 16))) {
- return parseInt(num, 16) || "";
- }
- var digit = next(true);
- if (isNaN(parseInt(digit, 16)))
- parse_error("Invalid hex-character pattern in string");
- num += digit;
- }
- return parseInt(num, 16);
- }
- var read_string = with_eof_error("Unterminated string constant", function() {
- const start_pos = S.pos;
- var quote = next(), ret = [];
- for (;;) {
- var ch = next(true, true);
- if (ch == "\\") ch = read_escaped_char(true, true);
- else if (ch == "\r" || ch == "\n") parse_error("Unterminated string constant");
- else if (ch == quote) break;
- ret.push(ch);
- }
- var tok = token("string", ret.join(""));
- LATEST_RAW = S.text.slice(start_pos, S.pos);
- tok.quote = quote;
- return tok;
- });
- var read_template_characters = with_eof_error("Unterminated template", function(begin) {
- if (begin) {
- S.template_braces.push(S.brace_counter);
- }
- var content = "", raw = "", ch, tok;
- next(true, true);
- while ((ch = next(true, true)) != "`") {
- if (ch == "\r") {
- if (peek() == "\n") ++S.pos;
- ch = "\n";
- } else if (ch == "$" && peek() == "{") {
- next(true, true);
- S.brace_counter++;
- tok = token(begin ? "template_head" : "template_cont", content);
- TEMPLATE_RAWS.set(tok, raw);
- tok.template_end = false;
- return tok;
- }
- raw += ch;
- if (ch == "\\") {
- var tmp = S.pos;
- var prev_is_tag = previous_token && (previous_token.type === "name" || previous_token.type === "punc" && (previous_token.value === ")" || previous_token.value === "]"));
- ch = read_escaped_char(true, !prev_is_tag, true);
- raw += S.text.substr(tmp, S.pos - tmp);
- }
- content += ch;
- }
- S.template_braces.pop();
- tok = token(begin ? "template_head" : "template_cont", content);
- TEMPLATE_RAWS.set(tok, raw);
- tok.template_end = true;
- return tok;
- });
- function skip_line_comment(type) {
- var regex_allowed = S.regex_allowed;
- var i = find_eol(), ret;
- if (i == -1) {
- ret = S.text.substr(S.pos);
- S.pos = S.text.length;
- } else {
- ret = S.text.substring(S.pos, i);
- S.pos = i;
- }
- S.col = S.tokcol + (S.pos - S.tokpos);
- S.comments_before.push(token(type, ret, true));
- S.regex_allowed = regex_allowed;
- return next_token;
- }
- var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function() {
- var regex_allowed = S.regex_allowed;
- var i = find("*/", true);
- var text = S.text.substring(S.pos, i).replace(/\r\n|\r|\u2028|\u2029/g, "\n");
- // update stream position
- forward(get_full_char_length(text) /* text length doesn't count \r\n as 2 char while S.pos - i does */ + 2);
- S.comments_before.push(token("comment2", text, true));
- S.newline_before = S.newline_before || text.includes("\n");
- S.regex_allowed = regex_allowed;
- return next_token;
- });
- var read_name = function () {
- let start = S.pos, end = start - 1, ch = "c";
- while (
- (ch = S.text.charAt(++end))
- && (ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z")
- );
- // 0x7F is very rare in actual code, so we compare it to "~" (0x7E)
- if (end > start + 1 && ch && ch !== "\\" && !is_identifier_char_broad(ch) && ch <= "~") {
- S.pos += end - start;
- S.col += end - start;
- return S.text.slice(start, S.pos);
- }
- return read_name_hard();
- };
- var read_name_hard = with_eof_error("Unterminated identifier name", function() {
- var name = [], ch, escaped = false;
- var read_escaped_identifier_char = function() {
- escaped = true;
- next();
- if (peek() !== "u") {
- parse_error("Expecting UnicodeEscapeSequence -- uXXXX or u{XXXX}");
- }
- return read_escaped_char(false, true);
- };
- // Read first character (ID_Start)
- if ((ch = peek()) === "\\") {
- ch = read_escaped_identifier_char();
- if (!is_identifier_start_broad(ch)) {
- parse_error("First identifier char is an invalid identifier char");
- }
- } else if (is_identifier_start_broad(ch)) {
- next();
- } else {
- return "";
- }
- name.push(ch);
- // Read ID_Continue
- while ((ch = peek()) != null) {
- if ((ch = peek()) === "\\") {
- ch = read_escaped_identifier_char();
- if (!is_identifier_char_broad(ch)) {
- parse_error("Invalid escaped identifier char");
- }
- } else {
- if (!is_identifier_char_broad(ch)) {
- break;
- }
- next();
- }
- name.push(ch);
- }
- const name_str = name.join("");
- if (RESERVED_WORDS.has(name_str) && escaped) {
- parse_error("Escaped characters are not allowed in keywords");
- }
- return name_str;
- });
- var read_regexp = with_eof_error("Unterminated regular expression", function(source) {
- var prev_backslash = false, ch, in_class = false;
- while ((ch = next(true))) if (NEWLINE_CHARS.has(ch)) {
- parse_error("Unexpected line terminator");
- } else if (prev_backslash) {
- if (/^[\u0000-\u007F]$/.test(ch)) {
- source += "\\" + ch;
- } else {
- // Remove the useless slash before the escape, but only for characters that won't be added to regexp syntax
- source += ch;
- }
- prev_backslash = false;
- } else if (ch == "[") {
- in_class = true;
- source += ch;
- } else if (ch == "]" && in_class) {
- in_class = false;
- source += ch;
- } else if (ch == "/" && !in_class) {
- break;
- } else if (ch == "\\") {
- prev_backslash = true;
- } else {
- source += ch;
- }
- const flags = read_name();
- return token("regexp", "/" + source + "/" + flags);
- });
- function read_operator(prefix) {
- function grow(op) {
- if (!peek()) return op;
- var bigger = op + peek();
- if (OPERATORS.has(bigger)) {
- next();
- return grow(bigger);
- } else {
- return op;
- }
- }
- return token("operator", grow(prefix || next()));
- }
- function handle_slash() {
- next();
- switch (peek()) {
- case "/":
- next();
- return skip_line_comment("comment1");
- case "*":
- next();
- return skip_multiline_comment();
- }
- return S.regex_allowed ? read_regexp("") : read_operator("/");
- }
- function handle_eq_sign() {
- next();
- if (peek() === ">") {
- next();
- return token("arrow", "=>");
- } else {
- return read_operator("=");
- }
- }
- function handle_dot() {
- next();
- if (is_digit(peek().charCodeAt(0))) {
- return read_num(".");
- }
- if (peek() === ".") {
- next(); // Consume second dot
- next(); // Consume third dot
- return token("expand", "...");
- }
- return token("punc", ".");
- }
- function read_word() {
- var word = read_name();
- if (prev_was_dot) return token("name", word);
- return KEYWORDS_ATOM.has(word) ? token("atom", word)
- : !KEYWORDS.has(word) ? token("name", word)
- : OPERATORS.has(word) ? token("operator", word)
- : token("keyword", word);
- }
- function read_private_word() {
- next();
- return token("privatename", read_name());
- }
- function with_eof_error(eof_error, cont) {
- return function(x) {
- try {
- return cont(x);
- } catch(ex) {
- if (ex === EX_EOF) parse_error(eof_error);
- else throw ex;
- }
- };
- }
- function next_token(force_regexp) {
- if (force_regexp != null)
- return read_regexp(force_regexp);
- if (shebang && S.pos == 0 && looking_at("#!")) {
- start_token();
- forward(2);
- skip_line_comment("comment5");
- }
- for (;;) {
- skip_whitespace();
- start_token();
- if (html5_comments) {
- if (looking_at("<!--")) {
- forward(4);
- skip_line_comment("comment3");
- continue;
- }
- if (looking_at("-->") && S.newline_before) {
- forward(3);
- skip_line_comment("comment4");
- continue;
- }
- }
- var ch = peek();
- if (!ch) return token("eof");
- var code = ch.charCodeAt(0);
- switch (code) {
- case 34: case 39: return read_string();
- case 46: return handle_dot();
- case 47: {
- var tok = handle_slash();
- if (tok === next_token) continue;
- return tok;
- }
- case 61: return handle_eq_sign();
- case 63: {
- if (!is_option_chain_op()) break; // Handled below
- next(); // ?
- next(); // .
- return token("punc", "?.");
- }
- case 96: return read_template_characters(true);
- case 123:
- S.brace_counter++;
- break;
- case 125:
- S.brace_counter--;
- if (S.template_braces.length > 0
- && S.template_braces[S.template_braces.length - 1] === S.brace_counter)
- return read_template_characters(false);
- break;
- }
- if (is_digit(code)) return read_num();
- if (PUNC_CHARS.has(ch)) return token("punc", next());
- if (OPERATOR_CHARS.has(ch)) return read_operator();
- if (code == 92 || is_identifier_start_broad(ch)) return read_word();
- if (code == 35) return read_private_word();
- break;
- }
- parse_error("Unexpected character '" + ch + "'");
- }
- next_token.next = next;
- next_token.peek = peek;
- next_token.context = function(nc) {
- if (nc) S = nc;
- return S;
- };
- next_token.add_directive = function(directive) {
- S.directive_stack[S.directive_stack.length - 1].push(directive);
- if (S.directives[directive] === undefined) {
- S.directives[directive] = 1;
- } else {
- S.directives[directive]++;
- }
- };
- next_token.push_directives_stack = function() {
- S.directive_stack.push([]);
- };
- next_token.pop_directives_stack = function() {
- var directives = S.directive_stack[S.directive_stack.length - 1];
- for (var i = 0; i < directives.length; i++) {
- S.directives[directives[i]]--;
- }
- S.directive_stack.pop();
- };
- next_token.has_directive = function(directive) {
- return S.directives[directive] > 0;
- };
- next_token.peek_next_token_start_or_newline = peek_next_token_start_or_newline;
- next_token.ch_starts_binding_identifier = ch_starts_binding_identifier;
- next_token.typescript_is_type_parameters_before_call = () => {
- const stack = [">"]; // We start at the opening "<"
- const peek = () => get_full_char(S.text, i + 1);
- const next = () => get_full_char(S.text, ++i);
- let i = S.pos;
- for (; stack.length; i++) {
- let ch = get_full_char(S.text, i);
- if (!ch) return false;
- if (ch === stack[stack.length - 1]) {
- stack.pop();
- continue;
- }
- // Skip comments
- if (ch === "/") {
- ch = next();
- if (ch === "/") {
- while ((ch = next()) && ch !== "\n");
- } else if (ch === "*") {
- while ((ch = next()) && !(ch === "*" && peek() === "/"));
- }
- }
- // Skip strings
- if (ch === "'" || ch === '"') {
- const start = ch;
- do {
- ch = next();
- if (ch === "\\") ++i; // skip over \"
- } while (ch && ch !== start && ch !== "\n");
- }
- // Skip template strings
- if (
- ch === "`"
- || ch === "}" && stack[stack.length - 1] === "${" && stack.pop()
- ) {
- do {
- ch = next();
- if (ch === "$" && peek() === "{") {
- next();
- stack.push("${");
- break;
- }
- } while (ch && ch !== "`");
- }
- // for each opener, push the closer
- if (ch === "<") { stack.push(">"); continue; }
- if (ch === "[") { stack.push("]"); continue; }
- if (ch === "(") { stack.push(")"); continue; }
- if (ch === "{") { stack.push("}"); continue; }
- // When we see a closer, see if it's the same as the opener
- if (ch === ">" || ch === "]" || ch === ")" || ch === "}") {
- if (stack.pop() !== ch) return false;
- continue;
- }
- }
- while (WHITESPACE_CHARS.has(get_full_char(S.text, i))) i++;
- return S.text[i] === "(" || S.text.slice(i, i + 2) === "?.";
- };
- return next_token;
- }
- /* -----[ Parser (constants) ]----- */
- var UNARY_PREFIX = makePredicate([
- "typeof",
- "void",
- "delete",
- "--",
- "++",
- "!",
- "~",
- "-",
- "+"
- ]);
- var UNARY_POSTFIX = makePredicate([ "--", "++" ]);
- var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "??=", "&&=", "||=", "/=", "*=", "**=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]);
- var LOGICAL_ASSIGNMENT = makePredicate([ "??=", "&&=", "||=" ]);
- var PRECEDENCE = (function(a, ret) {
- for (var i = 0; i < a.length; ++i) {
- for (const op of a[i]) {
- ret[op] = i + 1;
- }
- }
- return ret;
- })(
- [
- ["||"],
- ["??"],
- ["&&"],
- ["|"],
- ["^"],
- ["&"],
- ["==", "===", "!=", "!=="],
- ["<", ">", "<=", ">=", "in", "instanceof"],
- [">>", "<<", ">>>"],
- ["+", "-"],
- ["*", "/", "%"],
- ["**"]
- ],
- {}
- );
- var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "big_int", "string", "regexp", "name"]);
- /* -----[ Parser ]----- */
- function parse($TEXT, options) {
- // maps start tokens to count of comments found outside of their parens
- // Example: /* I count */ ( /* I don't */ foo() )
- // Useful because comments_before property of call with parens outside
- // contains both comments inside and outside these parens. Used to find the
-
- const outer_comments_before_counts = new WeakMap();
- options = defaults(options, {
- bare_returns : false,
- ecma : null, // Legacy
- expression : false,
- filename : null,
- html5_comments : true,
- module : false,
- shebang : true,
- strict : false,
- toplevel : null,
- experimental_typescript: false,
- }, true);
- var S = {
- input : (typeof $TEXT == "string"
- ? tokenizer($TEXT, options.filename,
- options.html5_comments, options.shebang)
- : $TEXT),
- token : null,
- prev : null,
- peeked : null,
- in_function : 0,
- in_async : -1,
- in_generator : -1,
- in_directives : true,
- in_loop : 0,
- labels : []
- };
- S.token = next();
- function is(type, value) {
- return is_token(S.token, type, value);
- }
- function peek() { return S.peeked || (S.peeked = S.input()); }
- function next() {
- S.prev = S.token;
- if (!S.peeked) peek();
- S.token = S.peeked;
- S.peeked = null;
- S.in_directives = S.in_directives && (
- S.token.type == "string" || is("punc", ";")
- );
- return S.token;
- }
- function prev() {
- return S.prev;
- }
- function croak(msg, line, col, pos) {
- var ctx = S.input.context();
- js_error(msg,
- ctx.filename,
- line != null ? line : ctx.tokline,
- col != null ? col : ctx.tokcol,
- pos != null ? pos : ctx.tokpos);
- }
- function token_error(token, msg) {
- croak(msg, token.line, token.col);
- }
- function unexpected(token) {
- if (token == null)
- token = S.token;
- token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
- }
- function expect_token(type, val) {
- if (is(type, val)) {
- return next();
- }
- token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»");
- }
- function expect(punc) { return expect_token("punc", punc); }
- function has_newline_before(token) {
- return token.nlb || !token.comments_before.every((comment) => !comment.nlb);
- }
- function can_insert_semicolon() {
- return !options.strict
- && (is("eof") || is("punc", "}") || has_newline_before(S.token));
- }
- function is_in_generator() {
- return S.in_generator === S.in_function;
- }
- function is_in_async() {
- return S.in_async === S.in_function;
- }
- function can_await() {
- return (
- S.in_async === S.in_function
- || S.in_function === 0 && S.input.has_directive("use strict")
- );
- }
- function semicolon(optional) {
- if (is("punc", ";")) next();
- else if (!optional && !can_insert_semicolon()) unexpected();
- }
- function parenthesised() {
- expect("(");
- var exp = expression(true);
- expect(")");
- return exp;
- }
- function embed_tokens(parser) {
- return function _embed_tokens_wrapper(...args) {
- const start = S.token;
- const expr = parser(...args);
- expr.start = start;
- expr.end = prev();
- return expr;
- };
- }
- function handle_regexp() {
- if (is("operator", "/") || is("operator", "/=")) {
- S.peeked = null;
- S.token = S.input(S.token.value.substr(1)); // force regexp
- }
- }
- var statement = embed_tokens(function statement(is_export_default, is_for_body, is_if_body) {
- handle_regexp();
- switch (S.token.type) {
- case "string":
- if (S.in_directives) {
- var token = peek();
- if (!LATEST_RAW.includes("\\")
- && (is_token(token, "punc", ";")
- || is_token(token, "punc", "}")
- || has_newline_before(token)
- || is_token(token, "eof"))) {
- S.input.add_directive(S.token.value);
- } else {
- S.in_directives = false;
- }
- }
- var dir = S.in_directives, stat = simple_statement();
- return dir && stat.body instanceof AST_String ? new AST_Directive(stat.body) : stat;
- case "template_head":
- case "num":
- case "big_int":
- case "regexp":
- case "operator":
- case "atom":
- return simple_statement();
- case "name":
- if (S.token.value == "async" && is_token(peek(), "keyword", "function")) {
- next();
- next();
- if (is_for_body) {
- croak("functions are not allowed as the body of a loop");
- }
- const func = function_(AST_Defun, false, true, is_export_default);
- if (func == typescript_ellide) return new AST_EmptyStatement();
- return func;
- }
- if (S.token.value == "import" && !is_token(peek(), "punc", "(") && !is_token(peek(), "punc", ".")) {
- next();
- var node = import_statement();
- semicolon();
- return node;
- }
- if (S.token.value == "using" && is_token(peek(), "name") && !has_newline_before(peek())) {
- next();
- var node = using_();
- semicolon();
- return node;
- }
- if (S.token.value == "await" && can_await() && is_token(peek(), "name", "using") && !has_newline_before(peek())) {
- var next_next = S.input.peek_next_token_start_or_newline();
- if (S.input.ch_starts_binding_identifier(next_next.char, next_next.pos)) {
- next();
- // The "using" token will be consumed by the await_using_ function.
- var node = await_using_();
- semicolon();
- return node;
- }
- }
- if (S.token.value === "type" && is_token(peek(), "name") && !has_newline_before(peek())) {
- typescript_type_statement();
- return new AST_EmptyStatement();
- }
- if (S.token.value === "interface" && is_token(peek(), "name") && !has_newline_before(peek())) {
- typescript_interface_statement();
- return new AST_EmptyStatement();
- }
- return is_token(peek(), "punc", ":")
- ? labeled_statement()
- : simple_statement();
- case "privatename":
- if(!S.in_class)
- croak("Private field must be used in an enclosing class");
- return simple_statement();
- case "punc":
- switch (S.token.value) {
- case "{":
- return new AST_BlockStatement({
- start : S.token,
- body : block_(),
- end : prev()
- });
- case "[":
- case "(":
- return simple_statement();
- case ";":
- S.in_directives = false;
- next();
- return new AST_EmptyStatement();
- default:
- unexpected();
- }
- case "keyword":
- switch (S.token.value) {
- case "break":
- next();
- return break_cont(AST_Break);
- case "continue":
- next();
- return break_cont(AST_Continue);
- case "debugger":
- next();
- semicolon();
- return new AST_Debugger();
- case "do":
- next();
- var body = in_loop(statement);
- expect_token("keyword", "while");
- var condition = parenthesised();
- semicolon(true);
- return new AST_Do({
- body : body,
- condition : condition
- });
- case "while":
- next();
- return new AST_While({
- condition : parenthesised(),
- body : in_loop(function() { return statement(false, true); })
- });
- case "for":
- next();
- return for_();
- case "class":
- next();
- if (is_for_body) {
- croak("classes are not allowed as the body of a loop");
- }
- if (is_if_body) {
- croak("classes are not allowed as the body of an if");
- }
- return class_(AST_DefClass, is_export_default);
- case "function":
- next();
- if (is_for_body) {
- croak("functions are not allowed as the body of a loop");
- }
- const func = function_(AST_Defun, false, false, is_export_default);
- if (func == typescript_ellide) return new AST_EmptyStatement();
- return func;
- case "if":
- next();
- return if_();
- case "return":
- if (S.in_function == 0 && !options.bare_returns)
- croak("'return' outside of function");
- next();
- var value = null;
- if (is("punc", ";")) {
- next();
- } else if (!can_insert_semicolon()) {
- value = expression(true);
- semicolon();
- }
- return new AST_Return({
- value: value
- });
- case "switch":
- next();
- return new AST_Switch({
- expression : parenthesised(),
- body : in_loop(switch_body_)
- });
- case "throw":
- next();
- if (has_newline_before(S.token))
- croak("Illegal newline after 'throw'");
- var value = expression(true);
- semicolon();
- return new AST_Throw({
- value: value
- });
- case "try":
- next();
- return try_();
- case "var":
- next();
- var node = var_();
- semicolon();
- return node;
- case "let":
- next();
- var node = let_();
- semicolon();
- return node;
- case "const":
- next();
- var node = const_();
- semicolon();
- return node;
- case "with":
- if (S.input.has_directive("use strict")) {
- croak("Strict mode may not include a with statement");
- }
- next();
- return new AST_With({
- expression : parenthesised(),
- body : statement()
- });
- case "export":
- if (!is_token(peek(), "punc", "(")) {
- next();
- var node = export_statement();
- if (is("punc", ";")) semicolon();
- return node;
- }
- }
- }
- unexpected();
- });
- function labeled_statement() {
- var label = as_symbol(AST_Label);
- if (label.name === "await" && is_in_async()) {
- token_error(S.prev, "await cannot be used as label inside async function");
- }
- if (S.labels.some((l) => l.name === label.name)) {
- // ECMA-262, 12.12: An ECMAScript program is considered
- // syntactically incorrect if it contains a
- // LabelledStatement that is enclosed by a
- // LabelledStatement with the same Identifier as label.
- croak("Label " + label.name + " defined twice");
- }
- expect(":");
- S.labels.push(label);
- var stat = statement();
- S.labels.pop();
- if (!(stat instanceof AST_IterationStatement)) {
- // check for `continue` that refers to this label.
- // those should be reported as syntax errors.
- // https://github.com/mishoo/UglifyJS2/issues/287
- label.references.forEach(function(ref) {
- if (ref instanceof AST_Continue) {
- ref = ref.label.start;
- croak("Continue label `" + label.name + "` refers to non-IterationStatement.",
- ref.line, ref.col, ref.pos);
- }
- });
- }
- return new AST_LabeledStatement({ body: stat, label: label });
- }
- function simple_statement(tmp) {
- return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) });
- }
- function break_cont(type) {
- var label = null, ldef;
- if (!can_insert_semicolon()) {
- label = as_symbol(AST_LabelRef, true);
- }
- if (label != null) {
- ldef = S.labels.find((l) => l.name === label.name);
- if (!ldef)
- croak("Undefined label " + label.name);
- label.thedef = ldef;
- } else if (S.in_loop == 0)
- croak(type.TYPE + " not inside a loop or switch");
- semicolon();
- var stat = new type({ label: label });
- if (ldef) ldef.references.push(stat);
- return stat;
- }
- function for_() {
- var for_await_error = "`for await` invalid in this context";
- var await_tok = S.token;
- if (await_tok.type == "name" && await_tok.value == "await") {
- if (!can_await()) {
- token_error(await_tok, for_await_error);
- }
- next();
- } else {
- await_tok = false;
- }
- expect("(");
- var init = null;
- if (!is("punc", ";")) {
- init =
- is("keyword", "var") ? (next(), var_(true)) :
- is("keyword", "let") ? (next(), let_(true)) :
- is("keyword", "const") ? (next(), const_(true)) :
- is("name", "using") && is_token(peek(), "name") && (peek().value != "of" || S.input.peek_next_token_start_or_newline().char == "=") ? (next(), using_(true)) :
- is("name", "await") && can_await() && is_token(peek(), "name", "using") ? (next(), await_using_(true)) :
- expression(true, true);
- var is_in = is("operator", "in");
- var is_of = is("name", "of");
- if (await_tok && !is_of) {
- token_error(await_tok, for_await_error);
- }
- if (is_in || is_of) {
- if (init instanceof AST_DefinitionsLike) {
- if (init.definitions.length > 1)
- token_error(init.start, "Only one variable declaration allowed in for..in loop");
- if (is_in && init instanceof AST_Using) {
- token_error(init.start, "Invalid using declaration in for..in loop");
- }
- } else if (!(is_assignable(init) || (init = to_destructuring(init)) instanceof AST_Destructuring)) {
- token_error(init.start, "Invalid left-hand side in for..in loop");
- }
- next();
- if (is_in) {
- return for_in(init);
- } else {
- return for_of(init, !!await_tok);
- }
- }
- } else if (await_tok) {
- token_error(await_tok, for_await_error);
- }
- return regular_for(init);
- }
- function regular_for(init) {
- expect(";");
- var test = is("punc", ";") ? null : expression(true);
- expect(";");
- var step = is("punc", ")") ? null : expression(true);
- expect(")");
- return new AST_For({
- init : init,
- condition : test,
- step : step,
- body : in_loop(function() { return statement(false, true); })
- });
- }
- function for_of(init, is_await) {
- var lhs = init instanceof AST_DefinitionsLike ? init.definitions[0].name : null;
- var obj = expression(true);
- expect(")");
- return new AST_ForOf({
- await : is_await,
- init : init,
- name : lhs,
- object : obj,
- body : in_loop(function() { return statement(false, true); })
- });
- }
- function for_in(init) {
- var obj = expression(true);
- expect(")");
- return new AST_ForIn({
- init : init,
- object : obj,
- body : in_loop(function() { return statement(false, true); })
- });
- }
- var arrow_function = function(start, argnames, is_async) {
- if (has_newline_before(S.token)) {
- croak("Unexpected newline before arrow (=>)");
- }
- expect_token("arrow", "=>");
- var body = _function_body(is("punc", "{"), false, is_async);
- // (should never return typescript_ellide)
- return new AST_Arrow({
- start : start,
- end : body.end,
- async : is_async,
- argnames : argnames,
- body : body
- });
- };
- var function_ = function(ctor, is_generator, is_async, is_export_default) {
- var in_statement = ctor === AST_Defun;
- if (is("operator", "*")) {
- is_generator = true;
- next();
- }
- var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
- if (in_statement && !name) {
- if (is_export_default) {
- ctor = AST_Function;
- } else {
- unexpected();
- }
- }
- if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
- unexpected(prev());
- if (is("operator", "<")) {
- typescript_type_parameters();
- }
- var args = [];
- const start = S.token;
- var body = _function_body(true, is_generator, is_async, name, args);
- if (body == typescript_ellide) return body;
- return new ctor({
- start,
- is_generator: is_generator,
- async : is_async,
- name : name,
- argnames: args,
- body : body,
- end : prev(),
- });
- };
- class UsedParametersTracker {
- constructor(is_parameter, strict, duplicates_ok = false) {
- this.is_parameter = is_parameter;
- this.duplicates_ok = duplicates_ok;
- this.parameters = new Set();
- this.duplicate = null;
- this.default_assignment = false;
- this.spread = false;
- this.strict_mode = !!strict;
- }
- add_parameter(token) {
- if (this.parameters.has(token.value)) {
- if (this.duplicate === null) {
- this.duplicate = token;
- }
- this.check_strict();
- } else {
- this.parameters.add(token.value);
- if (this.is_parameter) {
- switch (token.value) {
- case "arguments":
- case "eval":
- case "yield":
- if (this.strict_mode) {
- token_error(token, "Unexpected " + token.value + " identifier as parameter inside strict mode");
- }
- break;
- default:
- if (RESERVED_WORDS.has(token.value)) {
- unexpected();
- }
- }
- }
- }
- }
- mark_default_assignment(token) {
- if (this.default_assignment === false) {
- this.default_assignment = token;
- }
- }
- mark_spread(token) {
- if (this.spread === false) {
- this.spread = token;
- }
- }
- mark_strict_mode() {
- this.strict_mode = true;
- }
- is_strict() {
- return this.default_assignment !== false || this.spread !== false || this.strict_mode;
- }
- check_strict() {
- if (this.is_strict() && this.duplicate !== null && !this.duplicates_ok) {
- token_error(this.duplicate, "Parameter " + this.duplicate.value + " was used already");
- }
- }
- }
- function parameters(params) {
- var used_parameters = new UsedParametersTracker(true, S.input.has_directive("use strict"));
- expect("(");
- while (!is("punc", ")")) {
- if (is("name", "this") && typescript_skip_this_type()) {
- continue;
- }
- var param = parameter(used_parameters);
- params.push(param);
- if (!is("punc", ")")) {
- expect(",");
- }
- if (param instanceof AST_Expansion) {
- break;
- }
- }
- next();
- }
- function parameter(used_parameters, symbol_type) {
- var param;
- var expand = false;
- if (used_parameters === undefined) {
- used_parameters = new UsedParametersTracker(true, S.input.has_directive("use strict"));
- }
- if (is("expand", "...")) {
- expand = S.token;
- used_parameters.mark_spread(S.token);
- next();
- }
- param = binding_element(used_parameters, symbol_type);
- if (is("punc", ":") || is("operator", "?")) {
- typescript_maybe_annotation();
- }
- if (is("operator", "=") && expand === false) {
- used_parameters.mark_default_assignment(S.token);
- next();
- param = new AST_DefaultAssign({
- start: param.start,
- left: param,
- operator: "=",
- right: expression(false),
- end: S.token
- });
- }
- if (expand !== false) {
- if (!is("punc", ")")) {
- unexpected();
- }
- param = new AST_Expansion({
- start: expand,
- expression: param,
- end: expand
- });
- }
- used_parameters.check_strict();
- return param;
- }
- function binding_element(used_parameters, symbol_type) {
- var elements = [];
- var first = true;
- var is_expand = false;
- var expand_token;
- var first_token = S.token;
- if (used_parameters === undefined) {
- const strict = S.input.has_directive("use strict");
- const duplicates_ok = symbol_type === AST_SymbolVar;
- used_parameters = new UsedParametersTracker(false, strict, duplicates_ok);
- }
- symbol_type = symbol_type === undefined ? AST_SymbolFunarg : symbol_type;
- if (is("punc", "[")) {
- next();
- while (!is("punc", "]")) {
- if (first) {
- first = false;
- } else {
- expect(",");
- }
- if (is("expand", "...")) {
- is_expand = true;
- expand_token = S.token;
- used_parameters.mark_spread(S.token);
- next();
- }
- if (is("punc")) {
- switch (S.token.value) {
- case ",":
- elements.push(new AST_Hole({
- start: S.token,
- end: S.token
- }));
- continue;
- case "]": // Trailing comma after last element
- break;
- case "[":
- case "{":
- elements.push(binding_element(used_parameters, symbol_type));
- break;
- default:
- unexpected();
- }
- } else if (is("name")) {
- used_parameters.add_parameter(S.token);
- elements.push(as_symbol(symbol_type));
- } else {
- croak("Invalid function parameter");
- }
- if (is("operator", "=") && is_expand === false) {
- used_parameters.mark_default_assignment(S.token);
- next();
- elements[elements.length - 1] = new AST_DefaultAssign({
- start: elements[elements.length - 1].start,
- left: elements[elements.length - 1],
- operator: "=",
- right: expression(false),
- end: S.token
- });
- }
- if (is_expand) {
- if (!is("punc", "]")) {
- croak("Rest element must be last element");
- }
- elements[elements.length - 1] = new AST_Expansion({
- start: expand_token,
- expression: elements[elements.length - 1],
- end: expand_token
- });
- }
- }
- expect("]");
- used_parameters.check_strict();
- return new AST_Destructuring({
- start: first_token,
- names: elements,
- is_array: true,
- end: prev()
- });
- } else if (is("punc", "{")) {
- next();
- while (!is("punc", "}")) {
- if (first) {
- first = false;
- } else {
- expect(",");
- }
- if (is("expand", "...")) {
- is_expand = true;
- expand_token = S.token;
- used_parameters.mark_spread(S.token);
- next();
- }
- if (is("name") && (is_token(peek(), "punc") || is_token(peek(), "operator")) && [",", "}", "="].includes(peek().value)) {
- used_parameters.add_parameter(S.token);
- var start = prev();
- var value = as_symbol(symbol_type);
- if (is_expand) {
- elements.push(new AST_Expansion({
- start: expand_token,
- expression: value,
- end: value.end,
- }));
- } else {
- elements.push(new AST_ObjectKeyVal({
- start: start,
- key: value.name,
- value: value,
- end: value.end,
- }));
- }
- } else if (is("punc", "}")) {
- continue; // Allow trailing hole
- } else {
- var property_token = S.token;
- var property = as_property_name();
- if (property === null) {
- unexpected(prev());
- } else if (prev().type === "name" && !is("punc", ":")) {
- elements.push(new AST_ObjectKeyVal({
- start: prev(),
- key: property,
- value: new symbol_type({
- start: prev(),
- name: property,
- end: prev()
- }),
- end: prev()
- }));
- } else {
- expect(":");
- elements.push(new AST_ObjectKeyVal({
- start: property_token,
- quote: property_token.quote,
- key: property,
- value: binding_element(used_parameters, symbol_type),
- end: prev()
- }));
- }
- }
- if (is_expand) {
- if (!is("punc", "}")) {
- croak("Rest element must be last element");
- }
- } else if (is("operator", "=")) {
- used_parameters.mark_default_assignment(S.token);
- next();
- elements[elements.length - 1].value = new AST_DefaultAssign({
- start: elements[elements.length - 1].value.start,
- left: elements[elements.length - 1].value,
- operator: "=",
- right: expression(false),
- end: S.token
- });
- }
- }
- expect("}");
- used_parameters.check_strict();
- return new AST_Destructuring({
- start: first_token,
- names: elements,
- is_array: false,
- end: prev()
- });
- } else if (is("name")) {
- used_parameters.add_parameter(S.token);
- return as_symbol(symbol_type);
- } else {
- croak("Invalid function parameter");
- }
- }
- function params_or_seq_(allow_arrows, maybe_sequence) {
- var spread_token;
- var invalid_sequence;
- var trailing_comma;
- var a = [];
- expect("(");
- while (!is("punc", ")")) {
- if (spread_token) unexpected(spread_token);
- if (is("expand", "...")) {
- spread_token = S.token;
- if (maybe_sequence) invalid_sequence = S.token;
- next();
- a.push(new AST_Expansion({
- start: prev(),
- expression: expression(),
- end: S.token,
- }));
- } else {
- a.push(expression());
- }
- if (is("punc", ":") || is("operator", "?")) {
- typescript_maybe_annotation();
- }
- if (!is("punc", ")")) {
- expect(",");
- if (is("punc", ")")) {
- trailing_comma = prev();
- if (maybe_sequence) invalid_sequence = trailing_comma;
- }
- }
- }
- expect(")");
- if (allow_arrows && is("punc", ":")) {
- typescript_type_annotation();
- }
- if (allow_arrows && is("arrow", "=>")) {
- if (spread_token && trailing_comma) unexpected(trailing_comma);
- } else if (invalid_sequence) {
- unexpected(invalid_sequence);
- }
- return a;
- }
- function _function_body(block, generator, is_async, name, args) {
- var loop = S.in_loop;
- var labels = S.labels;
- var current_generator = S.in_generator;
- var current_async = S.in_async;
- ++S.in_function;
- if (generator)
- S.in_generator = S.in_function;
- if (is_async)
- S.in_async = S.in_function;
- if (args) {
- parameters(args);
- if (is("punc", ":")) typescript_type_annotation();
- if (block && !is("punc", "{") && typescript_is_function_no_body()) {
- return typescript_ellide;
- }
- }
- if (block)
- S.in_directives = true;
- S.in_loop = 0;
- S.labels = [];
- if (block) {
- S.input.push_directives_stack();
- var a = block_();
- if (name) _verify_symbol(name);
- if (args) args.forEach(_verify_symbol);
- S.input.pop_directives_stack();
- } else {
- var a = [new AST_Return({
- start: S.token,
- value: expression(false),
- end: S.token
- })];
- }
- --S.in_function;
- S.in_loop = loop;
- S.labels = labels;
- S.in_generator = current_generator;
- S.in_async = current_async;
- return a;
- }
- function _await_expression() {
- // Previous token must be "await" and not be interpreted as an identifier
- if (!can_await()) {
- croak("Unexpected await expression outside async function",
- S.prev.line, S.prev.col, S.prev.pos);
- }
- // the await expression is parsed as a unary expression in Babel
- return new AST_Await({
- start: prev(),
- end: S.token,
- expression : maybe_unary(true),
- });
- }
- function _yield_expression() {
- var start = S.token;
- var star = false;
- var has_expression = true;
- // Attempt to get expression or star (and then the mandatory expression)
- // behind yield on the same line.
- //
- // If nothing follows on the same line of the yieldExpression,
- // it should default to the value `undefined` for yield to return.
- // In that case, the `undefined` stored as `null` in ast.
- //
- // Note 1: It isn't allowed for yield* to close without an expression
- // Note 2: If there is a nlb between yield and star, it is interpret as
- // yield <explicit undefined> <inserted automatic semicolon> *
- if (
- can_insert_semicolon()
- || is("punc") && PUNC_AFTER_EXPRESSION.has(S.token.value)
- || is("template_cont")
- ) {
- has_expression = false;
- } else if (is("operator", "*")) {
- star = true;
- next();
- }
- return new AST_Yield({
- start : start,
- is_star : star,
- expression : has_expression ? expression() : null,
- end : prev()
- });
- }
- function if_() {
- var cond = parenthesised(), body = statement(false, false, true), belse = null;
- if (is("keyword", "else")) {
- next();
- belse = statement(false, false, true);
- }
- return new AST_If({
- condition : cond,
- body : body,
- alternative : belse
- });
- }
- function block_() {
- expect("{");
- var a = [];
- while (!is("punc", "}")) {
- if (is("eof")) unexpected();
- a.push(statement());
- }
- next();
- return a;
- }
- function switch_body_() {
- expect("{");
- var a = [], cur = null, branch = null, tmp;
- while (!is("punc", "}")) {
- if (is("eof")) unexpected();
- if (is("keyword", "case")) {
- if (branch) branch.end = prev();
- cur = [];
- branch = new AST_Case({
- start : (tmp = S.token, next(), tmp),
- expression : expression(true),
- body : cur
- });
- a.push(branch);
- expect(":");
- } else if (is("keyword", "default")) {
- if (branch) branch.end = prev();
- cur = [];
- branch = new AST_Default({
- start : (tmp = S.token, next(), expect(":"), tmp),
- body : cur
- });
- a.push(branch);
- } else {
- if (!cur) unexpected();
- cur.push(statement());
- }
- }
- if (branch) branch.end = prev();
- next();
- return a;
- }
- function try_() {
- var body, bcatch = null, bfinally = null;
- body = new AST_TryBlock({
- start : S.token,
- body : block_(),
- end : prev(),
- });
- if (is("keyword", "catch")) {
- var start = S.token;
- next();
- if (is("punc", "{")) {
- var name = null;
- } else {
- expect("(");
- var name = parameter(undefined, AST_SymbolCatch);
- expect(")");
- }
- bcatch = new AST_Catch({
- start : start,
- argname : name,
- body : block_(),
- end : prev()
- });
- }
- if (is("keyword", "finally")) {
- var start = S.token;
- next();
- bfinally = new AST_Finally({
- start : start,
- body : block_(),
- end : prev()
- });
- }
- if (!bcatch && !bfinally)
- croak("Missing catch/finally blocks");
- return new AST_Try({
- body : body,
- bcatch : bcatch,
- bfinally : bfinally
- });
- }
- /**
- * var
- * vardef1 = 2,
- * vardef2 = 3;
- */
- function vardefs(no_in, kind) {
- var var_defs = [];
- for (;;) {
- var sym_type =
- kind === "var" ? AST_SymbolVar :
- kind === "const" ? AST_SymbolConst :
- kind === "let" ? AST_SymbolLet :
- kind === "using" ? AST_SymbolUsing :
- kind === "await using" ? AST_SymbolUsing : null;
- var def_type = kind === "using" || kind === "await using" ? AST_UsingDef : AST_VarDef;
- var start = S.token;
- var name = is("punc", "{") || is("punc", "[")
- ? binding_element(undefined, sym_type)
- : as_symbol(sym_type);
- if (name.name == "import") croak("Unexpected token: import");
- if (is("punc", ":")) {
- typescript_type_annotation();
- }
- var value = is("operator", "=")
- ? (next(), expression(false, no_in))
- : null;
- if (!value && !no_in && (kind === "const" || kind === "using" || kind === "await using")) {
- croak("Missing initializer in " + kind + " declaration");
- }
- var def = new def_type({
- start,
- name,
- value,
- end: prev()
- });
- var_defs.push(def);
- if (!is("punc", ","))
- break;
- next();
- }
- return var_defs;
- }
- var var_ = function(no_in) {
- return new AST_Var({
- start : prev(),
- definitions : vardefs(no_in, "var"),
- end : prev()
- });
- };
- var let_ = function(no_in) {
- return new AST_Let({
- start : prev(),
- definitions : vardefs(no_in, "let"),
- end : prev()
- });
- };
- var const_ = function(no_in) {
- return new AST_Const({
- start : prev(),
- definitions : vardefs(no_in, "const"),
- end : prev()
- });
- };
- var using_ = function(no_in) {
- return new AST_Using({
- start : prev(),
- await : false,
- definitions : vardefs(no_in, "using"),
- end : prev()
- });
- };
- var await_using_ = function(no_in) {
- // Assumption: When await_using_ is called, only the `await` token has been consumed.
- return new AST_Using({
- start : prev(),
- await : true,
- definitions : (next(), vardefs(no_in, "await using")),
- end : prev()
- });
- };
- var new_ = function(allow_calls) {
- var start = S.token;
- expect_token("operator", "new");
- if (is("punc", ".")) {
- next();
- expect_token("name", "target");
- return subscripts(new AST_NewTarget({
- start : start,
- end : prev()
- }), allow_calls);
- }
- var newexp = expr_atom(false), args;
- if (is("punc", "(")) {
- next();
- args = expr_list(")", true);
- } else {
- args = [];
- }
- var call = new AST_New({
- start : start,
- expression : newexp,
- args : args,
- end : prev()
- });
- annotate(call);
- return subscripts(call, allow_calls);
- };
- function as_atom_node() {
- var tok = S.token, ret;
- switch (tok.type) {
- case "name":
- ret = _make_symbol(AST_SymbolRef);
- break;
- case "num":
- if (tok.value === Infinity) {
- // very large float values are parsed as Infinity
- ret = new AST_Infinity({
- start: tok,
- end: tok,
- });
- } else {
- ret = new AST_Number({
- start: tok,
- end: tok,
- value: tok.value,
- raw: LATEST_RAW
- });
- }
- break;
- case "big_int":
- ret = new AST_BigInt({
- start: tok,
- end: tok,
- value: tok.value,
- raw: LATEST_RAW,
- });
- break;
- case "string":
- ret = new AST_String({
- start : tok,
- end : tok,
- value : tok.value,
- quote : tok.quote
- });
- annotate(ret);
- break;
- case "regexp":
- const [_, source, flags] = tok.value.match(/^\/(.*)\/(\w*)$/);
- ret = new AST_RegExp({ start: tok, end: tok, value: { source, flags } });
- break;
- case "atom":
- switch (tok.value) {
- case "false":
- ret = new AST_False({ start: tok, end: tok });
- break;
- case "true":
- ret = new AST_True({ start: tok, end: tok });
- break;
- case "null":
- ret = new AST_Null({ start: tok, end: tok });
- break;
- }
- break;
- }
- next();
- return ret;
- }
- function to_fun_args(ex, default_seen_above) {
- var insert_default = function(ex, default_value) {
- if (default_value) {
- return new AST_DefaultAssign({
- start: ex.start,
- left: ex,
- operator: "=",
- right: default_value,
- end: default_value.end
- });
- }
- return ex;
- };
- if (ex instanceof AST_Object) {
- return insert_default(new AST_Destructuring({
- start: ex.start,
- end: ex.end,
- is_array: false,
- names: ex.properties.map(prop => to_fun_args(prop))
- }), default_seen_above);
- } else if (ex instanceof AST_ObjectKeyVal) {
- ex.value = to_fun_args(ex.value);
- return insert_default(ex, default_seen_above);
- } else if (ex instanceof AST_Hole) {
- return ex;
- } else if (ex instanceof AST_Destructuring) {
- ex.names = ex.names.map(name => to_fun_args(name));
- return insert_default(ex, default_seen_above);
- } else if (ex instanceof AST_SymbolRef) {
- return insert_default(new AST_SymbolFunarg({
- name: ex.name,
- start: ex.start,
- end: ex.end
- }), default_seen_above);
- } else if (ex instanceof AST_Expansion) {
- ex.expression = to_fun_args(ex.expression);
- return insert_default(ex, default_seen_above);
- } else if (ex instanceof AST_Array) {
- return insert_default(new AST_Destructuring({
- start: ex.start,
- end: ex.end,
- is_array: true,
- names: ex.elements.map(elm => to_fun_args(elm))
- }), default_seen_above);
- } else if (ex instanceof AST_Assign) {
- return insert_default(to_fun_args(ex.left, ex.right), default_seen_above);
- } else if (ex instanceof AST_DefaultAssign) {
- ex.left = to_fun_args(ex.left);
- return ex;
- } else {
- croak("Invalid function parameter", ex.start.line, ex.start.col);
- }
- }
- var expr_atom = function(allow_calls, allow_arrows) {
- if (is("operator", "<")) {
- typescript_skip_type_parameters_before_call();
- }
- if (is("operator", "new")) {
- return new_(allow_calls);
- }
- if (is("name", "import")) {
- return import_expr(allow_calls);
- }
- var start = S.token;
- var peeked;
- var async = is("name", "async")
- && (peeked = peek()).value != "["
- && peeked.type != "arrow"
- && as_atom_node();
- if (async && is("operator", "<")) {
- // async <T>() => null
- typescript_skip_type_parameters_before_call();
- }
- if (is("punc")) {
- switch (S.token.value) {
- case "(":
- if (async && !allow_calls) break;
- var exprs = params_or_seq_(allow_arrows, !async);
- if (allow_arrows && is("punc", ":")) {
- typescript_type_annotation();
- }
- if (allow_arrows && is("arrow", "=>")) {
- return arrow_function(start, exprs.map(e => to_fun_args(e)), !!async);
- }
- var ex = async ? new AST_Call({
- expression: async,
- args: exprs
- }) : to_expr_or_sequence(start, exprs);
- if (ex.start) {
- const outer_comments_before = start.comments_before.length;
- outer_comments_before_counts.set(start, outer_comments_before);
- ex.start.comments_before.unshift(...start.comments_before);
- start.comments_before = ex.start.comments_before;
- if (outer_comments_before == 0 && start.comments_before.length > 0) {
- var comment = start.comments_before[0];
- if (!comment.nlb) {
- comment.nlb = start.nlb;
- start.nlb = false;
- }
- }
- start.comments_after = ex.start.comments_after;
- }
- ex.start = start;
- var end = prev();
- if (ex.end) {
- end.comments_before = ex.end.comments_before;
- ex.end.comments_after.push(...end.comments_after);
- end.comments_after = ex.end.comments_after;
- }
- ex.end = end;
- if (ex instanceof AST_Call) annotate(ex);
- return subscripts(ex, allow_calls);
- case "[":
- return subscripts(array_(), allow_calls);
- case "{":
- return subscripts(object_or_destructuring_(), allow_calls);
- }
- if (!async) unexpected();
- }
- if (allow_arrows && is("name") && is_token(peek(), "arrow")) {
- var param = new AST_SymbolFunarg({
- name: S.token.value,
- start: start,
- end: start,
- });
- next();
- return arrow_function(start, [param], !!async);
- }
- if (is("keyword", "function")) {
- next();
- var func = function_(AST_Function, false, !!async);
- if (func == typescript_ellide) typescript_croak();
- func.start = start;
- func.end = prev();
- return subscripts(func, allow_calls);
- }
- if (async) return subscripts(async, allow_calls);
- if (is("keyword", "class")) {
- next();
- var cls = class_(AST_ClassExpression);
- cls.start = start;
- cls.end = prev();
- return subscripts(cls, allow_calls);
- }
- if (is("template_head")) {
- return subscripts(template_string(), allow_calls);
- }
- if (ATOMIC_START_TOKEN.has(S.token.type)) {
- return subscripts(as_atom_node(), allow_calls);
- }
- unexpected();
- };
- function template_string() {
- var segments = [], start = S.token;
- segments.push(new AST_TemplateSegment({
- start: S.token,
- raw: TEMPLATE_RAWS.get(S.token),
- value: S.token.value,
- end: S.token
- }));
- while (!S.token.template_end) {
- next();
- handle_regexp();
- segments.push(expression(true));
- segments.push(new AST_TemplateSegment({
- start: S.token,
- raw: TEMPLATE_RAWS.get(S.token),
- value: S.token.value,
- end: S.token
- }));
- }
- next();
- return new AST_TemplateString({
- start: start,
- segments: segments,
- end: S.token
- });
- }
- function expr_list(closing, allow_trailing_comma, allow_empty) {
- var first = true, a = [];
- while (!is("punc", closing)) {
- if (first) first = false; else expect(",");
- if (allow_trailing_comma && is("punc", closing)) break;
- if (is("punc", ",") && allow_empty) {
- a.push(new AST_Hole({ start: S.token, end: S.token }));
- } else if (is("expand", "...")) {
- next();
- a.push(new AST_Expansion({start: prev(), expression: expression(),end: S.token}));
- } else {
- a.push(expression(false));
- }
- }
- next();
- return a;
- }
- var array_ = embed_tokens(function() {
- expect("[");
- return new AST_Array({
- elements: expr_list("]", !options.strict, true)
- });
- });
- var create_accessor = (is_generator, is_async) => {
- return function_(AST_Accessor, is_generator, is_async);
- };
- var object_or_destructuring_ = embed_tokens(function object_or_destructuring_() {
- var start = S.token, first = true, a = [];
- expect("{");
- while (!is("punc", "}")) {
- if (first) first = false; else expect(",");
- if (!options.strict && is("punc", "}"))
- // allow trailing comma
- break;
- start = S.token;
- if (start.type == "expand") {
- next();
- a.push(new AST_Expansion({
- start: start,
- expression: expression(false),
- end: prev(),
- }));
- continue;
- }
- if(is("privatename")) {
- croak("private fields are not allowed in an object");
- }
- var name = as_property_name();
- var value;
- // Check property and fetch value
- if (!is("punc", ":")) {
- var concise = object_or_class_property(name, start);
- if (concise === typescript_ellide) {
- continue;
- }
- if (concise) {
- a.push(concise);
- continue;
- }
- value = new AST_SymbolRef({
- start: prev(),
- name: name,
- end: prev()
- });
- } else if (name === null) {
- unexpected(prev());
- } else {
- next(); // `:` - see first condition
- value = expression(false);
- }
- // Check for default value and alter value accordingly if necessary
- if (is("operator", "=")) {
- next();
- value = new AST_Assign({
- start: start,
- left: value,
- operator: "=",
- right: expression(false),
- logical: false,
- end: prev()
- });
- }
- // Create property
- const kv = new AST_ObjectKeyVal({
- start: start,
- quote: start.quote,
- key: name,
- value: value,
- end: prev()
- });
- a.push(annotate(kv));
- }
- next();
- return new AST_Object({ properties: a });
- });
- function class_(KindOfClass, is_export_default) {
- var start, method, class_name, extends_, properties = [];
- S.input.push_directives_stack(); // Push directive stack, but not scope stack
- S.input.add_directive("use strict");
- if (S.token.type == "name" && S.token.value != "extends") {
- class_name = as_symbol(KindOfClass === AST_DefClass ? AST_SymbolDefClass : AST_SymbolClass);
- }
- if (KindOfClass === AST_DefClass && !class_name) {
- if (is_export_default) {
- KindOfClass = AST_ClassExpression;
- } else {
- unexpected();
- }
- }
- if (is("operator", "<")) {
- typescript_type_parameters();
- }
- if (S.token.value == "extends") {
- next();
- extends_ = expression(true);
- }
- if (is("name", "implements")) {
- typescript_extends_implements();
- }
- expect("{");
- // mark in class feild,
- const save_in_class = S.in_class;
- S.in_class = true;
- while (is("punc", ";")) { next(); } // Leading semicolons are okay in class bodies.
- while (!is("punc", "}")) {
- start = S.token;
- method = object_or_class_property(as_property_name(true), start, true);
- if (!method) { unexpected(); }
- if (method !== typescript_ellide) {
- properties.push(method);
- }
- while (is("punc", ";")) { next(); }
- }
- // mark in class feild,
- S.in_class = save_in_class;
- S.input.pop_directives_stack();
- next();
- return new KindOfClass({
- start: start,
- name: class_name,
- extends: extends_,
- properties: properties,
- end: prev(),
- });
- }
- function object_or_class_property(name, start, is_class) {
- const get_symbol_ast = (name, SymbolClass) => {
- if (typeof name === "string") {
- return new SymbolClass({ start, name, end: prev() });
- } else if (name === null) {
- unexpected();
- }
- return name;
- };
- var is_private = prev().type === "privatename";
- const is_not_method_start = () =>
- !is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("punc", ";") && !is("operator", "=") && !is_private;
- var is_async = false;
- var is_static = false;
- var is_generator = false;
- var accessor_type = null;
- if (name === typescript_ellide) return name;
- if (is_class && (name === "public" || name === "private" || name === "protected") && is_not_method_start()) {
- const did_eat = typescript_is_accessibility_modifier();
- if (did_eat) name = as_property_name(true);
- }
- if (name === typescript_ellide) return name;
- if (is_class && name === "static" && is_not_method_start()) {
- const static_block = class_static_block();
- if (static_block != null) {
- return static_block;
- }
- is_static = true;
- name = as_property_name(true);
- }
- if (name === typescript_ellide) return name;
- if (name === "readonly" && typescript_is_readonly() && is_not_method_start()) {
- name = as_property_name(true);
- }
- if (name === typescript_ellide) return name;
- if (name === "async" && is_not_method_start()) {
- is_async = true;
- name = as_property_name();
- }
- if (prev().type === "operator" && prev().value === "*") {
- is_generator = true;
- name = as_property_name();
- }
- if ((name === "get" || name === "set") && is_not_method_start()) {
- accessor_type = name;
- name = as_property_name();
- }
- if (!is_private && prev().type === "privatename") {
- is_private = true;
- }
- const property_token = prev();
- if (is("punc", ":")) {
- typescript_type_annotation();
- }
- if (accessor_type != null) {
- if (!is_private) {
- const AccessorClass = accessor_type === "get"
- ? AST_ObjectGetter
- : AST_ObjectSetter;
- name = get_symbol_ast(name, AST_SymbolMethod);
- const accessor = create_accessor();
- if (accessor == typescript_ellide) return accessor;
- return annotate(new AccessorClass({
- start,
- static: is_static,
- key: name,
- quote: name instanceof AST_SymbolMethod ? property_token.quote : undefined,
- value: accessor,
- end: prev()
- }));
- } else {
- const AccessorClass = accessor_type === "get"
- ? AST_PrivateGetter
- : AST_PrivateSetter;
- name = get_symbol_ast(name, AST_SymbolMethod);
- const accessor = create_accessor();
- if (accessor == typescript_ellide) return accessor;
- return annotate(new AccessorClass({
- start,
- static: is_static,
- key: name,
- value: accessor,
- end: prev(),
- }));
- }
- }
- if (is_class && is("operator", "<")) {
- typescript_type_parameters();
- }
- if (is("punc", "(")) {
- name = get_symbol_ast(name, AST_SymbolMethod);
- const AST_MethodVariant = is_private
- ? AST_PrivateMethod
- : AST_ConciseMethod;
- const accessor = create_accessor(is_generator, is_async);
- if (accessor == typescript_ellide) return accessor;
- var node = new AST_MethodVariant({
- start : start,
- static : is_static,
- key : name,
- quote : name instanceof AST_SymbolMethod ?
- property_token.quote : undefined,
- value : accessor,
- end : prev()
- });
- return annotate(node);
- }
- if (is_class) {
- const AST_SymbolVariant = is_private
- ? AST_SymbolPrivateProperty
- : AST_SymbolClassProperty;
- const AST_ClassPropertyVariant = is_private
- ? AST_ClassPrivateProperty
- : AST_ClassProperty;
- const key = get_symbol_ast(name, AST_SymbolVariant);
- const quote = key instanceof AST_SymbolClassProperty
- ? property_token.quote
- : undefined;
- if (is("operator", "=")) {
- next();
- return annotate(
- new AST_ClassPropertyVariant({
- start,
- static: is_static,
- quote,
- key,
- value: expression(false),
- end: prev()
- })
- );
- } else if (
- is("name")
- || is("privatename")
- || is("punc", "[")
- || is("operator", "*")
- || is("punc", ";")
- || is("punc", "}")
- || is("string")
- || is("num")
- || is("big_int")
- ) {
- return annotate(
- new AST_ClassPropertyVariant({
- start,
- static: is_static,
- quote,
- key,
- end: prev()
- })
- );
- }
- }
- }
- function class_static_block() {
- if (!is("punc", "{")) {
- return null;
- }
- const start = S.token;
- const body = [];
- next();
- while (!is("punc", "}")) {
- body.push(statement());
- }
- next();
- return new AST_ClassStaticBlock({ start, body, end: prev() });
- }
- function maybe_import_attributes() {
- if (
- (is("keyword", "with") || is("name", "assert"))
- && !has_newline_before(S.token)
- ) {
- next();
- return object_or_destructuring_();
- }
- return null;
- }
- function import_statement() {
- var start = prev();
- // import source x from "..."
- // import defer * as x from "..."
- var phase = null;
- if (is("name", "source") || is("name", "defer")) {
- var peeked = peek();
- if (!is_token(peeked, "name", "from") && !is_token(peeked, "punc", ",")) {
- phase = S.token.value;
- next();
- }
- }
- if (
- is("name", "type")
- && typescript_import_type_statement()
- ) {
- return new AST_EmptyStatement({ start, end: prev() });
- }
- var imported_name;
- var imported_names;
- if (is("name")) {
- imported_name = as_symbol(AST_SymbolImport);
- }
- if (is("punc", ",")) {
- next();
- }
- imported_names = map_names(true);
- if (imported_names || imported_name) {
- expect_token("name", "from");
- }
- var mod_str = S.token; // expect_token("string");
- if (mod_str.type !== "string") {
- unexpected();
- }
- next();
- const attributes = maybe_import_attributes();
- return new AST_Import({
- start,
- imported_name,
- imported_names,
- module_name: new AST_String({
- start: mod_str,
- value: mod_str.value,
- quote: mod_str.quote,
- end: mod_str,
- }),
- attributes,
- phase,
- end: S.token,
- });
- }
- // import()
- // import.source("module")
- // import.defer("module")
- // import.meta
- function import_expr(allow_calls) {
- var start = S.token;
- expect_token("name", "import");
- if (is("punc", "(")) {
- next();
- const args = expr_list(")");
- return subscripts(new AST_DynamicImport({
- start: start,
- args,
- phase: null,
- end: prev(),
- }), allow_calls);
- }
- expect_token("punc", ".");
- if (is("name", "source") || is("name", "defer")) {
- var phase = S.token.value;
- next();
- if (!is("punc", "(")) {
- croak("'import." + phase + "' can only be used in a dynamic import");
- }
- next();
- var args = expr_list(")");
- return subscripts(new AST_DynamicImport({
- start: start,
- phase: phase,
- args: args,
- end: prev()
- }), allow_calls);
- }
- expect_token("name", "meta");
- return subscripts(new AST_ImportMeta({
- start: start,
- end: prev()
- }), allow_calls);
- }
- function map_name(is_import) {
- function make_symbol(type, quote) {
- return new type({
- name: as_property_name(),
- quote: quote || undefined,
- start: prev(),
- end: prev()
- });
- }
- var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
- var type = is_import ? AST_SymbolImport : AST_SymbolExport;
- var start = S.token;
- var foreign_name;
- var name;
- if (is_import) {
- foreign_name = make_symbol(foreign_type, start.quote);
- } else {
- name = make_symbol(type, start.quote);
- }
- if (is("name", "as")) {
- next(); // The "as" word
- if (is_import) {
- name = make_symbol(type);
- } else {
- foreign_name = make_symbol(foreign_type, S.token.quote);
- }
- } else {
- if (is_import) {
- name = new type(foreign_name);
- } else {
- foreign_name = new foreign_type(name);
- }
- }
- return new AST_NameMapping({
- start: start,
- foreign_name: foreign_name,
- name: name,
- end: prev(),
- });
- }
- function map_nameAsterisk(is_import, import_or_export_foreign_name) {
- var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
- var type = is_import ? AST_SymbolImport : AST_SymbolExport;
- var start = S.token;
- var name, foreign_name;
- var end = prev();
- if (is_import) {
- name = import_or_export_foreign_name;
- } else {
- foreign_name = import_or_export_foreign_name;
- }
- name = name || new type({
- start: start,
- name: "*",
- end: end,
- });
- foreign_name = foreign_name || new foreign_type({
- start: start,
- name: "*",
- end: end,
- });
- return new AST_NameMapping({
- start: start,
- foreign_name: foreign_name,
- name: name,
- end: end,
- });
- }
- function map_names(is_import) {
- var names;
- if (is("punc", "{")) {
- next();
- names = [];
- while (!is("punc", "}")) {
- if (
- is("name", "type")
- && !(is_token(peek(), "name", "as") || is_token(peek(), "punc", ",") || is_token(peek(), "punc", "}"))
- && typescript_import_named_type()
- ) ; else {
- names.push(map_name(is_import));
- }
- if (!is("punc", "}")) {
- expect_token("punc", ",");
- }
- }
- next();
- } else if (is("operator", "*")) {
- var name;
- next();
- if (is("name", "as")) {
- next(); // The "as" word
- name = is_import ? as_symbol(AST_SymbolImport) : as_symbol_or_string(AST_SymbolExportForeign);
- }
- names = [map_nameAsterisk(is_import, name)];
- }
- return names;
- }
- function export_statement() {
- var start = S.token;
- var is_default;
- var exported_names;
- if ((is("name", "type") || is("name", "interface"))) {
- typescript_export_type_statement();
- return new AST_EmptyStatement({ start, end: prev() });
- }
- if (is("keyword", "default")) {
- is_default = true;
- next();
- } else if (exported_names = map_names(false)) {
- if (is("name", "from")) {
- next();
- var mod_str = S.token;
- if (mod_str.type !== "string") {
- unexpected();
- }
- next();
- const attributes = maybe_import_attributes();
- return new AST_Export({
- start: start,
- is_default: is_default,
- exported_names: exported_names,
- module_name: new AST_String({
- start: mod_str,
- value: mod_str.value,
- quote: mod_str.quote,
- end: mod_str,
- }),
- end: prev(),
- attributes
- });
- } else {
- return new AST_Export({
- start: start,
- is_default: is_default,
- exported_names: exported_names,
- end: prev(),
- });
- }
- }
- var node;
- var exported_value;
- var exported_definition;
- if (is("punc", "{")
- || is_default
- && (is("keyword", "class") || is("keyword", "function"))
- && is_token(peek(), "punc")) {
- exported_value = expression(false);
- semicolon();
- } else if ((node = statement(is_default)) instanceof AST_Definitions && is_default) {
- unexpected(node.start);
- } else if (
- node instanceof AST_Definitions
- || node instanceof AST_Defun
- || node instanceof AST_DefClass
- ) {
- exported_definition = node;
- } else if (
- node instanceof AST_ClassExpression
- || node instanceof AST_Function
- ) {
- exported_value = node;
- } else if (node instanceof AST_SimpleStatement) {
- exported_value = node.body;
- } else {
- unexpected(node.start);
- }
- return new AST_Export({
- start: start,
- is_default: is_default,
- exported_value: exported_value,
- exported_definition: exported_definition,
- end: prev(),
- attributes: null
- });
- }
- function as_property_name(typescript_class_index_notation = false) {
- var tmp = S.token;
- switch (tmp.type) {
- case "punc":
- if (tmp.value === "[") {
- next();
- var ex = expression(false);
- if (typescript_class_index_notation && is("punc", ":") && typescript_type_annotation()) {
- expect("]");
- if (is("punc", ":")) typescript_type_annotation();
- return typescript_ellide;
- }
- expect("]");
- return ex;
- } else unexpected(tmp);
- case "operator":
- if (tmp.value === "*") {
- next();
- return null;
- }
- if (!["delete", "in", "instanceof", "new", "typeof", "void"].includes(tmp.value)) {
- unexpected(tmp);
- }
- /* falls through */
- case "name":
- case "privatename":
- case "string":
- case "keyword":
- case "atom":
- next();
- return tmp.value;
- case "num":
- case "big_int":
- next();
- return "" + tmp.value;
- default:
- unexpected(tmp);
- }
- }
- function as_name() {
- var tmp = S.token;
- if (tmp.type != "name" && tmp.type != "privatename") unexpected();
- next();
- return tmp.value;
- }
- function _make_symbol(type) {
- var name = S.token.value;
- return new (name == "this" ? AST_This :
- name == "super" ? AST_Super :
- type)({
- name : String(name),
- start : S.token,
- end : S.token
- });
- }
- function _verify_symbol(sym) {
- var name = sym.name;
- if (is_in_generator() && name == "yield") {
- token_error(sym.start, "Yield cannot be used as identifier inside generators");
- }
- if (S.input.has_directive("use strict")) {
- if (name == "yield") {
- token_error(sym.start, "Unexpected yield identifier inside strict mode");
- }
- if (sym instanceof AST_SymbolDeclaration && (name == "arguments" || name == "eval")) {
- token_error(sym.start, "Unexpected " + name + " in strict mode");
- }
- }
- }
- function as_symbol(type, noerror) {
- if (!is("name")) {
- if (!noerror) croak("Name expected");
- return null;
- }
- var sym = _make_symbol(type);
- _verify_symbol(sym);
- next();
- return sym;
- }
- function as_symbol_or_string(type) {
- if (!is("name")) {
- if (!is("string")) {
- croak("Name or string expected");
- }
- var tok = S.token;
- var ret = new type({
- start : tok,
- end : tok,
- name : tok.value,
- quote : tok.quote
- });
- next();
- return ret;
- }
- var sym = _make_symbol(type);
- _verify_symbol(sym);
- next();
- return sym;
- }
- // Annotate AST_Call, AST_Lambda or AST_New with the special comments
- function annotate(node, before_token = node.start) {
- var comments = before_token.comments_before;
- const comments_outside_parens = outer_comments_before_counts.get(before_token);
- var i = comments_outside_parens != null ? comments_outside_parens : comments.length;
- while (--i >= 0) {
- var comment = comments[i];
- if (/[@#]__/.test(comment.value)) {
- if (/[@#]__PURE__/.test(comment.value)) {
- set_annotation(node, _PURE);
- break;
- }
- if (/[@#]__INLINE__/.test(comment.value)) {
- set_annotation(node, _INLINE);
- break;
- }
- if (/[@#]__NOINLINE__/.test(comment.value)) {
- set_annotation(node, _NOINLINE);
- break;
- }
- if (/[@#]__KEY__/.test(comment.value)) {
- set_annotation(node, _KEY);
- break;
- }
- if (/[@#]__MANGLE_PROP__/.test(comment.value)) {
- set_annotation(node, _MANGLEPROP);
- break;
- }
- }
- }
- return node;
- }
- var subscripts = function(expr, allow_calls, is_chain) {
- var start = expr.start;
- if (is("punc", ".")) {
- next();
- if(is("privatename") && !S.in_class)
- croak("Private field must be used in an enclosing class");
- const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot;
- return annotate(subscripts(new AST_DotVariant({
- start : start,
- expression : expr,
- optional : false,
- property : as_name(),
- end : prev()
- }), allow_calls, is_chain));
- }
- if (is("punc", "[")) {
- next();
- var prop = expression(true);
- expect("]");
- return annotate(subscripts(new AST_Sub({
- start : start,
- expression : expr,
- optional : false,
- property : prop,
- end : prev()
- }), allow_calls, is_chain));
- }
- if (allow_calls && is("operator", "<")) typescript_skip_type_parameters_before_call();
- if (allow_calls && is("punc", "(")) {
- next();
- var call = new AST_Call({
- start : start,
- expression : expr,
- optional : false,
- args : call_args(),
- end : prev()
- });
- annotate(call);
- return subscripts(call, true, is_chain);
- }
- // Optional chain
- if (is("punc", "?.")) {
- next();
- let chain_contents;
- if (allow_calls && is("operator", "<")) typescript_type_parameters();
- if (allow_calls && is("punc", "(")) {
- next();
- const call = new AST_Call({
- start,
- optional: true,
- expression: expr,
- args: call_args(),
- end: prev()
- });
- annotate(call);
- chain_contents = subscripts(call, true, true);
- } else if (is("name") || is("privatename")) {
- if(is("privatename") && !S.in_class)
- croak("Private field must be used in an enclosing class");
- const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot;
- chain_contents = annotate(subscripts(new AST_DotVariant({
- start,
- expression: expr,
- optional: true,
- property: as_name(),
- end: prev()
- }), allow_calls, true));
- } else if (is("punc", "[")) {
- next();
- const property = expression(true);
- expect("]");
- chain_contents = annotate(subscripts(new AST_Sub({
- start,
- expression: expr,
- optional: true,
- property,
- end: prev()
- }), allow_calls, true));
- }
- if (!chain_contents) unexpected();
- if (chain_contents instanceof AST_Chain) return chain_contents;
- return new AST_Chain({
- start,
- expression: chain_contents,
- end: prev()
- });
- }
- if (is("template_head")) {
- if (is_chain) {
- // a?.b`c` is a syntax error
- unexpected();
- }
- return subscripts(new AST_PrefixedTemplateString({
- start: start,
- prefix: expr,
- template_string: template_string(),
- end: prev()
- }), allow_calls);
- }
- return expr;
- };
- function call_args() {
- var args = [];
- while (!is("punc", ")")) {
- if (is("expand", "...")) {
- next();
- args.push(new AST_Expansion({
- start: prev(),
- expression: expression(false),
- end: prev()
- }));
- } else {
- args.push(expression(false));
- }
- if (!is("punc", ")")) {
- expect(",");
- }
- }
- next();
- return args;
- }
- var maybe_unary = function(allow_calls, allow_arrows) {
- var start = S.token;
- if (start.type == "name" && start.value == "await" && can_await()) {
- next();
- return _await_expression();
- }
- if (is("operator") && UNARY_PREFIX.has(start.value)) {
- next();
- handle_regexp();
- var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
- ex.start = start;
- ex.end = prev();
- return ex;
- }
- var val = expr_atom(allow_calls, allow_arrows);
- while (is("operator") && UNARY_POSTFIX.has(S.token.value) && !has_newline_before(S.token)) {
- if (val instanceof AST_Arrow) unexpected();
- val = make_unary(AST_UnaryPostfix, S.token, val);
- val.start = start;
- val.end = S.token;
- next();
- }
- if (is("name", "as") || is("name", "satisfies")) {
- typescript_as_satisfies();
- }
- return val;
- };
- function make_unary(ctor, token, expr) {
- var op = token.value;
- switch (op) {
- case "++":
- case "--":
- if (!is_assignable(expr))
- croak("Invalid use of " + op + " operator", token.line, token.col, token.pos);
- break;
- case "delete":
- if (expr instanceof AST_SymbolRef && S.input.has_directive("use strict"))
- croak("Calling delete on expression not allowed in strict mode", expr.start.line, expr.start.col, expr.start.pos);
- break;
- }
- return new ctor({ operator: op, expression: expr });
- }
- var expr_op = function(left, min_prec, no_in) {
- var op = is("operator") ? S.token.value : null;
- if (op == "in" && no_in) op = null;
- if (op == "**" && left instanceof AST_UnaryPrefix
- /* unary token in front not allowed - parenthesis required */
- && !is_token(left.start, "punc", "(")
- && left.operator !== "--" && left.operator !== "++")
- unexpected(left.start);
- var prec = op != null ? PRECEDENCE[op] : null;
- if (prec != null && (prec > min_prec || (op === "**" && min_prec === prec))) {
- next();
- var right = expr_ops(no_in, prec, true);
- return expr_op(new AST_Binary({
- start : left.start,
- left : left,
- operator : op,
- right : right,
- end : right.end
- }), min_prec, no_in);
- }
- return left;
- };
- function expr_ops(no_in, min_prec, allow_calls, allow_arrows) {
- // maybe_unary won't return us a AST_SymbolPrivateProperty
- if (!no_in && min_prec < PRECEDENCE["in"] && is("privatename")) {
- if(!S.in_class) {
- croak("Private field must be used in an enclosing class");
- }
- const start = S.token;
- const key = new AST_SymbolPrivateProperty({
- start,
- name: start.value,
- end: start
- });
- next();
- expect_token("operator", "in");
- const private_in = new AST_PrivateIn({
- start,
- key,
- value: expr_ops(no_in, PRECEDENCE["in"], true),
- end: prev()
- });
- return expr_op(private_in, 0, no_in);
- } else {
- return expr_op(maybe_unary(allow_calls, allow_arrows), min_prec, no_in);
- }
- }
- var maybe_conditional = function(no_in) {
- var start = S.token;
- var expr = expr_ops(no_in, 0, true, true);
- if (is("operator", "?")) {
- next();
- if (is("punc", ":") && typescript_maybe_annotation()) {
- return expr;
- }
- var yes = expression(false);
- expect(":");
- return new AST_Conditional({
- start : start,
- condition : expr,
- consequent : yes,
- alternative : expression(false, no_in),
- end : prev()
- });
- }
- return expr;
- };
- function is_assignable(expr) {
- return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef;
- }
- function to_destructuring(node) {
- if (node instanceof AST_Object) {
- node = new AST_Destructuring({
- start: node.start,
- names: node.properties.map(to_destructuring),
- is_array: false,
- end: node.end
- });
- } else if (node instanceof AST_Array) {
- var names = [];
- for (var i = 0; i < node.elements.length; i++) {
- // Only allow expansion as last element
- if (node.elements[i] instanceof AST_Expansion) {
- if (i + 1 !== node.elements.length) {
- token_error(node.elements[i].start, "Spread must the be last element in destructuring array");
- }
- node.elements[i].expression = to_destructuring(node.elements[i].expression);
- }
- names.push(to_destructuring(node.elements[i]));
- }
- node = new AST_Destructuring({
- start: node.start,
- names: names,
- is_array: true,
- end: node.end
- });
- } else if (node instanceof AST_ObjectProperty) {
- node.value = to_destructuring(node.value);
- } else if (node instanceof AST_Assign) {
- node = new AST_DefaultAssign({
- start: node.start,
- left: node.left,
- operator: "=",
- right: node.right,
- end: node.end
- });
- }
- return node;
- }
- // In ES6, AssignmentExpression can also be an ArrowFunction
- var maybe_assign = function(no_in) {
- handle_regexp();
- var start = S.token;
- if (start.type == "name" && start.value == "yield") {
- if (is_in_generator()) {
- next();
- return _yield_expression();
- } else if (S.input.has_directive("use strict")) {
- token_error(S.token, "Unexpected yield identifier inside strict mode");
- }
- }
- var left = maybe_conditional(no_in);
- var val = S.token.value;
- if (is("operator") && ASSIGNMENT.has(val)) {
- if (is_assignable(left) || (left = to_destructuring(left)) instanceof AST_Destructuring) {
- next();
- return new AST_Assign({
- start : start,
- left : left,
- operator : val,
- right : maybe_assign(no_in),
- logical : LOGICAL_ASSIGNMENT.has(val),
- end : prev()
- });
- }
- croak("Invalid assignment");
- }
- return left;
- };
- var to_expr_or_sequence = function(start, exprs) {
- if (exprs.length === 1) {
- return exprs[0];
- } else if (exprs.length > 1) {
- return new AST_Sequence({ start, expressions: exprs, end: peek() });
- } else {
- croak("Invalid parenthesized expression");
- }
- };
- var expression = function(commas, no_in) {
- var start = S.token;
- var exprs = [];
- while (true) {
- exprs.push(maybe_assign(no_in));
- if (!commas || !is("punc", ",")) break;
- next();
- commas = true;
- }
- return to_expr_or_sequence(start, exprs);
- };
- function in_loop(cont) {
- ++S.in_loop;
- var ret = cont();
- --S.in_loop;
- return ret;
- }
- // TS type stripping
- // These functions are called when we know S.token begins some TS fluff
- // Just call next() and friends, skipping TypeScript information
- // Typescript entrypoints, from the rest of the parser
- function typescript_type_parameters() {
- if (!options.experimental_typescript) return;
- expect_token("operator", "<");
- do {
- _ts_type_parameter();
- } while (is("punc", ",") && next());
- if (!_ts_gt_operator()) typescript_croak();
- }
- const typescript_ellide = Symbol("typescript_ellide");
- function typescript_as_satisfies() {
- if (!options.experimental_typescript) return;
- while (is("name", "as") || is("name", "satisfies")) {
- next();
- _ts_type();
- }
- }
- function typescript_type_statement() {
- if (!options.experimental_typescript) return;
- expect_token("name", "type");
- expect_token("name");
- if (is("operator", "<")) {
- typescript_type_parameters();
- }
- expect_token("operator", "=");
- _ts_type();
- }
- function typescript_interface_statement() {
- if (!options.experimental_typescript) return;
- expect_token("name", "interface");
- expect_token("name");
- if (is("operator", "<")) {
- typescript_type_parameters();
- }
- if (is("keyword", "extends") || is("keyword", "implements")) {
- typescript_extends_implements();
- }
- _ts_object_body();
- }
- function typescript_import_type_statement() {
- if (!options.experimental_typescript) return;
- if (
- is_token(peek(), "name", "from")
- || is_token(peek(), "punc", ",")
- ) {
- // not TS: `import type from ...`, `import type, { ...`
- return false;
- }
- expect_token("name", "type");
- if (!is("punc", "{")) {
- next(); // star or name
- if (is("name", "as")) {
- next();
- _ts_type_name(); // import type 'string' as NotString
- }
- if (is("punc", ",")) {
- next();
- _ts_import_export_name_mapping();
- }
- } else if (is("punc", "{")) {
- _ts_import_export_name_mapping();
- }
- expect_token("name", "from");
- expect_token("string");
- return true;
- }
- function typescript_export_type_statement() {
- if (!options.experimental_typescript) return;
- if (is("name", "type") && is_token(peek(), "name")) {
- typescript_type_statement();
- return;
- }
- if (is("name", "interface")) {
- typescript_interface_statement();
- return;
- }
- expect_token("name", "type");
- if (is("operator", "*")) {
- next();
- if (is("name", "as")) {
- next();
- next();
- }
- }
- if (is("punc", "{")) {
- _ts_import_export_name_mapping();
- }
- if (is("name", "from")) {
- expect_token("name", "from");
- expect_token("string");
- }
- }
- function typescript_maybe_annotation() {
- if (!options.experimental_typescript) return;
- if (
- is("operator", "?") && is_token(peek(), "punc", ":") && next()
- || is("punc", ":")
- ) {
- typescript_type_annotation();
- return true;
- }
- return false;
- }
- function typescript_import_named_type() {
- if (!options.experimental_typescript) return false;
- expect_token("name", "type");
- next(); // name or string
- if (is("name", "as")) {
- next();
- if (is("keyword", "default")) next();
- else _ts_type();
- }
- return true;
- }
- function typescript_type_annotation() {
- if (!options.experimental_typescript) return;
- expect_token("punc", ":");
- _ts_type();
- return true;
- }
- function typescript_skip_this_type() {
- if (!options.experimental_typescript) return;
- if (is("name", "this")) {
- next();
- typescript_type_annotation();
- if (is("punc", ",")) next();
- return true;
- }
- }
- function typescript_extends_implements() {
- if (!options.experimental_typescript) return;
- next(); // "extends" / "implements"
- _ts_commatized_while("name", _ts_type);
- }
- function typescript_is_accessibility_modifier() {
- if (!options.experimental_typescript) return;
- // Known to be 'private', 'public' or 'protected'
- return true;
- }
- function typescript_is_readonly() {
- if (!options.experimental_typescript) return;
- // Known to be 'readonly'
- return true;
- }
- function typescript_is_function_no_body() {
- if (!options.experimental_typescript) return;
- // There's no body. Is this okay?
- return true;
- }
- function typescript_skip_type_parameters_before_call() {
- if (!options.experimental_typescript) return;
- // Skip type parameters without parsing ahead. Differentiates between comparisons and type parameters: varname < T > (1)
- // Go until "?." or "("
- const matches = S.input.typescript_is_type_parameters_before_call();
- if (matches) typescript_type_parameters();
- }
- function typescript_croak() {
- croak("invalid or unsupported TypeScript syntax");
- }
- // Internal stuff
- function _ts_gt_operator() {
- // HACK: JS has >, >>, >>>. TS only knows >
- if (S.token.type === "operator" && S.token.value.startsWith(">")) {
- if (S.token.value === ">") {
- return next();
- } else {
- S.token.value = S.token.value.slice(1);
- return true;
- }
- }
- }
- function _ts_type_parameter() {
- _ts_type();
- _ts_constraint();
- }
- function _ts_constraint() {
- if (is("keyword", "extends")) {
- expect_token("keyword", "extends");
- _ts_type();
- if (is("operator", "=")) {
- expect_token("operator", "=");
- _ts_type();
- }
- }
- }
- function _ts_type() {
- if (is("operator", "new")) {
- // new(...args) => Type
- next();
- if (is("operator", "<")) typescript_type_parameters();
- _ts_parenthesized_params();
- expect_token("arrow", "=>");
- _ts_type();
- } else if (is("punc", "(")) {
- // (...args) => Type
- _ts_parenthesized_params();
- expect_token("arrow", "=>");
- _ts_type();
- expect_token("punc", ")");
- } else {
- do {
- if (is("operator", "|") || is("operator", "&")) next();
- _ts_primary_type();
- } while (is("operator", "|") || is("operator", "&"));
- }
- }
- var _TS_PREDEFINED_TYPES = makePredicate(["any", "unknown", "const", "number", "boolean", "string", "symbol", "void"]);
- function _ts_primary_type() {
- if (is("name", "readonly")) next();
- if (is("name", "import") && is_token(peek(), "punc", "(")) {
- next();
- expect("(");
- _ts_type();
- expect(")");
- _ts_subscripts();
- } else if (is("punc", "(")) {
- next();
- _ts_type();
- expect(")");
- } else if (is("name") && _TS_PREDEFINED_TYPES.has(S.token.value)) {
- next();
- } else if (is("template_head")) {
- _ts_template_string();
- } else if (is("string") || is("num") || is("big_int") || is("atom")) {
- next();
- } else if (is("name")) {
- _ts_type_name();
- if (is("operator", "<")) typescript_type_parameters();
- } else if (is("punc", "{")) {
- _ts_object_body();
- } else if (is("punc", "[")) {
- next();
- _ts_tuple_types();
- expect_token("punc", "]");
- } else if (is("operator", "typeof")) {
- next();
- _ts_type_name();
- } else {
- typescript_croak();
- }
- // NestedArraySuffixes[][][][]
- while (is("punc", "[") && is_token(peek(), "punc", "]")) {
- next();
- next();
- }
- }
- // Also used as `typeof`'s argument
- function _ts_type_name() {
- expect_token("name");
- _ts_subscripts();
- }
- function _ts_subscripts() {
- if (is("punc", ".")) {
- next();
- expect_token("name");
- return _ts_subscripts();
- }
- if (is("punc", "[") && !is_token(peek(), "punc", "]")) {
- expect_token("punc", "[");
- _ts_type();
- expect_token("punc", "]");
- return _ts_subscripts();
- }
- }
- function _ts_object_body() {
- const is_method_key = (token) =>
- is_token(token, "name")
- || is_token(token, "num")
- || is_token(token, "string")
- || is_token(token, "operator", "new");
- expect_token("punc", "{");
- _ts_commas_or_semicolons("punc", "}", () => {
- // SKIP `readonly` WHEN IT'S A KEYWORD
- if (
- is("name", "readonly")
- && (is_method_key(peek())
- || is_token(peek(), "template_head")
- || is_token(peek(), "punc", "["))
- ) {
- next();
- }
- // KEY
- if (is_method_key(S.token)) {
- next();
- } else if (is("template_head")) {
- _ts_template_string();
- } else if (is("punc", "[")) {
- next();
- if (is_method_key(S.token)) next();
- typescript_maybe_annotation();
- expect("]");
- } else ;
- // OPTIONAL
- if (is("operator", "?")) next();
- // TYPE PARAMETERS
- if (is("operator", "<")) {
- typescript_type_parameters();
- }
- // VALUE (method or thing)
- if (is("punc", "(")) {
- _ts_parenthesized_params();
- typescript_maybe_annotation();
- } else if (is("punc", ":")) {
- next();
- _ts_type();
- } else {
- typescript_croak();
- }
- });
- expect_token("punc", "}");
- }
- function _ts_tuple_types() {
- _ts_commatized("punc", "]", () => {
- if (is("expand", "...")) next(); // [...T]
- _ts_type();
- if (is("punc", ":") || is("operator", "?")) {
- typescript_maybe_annotation(); // [name?: T]
- }
- if (is("operator", "?")) next(); // ["value"?]
- });
- }
- function _ts_parenthesized_params() {
- expect("(");
- _ts_commatized("punc", ")", () => {
- if (is("expand", "...")) next();
- expect_token("name");
- if (is("operator", "?")) next();
- expect(":");
- _ts_type();
- });
- expect(")");
- }
- function _ts_import_export_name_mapping() {
- expect("{");
- _ts_commatized("punc", "}", () => {
- next();
- if (is("name", "as")) {
- next();
- if (is("string") || is("keyword")) next();
- else _ts_type_name();
- }
- });
- expect("}");
- }
- function _ts_commatized(till_type, till, cb) {
- while (!(is(till_type, till))) {
- cb();
- if (!is(till_type, till)) expect(",");
- }
- }
- function _ts_commatized_while(while_type, cb) {
- while (is(while_type)) {
- cb();
- if (!is("punc", ",")) break;
- next();
- }
- }
- function _ts_commas_or_semicolons(till_type, till, cb) {
- while (!is(till_type, till)) {
- cb();
- if (!is(till_type, till)) {
- if (is("punc", ",") || is("punc", ";")) next();
- else if (S.token.nlb) ; // ASI
- else typescript_croak();
- }
- }
- }
- function _ts_template_string() {
- while (!S.token.template_end) {
- next(); // eat "string" part
- _ts_type(); // eat "code" part
- if (!is("template_cont")) typescript_croak();
- }
- next(); // eat last part
- }
- if (options.expression) {
- return expression(true);
- }
- return (function parse_toplevel() {
- var start = S.token;
- var body = [];
- S.input.push_directives_stack();
- if (options.module) S.input.add_directive("use strict");
- while (!is("eof")) {
- body.push(statement());
- }
- S.input.pop_directives_stack();
- var end = prev();
- var toplevel = options.toplevel;
- if (toplevel) {
- toplevel.body = toplevel.body.concat(body);
- toplevel.end = end;
- } else {
- toplevel = new AST_Toplevel({ start: start, body: body, end: end });
- }
- TEMPLATE_RAWS = new Map();
- return toplevel;
- })();
- }
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- function DEFNODE(type, props, ctor, methods, base = AST_Node) {
- if (!props) props = [];
- else props = props.split(/\s+/);
- var self_props = props;
- if (base && base.PROPS)
- props = props.concat(base.PROPS);
- const proto = base && Object.create(base.prototype);
- if (proto) {
- ctor.prototype = proto;
- ctor.BASE = base;
- }
- if (base) base.SUBCLASSES.push(ctor);
- ctor.prototype.CTOR = ctor;
- ctor.prototype.constructor = ctor;
- ctor.PROPS = props || null;
- ctor.SELF_PROPS = self_props;
- ctor.SUBCLASSES = [];
- if (type) {
- ctor.prototype.TYPE = ctor.TYPE = type;
- }
- if (methods) for (let i in methods) if (HOP(methods, i)) {
- if (i[0] === "$") {
- ctor[i.substr(1)] = methods[i];
- } else {
- ctor.prototype[i] = methods[i];
- }
- }
- ctor.DEFMETHOD = function(name, method) {
- this.prototype[name] = method;
- };
- return ctor;
- }
- const has_tok_flag = (tok, flag) => Boolean(tok.flags & flag);
- const set_tok_flag = (tok, flag, truth) => {
- if (truth) {
- tok.flags |= flag;
- } else {
- tok.flags &= ~flag;
- }
- };
- const TOK_FLAG_NLB = 0b0001;
- const TOK_FLAG_QUOTE_SINGLE = 0b0010;
- const TOK_FLAG_QUOTE_EXISTS = 0b0100;
- const TOK_FLAG_TEMPLATE_END = 0b1000;
- class AST_Token {
- constructor(type, value, line, col, pos, nlb, comments_before, comments_after, file) {
- this.flags = (nlb ? 1 : 0);
- this.type = type;
- this.value = value;
- this.line = line;
- this.col = col;
- this.pos = pos;
- this.comments_before = comments_before;
- this.comments_after = comments_after;
- this.file = file;
- Object.seal(this);
- }
- // Return a string summary of the token for node.js console.log
- [Symbol.for("nodejs.util.inspect.custom")](_depth, options) {
- const special = str => options.stylize(str, "special");
- const quote = typeof this.value === "string" && this.value.includes("`") ? "'" : "`";
- const value = `${quote}${this.value}${quote}`;
- return `${special("[AST_Token")} ${value} at ${this.line}:${this.col}${special("]")}`;
- }
- get nlb() {
- return has_tok_flag(this, TOK_FLAG_NLB);
- }
- set nlb(new_nlb) {
- set_tok_flag(this, TOK_FLAG_NLB, new_nlb);
- }
- get quote() {
- return !has_tok_flag(this, TOK_FLAG_QUOTE_EXISTS)
- ? ""
- : (has_tok_flag(this, TOK_FLAG_QUOTE_SINGLE) ? "'" : '"');
- }
- set quote(quote_type) {
- set_tok_flag(this, TOK_FLAG_QUOTE_SINGLE, quote_type === "'");
- set_tok_flag(this, TOK_FLAG_QUOTE_EXISTS, !!quote_type);
- }
- get template_end() {
- return has_tok_flag(this, TOK_FLAG_TEMPLATE_END);
- }
- set template_end(new_template_end) {
- set_tok_flag(this, TOK_FLAG_TEMPLATE_END, new_template_end);
- }
- }
- var AST_Node = DEFNODE("Node", "start end", function AST_Node(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- _clone: function(deep) {
- if (deep) {
- var self = this.clone();
- return self.transform(new TreeTransformer(function(node) {
- if (node !== self) {
- return node.clone(true);
- }
- }));
- }
- return new this.CTOR(this);
- },
- clone: function(deep) {
- return this._clone(deep);
- },
- $documentation: "Base class of all AST nodes",
- $propdoc: {
- start: "[AST_Token] The first token of this node",
- end: "[AST_Token] The last token of this node"
- },
- _walk: function(visitor) {
- return visitor._visit(this);
- },
- walk: function(visitor) {
- return this._walk(visitor); // not sure the indirection will be any help
- },
- _children_backwards: () => {}
- }, null);
- /* -----[ statements ]----- */
- var AST_Statement = DEFNODE("Statement", null, function AST_Statement(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Base class of all statements",
- });
- var AST_Debugger = DEFNODE("Debugger", null, function AST_Debugger(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Represents a debugger statement",
- }, AST_Statement);
- var AST_Directive = DEFNODE("Directive", "value quote", function AST_Directive(props) {
- if (props) {
- this.value = props.value;
- this.quote = props.quote;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Represents a directive, like \"use strict\";",
- $propdoc: {
- value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
- quote: "[string] the original quote character"
- },
- }, AST_Statement);
- var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", function AST_SimpleStatement(props) {
- if (props) {
- this.body = props.body;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A statement consisting of an expression, i.e. a = 1 + 2",
- $propdoc: {
- body: "[AST_Node] an expression node (should not be instanceof AST_Statement)"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.body._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.body);
- }
- }, AST_Statement);
- function walk_body(node, visitor) {
- const body = node.body;
- for (var i = 0, len = body.length; i < len; i++) {
- body[i]._walk(visitor);
- }
- }
- function clone_block_scope(deep) {
- var clone = this._clone(deep);
- if (this.block_scope) {
- clone.block_scope = this.block_scope.clone();
- }
- return clone;
- }
- var AST_Block = DEFNODE("Block", "body block_scope", function AST_Block(props) {
- if (props) {
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A body of statements (usually braced)",
- $propdoc: {
- body: "[AST_Statement*] an array of statements",
- block_scope: "[AST_Scope] the block scope"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- walk_body(this, visitor);
- });
- },
- _children_backwards(push) {
- let i = this.body.length;
- while (i--) push(this.body[i]);
- },
- clone: clone_block_scope
- }, AST_Statement);
- var AST_BlockStatement = DEFNODE("BlockStatement", null, function AST_BlockStatement(props) {
- if (props) {
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A block statement",
- }, AST_Block);
- var AST_EmptyStatement = DEFNODE("EmptyStatement", null, function AST_EmptyStatement(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "The empty statement (empty block or simply a semicolon)"
- }, AST_Statement);
- var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", function AST_StatementWithBody(props) {
- if (props) {
- this.body = props.body;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`",
- $propdoc: {
- body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement"
- }
- }, AST_Statement);
- var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", function AST_LabeledStatement(props) {
- if (props) {
- this.label = props.label;
- this.body = props.body;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Statement with a label",
- $propdoc: {
- label: "[AST_Label] a label definition"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.label._walk(visitor);
- this.body._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.body);
- push(this.label);
- },
- clone: function(deep) {
- var node = this._clone(deep);
- if (deep) {
- var label = node.label;
- var def = this.label;
- node.walk(new TreeWalker(function(node) {
- if (node instanceof AST_LoopControl
- && node.label && node.label.thedef === def) {
- node.label.thedef = label;
- label.references.push(node);
- }
- }));
- }
- return node;
- }
- }, AST_StatementWithBody);
- var AST_IterationStatement = DEFNODE(
- "IterationStatement",
- "block_scope",
- function AST_IterationStatement(props) {
- if (props) {
- this.block_scope = props.block_scope;
- this.body = props.body;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- },
- {
- $documentation: "Internal class. All loops inherit from it.",
- $propdoc: {
- block_scope: "[AST_Scope] the block scope for this iteration statement."
- },
- clone: clone_block_scope
- },
- AST_StatementWithBody
- );
- var AST_DWLoop = DEFNODE("DWLoop", "condition", function AST_DWLoop(props) {
- if (props) {
- this.condition = props.condition;
- this.block_scope = props.block_scope;
- this.body = props.body;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Base class for do/while statements",
- $propdoc: {
- condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"
- }
- }, AST_IterationStatement);
- var AST_Do = DEFNODE("Do", null, function AST_Do(props) {
- if (props) {
- this.condition = props.condition;
- this.block_scope = props.block_scope;
- this.body = props.body;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `do` statement",
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.body._walk(visitor);
- this.condition._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.condition);
- push(this.body);
- }
- }, AST_DWLoop);
- var AST_While = DEFNODE("While", null, function AST_While(props) {
- if (props) {
- this.condition = props.condition;
- this.block_scope = props.block_scope;
- this.body = props.body;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `while` statement",
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.condition._walk(visitor);
- this.body._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.body);
- push(this.condition);
- },
- }, AST_DWLoop);
- var AST_For = DEFNODE("For", "init condition step", function AST_For(props) {
- if (props) {
- this.init = props.init;
- this.condition = props.condition;
- this.step = props.step;
- this.block_scope = props.block_scope;
- this.body = props.body;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `for` statement",
- $propdoc: {
- init: "[AST_Node?] the `for` initialization code, or null if empty",
- condition: "[AST_Node?] the `for` termination clause, or null if empty",
- step: "[AST_Node?] the `for` update clause, or null if empty"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- if (this.init) this.init._walk(visitor);
- if (this.condition) this.condition._walk(visitor);
- if (this.step) this.step._walk(visitor);
- this.body._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.body);
- if (this.step) push(this.step);
- if (this.condition) push(this.condition);
- if (this.init) push(this.init);
- },
- }, AST_IterationStatement);
- var AST_ForIn = DEFNODE("ForIn", "init object", function AST_ForIn(props) {
- if (props) {
- this.init = props.init;
- this.object = props.object;
- this.block_scope = props.block_scope;
- this.body = props.body;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `for ... in` statement",
- $propdoc: {
- init: "[AST_Node] the `for/in` initialization code",
- object: "[AST_Node] the object that we're looping through"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.init._walk(visitor);
- this.object._walk(visitor);
- this.body._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.body);
- if (this.object) push(this.object);
- if (this.init) push(this.init);
- },
- }, AST_IterationStatement);
- var AST_ForOf = DEFNODE("ForOf", "await", function AST_ForOf(props) {
- if (props) {
- this.await = props.await;
- this.init = props.init;
- this.object = props.object;
- this.block_scope = props.block_scope;
- this.body = props.body;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `for ... of` statement",
- }, AST_ForIn);
- var AST_With = DEFNODE("With", "expression", function AST_With(props) {
- if (props) {
- this.expression = props.expression;
- this.body = props.body;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `with` statement",
- $propdoc: {
- expression: "[AST_Node] the `with` expression"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
- this.body._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.body);
- push(this.expression);
- },
- }, AST_StatementWithBody);
- /* -----[ scope and functions ]----- */
- var AST_Scope = DEFNODE(
- "Scope",
- "variables uses_with uses_eval screwy_argnames_scope parent_scope enclosed cname",
- function AST_Scope(props) {
- if (props) {
- this.variables = props.variables;
- this.uses_with = props.uses_with;
- this.uses_eval = props.uses_eval;
- this.screwy_argnames_scope = props.screwy_argnames_scope;
- this.parent_scope = props.parent_scope;
- this.enclosed = props.enclosed;
- this.cname = props.cname;
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- },
- {
- $documentation: "Base class for all statements introducing a lexical scope",
- $propdoc: {
- variables: "[Map/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
- uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
- uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`",
- parent_scope: "[AST_Scope?/S] link to the parent scope",
- enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
- cname: "[integer/S] current index for mangling variables (used internally by the mangler)",
- },
- get_defun_scope: function() {
- var self = this;
- while (self.is_block_scope()) {
- self = self.parent_scope;
- }
- return self;
- },
- clone: function(deep, toplevel) {
- var node = this._clone(deep);
- if (deep && this.variables && toplevel && !this._block_scope) {
- node.figure_out_scope({}, {
- toplevel: toplevel,
- parent_scope: this.parent_scope
- });
- } else {
- if (this.variables) node.variables = new Map(this.variables);
- if (this.enclosed) node.enclosed = this.enclosed.slice();
- if (this._block_scope) node._block_scope = this._block_scope;
- }
- return node;
- },
- pinned: function() {
- return this.uses_eval || this.uses_with;
- }
- },
- AST_Block
- );
- var AST_Toplevel = DEFNODE("Toplevel", "globals", function AST_Toplevel(props) {
- if (props) {
- this.globals = props.globals;
- this.variables = props.variables;
- this.uses_with = props.uses_with;
- this.uses_eval = props.uses_eval;
- this.parent_scope = props.parent_scope;
- this.enclosed = props.enclosed;
- this.cname = props.cname;
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "The toplevel scope",
- $propdoc: {
- globals: "[Map/S] a map of name -> SymbolDef for all undeclared names",
- },
- wrap_commonjs: function(name) {
- var body = this.body;
- var wrapped_tl = "(function(exports){'$ORIG';})(typeof " + name + "=='undefined'?(" + name + "={}):" + name + ");";
- wrapped_tl = parse(wrapped_tl);
- wrapped_tl = wrapped_tl.transform(new TreeTransformer(function(node) {
- if (node instanceof AST_Directive && node.value == "$ORIG") {
- return MAP.splice(body);
- }
- }));
- return wrapped_tl;
- },
- wrap_enclose: function(args_values) {
- if (typeof args_values != "string") args_values = "";
- var index = args_values.indexOf(":");
- if (index < 0) index = args_values.length;
- var body = this.body;
- return parse([
- "(function(",
- args_values.slice(0, index),
- '){"$ORIG"})(',
- args_values.slice(index + 1),
- ")"
- ].join("")).transform(new TreeTransformer(function(node) {
- if (node instanceof AST_Directive && node.value == "$ORIG") {
- return MAP.splice(body);
- }
- }));
- }
- }, AST_Scope);
- var AST_Expansion = DEFNODE("Expansion", "expression", function AST_Expansion(props) {
- if (props) {
- this.expression = props.expression;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "An expandible argument, such as ...rest, a splat, such as [1,2,...all], or an expansion in a variable declaration, such as var [first, ...rest] = list",
- $propdoc: {
- expression: "[AST_Node] the thing to be expanded"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression.walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.expression);
- },
- });
- var AST_Lambda = DEFNODE(
- "Lambda",
- "name argnames uses_arguments is_generator async",
- function AST_Lambda(props) {
- if (props) {
- this.name = props.name;
- this.argnames = props.argnames;
- this.uses_arguments = props.uses_arguments;
- this.is_generator = props.is_generator;
- this.async = props.async;
- this.variables = props.variables;
- this.uses_with = props.uses_with;
- this.uses_eval = props.uses_eval;
- this.parent_scope = props.parent_scope;
- this.enclosed = props.enclosed;
- this.cname = props.cname;
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- },
- {
- $documentation: "Base class for functions",
- $propdoc: {
- name: "[AST_SymbolDeclaration?] the name of this function",
- argnames: "[AST_SymbolFunarg|AST_Destructuring|AST_Expansion|AST_DefaultAssign*] array of function arguments, destructurings, or expanding arguments",
- uses_arguments: "[boolean/S] tells whether this function accesses the arguments array",
- screwy_argnames_scope: "[boolean/S] argnames contain a reference to a name that's shadowed in the function",
- is_generator: "[boolean] is this a generator method",
- async: "[boolean] is this method async",
- },
- args_as_names: function () {
- // fast-path
- if (this.argnames.every(a => a instanceof AST_SymbolDeclaration)) {
- return this.argnames;
- }
- var out = [];
- for (var i = 0; i < this.argnames.length; i++) {
- if (this.argnames[i] instanceof AST_Destructuring) {
- out.push(...this.argnames[i].all_symbols());
- } else if (this.argnames[i] instanceof AST_Expansion) {
- out.push(...this.argnames[i].expression.all_symbols());
- } else if (this.argnames[i] instanceof AST_DefaultAssign) {
- out.push(...this.argnames[i].left.all_symbols());
- } else {
- out.push(this.argnames[i]);
- }
- }
- return out;
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- if (this.name) this.name._walk(visitor);
- var argnames = this.argnames;
- for (var i = 0, len = argnames.length; i < len; i++) {
- argnames[i]._walk(visitor);
- }
- walk_body(this, visitor);
- });
- },
- _children_backwards(push) {
- let i = this.body.length;
- while (i--) push(this.body[i]);
- i = this.argnames.length;
- while (i--) push(this.argnames[i]);
- if (this.name) push(this.name);
- },
- is_braceless() {
- return this.body[0] instanceof AST_Return && this.body[0].value;
- },
- // Default args and expansion don't count, so .argnames.length doesn't cut it
- length_property() {
- let length = 0;
- for (const arg of this.argnames) {
- if (arg instanceof AST_SymbolFunarg || arg instanceof AST_Destructuring) {
- length++;
- }
- }
- return length;
- }
- },
- AST_Scope
- );
- var AST_Accessor = DEFNODE("Accessor", null, function AST_Accessor(props) {
- if (props) {
- this.name = props.name;
- this.argnames = props.argnames;
- this.uses_arguments = props.uses_arguments;
- this.is_generator = props.is_generator;
- this.async = props.async;
- this.variables = props.variables;
- this.uses_with = props.uses_with;
- this.uses_eval = props.uses_eval;
- this.parent_scope = props.parent_scope;
- this.enclosed = props.enclosed;
- this.cname = props.cname;
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A setter/getter function. The `name` property is always null."
- }, AST_Lambda);
- var AST_Function = DEFNODE("Function", null, function AST_Function(props) {
- if (props) {
- this.name = props.name;
- this.argnames = props.argnames;
- this.uses_arguments = props.uses_arguments;
- this.is_generator = props.is_generator;
- this.async = props.async;
- this.variables = props.variables;
- this.uses_with = props.uses_with;
- this.uses_eval = props.uses_eval;
- this.parent_scope = props.parent_scope;
- this.enclosed = props.enclosed;
- this.cname = props.cname;
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A function expression"
- }, AST_Lambda);
- var AST_Arrow = DEFNODE("Arrow", null, function AST_Arrow(props) {
- if (props) {
- this.name = props.name;
- this.argnames = props.argnames;
- this.uses_arguments = props.uses_arguments;
- this.is_generator = props.is_generator;
- this.async = props.async;
- this.variables = props.variables;
- this.uses_with = props.uses_with;
- this.uses_eval = props.uses_eval;
- this.parent_scope = props.parent_scope;
- this.enclosed = props.enclosed;
- this.cname = props.cname;
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "An ES6 Arrow function ((a) => b)"
- }, AST_Lambda);
- var AST_Defun = DEFNODE("Defun", null, function AST_Defun(props) {
- if (props) {
- this.name = props.name;
- this.argnames = props.argnames;
- this.uses_arguments = props.uses_arguments;
- this.is_generator = props.is_generator;
- this.async = props.async;
- this.variables = props.variables;
- this.uses_with = props.uses_with;
- this.uses_eval = props.uses_eval;
- this.parent_scope = props.parent_scope;
- this.enclosed = props.enclosed;
- this.cname = props.cname;
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A function definition"
- }, AST_Lambda);
- /* -----[ DESTRUCTURING ]----- */
- var AST_Destructuring = DEFNODE("Destructuring", "names is_array", function AST_Destructuring(props) {
- if (props) {
- this.names = props.names;
- this.is_array = props.is_array;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A destructuring of several names. Used in destructuring assignment and with destructuring function argument names",
- $propdoc: {
- "names": "[AST_Node*] Array of properties or elements",
- "is_array": "[Boolean] Whether the destructuring represents an object or array"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.names.forEach(function(name) {
- name._walk(visitor);
- });
- });
- },
- _children_backwards(push) {
- let i = this.names.length;
- while (i--) push(this.names[i]);
- },
- all_symbols: function() {
- var out = [];
- walk(this, node => {
- if (node instanceof AST_SymbolDeclaration) {
- out.push(node);
- }
- if (node instanceof AST_Lambda) {
- return true;
- }
- });
- return out;
- }
- });
- var AST_PrefixedTemplateString = DEFNODE(
- "PrefixedTemplateString",
- "template_string prefix",
- function AST_PrefixedTemplateString(props) {
- if (props) {
- this.template_string = props.template_string;
- this.prefix = props.prefix;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- },
- {
- $documentation: "A templatestring with a prefix, such as String.raw`foobarbaz`",
- $propdoc: {
- template_string: "[AST_TemplateString] The template string",
- prefix: "[AST_Node] The prefix, which will get called."
- },
- _walk: function(visitor) {
- return visitor._visit(this, function () {
- this.prefix._walk(visitor);
- this.template_string._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.template_string);
- push(this.prefix);
- },
- }
- );
- var AST_TemplateString = DEFNODE("TemplateString", "segments", function AST_TemplateString(props) {
- if (props) {
- this.segments = props.segments;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A template string literal",
- $propdoc: {
- segments: "[AST_Node*] One or more segments, starting with AST_TemplateSegment. AST_Node may follow AST_TemplateSegment, but each AST_Node must be followed by AST_TemplateSegment."
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.segments.forEach(function(seg) {
- seg._walk(visitor);
- });
- });
- },
- _children_backwards(push) {
- let i = this.segments.length;
- while (i--) push(this.segments[i]);
- }
- });
- var AST_TemplateSegment = DEFNODE("TemplateSegment", "value raw", function AST_TemplateSegment(props) {
- if (props) {
- this.value = props.value;
- this.raw = props.raw;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A segment of a template string literal",
- $propdoc: {
- value: "Content of the segment",
- raw: "Raw source of the segment",
- }
- });
- /* -----[ JUMPS ]----- */
- var AST_Jump = DEFNODE("Jump", null, function AST_Jump(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)"
- }, AST_Statement);
- /** Base class for “exits” (`return` and `throw`) */
- var AST_Exit = DEFNODE("Exit", "value", function AST_Exit(props) {
- if (props) {
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Base class for “exits” (`return` and `throw`)",
- $propdoc: {
- value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
- },
- _walk: function(visitor) {
- return visitor._visit(this, this.value && function() {
- this.value._walk(visitor);
- });
- },
- _children_backwards(push) {
- if (this.value) push(this.value);
- },
- }, AST_Jump);
- var AST_Return = DEFNODE("Return", null, function AST_Return(props) {
- if (props) {
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `return` statement"
- }, AST_Exit);
- var AST_Throw = DEFNODE("Throw", null, function AST_Throw(props) {
- if (props) {
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `throw` statement"
- }, AST_Exit);
- var AST_LoopControl = DEFNODE("LoopControl", "label", function AST_LoopControl(props) {
- if (props) {
- this.label = props.label;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Base class for loop control statements (`break` and `continue`)",
- $propdoc: {
- label: "[AST_LabelRef?] the label, or null if none",
- },
- _walk: function(visitor) {
- return visitor._visit(this, this.label && function() {
- this.label._walk(visitor);
- });
- },
- _children_backwards(push) {
- if (this.label) push(this.label);
- },
- }, AST_Jump);
- var AST_Break = DEFNODE("Break", null, function AST_Break(props) {
- if (props) {
- this.label = props.label;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `break` statement"
- }, AST_LoopControl);
- var AST_Continue = DEFNODE("Continue", null, function AST_Continue(props) {
- if (props) {
- this.label = props.label;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `continue` statement"
- }, AST_LoopControl);
- var AST_Await = DEFNODE("Await", "expression", function AST_Await(props) {
- if (props) {
- this.expression = props.expression;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "An `await` statement",
- $propdoc: {
- expression: "[AST_Node] the mandatory expression being awaited",
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.expression);
- },
- });
- var AST_Yield = DEFNODE("Yield", "expression is_star", function AST_Yield(props) {
- if (props) {
- this.expression = props.expression;
- this.is_star = props.is_star;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `yield` statement",
- $propdoc: {
- expression: "[AST_Node?] the value returned or thrown by this statement; could be null (representing undefined) but only when is_star is set to false",
- is_star: "[Boolean] Whether this is a yield or yield* statement"
- },
- _walk: function(visitor) {
- return visitor._visit(this, this.expression && function() {
- this.expression._walk(visitor);
- });
- },
- _children_backwards(push) {
- if (this.expression) push(this.expression);
- }
- });
- /* -----[ IF ]----- */
- var AST_If = DEFNODE("If", "condition alternative", function AST_If(props) {
- if (props) {
- this.condition = props.condition;
- this.alternative = props.alternative;
- this.body = props.body;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `if` statement",
- $propdoc: {
- condition: "[AST_Node] the `if` condition",
- alternative: "[AST_Statement?] the `else` part, or null if not present"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.condition._walk(visitor);
- this.body._walk(visitor);
- if (this.alternative) this.alternative._walk(visitor);
- });
- },
- _children_backwards(push) {
- if (this.alternative) {
- push(this.alternative);
- }
- push(this.body);
- push(this.condition);
- }
- }, AST_StatementWithBody);
- /* -----[ SWITCH ]----- */
- var AST_Switch = DEFNODE("Switch", "expression", function AST_Switch(props) {
- if (props) {
- this.expression = props.expression;
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `switch` statement",
- $propdoc: {
- expression: "[AST_Node] the `switch` “discriminant”"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
- walk_body(this, visitor);
- });
- },
- _children_backwards(push) {
- let i = this.body.length;
- while (i--) push(this.body[i]);
- push(this.expression);
- }
- }, AST_Block);
- var AST_SwitchBranch = DEFNODE("SwitchBranch", null, function AST_SwitchBranch(props) {
- if (props) {
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Base class for `switch` branches",
- }, AST_Block);
- var AST_Default = DEFNODE("Default", null, function AST_Default(props) {
- if (props) {
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `default` switch branch",
- }, AST_SwitchBranch);
- var AST_Case = DEFNODE("Case", "expression", function AST_Case(props) {
- if (props) {
- this.expression = props.expression;
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `case` switch branch",
- $propdoc: {
- expression: "[AST_Node] the `case` expression"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
- walk_body(this, visitor);
- });
- },
- _children_backwards(push) {
- let i = this.body.length;
- while (i--) push(this.body[i]);
- push(this.expression);
- },
- }, AST_SwitchBranch);
- /* -----[ EXCEPTIONS ]----- */
- var AST_Try = DEFNODE("Try", "body bcatch bfinally", function AST_Try(props) {
- if (props) {
- this.body = props.body;
- this.bcatch = props.bcatch;
- this.bfinally = props.bfinally;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `try` statement",
- $propdoc: {
- body: "[AST_TryBlock] the try block",
- bcatch: "[AST_Catch?] the catch block, or null if not present",
- bfinally: "[AST_Finally?] the finally block, or null if not present"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.body._walk(visitor);
- if (this.bcatch) this.bcatch._walk(visitor);
- if (this.bfinally) this.bfinally._walk(visitor);
- });
- },
- _children_backwards(push) {
- if (this.bfinally) push(this.bfinally);
- if (this.bcatch) push(this.bcatch);
- push(this.body);
- },
- }, AST_Statement);
- var AST_TryBlock = DEFNODE("TryBlock", null, function AST_TryBlock(props) {
- if (props) {
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "The `try` block of a try statement"
- }, AST_Block);
- var AST_Catch = DEFNODE("Catch", "argname", function AST_Catch(props) {
- if (props) {
- this.argname = props.argname;
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `catch` node; only makes sense as part of a `try` statement",
- $propdoc: {
- argname: "[AST_SymbolCatch|AST_Destructuring|AST_Expansion|AST_DefaultAssign] symbol for the exception"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- if (this.argname) this.argname._walk(visitor);
- walk_body(this, visitor);
- });
- },
- _children_backwards(push) {
- let i = this.body.length;
- while (i--) push(this.body[i]);
- if (this.argname) push(this.argname);
- },
- }, AST_Block);
- var AST_Finally = DEFNODE("Finally", null, function AST_Finally(props) {
- if (props) {
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `finally` node; only makes sense as part of a `try` statement"
- }, AST_Block);
- /* -----[ VAR/CONST ]----- */
- var AST_DefinitionsLike = DEFNODE("DefinitionsLike", "definitions", function AST_DefinitionsLike(props) {
- if (props) {
- this.definitions = props.definitions;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Base class for variable definitions and `using`",
- $propdoc: {
- definitions: "[AST_VarDef*|AST_UsingDef*] array of variable definitions"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- var definitions = this.definitions;
- for (var i = 0, len = definitions.length; i < len; i++) {
- definitions[i]._walk(visitor);
- }
- });
- },
- _children_backwards(push) {
- let i = this.definitions.length;
- while (i--) push(this.definitions[i]);
- },
- }, AST_Statement);
- var AST_Definitions = DEFNODE("Definitions", null, function AST_Definitions(props) {
- if (props) {
- this.definitions = props.definitions;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)",
- }, AST_DefinitionsLike);
- var AST_Var = DEFNODE("Var", null, function AST_Var(props) {
- if (props) {
- this.definitions = props.definitions;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `var` statement"
- }, AST_Definitions);
- var AST_Let = DEFNODE("Let", null, function AST_Let(props) {
- if (props) {
- this.definitions = props.definitions;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `let` statement"
- }, AST_Definitions);
- var AST_Const = DEFNODE("Const", null, function AST_Const(props) {
- if (props) {
- this.definitions = props.definitions;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `const` statement"
- }, AST_Definitions);
- var AST_Using = DEFNODE("Using", "await", function AST_Using(props) {
- if (props) {
- this.await = props.await;
- this.definitions = props.definitions;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `using` statement",
- $propdoc: {
- await: "[boolean] Whether it's `await using`"
- },
- }, AST_DefinitionsLike);
- var AST_VarDefLike = DEFNODE("VarDefLike", "name value", function AST_VarDefLike(props) {
- if (props) {
- this.name = props.name;
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A name=value pair in a variable definition statement or `using`",
- $propdoc: {
- name: "[AST_Destructuring|AST_SymbolDeclaration] name of the variable",
- value: "[AST_Node?] initializer, or null of there's no initializer"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.name._walk(visitor);
- if (this.value) this.value._walk(visitor);
- });
- },
- _children_backwards(push) {
- if (this.value) push(this.value);
- push(this.name);
- },
- declarations_as_names() {
- if (this.name instanceof AST_SymbolDeclaration) {
- return [this.name];
- } else {
- return this.name.all_symbols();
- }
- }
- });
- var AST_VarDef = DEFNODE("VarDef", null, function AST_VarDef(props) {
- if (props) {
- this.name = props.name;
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A variable declaration; only appears in a AST_Definitions node",
- }, AST_VarDefLike);
- var AST_UsingDef = DEFNODE("UsingDef", null, function AST_UsingDef(props) {
- if (props) {
- this.name = props.name;
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Like VarDef but specific to AST_Using",
- }, AST_VarDefLike);
- var AST_NameMapping = DEFNODE("NameMapping", "foreign_name name", function AST_NameMapping(props) {
- if (props) {
- this.foreign_name = props.foreign_name;
- this.name = props.name;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "The part of the export/import statement that declare names from a module.",
- $propdoc: {
- foreign_name: "[AST_SymbolExportForeign|AST_SymbolImportForeign] The name being exported/imported (as specified in the module)",
- name: "[AST_SymbolExport|AST_SymbolImport] The name as it is visible to this module."
- },
- _walk: function (visitor) {
- return visitor._visit(this, function() {
- this.foreign_name._walk(visitor);
- this.name._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.name);
- push(this.foreign_name);
- },
- });
- var AST_Import = DEFNODE(
- "Import",
- "phase imported_name imported_names module_name attributes",
- function AST_Import(props) {
- if (props) {
- this.phase = props.phase;
- this.imported_name = props.imported_name;
- this.imported_names = props.imported_names;
- this.module_name = props.module_name;
- this.attributes = props.attributes;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- },
- {
- $documentation: "An `import` statement",
- $propdoc: {
- phase: "[string?] Phase keyword: 'source', 'defer', or null.",
- imported_name: "[AST_SymbolImport] The name of the variable holding the module's default export.",
- imported_names: "[AST_NameMapping*] The names of non-default imported variables",
- module_name: "[AST_String] String literal describing where this module came from",
- attributes: "[AST_Object?] The import attributes (with {...})"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- if (this.imported_name) {
- this.imported_name._walk(visitor);
- }
- if (this.imported_names) {
- this.imported_names.forEach(function(name_import) {
- name_import._walk(visitor);
- });
- }
- this.module_name._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.module_name);
- if (this.imported_names) {
- let i = this.imported_names.length;
- while (i--) push(this.imported_names[i]);
- }
- if (this.imported_name) push(this.imported_name);
- },
- }
- );
- var AST_ImportMeta = DEFNODE("ImportMeta", null, function AST_ImportMeta(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A reference to import.meta",
- });
- var AST_DynamicImport = DEFNODE(
- "DynamicImport",
- "phase args",
- function AST_DynamicImport(props) {
- if (props) {
- this.phase = props.phase;
- this.args = props.args;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- },
- {
- $documentation: "A dynamic import expression",
- $propdoc: {
- phase: "[string?] Phase keyword ('source' or 'defer') if present",
- args: "[AST_Node*] specifier followed by optional options argument"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- var args = this.args;
- for (var i = 0, len = args.length; i < len; i++) {
- args[i]._walk(visitor);
- }
- });
- },
- _children_backwards(push) {
- let i = this.args.length;
- while (i--) push(this.args[i]);
- },
- }
- );
- var AST_Export = DEFNODE(
- "Export",
- "exported_definition exported_value is_default exported_names module_name attributes",
- function AST_Export(props) {
- if (props) {
- this.exported_definition = props.exported_definition;
- this.exported_value = props.exported_value;
- this.is_default = props.is_default;
- this.exported_names = props.exported_names;
- this.module_name = props.module_name;
- this.attributes = props.attributes;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- },
- {
- $documentation: "An `export` statement",
- $propdoc: {
- exported_definition: "[AST_Defun|AST_Definitions|AST_DefClass?] An exported definition",
- exported_value: "[AST_Node?] An exported value",
- exported_names: "[AST_NameMapping*?] List of exported names",
- module_name: "[AST_String?] Name of the file to load exports from",
- is_default: "[Boolean] Whether this is the default exported value of this module",
- attributes: "[AST_Object?] The import attributes"
- },
- _walk: function (visitor) {
- return visitor._visit(this, function () {
- if (this.exported_definition) {
- this.exported_definition._walk(visitor);
- }
- if (this.exported_value) {
- this.exported_value._walk(visitor);
- }
- if (this.exported_names) {
- this.exported_names.forEach(function(name_export) {
- name_export._walk(visitor);
- });
- }
- if (this.module_name) {
- this.module_name._walk(visitor);
- }
- });
- },
- _children_backwards(push) {
- if (this.module_name) push(this.module_name);
- if (this.exported_names) {
- let i = this.exported_names.length;
- while (i--) push(this.exported_names[i]);
- }
- if (this.exported_value) push(this.exported_value);
- if (this.exported_definition) push(this.exported_definition);
- }
- },
- AST_Statement
- );
- /* -----[ OTHER ]----- */
- var AST_Call = DEFNODE(
- "Call",
- "expression args optional _annotations",
- function AST_Call(props) {
- if (props) {
- this.expression = props.expression;
- this.args = props.args;
- this.optional = props.optional;
- this._annotations = props._annotations;
- this.start = props.start;
- this.end = props.end;
- this.initialize();
- }
- this.flags = 0;
- },
- {
- $documentation: "A function call expression",
- $propdoc: {
- expression: "[AST_Node] expression to invoke as function",
- args: "[AST_Node*] array of arguments",
- optional: "[boolean] whether this is an optional call (IE ?.() )",
- _annotations: "[number] bitfield containing information about the call"
- },
- initialize() {
- if (this._annotations == null) this._annotations = 0;
- },
- _walk(visitor) {
- return visitor._visit(this, function() {
- var args = this.args;
- for (var i = 0, len = args.length; i < len; i++) {
- args[i]._walk(visitor);
- }
- this.expression._walk(visitor); // TODO why do we need to crawl this last?
- });
- },
- _children_backwards(push) {
- let i = this.args.length;
- while (i--) push(this.args[i]);
- push(this.expression);
- },
- }
- );
- var AST_New = DEFNODE("New", null, function AST_New(props) {
- if (props) {
- this.expression = props.expression;
- this.args = props.args;
- this.optional = props.optional;
- this._annotations = props._annotations;
- this.start = props.start;
- this.end = props.end;
- this.initialize();
- }
- this.flags = 0;
- }, {
- $documentation: "An object instantiation. Derives from a function call since it has exactly the same properties"
- }, AST_Call);
- var AST_Sequence = DEFNODE("Sequence", "expressions", function AST_Sequence(props) {
- if (props) {
- this.expressions = props.expressions;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A sequence expression (comma-separated expressions)",
- $propdoc: {
- expressions: "[AST_Node*] array of expressions (at least two)"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expressions.forEach(function(node) {
- node._walk(visitor);
- });
- });
- },
- _children_backwards(push) {
- let i = this.expressions.length;
- while (i--) push(this.expressions[i]);
- },
- });
- var AST_PropAccess = DEFNODE(
- "PropAccess",
- "expression property optional",
- function AST_PropAccess(props) {
- if (props) {
- this.expression = props.expression;
- this.property = props.property;
- this.optional = props.optional;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- },
- {
- $documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`",
- $propdoc: {
- expression: "[AST_Node] the “container” expression",
- property: "[AST_Node|string] the property to access. For AST_Dot & AST_DotHash this is always a plain string, while for AST_Sub it's an arbitrary AST_Node",
- optional: "[boolean] whether this is an optional property access (IE ?.)"
- }
- }
- );
- var AST_Dot = DEFNODE("Dot", "quote", function AST_Dot(props) {
- if (props) {
- this.quote = props.quote;
- this.expression = props.expression;
- this.property = props.property;
- this.optional = props.optional;
- this._annotations = props._annotations;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A dotted property access expression",
- $propdoc: {
- quote: "[string] the original quote character when transformed from AST_Sub",
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.expression);
- },
- }, AST_PropAccess);
- var AST_DotHash = DEFNODE("DotHash", "", function AST_DotHash(props) {
- if (props) {
- this.expression = props.expression;
- this.property = props.property;
- this.optional = props.optional;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A dotted property access to a private property",
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.expression);
- },
- }, AST_PropAccess);
- var AST_Sub = DEFNODE("Sub", null, function AST_Sub(props) {
- if (props) {
- this.expression = props.expression;
- this.property = props.property;
- this.optional = props.optional;
- this._annotations = props._annotations;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Index-style property access, i.e. `a[\"foo\"]`",
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
- this.property._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.property);
- push(this.expression);
- },
- }, AST_PropAccess);
- var AST_Chain = DEFNODE("Chain", "expression", function AST_Chain(props) {
- if (props) {
- this.expression = props.expression;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A chain expression like a?.b?.(c)?.[d]",
- $propdoc: {
- expression: "[AST_Call|AST_Dot|AST_DotHash|AST_Sub] chain element."
- },
- _walk: function (visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.expression);
- },
- });
- var AST_Unary = DEFNODE("Unary", "operator expression", function AST_Unary(props) {
- if (props) {
- this.operator = props.operator;
- this.expression = props.expression;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Base class for unary expressions",
- $propdoc: {
- operator: "[string] the operator",
- expression: "[AST_Node] expression that this unary operator applies to"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.expression);
- },
- });
- var AST_UnaryPrefix = DEFNODE("UnaryPrefix", null, function AST_UnaryPrefix(props) {
- if (props) {
- this.operator = props.operator;
- this.expression = props.expression;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Unary prefix expression, i.e. `typeof i` or `++i`"
- }, AST_Unary);
- var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, function AST_UnaryPostfix(props) {
- if (props) {
- this.operator = props.operator;
- this.expression = props.expression;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Unary postfix expression, i.e. `i++`"
- }, AST_Unary);
- var AST_Binary = DEFNODE("Binary", "operator left right", function AST_Binary(props) {
- if (props) {
- this.operator = props.operator;
- this.left = props.left;
- this.right = props.right;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Binary expression, i.e. `a + b`",
- $propdoc: {
- left: "[AST_Node] left-hand side expression",
- operator: "[string] the operator",
- right: "[AST_Node] right-hand side expression"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.left._walk(visitor);
- this.right._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.right);
- push(this.left);
- },
- });
- var AST_Conditional = DEFNODE(
- "Conditional",
- "condition consequent alternative",
- function AST_Conditional(props) {
- if (props) {
- this.condition = props.condition;
- this.consequent = props.consequent;
- this.alternative = props.alternative;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- },
- {
- $documentation: "Conditional expression using the ternary operator, i.e. `a ? b : c`",
- $propdoc: {
- condition: "[AST_Node]",
- consequent: "[AST_Node]",
- alternative: "[AST_Node]"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.condition._walk(visitor);
- this.consequent._walk(visitor);
- this.alternative._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.alternative);
- push(this.consequent);
- push(this.condition);
- },
- }
- );
- var AST_Assign = DEFNODE("Assign", "logical", function AST_Assign(props) {
- if (props) {
- this.logical = props.logical;
- this.operator = props.operator;
- this.left = props.left;
- this.right = props.right;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "An assignment expression — `a = b + 5`",
- $propdoc: {
- logical: "Whether it's a logical assignment"
- }
- }, AST_Binary);
- var AST_DefaultAssign = DEFNODE("DefaultAssign", null, function AST_DefaultAssign(props) {
- if (props) {
- this.operator = props.operator;
- this.left = props.left;
- this.right = props.right;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A default assignment expression like in `(a = 3) => a`",
- all_symbols() {
- return this.left.all_symbols();
- },
- }, AST_Binary);
- /* -----[ LITERALS ]----- */
- var AST_Array = DEFNODE("Array", "elements", function AST_Array(props) {
- if (props) {
- this.elements = props.elements;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "An array literal",
- $propdoc: {
- elements: "[AST_Node*] array of elements"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- var elements = this.elements;
- for (var i = 0, len = elements.length; i < len; i++) {
- elements[i]._walk(visitor);
- }
- });
- },
- _children_backwards(push) {
- let i = this.elements.length;
- while (i--) push(this.elements[i]);
- },
- });
- var AST_Object = DEFNODE("Object", "properties", function AST_Object(props) {
- if (props) {
- this.properties = props.properties;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "An object literal",
- $propdoc: {
- properties: "[AST_ObjectProperty*] array of properties"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- var properties = this.properties;
- for (var i = 0, len = properties.length; i < len; i++) {
- properties[i]._walk(visitor);
- }
- });
- },
- _children_backwards(push) {
- let i = this.properties.length;
- while (i--) push(this.properties[i]);
- },
- });
- /* -----[ OBJECT/CLASS PROPERTIES ]----- */
- /**
- * Everything inside the curly braces of an object/class is a subclass of AST_ObjectProperty, except for AST_ClassStaticBlock.
- **/
- var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", function AST_ObjectProperty(props) {
- if (props) {
- this.key = props.key;
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- this._annotations = props._annotations;
- }
- this.flags = 0;
- }, {
- $documentation: "Base class for literal object properties",
- $propdoc: {
- key: "[string|AST_Node] property name. For ObjectKeyVal this is a string. For getters, setters and computed property this is an AST_Node.",
- value: "[AST_Node] property value. For getters, setters and methods this is an AST_Accessor."
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- if (this.key instanceof AST_Node)
- this.key._walk(visitor);
- this.value._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.value);
- if (this.key instanceof AST_Node) push(this.key);
- },
- });
- var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", "quote", function AST_ObjectKeyVal(props) {
- if (props) {
- this.quote = props.quote;
- this.key = props.key;
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- this._annotations = props._annotations;
- }
- this.flags = 0;
- }, {
- $documentation: "A key: value object property",
- $propdoc: {
- quote: "[string] the original quote character"
- },
- computed_key() {
- return this.key instanceof AST_Node;
- }
- }, AST_ObjectProperty);
- var AST_PrivateSetter = DEFNODE("PrivateSetter", "static", function AST_PrivateSetter(props) {
- if (props) {
- this.static = props.static;
- this.key = props.key;
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $propdoc: {
- static: "[boolean] whether this is a static private setter"
- },
- $documentation: "A private setter property",
- computed_key() {
- return false;
- }
- }, AST_ObjectProperty);
- var AST_PrivateGetter = DEFNODE("PrivateGetter", "static", function AST_PrivateGetter(props) {
- if (props) {
- this.static = props.static;
- this.key = props.key;
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $propdoc: {
- static: "[boolean] whether this is a static private getter"
- },
- $documentation: "A private getter property",
- computed_key() {
- return false;
- }
- }, AST_ObjectProperty);
- var AST_ObjectSetter = DEFNODE("ObjectSetter", "quote static", function AST_ObjectSetter(props) {
- if (props) {
- this.quote = props.quote;
- this.static = props.static;
- this.key = props.key;
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- this._annotations = props._annotations;
- }
- this.flags = 0;
- }, {
- $propdoc: {
- quote: "[string|undefined] the original quote character, if any",
- static: "[boolean] whether this is a static setter (classes only)"
- },
- $documentation: "An object setter property",
- computed_key() {
- return !(this.key instanceof AST_SymbolMethod);
- }
- }, AST_ObjectProperty);
- var AST_ObjectGetter = DEFNODE("ObjectGetter", "quote static", function AST_ObjectGetter(props) {
- if (props) {
- this.quote = props.quote;
- this.static = props.static;
- this.key = props.key;
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- this._annotations = props._annotations;
- }
- this.flags = 0;
- }, {
- $propdoc: {
- quote: "[string|undefined] the original quote character, if any",
- static: "[boolean] whether this is a static getter (classes only)"
- },
- $documentation: "An object getter property",
- computed_key() {
- return !(this.key instanceof AST_SymbolMethod);
- }
- }, AST_ObjectProperty);
- var AST_ConciseMethod = DEFNODE("ConciseMethod", "quote static", function AST_ConciseMethod(props) {
- if (props) {
- this.quote = props.quote;
- this.static = props.static;
- this.key = props.key;
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- this._annotations = props._annotations;
- }
- this.flags = 0;
- }, {
- $propdoc: {
- quote: "[string|undefined] the original quote character, if any",
- static: "[boolean] is this method static (classes only)",
- },
- $documentation: "An ES6 concise method inside an object or class",
- computed_key() {
- return !(this.key instanceof AST_SymbolMethod);
- }
- }, AST_ObjectProperty);
- var AST_PrivateMethod = DEFNODE("PrivateMethod", "static", function AST_PrivateMethod(props) {
- if (props) {
- this.static = props.static;
- this.key = props.key;
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A private class method inside a class",
- $propdoc: {
- static: "[boolean] is this a static private method",
- },
- computed_key() {
- return false;
- },
- }, AST_ObjectProperty);
- var AST_Class = DEFNODE("Class", "name extends properties", function AST_Class(props) {
- if (props) {
- this.name = props.name;
- this.extends = props.extends;
- this.properties = props.properties;
- this.variables = props.variables;
- this.uses_with = props.uses_with;
- this.uses_eval = props.uses_eval;
- this.parent_scope = props.parent_scope;
- this.enclosed = props.enclosed;
- this.cname = props.cname;
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $propdoc: {
- name: "[AST_SymbolClass|AST_SymbolDefClass?] optional class name.",
- extends: "[AST_Node]? optional parent class",
- properties: "[AST_ObjectProperty|AST_ClassStaticBlock]* array of properties or static blocks"
- },
- $documentation: "An ES6 class",
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- if (this.name) {
- this.name._walk(visitor);
- }
- if (this.extends) {
- this.extends._walk(visitor);
- }
- this.properties.forEach((prop) => prop._walk(visitor));
- });
- },
- _children_backwards(push) {
- let i = this.properties.length;
- while (i--) push(this.properties[i]);
- if (this.extends) push(this.extends);
- if (this.name) push(this.name);
- },
- /** go through the bits that are executed instantly, not when the class is `new`'d. Doesn't walk the name. */
- visit_nondeferred_class_parts(visitor) {
- if (this.extends) {
- this.extends._walk(visitor);
- }
- this.properties.forEach((prop) => {
- if (prop instanceof AST_ClassStaticBlock) {
- prop._walk(visitor);
- return;
- }
- if (prop.computed_key()) {
- visitor.push(prop);
- prop.key._walk(visitor);
- visitor.pop();
- }
- if (
- prop instanceof AST_ClassPrivateProperty && prop.static && prop.value
- || prop instanceof AST_ClassProperty && prop.static && prop.value
- ) {
- visitor.push(prop);
- prop.value._walk(visitor);
- visitor.pop();
- }
- });
- },
- /** go through the bits that are executed later, when the class is `new`'d or a static method is called */
- visit_deferred_class_parts(visitor) {
- this.properties.forEach((prop) => {
- if (
- prop instanceof AST_ConciseMethod
- || prop instanceof AST_PrivateMethod
- ) {
- prop.walk(visitor);
- } else if (
- prop instanceof AST_ClassProperty && !prop.static && prop.value
- || prop instanceof AST_ClassPrivateProperty && !prop.static && prop.value
- ) {
- visitor.push(prop);
- prop.value._walk(visitor);
- visitor.pop();
- }
- });
- },
- is_self_referential: function() {
- const this_id = this.name && this.name.definition().id;
- let found = false;
- let class_this = true;
- this.visit_nondeferred_class_parts(new TreeWalker((node, descend) => {
- if (found) return true;
- if (node instanceof AST_This) return (found = class_this);
- if (node instanceof AST_SymbolRef) return (found = node.definition().id === this_id);
- if (node instanceof AST_Lambda && !(node instanceof AST_Arrow)) {
- const class_this_save = class_this;
- class_this = false;
- descend();
- class_this = class_this_save;
- return true;
- }
- }));
- return found;
- },
- }, AST_Scope /* TODO a class might have a scope but it's not a scope */);
- var AST_ClassProperty = DEFNODE("ClassProperty", "static quote", function AST_ClassProperty(props) {
- if (props) {
- this.static = props.static;
- this.quote = props.quote;
- this.key = props.key;
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- this._annotations = props._annotations;
- }
- this.flags = 0;
- }, {
- $documentation: "A class property",
- $propdoc: {
- static: "[boolean] whether this is a static key",
- quote: "[string] which quote is being used"
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- if (this.key instanceof AST_Node)
- this.key._walk(visitor);
- if (this.value instanceof AST_Node)
- this.value._walk(visitor);
- });
- },
- _children_backwards(push) {
- if (this.value instanceof AST_Node) push(this.value);
- if (this.key instanceof AST_Node) push(this.key);
- },
- computed_key() {
- return !(this.key instanceof AST_SymbolClassProperty);
- }
- }, AST_ObjectProperty);
- var AST_ClassPrivateProperty = DEFNODE("ClassPrivateProperty", "", function AST_ClassPrivateProperty(props) {
- if (props) {
- this.static = props.static;
- this.key = props.key;
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A class property for a private property",
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- if (this.value instanceof AST_Node)
- this.value._walk(visitor);
- });
- },
- _children_backwards(push) {
- if (this.value instanceof AST_Node) push(this.value);
- },
- computed_key() {
- return false;
- },
- }, AST_ObjectProperty);
- var AST_PrivateIn = DEFNODE("PrivateIn", "key value", function AST_PrivateIn(props) {
- if (props) {
- this.key = props.key;
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "An `in` binop when the key is private, eg #x in this",
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.key._walk(visitor);
- this.value._walk(visitor);
- });
- },
- _children_backwards(push) {
- push(this.value);
- push(this.key);
- },
- });
- var AST_DefClass = DEFNODE("DefClass", null, function AST_DefClass(props) {
- if (props) {
- this.name = props.name;
- this.extends = props.extends;
- this.properties = props.properties;
- this.variables = props.variables;
- this.uses_with = props.uses_with;
- this.uses_eval = props.uses_eval;
- this.parent_scope = props.parent_scope;
- this.enclosed = props.enclosed;
- this.cname = props.cname;
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A class definition",
- }, AST_Class);
- var AST_ClassStaticBlock = DEFNODE("ClassStaticBlock", "body block_scope", function AST_ClassStaticBlock (props) {
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }, {
- $documentation: "A block containing statements to be executed in the context of the class",
- $propdoc: {
- body: "[AST_Statement*] an array of statements",
- },
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- walk_body(this, visitor);
- });
- },
- _children_backwards(push) {
- let i = this.body.length;
- while (i--) push(this.body[i]);
- },
- clone: clone_block_scope,
- computed_key() {
- return false;
- },
- }, AST_Scope);
- var AST_ClassExpression = DEFNODE("ClassExpression", null, function AST_ClassExpression(props) {
- if (props) {
- this.name = props.name;
- this.extends = props.extends;
- this.properties = props.properties;
- this.variables = props.variables;
- this.uses_with = props.uses_with;
- this.uses_eval = props.uses_eval;
- this.parent_scope = props.parent_scope;
- this.enclosed = props.enclosed;
- this.cname = props.cname;
- this.body = props.body;
- this.block_scope = props.block_scope;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A class expression."
- }, AST_Class);
- var AST_Symbol = DEFNODE("Symbol", "scope name thedef", function AST_Symbol(props) {
- if (props) {
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $propdoc: {
- name: "[string] name of this symbol",
- scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
- thedef: "[SymbolDef/S] the definition of this symbol"
- },
- $documentation: "Base class for all symbols"
- });
- var AST_NewTarget = DEFNODE("NewTarget", null, function AST_NewTarget(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A reference to new.target"
- });
- var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", function AST_SymbolDeclaration(props) {
- if (props) {
- this.init = props.init;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",
- all_symbols() {
- return [this];
- },
- }, AST_Symbol);
- var AST_SymbolVar = DEFNODE("SymbolVar", null, function AST_SymbolVar(props) {
- if (props) {
- this.init = props.init;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Symbol defining a variable",
- }, AST_SymbolDeclaration);
- var AST_SymbolBlockDeclaration = DEFNODE(
- "SymbolBlockDeclaration",
- null,
- function AST_SymbolBlockDeclaration(props) {
- if (props) {
- this.init = props.init;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- },
- {
- $documentation: "Base class for block-scoped declaration symbols"
- },
- AST_SymbolDeclaration
- );
- var AST_SymbolConst = DEFNODE("SymbolConst", null, function AST_SymbolConst(props) {
- if (props) {
- this.init = props.init;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A constant declaration"
- }, AST_SymbolBlockDeclaration);
- var AST_SymbolUsing = DEFNODE("SymbolUsing", null, function AST_SymbolUsing(props) {
- if (props) {
- this.init = props.init;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A `using` declaration"
- }, AST_SymbolBlockDeclaration);
- var AST_SymbolLet = DEFNODE("SymbolLet", null, function AST_SymbolLet(props) {
- if (props) {
- this.init = props.init;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A block-scoped `let` declaration"
- }, AST_SymbolBlockDeclaration);
- var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, function AST_SymbolFunarg(props) {
- if (props) {
- this.init = props.init;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Symbol naming a function argument",
- }, AST_SymbolVar);
- var AST_SymbolDefun = DEFNODE("SymbolDefun", null, function AST_SymbolDefun(props) {
- if (props) {
- this.init = props.init;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Symbol defining a function",
- }, AST_SymbolDeclaration);
- var AST_SymbolMethod = DEFNODE("SymbolMethod", null, function AST_SymbolMethod(props) {
- if (props) {
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Symbol in an object defining a method",
- }, AST_Symbol);
- var AST_SymbolClassProperty = DEFNODE("SymbolClassProperty", null, function AST_SymbolClassProperty(props) {
- if (props) {
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Symbol for a class property",
- }, AST_Symbol);
- var AST_SymbolLambda = DEFNODE("SymbolLambda", null, function AST_SymbolLambda(props) {
- if (props) {
- this.init = props.init;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Symbol naming a function expression",
- }, AST_SymbolDeclaration);
- var AST_SymbolDefClass = DEFNODE("SymbolDefClass", null, function AST_SymbolDefClass(props) {
- if (props) {
- this.init = props.init;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Symbol naming a class's name in a class declaration. Lexically scoped to its containing scope, and accessible within the class."
- }, AST_SymbolBlockDeclaration);
- var AST_SymbolClass = DEFNODE("SymbolClass", null, function AST_SymbolClass(props) {
- if (props) {
- this.init = props.init;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Symbol naming a class's name. Lexically scoped to the class."
- }, AST_SymbolDeclaration);
- var AST_SymbolCatch = DEFNODE("SymbolCatch", null, function AST_SymbolCatch(props) {
- if (props) {
- this.init = props.init;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Symbol naming the exception in catch",
- }, AST_SymbolBlockDeclaration);
- var AST_SymbolImport = DEFNODE("SymbolImport", null, function AST_SymbolImport(props) {
- if (props) {
- this.init = props.init;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Symbol referring to an imported name",
- }, AST_SymbolBlockDeclaration);
- var AST_SymbolImportForeign = DEFNODE("SymbolImportForeign", "quote", function AST_SymbolImportForeign(props) {
- if (props) {
- this.quote = props.quote;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A symbol imported from a module, but it is defined in the other module, and its real name is irrelevant for this module's purposes",
- }, AST_Symbol);
- var AST_Label = DEFNODE("Label", "references", function AST_Label(props) {
- if (props) {
- this.references = props.references;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- this.initialize();
- }
- this.flags = 0;
- }, {
- $documentation: "Symbol naming a label (declaration)",
- $propdoc: {
- references: "[AST_LoopControl*] a list of nodes referring to this label"
- },
- initialize: function() {
- this.references = [];
- this.thedef = this;
- }
- }, AST_Symbol);
- var AST_SymbolRef = DEFNODE("SymbolRef", null, function AST_SymbolRef(props) {
- if (props) {
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Reference to some symbol (not definition/declaration)",
- }, AST_Symbol);
- var AST_SymbolExport = DEFNODE("SymbolExport", "quote", function AST_SymbolExport(props) {
- if (props) {
- this.quote = props.quote;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Symbol referring to a name to export",
- }, AST_SymbolRef);
- var AST_SymbolExportForeign = DEFNODE("SymbolExportForeign", "quote", function AST_SymbolExportForeign(props) {
- if (props) {
- this.quote = props.quote;
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A symbol exported from this module, but it is used in the other module, and its real name is irrelevant for this module's purposes",
- }, AST_Symbol);
- var AST_LabelRef = DEFNODE("LabelRef", null, function AST_LabelRef(props) {
- if (props) {
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Reference to a label symbol",
- }, AST_Symbol);
- var AST_SymbolPrivateProperty = DEFNODE("SymbolPrivateProperty", null, function AST_SymbolPrivateProperty(props) {
- if (props) {
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A symbol that refers to a private property",
- }, AST_Symbol);
- var AST_This = DEFNODE("This", null, function AST_This(props) {
- if (props) {
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "The `this` symbol",
- }, AST_Symbol);
- var AST_Super = DEFNODE("Super", null, function AST_Super(props) {
- if (props) {
- this.scope = props.scope;
- this.name = props.name;
- this.thedef = props.thedef;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "The `super` symbol",
- }, AST_This);
- var AST_Constant = DEFNODE("Constant", null, function AST_Constant(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Base class for all constants",
- getValue: function() {
- return this.value;
- }
- });
- var AST_String = DEFNODE("String", "value quote", function AST_String(props) {
- if (props) {
- this.value = props.value;
- this.quote = props.quote;
- this.start = props.start;
- this.end = props.end;
- this._annotations = props._annotations;
- }
- this.flags = 0;
- }, {
- $documentation: "A string literal",
- $propdoc: {
- value: "[string] the contents of this string",
- quote: "[string] the original quote character"
- }
- }, AST_Constant);
- var AST_Number = DEFNODE("Number", "value raw", function AST_Number(props) {
- if (props) {
- this.value = props.value;
- this.raw = props.raw;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A number literal",
- $propdoc: {
- value: "[number] the numeric value",
- raw: "[string] numeric value as string"
- }
- }, AST_Constant);
- var AST_BigInt = DEFNODE("BigInt", "value raw", function AST_BigInt(props) {
- if (props) {
- this.value = props.value;
- this.raw = props.raw;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A big int literal",
- $propdoc: {
- value: "[string] big int value, represented as a string",
- raw: "[string] the original format preserved"
- }
- }, AST_Constant);
- var AST_RegExp = DEFNODE("RegExp", "value", function AST_RegExp(props) {
- if (props) {
- this.value = props.value;
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A regexp literal",
- $propdoc: {
- value: "[RegExp] the actual regexp",
- }
- }, AST_Constant);
- var AST_Atom = DEFNODE("Atom", null, function AST_Atom(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Base class for atoms",
- }, AST_Constant);
- var AST_Null = DEFNODE("Null", null, function AST_Null(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "The `null` atom",
- value: null
- }, AST_Atom);
- var AST_NaN = DEFNODE("NaN", null, function AST_NaN(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "The impossible value",
- value: 0/0
- }, AST_Atom);
- var AST_Undefined = DEFNODE("Undefined", null, function AST_Undefined(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "The `undefined` value",
- value: (function() {}())
- }, AST_Atom);
- var AST_Hole = DEFNODE("Hole", null, function AST_Hole(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "A hole in an array",
- value: (function() {}())
- }, AST_Atom);
- var AST_Infinity = DEFNODE("Infinity", null, function AST_Infinity(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "The `Infinity` value",
- value: 1/0
- }, AST_Atom);
- var AST_Boolean = DEFNODE("Boolean", null, function AST_Boolean(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "Base class for booleans",
- }, AST_Atom);
- var AST_False = DEFNODE("False", null, function AST_False(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "The `false` atom",
- value: false
- }, AST_Boolean);
- var AST_True = DEFNODE("True", null, function AST_True(props) {
- if (props) {
- this.start = props.start;
- this.end = props.end;
- }
- this.flags = 0;
- }, {
- $documentation: "The `true` atom",
- value: true
- }, AST_Boolean);
- /* -----[ Walk function ]---- */
- /**
- * Walk nodes in depth-first search fashion.
- * Callback can return `walk_abort` symbol to stop iteration.
- * It can also return `true` to stop iteration just for child nodes.
- * Iteration can be stopped and continued by passing the `to_visit` argument,
- * which is given to the callback in the second argument.
- **/
- function walk(node, cb, to_visit = [node]) {
- const push = to_visit.push.bind(to_visit);
- while (to_visit.length) {
- const node = to_visit.pop();
- const ret = cb(node, to_visit);
- if (ret) {
- if (ret === walk_abort) return true;
- continue;
- }
- node._children_backwards(push);
- }
- return false;
- }
- /**
- * Walks an AST node and its children.
- *
- * {cb} can return `walk_abort` to interrupt the walk.
- *
- * @param node
- * @param cb {(node, info: { parent: (nth) => any }) => (boolean | undefined)}
- *
- * @returns {boolean} whether the walk was aborted
- *
- * @example
- * const found_some_cond = walk_parent(my_ast_node, (node, { parent }) => {
- * if (some_cond(node, parent())) return walk_abort
- * });
- */
- function walk_parent(node, cb, initial_stack) {
- const to_visit = [node];
- const push = to_visit.push.bind(to_visit);
- const stack = initial_stack ? initial_stack.slice() : [];
- const parent_pop_indices = [];
- let current;
- const info = {
- parent: (n = 0) => {
- if (n === -1) {
- return current;
- }
- // [ p1 p0 ] [ 1 0 ]
- if (initial_stack && n >= stack.length) {
- n -= stack.length;
- return initial_stack[
- initial_stack.length - (n + 1)
- ];
- }
- return stack[stack.length - (1 + n)];
- },
- };
- while (to_visit.length) {
- current = to_visit.pop();
- while (
- parent_pop_indices.length &&
- to_visit.length == parent_pop_indices[parent_pop_indices.length - 1]
- ) {
- stack.pop();
- parent_pop_indices.pop();
- }
- const ret = cb(current, info);
- if (ret) {
- if (ret === walk_abort) return true;
- continue;
- }
- const visit_length = to_visit.length;
- current._children_backwards(push);
- // Push only if we're going to traverse the children
- if (to_visit.length > visit_length) {
- stack.push(current);
- parent_pop_indices.push(visit_length - 1);
- }
- }
- return false;
- }
- const walk_abort = Symbol("abort walk");
- /* -----[ TreeWalker ]----- */
- class TreeWalker {
- constructor(callback) {
- this.visit = callback;
- this.stack = [];
- this.directives = Object.create(null);
- }
- _visit(node, descend) {
- this.push(node);
- var ret = this.visit(node, descend ? function() {
- descend.call(node);
- } : noop);
- if (!ret && descend) {
- descend.call(node);
- }
- this.pop();
- return ret;
- }
- parent(n) {
- return this.stack[this.stack.length - 2 - (n || 0)];
- }
- push(node) {
- if (node instanceof AST_Lambda) {
- this.directives = Object.create(this.directives);
- } else if (node instanceof AST_Directive && !this.directives[node.value]) {
- this.directives[node.value] = node;
- } else if (node instanceof AST_Class) {
- this.directives = Object.create(this.directives);
- if (!this.directives["use strict"]) {
- this.directives["use strict"] = node;
- }
- }
- this.stack.push(node);
- }
- pop() {
- var node = this.stack.pop();
- if (node instanceof AST_Lambda || node instanceof AST_Class) {
- this.directives = Object.getPrototypeOf(this.directives);
- }
- }
- self() {
- return this.stack[this.stack.length - 1];
- }
- find_parent(type) {
- var stack = this.stack;
- for (var i = stack.length; --i >= 0;) {
- var x = stack[i];
- if (x instanceof type) return x;
- }
- }
- is_within_loop() {
- let i = this.stack.length - 1;
- let child = this.stack[i];
- while (i--) {
- const node = this.stack[i];
- if (node instanceof AST_Lambda) return false;
- if (
- node instanceof AST_IterationStatement
- // exclude for-loop bits that only run once
- && !((node instanceof AST_For) && child === node.init)
- && !((node instanceof AST_ForIn || node instanceof AST_ForOf) && child === node.object)
- ) {
- return true;
- }
- child = node;
- }
- return false;
- }
- find_scope() {
- var stack = this.stack;
- for (var i = stack.length; --i >= 0;) {
- const p = stack[i];
- if (p instanceof AST_Toplevel) return p;
- if (p instanceof AST_Lambda) return p;
- if (p.block_scope) return p.block_scope;
- }
- }
- has_directive(type) {
- var dir = this.directives[type];
- if (dir) return dir;
- var node = this.stack[this.stack.length - 1];
- if (node instanceof AST_Scope && node.body) {
- for (var i = 0; i < node.body.length; ++i) {
- var st = node.body[i];
- if (!(st instanceof AST_Directive)) break;
- if (st.value == type) return st;
- }
- }
- }
- loopcontrol_target(node) {
- var stack = this.stack;
- if (node.label) for (var i = stack.length; --i >= 0;) {
- var x = stack[i];
- if (x instanceof AST_LabeledStatement && x.label.name == node.label.name)
- return x.body;
- } else for (var i = stack.length; --i >= 0;) {
- var x = stack[i];
- if (x instanceof AST_IterationStatement
- || node instanceof AST_Break && x instanceof AST_Switch)
- return x;
- }
- }
- }
- // Tree transformer helpers.
- class TreeTransformer extends TreeWalker {
- constructor(before, after) {
- super();
- this.before = before;
- this.after = after;
- }
- }
- const _PURE = 0b00000001;
- const _INLINE = 0b00000010;
- const _NOINLINE = 0b00000100;
- const _KEY = 0b00001000;
- const _MANGLEPROP = 0b00010000;
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- function def_transform(node, descend) {
- node.DEFMETHOD("transform", function(tw, in_list) {
- let transformed = undefined;
- tw.push(this);
- if (tw.before) transformed = tw.before(this, descend, in_list);
- if (transformed === undefined) {
- transformed = this;
- descend(transformed, tw);
- if (tw.after) {
- const after_ret = tw.after(transformed, in_list);
- if (after_ret !== undefined) transformed = after_ret;
- }
- }
- tw.pop();
- return transformed;
- });
- }
- def_transform(AST_Node, noop);
- def_transform(AST_LabeledStatement, function(self, tw) {
- self.label = self.label.transform(tw);
- self.body = self.body.transform(tw);
- });
- def_transform(AST_SimpleStatement, function(self, tw) {
- self.body = self.body.transform(tw);
- });
- def_transform(AST_Block, function(self, tw) {
- self.body = MAP(self.body, tw);
- });
- def_transform(AST_Do, function(self, tw) {
- self.body = self.body.transform(tw);
- self.condition = self.condition.transform(tw);
- });
- def_transform(AST_While, function(self, tw) {
- self.condition = self.condition.transform(tw);
- self.body = self.body.transform(tw);
- });
- def_transform(AST_For, function(self, tw) {
- if (self.init) self.init = self.init.transform(tw);
- if (self.condition) self.condition = self.condition.transform(tw);
- if (self.step) self.step = self.step.transform(tw);
- self.body = self.body.transform(tw);
- });
- def_transform(AST_ForIn, function(self, tw) {
- self.init = self.init.transform(tw);
- self.object = self.object.transform(tw);
- self.body = self.body.transform(tw);
- });
- def_transform(AST_With, function(self, tw) {
- self.expression = self.expression.transform(tw);
- self.body = self.body.transform(tw);
- });
- def_transform(AST_Exit, function(self, tw) {
- if (self.value) self.value = self.value.transform(tw);
- });
- def_transform(AST_LoopControl, function(self, tw) {
- if (self.label) self.label = self.label.transform(tw);
- });
- def_transform(AST_If, function(self, tw) {
- self.condition = self.condition.transform(tw);
- self.body = self.body.transform(tw);
- if (self.alternative) self.alternative = self.alternative.transform(tw);
- });
- def_transform(AST_Switch, function(self, tw) {
- self.expression = self.expression.transform(tw);
- self.body = MAP(self.body, tw);
- });
- def_transform(AST_Case, function(self, tw) {
- self.expression = self.expression.transform(tw);
- self.body = MAP(self.body, tw);
- });
- def_transform(AST_Try, function(self, tw) {
- self.body = self.body.transform(tw);
- if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
- if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
- });
- def_transform(AST_Catch, function(self, tw) {
- if (self.argname) self.argname = self.argname.transform(tw);
- self.body = MAP(self.body, tw);
- });
- def_transform(AST_DefinitionsLike, function(self, tw) {
- self.definitions = MAP(self.definitions, tw);
- });
- def_transform(AST_VarDefLike, function(self, tw) {
- self.name = self.name.transform(tw);
- if (self.value) self.value = self.value.transform(tw);
- });
- def_transform(AST_Destructuring, function(self, tw) {
- self.names = MAP(self.names, tw);
- });
- def_transform(AST_Lambda, function(self, tw) {
- if (self.name) self.name = self.name.transform(tw);
- self.argnames = MAP(self.argnames, tw, /* allow_splicing */ false);
- if (self.body instanceof AST_Node) {
- self.body = self.body.transform(tw);
- } else {
- self.body = MAP(self.body, tw);
- }
- });
- def_transform(AST_Call, function(self, tw) {
- self.expression = self.expression.transform(tw);
- self.args = MAP(self.args, tw, /* allow_splicing */ false);
- });
- def_transform(AST_Sequence, function(self, tw) {
- const result = MAP(self.expressions, tw);
- self.expressions = result.length
- ? result
- : [new AST_Number({ value: 0 })];
- });
- def_transform(AST_PropAccess, function(self, tw) {
- self.expression = self.expression.transform(tw);
- });
- def_transform(AST_Sub, function(self, tw) {
- self.expression = self.expression.transform(tw);
- self.property = self.property.transform(tw);
- });
- def_transform(AST_Chain, function(self, tw) {
- self.expression = self.expression.transform(tw);
- });
- def_transform(AST_Yield, function(self, tw) {
- if (self.expression) self.expression = self.expression.transform(tw);
- });
- def_transform(AST_Await, function(self, tw) {
- self.expression = self.expression.transform(tw);
- });
- def_transform(AST_Unary, function(self, tw) {
- self.expression = self.expression.transform(tw);
- });
- def_transform(AST_Binary, function(self, tw) {
- self.left = self.left.transform(tw);
- self.right = self.right.transform(tw);
- });
- def_transform(AST_PrivateIn, function(self, tw) {
- self.key = self.key.transform(tw);
- self.value = self.value.transform(tw);
- });
- def_transform(AST_Conditional, function(self, tw) {
- self.condition = self.condition.transform(tw);
- self.consequent = self.consequent.transform(tw);
- self.alternative = self.alternative.transform(tw);
- });
- def_transform(AST_Array, function(self, tw) {
- self.elements = MAP(self.elements, tw);
- });
- def_transform(AST_Object, function(self, tw) {
- self.properties = MAP(self.properties, tw);
- });
- def_transform(AST_ObjectProperty, function(self, tw) {
- if (self.key instanceof AST_Node) {
- self.key = self.key.transform(tw);
- }
- if (self.value) self.value = self.value.transform(tw);
- });
- def_transform(AST_Class, function(self, tw) {
- if (self.name) self.name = self.name.transform(tw);
- if (self.extends) self.extends = self.extends.transform(tw);
- self.properties = MAP(self.properties, tw);
- });
- def_transform(AST_ClassStaticBlock, function(self, tw) {
- self.body = MAP(self.body, tw);
- });
- def_transform(AST_Expansion, function(self, tw) {
- self.expression = self.expression.transform(tw);
- });
- def_transform(AST_NameMapping, function(self, tw) {
- self.foreign_name = self.foreign_name.transform(tw);
- self.name = self.name.transform(tw);
- });
- def_transform(AST_Import, function(self, tw) {
- if (self.imported_name) self.imported_name = self.imported_name.transform(tw);
- if (self.imported_names) MAP(self.imported_names, tw);
- self.module_name = self.module_name.transform(tw);
- });
- def_transform(AST_DynamicImport, function(self, tw) {
- self.args = MAP(self.args, tw);
- });
- def_transform(AST_Export, function(self, tw) {
- if (self.exported_definition) self.exported_definition = self.exported_definition.transform(tw);
- if (self.exported_value) self.exported_value = self.exported_value.transform(tw);
- if (self.exported_names) MAP(self.exported_names, tw);
- if (self.module_name) self.module_name = self.module_name.transform(tw);
- });
- def_transform(AST_TemplateString, function(self, tw) {
- self.segments = MAP(self.segments, tw);
- });
- def_transform(AST_PrefixedTemplateString, function(self, tw) {
- self.prefix = self.prefix.transform(tw);
- self.template_string = self.template_string.transform(tw);
- });
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- (function() {
- var normalize_directives = function(body) {
- for (var i = 0; i < body.length; i++) {
- if (body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
- body[i] = new AST_Directive({
- start: body[i].start,
- end: body[i].end,
- quote: '"',
- value: body[i].body.value
- });
- } else {
- return body;
- }
- }
- return body;
- };
- function import_attributes_from_moz(attributes) {
- if (attributes && attributes.length > 0) {
- return new AST_Object({
- start: my_start_token(attributes),
- end: my_end_token(attributes),
- properties: attributes.map((attr) =>
- new AST_ObjectKeyVal({
- start: my_start_token(attr),
- end: my_end_token(attr),
- key: attr.key.name || attr.key.value,
- value: from_moz(attr.value)
- })
- )
- });
- }
- return null;
- }
- var MOZ_TO_ME = {
- Program: function(M) {
- return new AST_Toplevel({
- start: my_start_token(M),
- end: my_end_token(M),
- body: normalize_directives(M.body.map(from_moz))
- });
- },
- ArrayPattern: function(M) {
- return new AST_Destructuring({
- start: my_start_token(M),
- end: my_end_token(M),
- names: M.elements.map(function(elm) {
- if (elm === null) {
- return new AST_Hole();
- }
- return from_moz(elm);
- }),
- is_array: true
- });
- },
- ObjectPattern: function(M) {
- return new AST_Destructuring({
- start: my_start_token(M),
- end: my_end_token(M),
- names: M.properties.map(from_moz),
- is_array: false
- });
- },
- AssignmentPattern: function(M) {
- return new AST_DefaultAssign({
- start: my_start_token(M),
- end: my_end_token(M),
- left: from_moz(M.left),
- operator: "=",
- right: from_moz(M.right)
- });
- },
- SpreadElement: function(M) {
- return new AST_Expansion({
- start: my_start_token(M),
- end: my_end_token(M),
- expression: from_moz(M.argument)
- });
- },
- RestElement: function(M) {
- return new AST_Expansion({
- start: my_start_token(M),
- end: my_end_token(M),
- expression: from_moz(M.argument)
- });
- },
- TemplateElement: function(M) {
- return new AST_TemplateSegment({
- start: my_start_token(M),
- end: my_end_token(M),
- value: M.value.cooked,
- raw: M.value.raw
- });
- },
- TemplateLiteral: function(M) {
- var segments = [];
- for (var i = 0; i < M.quasis.length; i++) {
- segments.push(from_moz(M.quasis[i]));
- if (M.expressions[i]) {
- segments.push(from_moz(M.expressions[i]));
- }
- }
- return new AST_TemplateString({
- start: my_start_token(M),
- end: my_end_token(M),
- segments: segments
- });
- },
- TaggedTemplateExpression: function(M) {
- return new AST_PrefixedTemplateString({
- start: my_start_token(M),
- end: my_end_token(M),
- template_string: from_moz(M.quasi),
- prefix: from_moz(M.tag)
- });
- },
- FunctionDeclaration: function(M) {
- return new AST_Defun({
- start: my_start_token(M),
- end: my_end_token(M),
- name: M.id && from_moz_symbol(AST_SymbolDefun, M.id),
- argnames: M.params.map(M => from_moz_pattern(M, AST_SymbolFunarg)),
- is_generator: M.generator,
- async: M.async,
- body: normalize_directives(from_moz(M.body).body)
- });
- },
- FunctionExpression: function(M) {
- return from_moz_lambda(M, /*is_method=*/false);
- },
- ArrowFunctionExpression: function(M) {
- const body = M.body.type === "BlockStatement"
- ? from_moz(M.body).body
- : [make_node(AST_Return, {}, { value: from_moz(M.body) })];
- return new AST_Arrow({
- start: my_start_token(M),
- end: my_end_token(M),
- argnames: M.params.map(p => from_moz_pattern(p, AST_SymbolFunarg)),
- body,
- async: M.async,
- });
- },
- ExpressionStatement: function(M) {
- return new AST_SimpleStatement({
- start: my_start_token(M),
- end: my_end_token(M),
- body: from_moz(M.expression)
- });
- },
- TryStatement: function(M) {
- var handlers = M.handlers || [M.handler];
- if (handlers.length > 1 || M.guardedHandlers && M.guardedHandlers.length) {
- throw new Error("Multiple catch clauses are not supported.");
- }
- return new AST_Try({
- start : my_start_token(M),
- end : my_end_token(M),
- body : new AST_TryBlock(from_moz(M.block)),
- bcatch : from_moz(handlers[0]),
- bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null
- });
- },
- Property: function(M) {
- if (M.kind == "init" && !M.method) {
- var args = {
- start : my_start_token(M.key || M.value),
- end : my_end_token(M.value),
- key : M.computed
- ? from_moz(M.key)
- : M.key.name || String(M.key.value),
- quote : from_moz_quote(M.key, M.computed),
- static : false, // always an object
- value : from_moz(M.value)
- };
- return new AST_ObjectKeyVal(args);
- } else {
- var value = from_moz_lambda(M.value, /*is_method=*/true);
- var args = {
- start : my_start_token(M.key || M.value),
- end : my_end_token(M.value),
- key : M.computed
- ? from_moz(M.key)
- : from_moz_symbol(AST_SymbolMethod, M.key),
- quote : from_moz_quote(M.key, M.computed),
- static : false, // always an object
- value,
- };
- if (M.kind == "get") return new AST_ObjectGetter(args);
- if (M.kind == "set") return new AST_ObjectSetter(args);
- if (M.method) return new AST_ConciseMethod(args);
- }
- },
- MethodDefinition: function(M) {
- const is_private = M.key.type === "PrivateIdentifier";
- const key = M.computed ? from_moz(M.key) : new AST_SymbolMethod({ name: M.key.name || String(M.key.value) });
- var args = {
- start : my_start_token(M),
- end : my_end_token(M),
- key,
- quote : from_moz_quote(M.key, M.computed),
- value : from_moz_lambda(M.value, /*is_method=*/true),
- static : M.static,
- };
- if (M.kind == "get") {
- return new (is_private ? AST_PrivateGetter : AST_ObjectGetter)(args);
- }
- if (M.kind == "set") {
- return new (is_private ? AST_PrivateSetter : AST_ObjectSetter)(args);
- }
- return new (is_private ? AST_PrivateMethod : AST_ConciseMethod)(args);
- },
- FieldDefinition: function(M) {
- let key;
- if (M.computed) {
- key = from_moz(M.key);
- } else {
- if (M.key.type !== "Identifier") throw new Error("Non-Identifier key in FieldDefinition");
- key = from_moz(M.key);
- }
- return new AST_ClassProperty({
- start : my_start_token(M),
- end : my_end_token(M),
- quote : from_moz_quote(M.key, M.computed),
- key,
- value : from_moz(M.value),
- static : M.static,
- });
- },
- PropertyDefinition: function(M) {
- let key;
- if (M.computed) {
- key = from_moz(M.key);
- } else if (M.key.type === "PrivateIdentifier") {
- return new AST_ClassPrivateProperty({
- start : my_start_token(M),
- end : my_end_token(M),
- key : from_moz(M.key),
- value : from_moz(M.value),
- static : M.static,
- });
- } else {
- key = from_moz_symbol(AST_SymbolClassProperty, M.key);
- }
- return new AST_ClassProperty({
- start : my_start_token(M),
- end : my_end_token(M),
- quote : from_moz_quote(M.key, M.computed),
- key,
- value : from_moz(M.value),
- static : M.static,
- });
- },
- PrivateIdentifier: function (M) {
- return new AST_SymbolPrivateProperty({
- start: my_start_token(M),
- end: my_end_token(M),
- name: M.name
- });
- },
- StaticBlock: function(M) {
- return new AST_ClassStaticBlock({
- start : my_start_token(M),
- end : my_end_token(M),
- body : M.body.map(from_moz),
- });
- },
- ArrayExpression: function(M) {
- return new AST_Array({
- start : my_start_token(M),
- end : my_end_token(M),
- elements : M.elements.map(function(elem) {
- return elem === null ? new AST_Hole() : from_moz(elem);
- })
- });
- },
- ObjectExpression: function(M) {
- return new AST_Object({
- start : my_start_token(M),
- end : my_end_token(M),
- properties : M.properties.map(function(prop) {
- if (prop.type === "SpreadElement") {
- return from_moz(prop);
- }
- prop.type = "Property";
- return from_moz(prop);
- })
- });
- },
- SequenceExpression: function(M) {
- return new AST_Sequence({
- start : my_start_token(M),
- end : my_end_token(M),
- expressions: M.expressions.map(from_moz)
- });
- },
- MemberExpression: function(M) {
- if (M.property.type === "PrivateIdentifier") {
- return new AST_DotHash({
- start : my_start_token(M),
- end : my_end_token(M),
- property : M.property.name,
- expression : from_moz(M.object),
- optional : M.optional || false
- });
- }
- return new (M.computed ? AST_Sub : AST_Dot)({
- start : my_start_token(M),
- end : my_end_token(M),
- property : M.computed ? from_moz(M.property) : M.property.name,
- expression : from_moz(M.object),
- optional : M.optional || false
- });
- },
- ChainExpression: function(M) {
- return new AST_Chain({
- start : my_start_token(M),
- end : my_end_token(M),
- expression : from_moz(M.expression)
- });
- },
- SwitchCase: function(M) {
- return new (M.test ? AST_Case : AST_Default)({
- start : my_start_token(M),
- end : my_end_token(M),
- expression : from_moz(M.test),
- body : M.consequent.map(from_moz)
- });
- },
- VariableDeclaration: function(M) {
- let decl_type;
- let defs_type = AST_VarDef;
- let sym_type;
- let await_using = false;
- if (M.kind === "const") {
- decl_type = AST_Const;
- sym_type = AST_SymbolConst;
- } else if (M.kind === "let") {
- decl_type = AST_Let;
- sym_type = AST_SymbolLet;
- } else if (M.kind === "using") {
- decl_type = AST_Using;
- defs_type = AST_UsingDef;
- sym_type = AST_SymbolUsing;
- } else if (M.kind === "await using") {
- decl_type = AST_Using;
- defs_type = AST_UsingDef;
- sym_type = AST_SymbolUsing;
- await_using = true;
- } else {
- decl_type = AST_Var;
- sym_type = AST_SymbolVar;
- }
- const definitions = M.declarations.map(M => {
- return new defs_type({
- start: my_start_token(M),
- end: my_end_token(M),
- name: from_moz_pattern(M.id, sym_type),
- value: from_moz(M.init),
- });
- });
- return new decl_type({
- start : my_start_token(M),
- end : my_end_token(M),
- definitions : definitions,
- await : await_using,
- });
- },
- ImportDeclaration: function(M) {
- var imported_name = null;
- var imported_names = null;
- M.specifiers.forEach(function (specifier) {
- if (specifier.type === "ImportSpecifier" || specifier.type === "ImportNamespaceSpecifier") {
- if (!imported_names) { imported_names = []; }
- imported_names.push(from_moz(specifier));
- } else if (specifier.type === "ImportDefaultSpecifier") {
- imported_name = from_moz(specifier);
- }
- });
- return new AST_Import({
- start : my_start_token(M),
- end : my_end_token(M),
- imported_name: imported_name,
- imported_names : imported_names,
- module_name : from_moz(M.source),
- attributes: import_attributes_from_moz(M.attributes || M.assertions),
- phase: M.phase || null
- });
- },
- ImportSpecifier: function(M) {
- return new AST_NameMapping({
- start: my_start_token(M),
- end: my_end_token(M),
- foreign_name: from_moz_symbol(AST_SymbolImportForeign, M.imported, M.imported.type === "Literal"),
- name: from_moz_symbol(AST_SymbolImport, M.local)
- });
- },
- ImportDefaultSpecifier: function(M) {
- return from_moz_symbol(AST_SymbolImport, M.local);
- },
- ImportNamespaceSpecifier: function(M) {
- return new AST_NameMapping({
- start: my_start_token(M),
- end: my_end_token(M),
- foreign_name: new AST_SymbolImportForeign({ name: "*" }),
- name: from_moz_symbol(AST_SymbolImport, M.local)
- });
- },
- ImportExpression: function(M) {
- const args = [from_moz(M.source)];
- if (M.options) {
- args.push(from_moz(M.options));
- }
- return new AST_DynamicImport({
- start: my_start_token(M),
- end: my_end_token(M),
- phase: M.phase,
- args: args,
- });
- },
- ExportAllDeclaration: function(M) {
- var foreign_name = M.exported == null ?
- new AST_SymbolExportForeign({ name: "*" }) :
- from_moz_symbol(AST_SymbolExportForeign, M.exported, M.exported.type === "Literal");
- return new AST_Export({
- start: my_start_token(M),
- end: my_end_token(M),
- exported_names: [
- new AST_NameMapping({
- start: my_start_token(M),
- end: my_end_token(M),
- name: new AST_SymbolExport({ name: "*" }),
- foreign_name: foreign_name
- })
- ],
- module_name: from_moz(M.source),
- attributes: import_attributes_from_moz(M.attributes || M.assertions)
- });
- },
- ExportNamedDeclaration: function(M) {
- if (M.declaration) {
- // export const, export function, ...
- return new AST_Export({
- start: my_start_token(M),
- end: my_end_token(M),
- exported_definition: from_moz(M.declaration),
- exported_names: null,
- module_name: null,
- attributes: null,
- });
- } else {
- return new AST_Export({
- start: my_start_token(M),
- end: my_end_token(M),
- exported_definition: null,
- exported_names: M.specifiers && M.specifiers.length ? M.specifiers.map(from_moz) : [],
- module_name: from_moz(M.source),
- attributes: import_attributes_from_moz(M.attributes || M.assertions),
- });
- }
- },
- ExportDefaultDeclaration: function(M) {
- return new AST_Export({
- start: my_start_token(M),
- end: my_end_token(M),
- exported_value: from_moz(M.declaration),
- is_default: true
- });
- },
- ExportSpecifier: function(M) {
- return new AST_NameMapping({
- start: my_start_token(M),
- end: my_end_token(M),
- foreign_name: from_moz_symbol(AST_SymbolExportForeign, M.exported, M.exported.type === "Literal"),
- name: from_moz_symbol(AST_SymbolExport, M.local, M.local.type === "Literal"),
- });
- },
- Literal: function(M) {
- var val = M.value, args = {
- start : my_start_token(M),
- end : my_end_token(M)
- };
- var rx = M.regex;
- if (rx && rx.pattern) {
- // RegExpLiteral as per ESTree AST spec
- args.value = {
- source: rx.pattern,
- flags: rx.flags
- };
- return new AST_RegExp(args);
- } else if (rx) {
- // support legacy RegExp
- const rx_source = M.raw || val;
- const match = rx_source.match(/^\/(.*)\/(\w*)$/);
- if (!match) throw new Error("Invalid regex source " + rx_source);
- const [_, source, flags] = match;
- args.value = { source, flags };
- return new AST_RegExp(args);
- }
- const bi = typeof M.value === "bigint" ? M.value.toString() : M.bigint;
- if (typeof bi === "string") {
- args.value = bi;
- args.raw = M.raw;
- return new AST_BigInt(args);
- }
- if (val === null) return new AST_Null(args);
- switch (typeof val) {
- case "string":
- args.quote = "\"";
- args.value = val;
- return new AST_String(args);
- case "number":
- args.value = val;
- args.raw = M.raw || val.toString();
- return new AST_Number(args);
- case "boolean":
- return new (val ? AST_True : AST_False)(args);
- }
- },
- MetaProperty: function(M) {
- if (M.meta.name === "new" && M.property.name === "target") {
- return new AST_NewTarget({
- start: my_start_token(M),
- end: my_end_token(M)
- });
- } else if (M.meta.name === "import" && M.property.name === "meta") {
- return new AST_ImportMeta({
- start: my_start_token(M),
- end: my_end_token(M)
- });
- }
- },
- Identifier: function(M) {
- return new AST_SymbolRef({
- start : my_start_token(M),
- end : my_end_token(M),
- name : M.name
- });
- },
- EmptyStatement: function(M) {
- return new AST_EmptyStatement({
- start: my_start_token(M),
- end: my_end_token(M)
- });
- },
- BlockStatement: function(M) {
- return new AST_BlockStatement({
- start: my_start_token(M),
- end: my_end_token(M),
- body: M.body.map(from_moz)
- });
- },
- IfStatement: function(M) {
- return new AST_If({
- start: my_start_token(M),
- end: my_end_token(M),
- condition: from_moz(M.test),
- body: from_moz(M.consequent),
- alternative: from_moz(M.alternate)
- });
- },
- LabeledStatement: function(M) {
- try {
- const label = from_moz_symbol(AST_Label, M.label);
- FROM_MOZ_LABELS.push(label);
- const stat = new AST_LabeledStatement({
- start: my_start_token(M),
- end: my_end_token(M),
- label,
- body: from_moz(M.body)
- });
- return stat;
- } finally {
- FROM_MOZ_LABELS.pop();
- }
- },
- BreakStatement: function(M) {
- return new AST_Break({
- start: my_start_token(M),
- end: my_end_token(M),
- label: from_moz_label_ref(M.label),
- });
- },
- ContinueStatement: function(M) {
- return new AST_Continue({
- start: my_start_token(M),
- end: my_end_token(M),
- label: from_moz_label_ref(M.label),
- });
- },
- WithStatement: function(M) {
- return new AST_With({
- start: my_start_token(M),
- end: my_end_token(M),
- expression: from_moz(M.object),
- body: from_moz(M.body)
- });
- },
- SwitchStatement: function(M) {
- return new AST_Switch({
- start: my_start_token(M),
- end: my_end_token(M),
- expression: from_moz(M.discriminant),
- body: M.cases.map(from_moz)
- });
- },
- ReturnStatement: function(M) {
- return new AST_Return({
- start: my_start_token(M),
- end: my_end_token(M),
- value: from_moz(M.argument)
- });
- },
- ThrowStatement: function(M) {
- return new AST_Throw({
- start: my_start_token(M),
- end: my_end_token(M),
- value: from_moz(M.argument)
- });
- },
- WhileStatement: function(M) {
- return new AST_While({
- start: my_start_token(M),
- end: my_end_token(M),
- condition: from_moz(M.test),
- body: from_moz(M.body)
- });
- },
- DoWhileStatement: function(M) {
- return new AST_Do({
- start: my_start_token(M),
- end: my_end_token(M),
- condition: from_moz(M.test),
- body: from_moz(M.body)
- });
- },
- ForStatement: function(M) {
- return new AST_For({
- start: my_start_token(M),
- end: my_end_token(M),
- init: from_moz(M.init),
- condition: from_moz(M.test),
- step: from_moz(M.update),
- body: from_moz(M.body)
- });
- },
- ForInStatement: function(M) {
- return new AST_ForIn({
- start: my_start_token(M),
- end: my_end_token(M),
- init: from_moz(M.left),
- object: from_moz(M.right),
- body: from_moz(M.body)
- });
- },
- ForOfStatement: function(M) {
- return new AST_ForOf({
- start: my_start_token(M),
- end: my_end_token(M),
- init: from_moz(M.left),
- object: from_moz(M.right),
- body: from_moz(M.body),
- await: M.await
- });
- },
- AwaitExpression: function(M) {
- return new AST_Await({
- start: my_start_token(M),
- end: my_end_token(M),
- expression: from_moz(M.argument)
- });
- },
- YieldExpression: function(M) {
- return new AST_Yield({
- start: my_start_token(M),
- end: my_end_token(M),
- expression: from_moz(M.argument),
- is_star: M.delegate
- });
- },
- DebuggerStatement: function(M) {
- return new AST_Debugger({
- start: my_start_token(M),
- end: my_end_token(M)
- });
- },
- CatchClause: function(M) {
- return new AST_Catch({
- start: my_start_token(M),
- end: my_end_token(M),
- argname: M.param ? from_moz_pattern(M.param, AST_SymbolCatch) : null,
- body: from_moz(M.body).body
- });
- },
- ThisExpression: function(M) {
- return new AST_This({
- start: my_start_token(M),
- name: "this",
- end: my_end_token(M)
- });
- },
- Super: function(M) {
- return new AST_Super({
- start: my_start_token(M),
- end: my_end_token(M),
- name: "super",
- });
- },
- BinaryExpression: function(M) {
- if (M.left.type === "PrivateIdentifier") {
- return new AST_PrivateIn({
- start: my_start_token(M),
- end: my_end_token(M),
- key: new AST_SymbolPrivateProperty({
- start: my_start_token(M.left),
- end: my_end_token(M.left),
- name: M.left.name
- }),
- value: from_moz(M.right),
- });
- }
- return new AST_Binary({
- start: my_start_token(M),
- end: my_end_token(M),
- operator: M.operator,
- left: from_moz(M.left),
- right: from_moz(M.right)
- });
- },
- LogicalExpression: function(M) {
- return new AST_Binary({
- start: my_start_token(M),
- end: my_end_token(M),
- operator: M.operator,
- left: from_moz(M.left),
- right: from_moz(M.right)
- });
- },
- AssignmentExpression: function(M) {
- return new AST_Assign({
- start: my_start_token(M),
- end: my_end_token(M),
- operator: M.operator,
- logical: M.operator === "??=" || M.operator === "&&=" || M.operator === "||=",
- left: from_moz(M.left),
- right: from_moz(M.right)
- });
- },
- ConditionalExpression: function(M) {
- return new AST_Conditional({
- start: my_start_token(M),
- end: my_end_token(M),
- condition: from_moz(M.test),
- consequent: from_moz(M.consequent),
- alternative: from_moz(M.alternate)
- });
- },
- NewExpression: function(M) {
- return new AST_New({
- start: my_start_token(M),
- end: my_end_token(M),
- expression: from_moz(M.callee),
- args: M.arguments.map(from_moz)
- });
- },
- CallExpression: function(M) {
- return new AST_Call({
- start: my_start_token(M),
- end: my_end_token(M),
- expression: from_moz(M.callee),
- optional: M.optional,
- args: M.arguments.map(from_moz)
- });
- }
- };
- MOZ_TO_ME.UpdateExpression =
- MOZ_TO_ME.UnaryExpression = function To_Moz_Unary(M) {
- var prefix = "prefix" in M ? M.prefix
- : M.type == "UnaryExpression" ? true : false;
- return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({
- start : my_start_token(M),
- end : my_end_token(M),
- operator : M.operator,
- expression : from_moz(M.argument)
- });
- };
- MOZ_TO_ME.ClassDeclaration =
- MOZ_TO_ME.ClassExpression = function From_Moz_Class(M) {
- return new (M.type === "ClassDeclaration" ? AST_DefClass : AST_ClassExpression)({
- start : my_start_token(M),
- end : my_end_token(M),
- name : M.id && from_moz_symbol(M.type === "ClassDeclaration" ? AST_SymbolDefClass : AST_SymbolClass, M.id),
- extends : from_moz(M.superClass),
- properties: M.body.body.map(from_moz)
- });
- };
- def_to_moz(AST_EmptyStatement, function To_Moz_EmptyStatement() {
- return {
- type: "EmptyStatement"
- };
- });
- def_to_moz(AST_BlockStatement, function To_Moz_BlockStatement(M) {
- return {
- type: "BlockStatement",
- body: M.body.map(to_moz)
- };
- });
- def_to_moz(AST_If, function To_Moz_IfStatement(M) {
- return {
- type: "IfStatement",
- test: to_moz(M.condition),
- consequent: to_moz(M.body),
- alternate: to_moz(M.alternative)
- };
- });
- def_to_moz(AST_LabeledStatement, function To_Moz_LabeledStatement(M) {
- return {
- type: "LabeledStatement",
- label: to_moz(M.label),
- body: to_moz(M.body)
- };
- });
- def_to_moz(AST_Break, function To_Moz_BreakStatement(M) {
- return {
- type: "BreakStatement",
- label: to_moz(M.label)
- };
- });
- def_to_moz(AST_Continue, function To_Moz_ContinueStatement(M) {
- return {
- type: "ContinueStatement",
- label: to_moz(M.label)
- };
- });
- def_to_moz(AST_With, function To_Moz_WithStatement(M) {
- return {
- type: "WithStatement",
- object: to_moz(M.expression),
- body: to_moz(M.body)
- };
- });
- def_to_moz(AST_Switch, function To_Moz_SwitchStatement(M) {
- return {
- type: "SwitchStatement",
- discriminant: to_moz(M.expression),
- cases: M.body.map(to_moz)
- };
- });
- def_to_moz(AST_Return, function To_Moz_ReturnStatement(M) {
- return {
- type: "ReturnStatement",
- argument: to_moz(M.value)
- };
- });
- def_to_moz(AST_Throw, function To_Moz_ThrowStatement(M) {
- return {
- type: "ThrowStatement",
- argument: to_moz(M.value)
- };
- });
- def_to_moz(AST_While, function To_Moz_WhileStatement(M) {
- return {
- type: "WhileStatement",
- test: to_moz(M.condition),
- body: to_moz(M.body)
- };
- });
- def_to_moz(AST_Do, function To_Moz_DoWhileStatement(M) {
- return {
- type: "DoWhileStatement",
- test: to_moz(M.condition),
- body: to_moz(M.body)
- };
- });
- def_to_moz(AST_For, function To_Moz_ForStatement(M) {
- return {
- type: "ForStatement",
- init: to_moz(M.init),
- test: to_moz(M.condition),
- update: to_moz(M.step),
- body: to_moz(M.body)
- };
- });
- def_to_moz(AST_ForIn, function To_Moz_ForInStatement(M) {
- return {
- type: "ForInStatement",
- left: to_moz(M.init),
- right: to_moz(M.object),
- body: to_moz(M.body)
- };
- });
- def_to_moz(AST_ForOf, function To_Moz_ForOfStatement(M) {
- return {
- type: "ForOfStatement",
- left: to_moz(M.init),
- right: to_moz(M.object),
- body: to_moz(M.body),
- await: M.await
- };
- });
- def_to_moz(AST_Await, function To_Moz_AwaitExpression(M) {
- return {
- type: "AwaitExpression",
- argument: to_moz(M.expression)
- };
- });
- def_to_moz(AST_Yield, function To_Moz_YieldExpression(M) {
- return {
- type: "YieldExpression",
- argument: to_moz(M.expression),
- delegate: M.is_star
- };
- });
- def_to_moz(AST_Debugger, function To_Moz_DebuggerStatement() {
- return {
- type: "DebuggerStatement"
- };
- });
- def_to_moz(AST_VarDefLike, function To_Moz_VariableDeclarator(M) {
- return {
- type: "VariableDeclarator",
- id: to_moz(M.name),
- init: to_moz(M.value)
- };
- });
- def_to_moz(AST_This, function To_Moz_ThisExpression() {
- return {
- type: "ThisExpression"
- };
- });
- def_to_moz(AST_Super, function To_Moz_Super() {
- return {
- type: "Super"
- };
- });
- def_to_moz(AST_Conditional, function To_Moz_ConditionalExpression(M) {
- return {
- type: "ConditionalExpression",
- test: to_moz(M.condition),
- consequent: to_moz(M.consequent),
- alternate: to_moz(M.alternative)
- };
- });
- def_to_moz(AST_New, function To_Moz_NewExpression(M) {
- return {
- type: "NewExpression",
- callee: to_moz(M.expression),
- arguments: M.args.map(to_moz)
- };
- });
- def_to_moz(AST_Call, function To_Moz_CallExpression(M) {
- return {
- type: "CallExpression",
- callee: to_moz(M.expression),
- optional: M.optional,
- arguments: M.args.map(to_moz)
- };
- });
- def_to_moz(AST_DynamicImport, function To_Moz_ImportExpression(M) {
- const [source, options] = M.args.map(to_moz);
- return {
- type: "ImportExpression",
- source,
- options: options || null,
- phase: M.phase
- };
- });
- def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
- return to_moz_scope("Program", M);
- });
- def_to_moz(AST_Expansion, function To_Moz_Spread(M) {
- return {
- type: to_moz_in_destructuring() ? "RestElement" : "SpreadElement",
- argument: to_moz(M.expression)
- };
- });
- def_to_moz(AST_PrefixedTemplateString, function To_Moz_TaggedTemplateExpression(M) {
- return {
- type: "TaggedTemplateExpression",
- tag: to_moz(M.prefix),
- quasi: to_moz(M.template_string)
- };
- });
- def_to_moz(AST_TemplateString, function To_Moz_TemplateLiteral(M) {
- var quasis = [];
- var expressions = [];
- for (var i = 0; i < M.segments.length; i++) {
- if (i % 2 !== 0) {
- expressions.push(to_moz(M.segments[i]));
- } else {
- quasis.push({
- type: "TemplateElement",
- value: {
- raw: M.segments[i].raw,
- cooked: M.segments[i].value
- },
- tail: i === M.segments.length - 1
- });
- }
- }
- return {
- type: "TemplateLiteral",
- quasis: quasis,
- expressions: expressions
- };
- });
- def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) {
- return {
- type: "FunctionDeclaration",
- id: to_moz(M.name),
- params: M.argnames.map(to_moz_pattern),
- generator: M.is_generator,
- async: M.async,
- body: to_moz_scope("BlockStatement", M)
- };
- });
- def_to_moz(AST_Function, function To_Moz_FunctionExpression(M) {
- return {
- type: "FunctionExpression",
- id: to_moz(M.name),
- params: M.argnames.map(to_moz_pattern),
- generator: M.is_generator || false,
- async: M.async || false,
- body: to_moz_scope("BlockStatement", M)
- };
- });
- def_to_moz(AST_Arrow, function To_Moz_ArrowFunctionExpression(M) {
- var body = M.body.length === 1 && M.body[0] instanceof AST_Return && M.body[0].value
- ? to_moz(M.body[0].value)
- : {
- type: "BlockStatement",
- body: M.body.map(to_moz)
- };
- return {
- type: "ArrowFunctionExpression",
- params: M.argnames.map(to_moz_pattern),
- async: M.async,
- body: body,
- };
- });
- def_to_moz(AST_Destructuring, function To_Moz_ObjectPattern(M) {
- if (M.is_array) {
- return {
- type: "ArrayPattern",
- elements: M.names.map(
- M => M instanceof AST_Hole ? null : to_moz_pattern(M)
- ),
- };
- }
- return {
- type: "ObjectPattern",
- properties: M.names.map(M => {
- if (M instanceof AST_ObjectKeyVal) {
- var computed = M.computed_key();
- const [shorthand, key] = to_moz_property_key(M.key, computed, M.quote, M.value);
- return {
- type: "Property",
- computed,
- kind: "init",
- key: key,
- method: false,
- shorthand,
- value: to_moz_pattern(M.value)
- };
- } else {
- return to_moz_pattern(M);
- }
- }),
- };
- });
- def_to_moz(AST_DefaultAssign, function To_Moz_AssignmentExpression(M) {
- return {
- type: "AssignmentPattern",
- left: to_moz_pattern(M.left),
- right: to_moz(M.right),
- };
- });
- def_to_moz(AST_Directive, function To_Moz_Directive(M) {
- return {
- type: "ExpressionStatement",
- expression: {
- type: "Literal",
- value: M.value,
- raw: M.print_to_string()
- },
- directive: M.value
- };
- });
- def_to_moz(AST_SimpleStatement, function To_Moz_ExpressionStatement(M) {
- return {
- type: "ExpressionStatement",
- expression: to_moz(M.body)
- };
- });
- def_to_moz(AST_SwitchBranch, function To_Moz_SwitchCase(M) {
- return {
- type: "SwitchCase",
- test: to_moz(M.expression),
- consequent: M.body.map(to_moz)
- };
- });
- def_to_moz(AST_Try, function To_Moz_TryStatement(M) {
- return {
- type: "TryStatement",
- block: to_moz_block(M.body),
- handler: to_moz(M.bcatch),
- guardedHandlers: [],
- finalizer: to_moz(M.bfinally)
- };
- });
- def_to_moz(AST_Catch, function To_Moz_CatchClause(M) {
- return {
- type: "CatchClause",
- param: M.argname != null ? to_moz_pattern(M.argname) : null,
- body: to_moz_block(M)
- };
- });
- def_to_moz(AST_DefinitionsLike, function To_Moz_VariableDeclaration(M) {
- return {
- type: "VariableDeclaration",
- kind:
- M instanceof AST_Const ? "const" :
- M instanceof AST_Let ? "let" :
- M instanceof AST_Using ? (M.await ? "await using" : "using") :
- "var",
- declarations: M.definitions.map(to_moz)
- };
- });
- function import_attributes_to_moz(attribute) {
- const import_attributes = [];
- if (attribute) {
- for (const { key, value } of attribute.properties) {
- const key_moz = is_basic_identifier_string(key)
- ? { type: "Identifier", name: key }
- : { type: "Literal", value: key, raw: JSON.stringify(key) };
- import_attributes.push({
- type: "ImportAttribute",
- key: key_moz,
- value: to_moz(value)
- });
- }
- }
- return import_attributes;
- }
- def_to_moz(AST_Export, function To_Moz_ExportDeclaration(M) {
- if (M.exported_names) {
- var first_exported = M.exported_names[0];
- if (first_exported && first_exported.name.name === "*" && !first_exported.name.quote) {
- var foreign_name = first_exported.foreign_name;
- var exported = foreign_name.name === "*" && !foreign_name.quote
- ? null
- : to_moz(foreign_name);
- return {
- type: "ExportAllDeclaration",
- source: to_moz(M.module_name),
- exported: exported,
- attributes: import_attributes_to_moz(M.attributes)
- };
- }
- return {
- type: "ExportNamedDeclaration",
- specifiers: M.exported_names.map(function (name_mapping) {
- return {
- type: "ExportSpecifier",
- exported: to_moz(name_mapping.foreign_name),
- local: to_moz(name_mapping.name)
- };
- }),
- declaration: to_moz(M.exported_definition),
- source: to_moz(M.module_name),
- attributes: import_attributes_to_moz(M.attributes)
- };
- }
- if (M.is_default) {
- return {
- type: "ExportDefaultDeclaration",
- declaration: to_moz(M.exported_value || M.exported_definition),
- };
- } else {
- return {
- type: "ExportNamedDeclaration",
- declaration: to_moz(M.exported_value || M.exported_definition),
- specifiers: [],
- source: null,
- };
- }
- });
- def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) {
- var specifiers = [];
- if (M.imported_name) {
- specifiers.push({
- type: "ImportDefaultSpecifier",
- local: to_moz(M.imported_name)
- });
- }
- if (M.imported_names) {
- var first_foreign_name = M.imported_names[0] && M.imported_names[0].foreign_name;
- if (first_foreign_name && first_foreign_name.name === "*" && !first_foreign_name.quote) {
- specifiers.push({
- type: "ImportNamespaceSpecifier",
- local: to_moz(M.imported_names[0].name)
- });
- } else {
- M.imported_names.forEach(function(name_mapping) {
- specifiers.push({
- type: "ImportSpecifier",
- local: to_moz(name_mapping.name),
- imported: to_moz(name_mapping.foreign_name)
- });
- });
- }
- }
- var moz = {
- type: "ImportDeclaration",
- specifiers: specifiers,
- source: to_moz(M.module_name),
- attributes: import_attributes_to_moz(M.attributes)
- };
- if (M.phase) moz.phase = M.phase;
- return moz;
- });
- def_to_moz(AST_ImportMeta, function To_Moz_MetaProperty() {
- return {
- type: "MetaProperty",
- meta: {
- type: "Identifier",
- name: "import"
- },
- property: {
- type: "Identifier",
- name: "meta"
- }
- };
- });
- def_to_moz(AST_Sequence, function To_Moz_SequenceExpression(M) {
- return {
- type: "SequenceExpression",
- expressions: M.expressions.map(to_moz)
- };
- });
- def_to_moz(AST_DotHash, function To_Moz_PrivateMemberExpression(M) {
- return {
- type: "MemberExpression",
- object: to_moz(M.expression),
- computed: false,
- property: {
- type: "PrivateIdentifier",
- name: M.property
- },
- optional: M.optional
- };
- });
- def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) {
- var isComputed = M instanceof AST_Sub;
- return {
- type: "MemberExpression",
- object: to_moz(M.expression),
- computed: isComputed,
- property: isComputed ? to_moz(M.property) : {type: "Identifier", name: M.property},
- optional: M.optional
- };
- });
- def_to_moz(AST_Chain, function To_Moz_ChainExpression(M) {
- return {
- type: "ChainExpression",
- expression: to_moz(M.expression)
- };
- });
- def_to_moz(AST_Unary, function To_Moz_Unary(M) {
- return {
- type: M.operator == "++" || M.operator == "--" ? "UpdateExpression" : "UnaryExpression",
- operator: M.operator,
- prefix: M instanceof AST_UnaryPrefix,
- argument: to_moz(M.expression)
- };
- });
- def_to_moz(AST_Binary, function To_Moz_BinaryExpression(M) {
- if (M.operator == "=" && to_moz_in_destructuring()) {
- return {
- type: "AssignmentPattern",
- left: to_moz(M.left),
- right: to_moz(M.right)
- };
- }
- const type = M.operator == "&&" || M.operator == "||" || M.operator === "??"
- ? "LogicalExpression"
- : "BinaryExpression";
- return {
- type,
- left: to_moz(M.left),
- operator: M.operator,
- right: to_moz(M.right)
- };
- });
- def_to_moz(AST_Assign, function To_Moz_AssignmentExpression(M) {
- return {
- type: "AssignmentExpression",
- operator: M.operator,
- left: to_moz(M.left),
- right: to_moz(M.right)
- };
- });
- def_to_moz(AST_PrivateIn, function To_Moz_BinaryExpression_PrivateIn(M) {
- return {
- type: "BinaryExpression",
- left: { type: "PrivateIdentifier", name: M.key.name },
- operator: "in",
- right: to_moz(M.value),
- };
- });
- def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) {
- return {
- type: "ArrayExpression",
- elements: M.elements.map(to_moz)
- };
- });
- def_to_moz(AST_Object, function To_Moz_ObjectExpression(M) {
- return {
- type: "ObjectExpression",
- properties: M.properties.map(to_moz)
- };
- });
- def_to_moz(AST_ObjectProperty, function To_Moz_Property(M, parent) {
- var computed = M.computed_key();
- const [shorthand, key] = to_moz_property_key(M.key, computed, M.quote, M.value);
- var kind;
- if (M instanceof AST_ObjectGetter) {
- kind = "get";
- } else
- if (M instanceof AST_ObjectSetter) {
- kind = "set";
- }
- if (M instanceof AST_PrivateGetter || M instanceof AST_PrivateSetter) {
- const kind = M instanceof AST_PrivateGetter ? "get" : "set";
- return {
- type: "MethodDefinition",
- computed: false,
- kind: kind,
- static: M.static,
- key: {
- type: "PrivateIdentifier",
- name: M.key.name
- },
- value: to_moz(M.value)
- };
- }
- if (M instanceof AST_ClassPrivateProperty) {
- return {
- type: "PropertyDefinition",
- key: {
- type: "PrivateIdentifier",
- name: M.key.name
- },
- value: to_moz(M.value),
- computed: false,
- static: M.static
- };
- }
- if (M instanceof AST_ClassProperty) {
- return {
- type: "PropertyDefinition",
- key,
- value: to_moz(M.value),
- computed,
- static: M.static
- };
- }
- if (parent instanceof AST_Class) {
- return {
- type: "MethodDefinition",
- computed: computed,
- kind: kind,
- static: M.static,
- key: to_moz(M.key),
- value: to_moz(M.value)
- };
- }
- return {
- type: "Property",
- computed: computed,
- method: false,
- shorthand,
- kind: kind,
- key: key,
- value: to_moz(M.value)
- };
- });
- def_to_moz(AST_ObjectKeyVal, function To_Moz_Property(M) {
- var computed = M.computed_key();
- const [shorthand, key] = to_moz_property_key(M.key, computed, M.quote, M.value);
- return {
- type: "Property",
- computed: computed,
- shorthand: shorthand,
- method: false,
- kind: "init",
- key: key,
- value: to_moz(M.value)
- };
- });
- def_to_moz(AST_ConciseMethod, function To_Moz_MethodDefinition(M, parent) {
- const computed = M.computed_key();
- const [_always_false, key] = to_moz_property_key(M.key, computed, M.quote, M.value);
- if (parent instanceof AST_Object) {
- return {
- type: "Property",
- kind: "init",
- computed,
- method: true,
- shorthand: false,
- key,
- value: to_moz(M.value),
- };
- }
- return {
- type: "MethodDefinition",
- kind: !computed && M.key.name === "constructor" ? "constructor" : "method",
- computed,
- key,
- value: to_moz(M.value),
- static: M.static,
- };
- });
- def_to_moz(AST_PrivateMethod, function To_Moz_MethodDefinition(M) {
- return {
- type: "MethodDefinition",
- kind: "method",
- key: { type: "PrivateIdentifier", name: M.key.name },
- value: to_moz(M.value),
- computed: false,
- static: M.static,
- };
- });
- def_to_moz(AST_Class, function To_Moz_Class(M) {
- var type = M instanceof AST_ClassExpression ? "ClassExpression" : "ClassDeclaration";
- return {
- type: type,
- superClass: to_moz(M.extends),
- id: M.name ? to_moz(M.name) : null,
- body: {
- type: "ClassBody",
- body: M.properties.map(to_moz)
- }
- };
- });
- def_to_moz(AST_ClassStaticBlock, function To_Moz_StaticBlock(M) {
- return {
- type: "StaticBlock",
- body: M.body.map(to_moz),
- };
- });
- def_to_moz(AST_NewTarget, function To_Moz_MetaProperty() {
- return {
- type: "MetaProperty",
- meta: {
- type: "Identifier",
- name: "new"
- },
- property: {
- type: "Identifier",
- name: "target"
- }
- };
- });
- def_to_moz(AST_Symbol, function To_Moz_Identifier(M, parent) {
- if (
- (M instanceof AST_SymbolMethod && parent.quote) ||
- ((
- M instanceof AST_SymbolImportForeign ||
- M instanceof AST_SymbolExportForeign ||
- M instanceof AST_SymbolExport
- ) && M.quote)
- ) {
- return {
- type: "Literal",
- value: M.name
- };
- }
- var def = M.definition();
- return {
- type: "Identifier",
- name: def ? def.mangled_name || def.name : M.name
- };
- });
- def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) {
- const pattern = M.value.source;
- const flags = M.value.flags;
- return {
- type: "Literal",
- value: null,
- raw: M.print_to_string(),
- regex: { pattern, flags }
- };
- });
- def_to_moz(AST_Constant, function To_Moz_Literal(M) {
- var value = M.value;
- return {
- type: "Literal",
- value: value,
- raw: M.raw || M.print_to_string()
- };
- });
- def_to_moz(AST_Atom, function To_Moz_Atom(M) {
- return {
- type: "Identifier",
- name: String(M.value)
- };
- });
- def_to_moz(AST_BigInt, M => ({
- type: "Literal",
- // value cannot be represented natively
- // see: https://github.com/estree/estree/blob/master/es2020.md#bigintliteral
- value: null,
- // `M.value` is a string that may be a hex number representation.
- // but "bigint" property should have only decimal digits
- bigint: typeof BigInt === "function" ? BigInt(M.value).toString() : M.value,
- raw: M.raw,
- }));
- AST_Boolean.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast);
- AST_Null.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast);
- AST_Hole.DEFMETHOD("to_mozilla_ast", function To_Moz_ArrayHole() { return null; });
- AST_Block.DEFMETHOD("to_mozilla_ast", AST_BlockStatement.prototype.to_mozilla_ast);
- AST_Lambda.DEFMETHOD("to_mozilla_ast", AST_Function.prototype.to_mozilla_ast);
- /* -----[ tools ]----- */
- function my_start_token(moznode) {
- var loc = moznode.loc, start = loc && loc.start;
- var range = moznode.range;
- return new AST_Token(
- "",
- "",
- start && start.line || 0,
- start && start.column || 0,
- range ? range [0] : moznode.start,
- false,
- [],
- [],
- loc && loc.source,
- );
- }
- function my_end_token(moznode) {
- var loc = moznode.loc, end = loc && loc.end;
- var range = moznode.range;
- return new AST_Token(
- "",
- "",
- end && end.line || 0,
- end && end.column || 0,
- range ? range [0] : moznode.end,
- false,
- [],
- [],
- loc && loc.source,
- );
- }
- var FROM_MOZ_LABELS = null;
- function from_moz(node) {
- if (node == null) return null;
- return MOZ_TO_ME[node.type](node);
- }
- function from_moz_quote(moz_key, computed) {
- if (!computed && moz_key.type === "Literal" && typeof moz_key.value === "string") {
- return '"';
- } else {
- return "";
- }
- }
- function from_moz_symbol(symbol_type, M, has_quote) {
- return new symbol_type({
- start: my_start_token(M),
- quote: has_quote ? '"' : undefined,
- name: M.type === "Identifier" ? M.name : String(M.value),
- end: my_end_token(M),
- });
- }
- function from_moz_lambda(M, is_method) {
- return new (is_method ? AST_Accessor : AST_Function)({
- start: my_start_token(M),
- end: my_end_token(M),
- name: M.id && from_moz_symbol(is_method ? AST_SymbolMethod : AST_SymbolLambda, M.id),
- argnames: M.params.map(M => from_moz_pattern(M, AST_SymbolFunarg)),
- is_generator: M.generator,
- async: M.async,
- body: normalize_directives(from_moz(M.body).body)
- });
- }
- function from_moz_pattern(M, sym_type) {
- switch (M.type) {
- case "ObjectPattern":
- return new AST_Destructuring({
- start: my_start_token(M),
- end: my_end_token(M),
- names: M.properties.map(p => from_moz_pattern(p, sym_type)),
- is_array: false
- });
- case "Property":
- var key = M.key;
- var args = {
- start : my_start_token(key || M.value),
- end : my_end_token(M.value),
- key : key.type == "Identifier" ? key.name : String(key.value),
- quote : !M.computed && key.type === "Literal" && typeof key.value === "string"
- ? '"'
- : "",
- value : from_moz_pattern(M.value, sym_type)
- };
- if (M.computed) {
- args.key = from_moz(M.key);
- }
- return new AST_ObjectKeyVal(args);
- case "ArrayPattern":
- return new AST_Destructuring({
- start: my_start_token(M),
- end: my_end_token(M),
- names: M.elements.map(function(elm) {
- if (elm === null) {
- return new AST_Hole();
- }
- return from_moz_pattern(elm, sym_type);
- }),
- is_array: true
- });
- case "SpreadElement":
- case "RestElement":
- return new AST_Expansion({
- start: my_start_token(M),
- end: my_end_token(M),
- expression: from_moz_pattern(M.argument, sym_type),
- });
- case "AssignmentPattern":
- return new AST_DefaultAssign({
- start : my_start_token(M),
- end : my_end_token(M),
- left : from_moz_pattern(M.left, sym_type),
- operator: "=",
- right : from_moz(M.right),
- });
- case "Identifier":
- return new sym_type({
- start : my_start_token(M),
- end : my_end_token(M),
- name : M.name,
- });
- default:
- throw new Error("Invalid node type for destructuring: " + M.type);
- }
- }
- function from_moz_label_ref(m_label) {
- if (!m_label) return null;
- const label = from_moz_symbol(AST_LabelRef, m_label);
- let i = FROM_MOZ_LABELS.length;
- while (i--) {
- const label_origin = FROM_MOZ_LABELS[i];
- if (label.name === label_origin.name) {
- label.thedef = label_origin;
- break;
- }
- }
- return label;
- }
- AST_Node.from_mozilla_ast = function(node) {
- var save_labels = FROM_MOZ_LABELS;
- FROM_MOZ_LABELS = [];
- var ast = from_moz(node);
- FROM_MOZ_LABELS = save_labels;
- return ast;
- };
- function set_moz_loc(mynode, moznode) {
- var start = mynode.start;
- var end = mynode.end;
- if (!(start && end)) {
- return moznode;
- }
- if (start.pos != null && end.endpos != null) {
- moznode.range = [start.pos, end.endpos];
- }
- if (start.line) {
- moznode.loc = {
- start: {line: start.line, column: start.col},
- end: end.endline ? {line: end.endline, column: end.endcol} : null
- };
- if (start.file) {
- moznode.loc.source = start.file;
- }
- }
- return moznode;
- }
- function def_to_moz(mytype, handler) {
- mytype.DEFMETHOD("to_mozilla_ast", function(parent) {
- return set_moz_loc(this, handler(this, parent));
- });
- }
- var TO_MOZ_STACK = null;
- function to_moz(node) {
- if (TO_MOZ_STACK === null) { TO_MOZ_STACK = []; }
- TO_MOZ_STACK.push(node);
- var ast = node != null ? node.to_mozilla_ast(TO_MOZ_STACK[TO_MOZ_STACK.length - 2]) : null;
- TO_MOZ_STACK.pop();
- if (TO_MOZ_STACK.length === 0) { TO_MOZ_STACK = null; }
- return ast;
- }
- /** Object property keys can be number literals, string literals, or raw names. Additionally they can be shorthand. We decide that here. */
- function to_moz_property_key(key, computed = false, quote = false, value = null) {
- if (computed) {
- return [false, to_moz(key)];
- }
- const key_name = typeof key === "string" ? key : key.name;
- let moz_key;
- if (quote) {
- moz_key = { type: "Literal", value: key_name, raw: JSON.stringify(key_name) };
- } else if ("" + +key_name === key_name && +key_name >= 0) {
- // representable as a number
- moz_key = { type: "Literal", value: +key_name, raw: JSON.stringify(+key_name) };
- } else {
- moz_key = { type: "Identifier", name: key_name };
- }
- const shorthand =
- moz_key.type === "Identifier"
- && moz_key.name === key_name
- && (value instanceof AST_Symbol && value.name === key_name
- || value instanceof AST_DefaultAssign && value.left.name === key_name);
- return [shorthand, moz_key];
- }
- function to_moz_pattern(node) {
- if (node instanceof AST_Expansion) {
- return {
- type: "RestElement",
- argument: to_moz_pattern(node.expression),
- };
- }
- if ((
- node instanceof AST_Symbol
- || node instanceof AST_Destructuring
- || node instanceof AST_DefaultAssign
- || node instanceof AST_PropAccess
- )) {
- // Plain translation
- return to_moz(node);
- }
- throw new Error(node.TYPE);
- }
- function to_moz_in_destructuring() {
- var i = TO_MOZ_STACK.length;
- while (i--) {
- if (TO_MOZ_STACK[i] instanceof AST_Destructuring) {
- return true;
- }
- }
- return false;
- }
- function to_moz_block(node) {
- return {
- type: "BlockStatement",
- body: node.body.map(to_moz)
- };
- }
- function to_moz_scope(type, node) {
- var body = node.body.map(to_moz);
- if (node.body[0] instanceof AST_SimpleStatement && node.body[0].body instanceof AST_String) {
- body.unshift(to_moz(new AST_EmptyStatement(node.body[0])));
- }
- return {
- type: type,
- body: body
- };
- }
- })();
- // return true if the node at the top of the stack (that means the
- // innermost node in the current output) is lexically the first in
- // a statement.
- function first_in_statement(stack) {
- let node = stack.parent(-1);
- for (let i = 0, p; p = stack.parent(i); i++) {
- if (p instanceof AST_Statement && p.body === node)
- return true;
- if ((p instanceof AST_Sequence && p.expressions[0] === node) ||
- (p.TYPE === "Call" && p.expression === node) ||
- (p instanceof AST_PrefixedTemplateString && p.prefix === node) ||
- (p instanceof AST_Dot && p.expression === node) ||
- (p instanceof AST_Sub && p.expression === node) ||
- (p instanceof AST_Chain && p.expression === node) ||
- (p instanceof AST_Conditional && p.condition === node) ||
- (p instanceof AST_Binary && p.left === node) ||
- (p instanceof AST_UnaryPostfix && p.expression === node)
- ) {
- node = p;
- } else {
- return false;
- }
- }
- }
- // Returns whether the leftmost item in the expression is an object
- function left_is_object(node) {
- if (node instanceof AST_Object) return true;
- if (node instanceof AST_Sequence) return left_is_object(node.expressions[0]);
- if (node.TYPE === "Call") return left_is_object(node.expression);
- if (node instanceof AST_PrefixedTemplateString) return left_is_object(node.prefix);
- if (node instanceof AST_Dot || node instanceof AST_Sub) return left_is_object(node.expression);
- if (node instanceof AST_Chain) return left_is_object(node.expression);
- if (node instanceof AST_Conditional) return left_is_object(node.condition);
- if (node instanceof AST_Binary) return left_is_object(node.left);
- if (node instanceof AST_UnaryPostfix) return left_is_object(node.expression);
- return false;
- }
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- const CODE_LINE_BREAK = 10;
- const CODE_SPACE = 32;
- const r_annotation = /[@#]__(PURE|INLINE|NOINLINE)__/;
- function is_some_comments(comment) {
- // multiline comment
- return (
- (comment.type === "comment2" || comment.type === "comment1")
- && /@preserve|@copyright|@lic|@cc_on|^\**!/i.test(comment.value)
- );
- }
- const ROPE_COMMIT_WHEN = 8 * 1000;
- class Rope {
- constructor() {
- this.committed = "";
- this.current = "";
- }
- append(str) {
- /** When `this.current` is too long, commit it. */
- if (this.current.length > ROPE_COMMIT_WHEN) {
- this.committed += this.current + str;
- this.current = "";
- } else {
- this.current += str;
- }
- }
- insertAt(char, index) {
- const { committed, current } = this;
- if (index < committed.length) {
- this.committed = committed.slice(0, index) + char + committed.slice(index);
- } else if (index === committed.length) {
- this.committed += char;
- } else {
- index -= committed.length;
- this.committed += current.slice(0, index) + char;
- this.current = current.slice(index);
- }
- }
- charAt(index) {
- const { committed } = this;
- if (index < committed.length) return committed[index];
- return this.current[index - committed.length];
- }
- charCodeAt(index) {
- const { committed } = this;
- if (index < committed.length) return committed.charCodeAt(index);
- return this.current.charCodeAt(index - committed.length);
- }
- length() {
- return this.committed.length + this.current.length;
- }
- expectDirective() {
- // /^$|[;{][\s\n]*$/
- let ch, n = this.length();
- if (n <= 0) return true;
- // Skip N whitespace from the end
- while (
- (ch = this.charCodeAt(--n))
- && (ch == CODE_SPACE || ch == CODE_LINE_BREAK)
- );
- // either ";", or "{", or the string ended
- return !ch || ch === 59 || ch === 123;
- }
- hasNLB() {
- let n = this.length() - 1;
- while (n >= 0) {
- const code = this.charCodeAt(n--);
- if (code === CODE_LINE_BREAK) return true;
- if (code !== CODE_SPACE) return false;
- }
- return true;
- }
- toString() {
- return this.committed + this.current;
- }
- }
- function OutputStream(options) {
- var readonly = !options;
- options = defaults(options, {
- ascii_only : false,
- beautify : false,
- braces : false,
- comments : "some",
- ecma : 5,
- ie8 : false,
- indent_level : 4,
- indent_start : 0,
- inline_script : true,
- keep_numbers : false,
- keep_quoted_props : false,
- max_line_len : false,
- preamble : null,
- preserve_annotations : false,
- quote_keys : false,
- quote_style : 0,
- safari10 : false,
- semicolons : true,
- shebang : true,
- shorthand : undefined,
- source_map : null,
- webkit : false,
- width : 80,
- wrap_iife : false,
- wrap_func_args : false,
- _destroy_ast : false
- }, true);
- if (options.shorthand === undefined)
- options.shorthand = options.ecma > 5;
- // Convert comment option to RegExp if necessary and set up comments filter
- var comment_filter = return_false; // Default case, throw all comments away
- if (options.comments) {
- let comments = options.comments;
- if (typeof options.comments === "string" && /^\/.*\/[a-zA-Z]*$/.test(options.comments)) {
- var regex_pos = options.comments.lastIndexOf("/");
- comments = new RegExp(
- options.comments.substr(1, regex_pos - 1),
- options.comments.substr(regex_pos + 1)
- );
- }
- if (comments instanceof RegExp) {
- comment_filter = function(comment) {
- return comment.type != "comment5" && comments.test(comment.value);
- };
- } else if (typeof comments === "function") {
- comment_filter = function(comment) {
- return comment.type != "comment5" && comments(this, comment);
- };
- } else if (comments === "some") {
- comment_filter = is_some_comments;
- } else { // NOTE includes "all" option
- comment_filter = return_true;
- }
- }
- if (options.preserve_annotations) {
- let prev_comment_filter = comment_filter;
- comment_filter = function (comment) {
- return r_annotation.test(comment.value) || prev_comment_filter.apply(this, arguments);
- };
- }
- var indentation = 0;
- var current_col = 0;
- var current_line = 1;
- var current_pos = 0;
- var OUTPUT = new Rope();
- let printed_comments = new Set();
- var to_utf8 = options.ascii_only ? function(str, identifier = false, regexp = false) {
- if (options.ecma >= 2015 && !options.safari10 && !regexp) {
- str = str.replace(/[\ud800-\udbff][\udc00-\udfff]/g, function(ch) {
- var code = get_full_char_code(ch, 0).toString(16);
- return "\\u{" + code + "}";
- });
- }
- return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) {
- var code = ch.charCodeAt(0).toString(16);
- if (code.length <= 2 && !identifier) {
- while (code.length < 2) code = "0" + code;
- return "\\x" + code;
- } else {
- while (code.length < 4) code = "0" + code;
- return "\\u" + code;
- }
- });
- } : function(str) {
- return str.replace(/[\ud800-\udbff][\udc00-\udfff]|([\ud800-\udbff]|[\udc00-\udfff])/g, function(match, lone) {
- if (lone) {
- return "\\u" + lone.charCodeAt(0).toString(16);
- }
- return match;
- });
- };
- /** Matches an identifier with non-ascii characters */
- var re_high_identifier = (() => {
- try {
- return new RegExp("^(?![\\u0000-\\u00ff]+$)([\\p{ID_Start}][\\p{ID_Continue}]*)$", "u");
- } catch (_) {
- return undefined; /* \p in regex above is unsupported */
- }
- })();
- var ident_to_utf8 = (options.ascii_only || !re_high_identifier) ? to_utf8 : function (str) {
- if (re_high_identifier.test(str)) {
- str = str.replace(/[\ud800-\udbff][\udc00-\udfff]|([\ud800-\udbff]|[\udc00-\udfff])/g, function(match, lone) {
- if (lone) {
- return "\\u" + lone.charCodeAt(0).toString(16).padStart(4, "0");
- }
- return match;
- });
- // Escape identifier characters from higher unicode versions
- var char = get_full_char(str, 0);
- var escaped = char;
- if (
- is_identifier_start_broad(char)
- && !is_identifier_start(char)
- ) {
- const code_point = char.codePointAt(0);
- escaped = code_point <= 0xffff
- ? `\\u${code_point.toString(16).padStart(4, "0")}`
- : `\\u{${code_point.toString(16)}}`;
- }
- for (var i = char.length; i < str.length; i += char.length) {
- char = get_full_char(str, i);
- if (
- is_identifier_char_broad(char)
- && !is_identifier_char(char)
- ) {
- const code_point = char.codePointAt(0);
- escaped += code_point <= 0xffff
- ? `\\u${code_point.toString(16).padStart(4, "0")}`
- : `\\u{${code_point.toString(16)}}`;
- } else {
- escaped += char;
- }
- }
- return escaped;
- } else {
- return str;
- }
- };
- function make_string(str, quote) {
- var dq = 0, sq = 0;
- str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g,
- function(s, i) {
- switch (s) {
- case '"': ++dq; return '"';
- case "'": ++sq; return "'";
- case "\\": return "\\\\";
- case "\n": return "\\n";
- case "\r": return "\\r";
- case "\t": return "\\t";
- case "\b": return "\\b";
- case "\f": return "\\f";
- case "\x0B": return options.ie8 ? "\\x0B" : "\\v";
- case "\u2028": return "\\u2028";
- case "\u2029": return "\\u2029";
- case "\ufeff": return "\\ufeff";
- case "\0":
- return /[0-9]/.test(get_full_char(str, i+1)) ? "\\x00" : "\\0";
- }
- return s;
- });
- function quote_single() {
- return "'" + str.replace(/\x27/g, "\\'") + "'";
- }
- function quote_double() {
- return '"' + str.replace(/\x22/g, '\\"') + '"';
- }
- function quote_template() {
- return "`" + str.replace(/`/g, "\\`") + "`";
- }
- str = to_utf8(str);
- if (quote === "`") return quote_template();
- switch (options.quote_style) {
- case 1:
- return quote_single();
- case 2:
- return quote_double();
- case 3:
- return quote == "'" ? quote_single() : quote_double();
- default:
- return dq > sq ? quote_single() : quote_double();
- }
- }
- function encode_string(str, quote) {
- var ret = make_string(str, quote);
- if (options.inline_script) {
- ret = ret.replace(/<\x2f(script)([>\/\t\n\f\r ])/gi, "<\\/$1$2");
- ret = ret.replace(/\x3c!--/g, "\\x3c!--");
- ret = ret.replace(/--\x3e/g, "--\\x3e");
- }
- return ret;
- }
- function make_name(name) {
- name = name.toString();
- name = ident_to_utf8(name, true);
- return name;
- }
- function make_indent(back) {
- return " ".repeat(options.indent_start + indentation - back * options.indent_level);
- }
- /* -----[ beautification/minification ]----- */
- var has_parens = false;
- var might_need_space = false;
- var might_need_semicolon = false;
- var might_add_newline = 0;
- var need_newline_indented = false;
- var need_space = false;
- var newline_insert = -1;
- var last = "";
- var mapping_token, mapping_name, mappings = options.source_map && [];
- var do_add_mapping = mappings ? function() {
- mappings.forEach(function(mapping) {
- try {
- let { name, token } = mapping;
- if (name !== false) {
- if (token.type == "name" || token.type === "privatename") {
- name = token.value;
- } else if (name instanceof AST_Symbol) {
- name = token.type === "string" ? token.value : name.name;
- }
- }
- options.source_map.add(
- mapping.token.file,
- mapping.line, mapping.col,
- mapping.token.line, mapping.token.col,
- is_basic_identifier_string(name) ? name : undefined
- );
- } catch(ex) {
- // Ignore bad mapping
- }
- });
- mappings = [];
- } : noop;
- var ensure_line_len = options.max_line_len ? function() {
- if (current_col > options.max_line_len) {
- if (might_add_newline) {
- OUTPUT.insertAt("\n", might_add_newline);
- const len_after_newline = OUTPUT.length() - might_add_newline - 1;
- if (mappings) {
- var delta = len_after_newline - current_col;
- mappings.forEach(function(mapping) {
- mapping.line++;
- mapping.col += delta;
- });
- }
- current_line++;
- current_pos++;
- current_col = len_after_newline;
- }
- }
- if (might_add_newline) {
- might_add_newline = 0;
- do_add_mapping();
- }
- } : noop;
- var requireSemicolonChars = makePredicate("( [ + * / - , . `");
- function print(str) {
- str = String(str);
- var ch = get_full_char(str, 0);
- if (need_newline_indented && ch) {
- need_newline_indented = false;
- if (ch !== "\n") {
- print("\n");
- indent();
- }
- }
- if (need_space && ch) {
- need_space = false;
- if (!/[\s;})]/.test(ch)) {
- space();
- }
- }
- newline_insert = -1;
- var prev = last.charAt(last.length - 1);
- if (might_need_semicolon) {
- might_need_semicolon = false;
- if (prev === ":" && ch === "}" || (!ch || !";}".includes(ch)) && prev !== ";") {
- if (options.semicolons || requireSemicolonChars.has(ch)) {
- OUTPUT.append(";");
- current_col++;
- current_pos++;
- } else {
- ensure_line_len();
- if (current_col > 0) {
- OUTPUT.append("\n");
- current_pos++;
- current_line++;
- current_col = 0;
- }
- if (/^\s+$/.test(str)) {
- // reset the semicolon flag, since we didn't print one
- // now and might still have to later
- might_need_semicolon = true;
- }
- }
- if (!options.beautify)
- might_need_space = false;
- }
- }
- if (might_need_space) {
- if ((is_identifier_char_broad(prev)
- && (is_identifier_char_broad(ch) || ch == "\\"))
- || (ch == "/" && ch == prev)
- || ((ch == "+" || ch == "-") && ch == last)
- ) {
- OUTPUT.append(" ");
- current_col++;
- current_pos++;
- }
- might_need_space = false;
- }
- if (mapping_token) {
- mappings.push({
- token: mapping_token,
- name: mapping_name,
- line: current_line,
- col: current_col
- });
- mapping_token = false;
- if (!might_add_newline) do_add_mapping();
- }
- OUTPUT.append(str);
- has_parens = str[str.length - 1] == "(";
- current_pos += str.length;
- var a = str.split(/\r?\n/), n = a.length - 1;
- current_line += n;
- current_col += a[0].length;
- if (n > 0) {
- ensure_line_len();
- current_col = a[n].length;
- }
- last = str;
- }
- var star = function() {
- print("*");
- };
- var space = options.beautify ? function() {
- print(" ");
- } : function() {
- might_need_space = true;
- };
- var indent = options.beautify ? function(half) {
- if (options.beautify) {
- print(make_indent(half ? 0.5 : 0));
- }
- } : noop;
- var with_indent = options.beautify ? function(col, cont) {
- if (col === true) col = next_indent();
- var save_indentation = indentation;
- indentation = col;
- var ret = cont();
- indentation = save_indentation;
- return ret;
- } : function(col, cont) { return cont(); };
- var newline = options.beautify ? function() {
- if (newline_insert < 0) return print("\n");
- if (OUTPUT.charAt(newline_insert) != "\n") {
- OUTPUT.insertAt("\n", newline_insert);
- current_pos++;
- current_line++;
- }
- newline_insert++;
- } : options.max_line_len ? function() {
- ensure_line_len();
- might_add_newline = OUTPUT.length();
- } : noop;
- var semicolon = options.beautify ? function() {
- print(";");
- } : function() {
- might_need_semicolon = true;
- };
- function force_semicolon() {
- might_need_semicolon = false;
- print(";");
- }
- function next_indent() {
- return indentation + options.indent_level;
- }
- function with_block(cont) {
- var ret;
- print("{");
- newline();
- with_indent(next_indent(), function() {
- ret = cont();
- });
- indent();
- print("}");
- return ret;
- }
- function with_parens(cont) {
- print("(");
- //XXX: still nice to have that for argument lists
- //var ret = with_indent(current_col, cont);
- var ret = cont();
- print(")");
- return ret;
- }
- function with_square(cont) {
- print("[");
- //var ret = with_indent(current_col, cont);
- var ret = cont();
- print("]");
- return ret;
- }
- function comma() {
- print(",");
- space();
- }
- function colon() {
- print(":");
- space();
- }
- var add_mapping = mappings ? function(token, name) {
- mapping_token = token;
- mapping_name = name;
- } : noop;
- function get() {
- if (might_add_newline) {
- ensure_line_len();
- }
- return OUTPUT.toString();
- }
- function filter_comment(comment) {
- if (!options.preserve_annotations) {
- comment = comment.replace(r_annotation, " ");
- }
- if (/^\s*$/.test(comment)) {
- return "";
- }
- return comment.replace(/(<\s*\/\s*)(script)/i, "<\\/$2");
- }
- function prepend_comments(node) {
- var self = this;
- var start = node.start;
- if (!start) return;
- var printed_comments = self.printed_comments;
- // There cannot be a newline between return/yield and its value.
- const keyword_with_value =
- node instanceof AST_Exit && node.value
- || (node instanceof AST_Await || node instanceof AST_Yield)
- && node.expression;
- if (
- start.comments_before
- && printed_comments.has(start.comments_before)
- ) {
- if (keyword_with_value) {
- start.comments_before = [];
- } else {
- return;
- }
- }
- var comments = start.comments_before;
- if (!comments) {
- comments = start.comments_before = [];
- }
- printed_comments.add(comments);
- if (keyword_with_value) {
- var tw = new TreeWalker(function(node) {
- var parent = tw.parent();
- if (parent instanceof AST_Exit
- || parent instanceof AST_Await
- || parent instanceof AST_Yield
- || parent instanceof AST_Binary && parent.left === node
- || parent.TYPE == "Call" && parent.expression === node
- || parent instanceof AST_Conditional && parent.condition === node
- || parent instanceof AST_Dot && parent.expression === node
- || parent instanceof AST_Sequence && parent.expressions[0] === node
- || parent instanceof AST_Sub && parent.expression === node
- || parent instanceof AST_UnaryPostfix) {
- if (!node.start) return;
- var text = node.start.comments_before;
- if (text && !printed_comments.has(text)) {
- printed_comments.add(text);
- comments = comments.concat(text);
- }
- } else {
- return true;
- }
- });
- tw.push(node);
- keyword_with_value.walk(tw);
- }
- if (current_pos == 0) {
- if (comments.length > 0 && options.shebang && comments[0].type === "comment5"
- && !printed_comments.has(comments[0])) {
- print("#!" + comments.shift().value + "\n");
- indent();
- }
- var preamble = options.preamble;
- if (preamble) {
- print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
- }
- }
- comments = comments.filter(comment_filter, node).filter(c => !printed_comments.has(c));
- if (comments.length == 0) return;
- var last_nlb = OUTPUT.hasNLB();
- comments.forEach(function(c, i) {
- printed_comments.add(c);
- if (!last_nlb) {
- if (c.nlb) {
- print("\n");
- indent();
- last_nlb = true;
- } else if (i > 0) {
- space();
- }
- }
- if (/comment[134]/.test(c.type)) {
- var value = filter_comment(c.value);
- if (value) {
- print("//" + value + "\n");
- indent();
- }
- last_nlb = true;
- } else if (c.type == "comment2") {
- var value = filter_comment(c.value);
- if (value) {
- print("/*" + value + "*/");
- }
- last_nlb = false;
- }
- });
- if (!last_nlb) {
- if (start.nlb) {
- print("\n");
- indent();
- } else {
- space();
- }
- }
- }
- function append_comments(node, tail) {
- var self = this;
- var token = node.end;
- if (!token) return;
- var printed_comments = self.printed_comments;
- var comments = token[tail ? "comments_before" : "comments_after"];
- if (!comments || printed_comments.has(comments)) return;
- if (!(node instanceof AST_Statement || comments.every((c) =>
- !/comment[134]/.test(c.type)
- ))) return;
- printed_comments.add(comments);
- var insert = OUTPUT.length();
- comments.filter(comment_filter, node).forEach(function(c, i) {
- if (printed_comments.has(c)) return;
- printed_comments.add(c);
- need_space = false;
- if (need_newline_indented) {
- print("\n");
- indent();
- need_newline_indented = false;
- } else if (c.nlb && (i > 0 || !OUTPUT.hasNLB())) {
- print("\n");
- indent();
- } else if (i > 0 || !tail) {
- space();
- }
- if (/comment[134]/.test(c.type)) {
- const value = filter_comment(c.value);
- if (value) {
- print("//" + value);
- }
- need_newline_indented = true;
- } else if (c.type == "comment2") {
- const value = filter_comment(c.value);
- if (value) {
- print("/*" + value + "*/");
- }
- need_space = true;
- }
- });
- if (OUTPUT.length() > insert) newline_insert = insert;
- }
- /**
- * When output.option("_destroy_ast") is enabled, destroy the function.
- * Call this after printing it.
- */
- const gc_scope =
- options["_destroy_ast"]
- ? function gc_scope(scope) {
- scope.body.length = 0;
- scope.argnames.length = 0;
- }
- : noop;
- var stack = [];
- return {
- get : get,
- toString : get,
- indent : indent,
- in_directive : false,
- use_asm : null,
- active_scope : null,
- indentation : function() { return indentation; },
- current_width : function() { return current_col - indentation; },
- should_break : function() { return options.width && this.current_width() >= options.width; },
- has_parens : function() { return has_parens; },
- newline : newline,
- print : print,
- star : star,
- space : space,
- comma : comma,
- colon : colon,
- last : function() { return last; },
- semicolon : semicolon,
- force_semicolon : force_semicolon,
- to_utf8 : to_utf8,
- print_name : function(name) { print(make_name(name)); },
- print_string : function(str, quote, escape_directive) {
- var encoded = encode_string(str, quote);
- if (escape_directive === true && !encoded.includes("\\")) {
- // Insert semicolons to break directive prologue
- if (!OUTPUT.expectDirective()) {
- force_semicolon();
- }
- force_semicolon();
- }
- print(encoded);
- },
- print_template_string_chars: function(str) {
- var encoded = encode_string(str, "`").replace(/\${/g, "\\${");
- return print(encoded.substr(1, encoded.length - 2));
- },
- encode_string : encode_string,
- next_indent : next_indent,
- with_indent : with_indent,
- with_block : with_block,
- with_parens : with_parens,
- with_square : with_square,
- add_mapping : add_mapping,
- option : function(opt) { return options[opt]; },
- gc_scope,
- printed_comments: printed_comments,
- prepend_comments: readonly ? noop : prepend_comments,
- append_comments : readonly || comment_filter === return_false ? noop : append_comments,
- line : function() { return current_line; },
- col : function() { return current_col; },
- pos : function() { return current_pos; },
- push_node : function(node) { stack.push(node); },
- pop_node : function() { return stack.pop(); },
- parent : function(n) {
- return stack[stack.length - 2 - (n || 0)];
- }
- };
- }
- /* -----[ code generators ]----- */
- (function() {
- /* -----[ utils ]----- */
- function DEFPRINT(nodetype, generator) {
- nodetype.DEFMETHOD("_codegen", generator);
- }
- AST_Node.DEFMETHOD("print", function(output, force_parens) {
- var self = this, generator = self._codegen;
- if (self instanceof AST_Scope) {
- output.active_scope = self;
- } else if (!output.use_asm && self instanceof AST_Directive && self.value == "use asm") {
- output.use_asm = output.active_scope;
- }
- function doit() {
- output.prepend_comments(self);
- self.add_source_map(output);
- generator(self, output);
- output.append_comments(self);
- }
- output.push_node(self);
- if (force_parens || self.needs_parens(output)) {
- output.with_parens(doit);
- } else {
- doit();
- }
- output.pop_node();
- if (self === output.use_asm) {
- output.use_asm = null;
- }
- });
- AST_Node.DEFMETHOD("_print", AST_Node.prototype.print);
- AST_Node.DEFMETHOD("print_to_string", function(options) {
- var output = OutputStream(options);
- this.print(output);
- return output.get();
- });
- /* -----[ PARENTHESES ]----- */
- function PARENS(nodetype, func) {
- if (Array.isArray(nodetype)) {
- nodetype.forEach(function(nodetype) {
- PARENS(nodetype, func);
- });
- } else {
- nodetype.DEFMETHOD("needs_parens", func);
- }
- }
- PARENS(AST_Node, return_false);
- // a function expression needs parens around it when it's provably
- // the first token to appear in a statement.
- PARENS(AST_Function, function(output) {
- if (!output.has_parens() && first_in_statement(output)) {
- return true;
- }
- if (output.option("webkit")) {
- var p = output.parent();
- if (p instanceof AST_PropAccess && p.expression === this) {
- return true;
- }
- }
- if (output.option("wrap_iife")) {
- var p = output.parent();
- if (p instanceof AST_Call && p.expression === this) {
- return true;
- }
- }
- if (output.option("wrap_func_args")) {
- var p = output.parent();
- if (p instanceof AST_Call && p.args.includes(this)) {
- return true;
- }
- }
- return false;
- });
- PARENS(AST_Arrow, function(output) {
- var p = output.parent();
- if (
- output.option("wrap_func_args")
- && p instanceof AST_Call
- && p.args.includes(this)
- ) {
- return true;
- }
- return p instanceof AST_PropAccess && p.expression === this
- || p instanceof AST_Conditional && p.condition === this;
- });
- // same goes for an object literal (as in AST_Function), because
- // otherwise {...} would be interpreted as a block of code.
- PARENS(AST_Object, function(output) {
- return !output.has_parens() && first_in_statement(output);
- });
- PARENS(AST_ClassExpression, first_in_statement);
- PARENS(AST_Unary, function(output) {
- var p = output.parent();
- return p instanceof AST_PropAccess && p.expression === this
- || p instanceof AST_Call && p.expression === this
- || p instanceof AST_Binary
- && p.operator === "**"
- && this instanceof AST_UnaryPrefix
- && p.left === this
- && this.operator !== "++"
- && this.operator !== "--";
- });
- PARENS(AST_Await, function(output) {
- var p = output.parent();
- return p instanceof AST_PropAccess && p.expression === this
- || p instanceof AST_Call && p.expression === this
- || p instanceof AST_Binary && p.operator === "**" && p.left === this
- || output.option("safari10") && p instanceof AST_UnaryPrefix;
- });
- PARENS(AST_Sequence, function(output) {
- var p = output.parent();
- return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
- || p instanceof AST_Unary // !(foo, bar, baz)
- || p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8
- || p instanceof AST_VarDefLike // var a = (1, 2), b = a + a; ==> b == 4
- || p instanceof AST_PropAccess && this !== p.property // (1, {foo:2}).foo, (1, {foo:2})["foo"], not foo[1, 2]
- || p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
- || p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
- || p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
- * ==> 20 (side effect, set a := 10 and b := 20) */
- || p instanceof AST_Arrow // x => (x, x)
- || p instanceof AST_DefaultAssign // x => (x = (0, function(){}))
- || p instanceof AST_Expansion // [...(a, b)]
- || p instanceof AST_ForOf && this === p.object // for (e of (foo, bar)) {}
- || p instanceof AST_Yield // yield (foo, bar)
- || p instanceof AST_Export // export default (foo, bar)
- ;
- });
- PARENS(AST_Binary, function(output) {
- var p = output.parent();
- // (foo && bar)()
- if (p instanceof AST_Call && p.expression === this)
- return true;
- // typeof (foo && bar)
- if (p instanceof AST_Unary)
- return true;
- // (foo && bar)["prop"], (foo && bar).prop
- if (p instanceof AST_PropAccess && p.expression === this)
- return true;
- // this deals with precedence: 3 * (2 + 1)
- if (p instanceof AST_Binary) {
- const parent_op = p.operator;
- const op = this.operator;
- // It is forbidden for ?? to be used with || or && without parens.
- if (op === "??" && (parent_op === "||" || parent_op === "&&")) {
- return true;
- }
- if (parent_op === "??" && (op === "||" || op === "&&")) {
- return true;
- }
- const pp = PRECEDENCE[parent_op];
- const sp = PRECEDENCE[op];
- if (pp > sp
- || (pp == sp
- && (this === p.right || parent_op == "**"))) {
- return true;
- }
- }
- if (p instanceof AST_PrivateIn) {
- const op = this.operator;
- const pp = PRECEDENCE["in"];
- const sp = PRECEDENCE[op];
- if (pp > sp || (pp == sp && this === p.value)) {
- return true;
- }
- }
- });
- PARENS(AST_PrivateIn, function(output) {
- var p = output.parent();
- // (#x in this)()
- if (p instanceof AST_Call && p.expression === this) {
- return true;
- }
- // typeof (#x in this)
- if (p instanceof AST_Unary) {
- return true;
- }
- // (#x in this)["prop"], (#x in this).prop
- if (p instanceof AST_PropAccess && p.expression === this) {
- return true;
- }
- // same precedence as regular in operator
- if (p instanceof AST_Binary) {
- const parent_op = p.operator;
- const pp = PRECEDENCE[parent_op];
- const sp = PRECEDENCE["in"];
- if (pp > sp
- || (pp == sp
- && (this === p.right || parent_op == "**"))) {
- return true;
- }
- }
- // rules are the same as binary in, but the class differs
- if (p instanceof AST_PrivateIn && this === p.value) {
- return true;
- }
- });
- PARENS(AST_Yield, function(output) {
- var p = output.parent();
- // (yield 1) + (yield 2)
- // a = yield 3
- if (p instanceof AST_Binary && p.operator !== "=")
- return true;
- // (yield 1)()
- // new (yield 1)()
- if (p instanceof AST_Call && p.expression === this)
- return true;
- // (yield 1) ? yield 2 : yield 3
- if (p instanceof AST_Conditional && p.condition === this)
- return true;
- // -(yield 4)
- if (p instanceof AST_Unary)
- return true;
- // (yield x).foo
- // (yield x)['foo']
- if (p instanceof AST_PropAccess && p.expression === this)
- return true;
- });
- PARENS(AST_Chain, function(output) {
- var p = output.parent();
- if (!(p instanceof AST_Call || p instanceof AST_PropAccess)) return false;
- return p.expression === this;
- });
- PARENS(AST_PropAccess, function(output) {
- var p = output.parent();
- if (p instanceof AST_New && p.expression === this) {
- // i.e. new (foo.bar().baz)
- //
- // if there's one call into this subtree, then we need
- // parens around it too, otherwise the call will be
- // interpreted as passing the arguments to the upper New
- // expression.
- return walk(this, node => {
- if (node instanceof AST_Scope) return true;
- if (node instanceof AST_Call) {
- return walk_abort; // makes walk() return true.
- }
- });
- }
- });
- PARENS(AST_PrefixedTemplateString, function(output) {
- var p = output.parent();
- if (p instanceof AST_New && p.expression === this) {
- return true; // new (foo()`bar`)
- }
- });
- PARENS(AST_Call, function(output) {
- var p = output.parent(), p1;
- if (p instanceof AST_New && p.expression === this
- || p instanceof AST_Export && p.is_default && this.expression instanceof AST_Function)
- return true;
- // workaround for Safari bug.
- // https://bugs.webkit.org/show_bug.cgi?id=123506
- return this.expression instanceof AST_Function
- && p instanceof AST_PropAccess
- && p.expression === this
- && (p1 = output.parent(1)) instanceof AST_Assign
- && p1.left === p;
- });
- PARENS(AST_New, function(output) {
- var p = output.parent();
- if (this.args.length === 0
- && (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]()
- || p instanceof AST_Call && p.expression === this
- || p instanceof AST_PrefixedTemplateString && p.prefix === this)) // (new foo)(bar)
- return true;
- });
- PARENS(AST_Number, function(output) {
- var p = output.parent();
- if (p instanceof AST_PropAccess && p.expression === this) {
- var value = this.getValue();
- if (value < 0 || /^0/.test(make_num(value))) {
- return true;
- }
- }
- });
- PARENS(AST_BigInt, function(output) {
- var p = output.parent();
- if (p instanceof AST_PropAccess && p.expression === this) {
- var value = this.getValue();
- if (value.startsWith("-")) {
- return true;
- }
- }
- });
- PARENS([ AST_Assign, AST_Conditional ], function(output) {
- var p = output.parent();
- // !(a = false) → true
- if (p instanceof AST_Unary)
- return true;
- // 1 + (a = 2) + 3 → 6, side effect setting a = 2
- if (p instanceof AST_Binary && !(p instanceof AST_Assign))
- return true;
- // (a = func)() —or— new (a = Object)()
- if (p instanceof AST_Call && p.expression === this)
- return true;
- // (a = foo) ? bar : baz
- if (p instanceof AST_Conditional && p.condition === this)
- return true;
- // (a = foo)["prop"] —or— (a = foo).prop
- if (p instanceof AST_PropAccess && p.expression === this)
- return true;
- // ({a, b} = {a: 1, b: 2}), a destructuring assignment
- if (this instanceof AST_Assign && this.left instanceof AST_Destructuring && this.left.is_array === false)
- return true;
- });
- /* -----[ PRINTERS ]----- */
- DEFPRINT(AST_Directive, function(self, output) {
- output.print_string(self.value, self.quote);
- output.semicolon();
- });
- DEFPRINT(AST_Expansion, function (self, output) {
- output.print("...");
- self.expression.print(output);
- });
- DEFPRINT(AST_Destructuring, function (self, output) {
- output.print(self.is_array ? "[" : "{");
- var len = self.names.length;
- self.names.forEach(function (name, i) {
- if (i > 0) output.comma();
- name.print(output);
- // If the final element is a hole, we need to make sure it
- // doesn't look like a trailing comma, by inserting an actual
- // trailing comma.
- if (i == len - 1 && name instanceof AST_Hole) output.comma();
- });
- output.print(self.is_array ? "]" : "}");
- });
- DEFPRINT(AST_Debugger, function(self, output) {
- output.print("debugger");
- output.semicolon();
- });
- /* -----[ statements ]----- */
- function display_body(body, is_toplevel, output, allow_directives) {
- var last = body.length - 1;
- output.in_directive = allow_directives;
- body.forEach(function(stmt, i) {
- if (output.in_directive === true && !(stmt instanceof AST_Directive ||
- stmt instanceof AST_EmptyStatement ||
- (stmt instanceof AST_SimpleStatement && stmt.body instanceof AST_String)
- )) {
- output.in_directive = false;
- }
- if (!(stmt instanceof AST_EmptyStatement)) {
- output.indent();
- stmt.print(output);
- if (!(i == last && is_toplevel)) {
- output.newline();
- if (is_toplevel) output.newline();
- }
- }
- if (output.in_directive === true &&
- stmt instanceof AST_SimpleStatement &&
- stmt.body instanceof AST_String
- ) {
- output.in_directive = false;
- }
- });
- output.in_directive = false;
- }
- AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output) {
- print_maybe_braced_body(this.body, output);
- });
- DEFPRINT(AST_Statement, function(self, output) {
- self.body.print(output);
- output.semicolon();
- });
- DEFPRINT(AST_Toplevel, function(self, output) {
- display_body(self.body, true, output, true);
- output.print("");
- });
- DEFPRINT(AST_LabeledStatement, function(self, output) {
- self.label.print(output);
- output.colon();
- self.body.print(output);
- });
- DEFPRINT(AST_SimpleStatement, function(self, output) {
- self.body.print(output);
- output.semicolon();
- });
- function print_braced_empty(self, output) {
- output.print("{");
- output.with_indent(output.next_indent(), function() {
- output.append_comments(self, true);
- });
- output.add_mapping(self.end);
- output.print("}");
- }
- function print_braced(self, output, allow_directives) {
- if (self.body.length > 0) {
- output.with_block(function() {
- display_body(self.body, false, output, allow_directives);
- output.add_mapping(self.end);
- });
- } else print_braced_empty(self, output);
- }
- DEFPRINT(AST_BlockStatement, function(self, output) {
- print_braced(self, output);
- });
- DEFPRINT(AST_EmptyStatement, function(self, output) {
- output.semicolon();
- });
- DEFPRINT(AST_Do, function(self, output) {
- output.print("do");
- output.space();
- make_block(self.body, output);
- output.space();
- output.print("while");
- output.space();
- output.with_parens(function() {
- self.condition.print(output);
- });
- output.semicolon();
- });
- DEFPRINT(AST_While, function(self, output) {
- output.print("while");
- output.space();
- output.with_parens(function() {
- self.condition.print(output);
- });
- output.space();
- self._do_print_body(output);
- });
- DEFPRINT(AST_For, function(self, output) {
- output.print("for");
- output.space();
- output.with_parens(function() {
- if (self.init) {
- if (self.init instanceof AST_DefinitionsLike) {
- self.init.print(output);
- } else {
- parenthesize_for_noin(self.init, output, true);
- }
- output.print(";");
- output.space();
- } else {
- output.print(";");
- }
- if (self.condition) {
- self.condition.print(output);
- output.print(";");
- output.space();
- } else {
- output.print(";");
- }
- if (self.step) {
- self.step.print(output);
- }
- });
- output.space();
- self._do_print_body(output);
- });
- DEFPRINT(AST_ForIn, function(self, output) {
- output.print("for");
- if (self.await) {
- output.space();
- output.print("await");
- }
- output.space();
- output.with_parens(function() {
- self.init.print(output);
- output.space();
- output.print(self instanceof AST_ForOf ? "of" : "in");
- output.space();
- self.object.print(output);
- });
- output.space();
- self._do_print_body(output);
- });
- DEFPRINT(AST_With, function(self, output) {
- output.print("with");
- output.space();
- output.with_parens(function() {
- self.expression.print(output);
- });
- output.space();
- self._do_print_body(output);
- });
- /* -----[ functions ]----- */
- AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword) {
- var self = this;
- if (!nokeyword) {
- if (self.async) {
- output.print("async");
- output.space();
- }
- output.print("function");
- if (self.is_generator) {
- output.star();
- }
- if (self.name) {
- output.space();
- }
- }
- if (self.name instanceof AST_Symbol) {
- self.name.print(output);
- } else if (nokeyword && self.name instanceof AST_Node) {
- output.with_square(function() {
- self.name.print(output); // Computed method name
- });
- }
- output.with_parens(function() {
- self.argnames.forEach(function(arg, i) {
- if (i) output.comma();
- arg.print(output);
- });
- });
- output.space();
- print_braced(self, output, true);
- });
- DEFPRINT(AST_Lambda, function(self, output) {
- self._do_print(output);
- output.gc_scope(self);
- });
- DEFPRINT(AST_PrefixedTemplateString, function(self, output) {
- var tag = self.prefix;
- var parenthesize_tag = tag instanceof AST_Lambda
- || tag instanceof AST_Binary
- || tag instanceof AST_Conditional
- || tag instanceof AST_Sequence
- || tag instanceof AST_Unary
- || tag instanceof AST_Dot && tag.expression instanceof AST_Object;
- if (parenthesize_tag) output.print("(");
- self.prefix.print(output);
- if (parenthesize_tag) output.print(")");
- self.template_string.print(output);
- });
- DEFPRINT(AST_TemplateString, function(self, output) {
- var is_tagged = output.parent() instanceof AST_PrefixedTemplateString;
- output.print("`");
- for (var i = 0; i < self.segments.length; i++) {
- if (!(self.segments[i] instanceof AST_TemplateSegment)) {
- output.print("${");
- self.segments[i].print(output);
- output.print("}");
- } else if (is_tagged) {
- output.print(self.segments[i].raw);
- } else {
- output.print_template_string_chars(self.segments[i].value);
- }
- }
- output.print("`");
- });
- DEFPRINT(AST_TemplateSegment, function(self, output) {
- output.print_template_string_chars(self.value);
- });
- AST_Arrow.DEFMETHOD("_do_print", function(output) {
- var self = this;
- var parent = output.parent();
- var needs_parens = (parent instanceof AST_Binary &&
- !(parent instanceof AST_Assign) &&
- !(parent instanceof AST_DefaultAssign)) ||
- parent instanceof AST_Unary ||
- (parent instanceof AST_Call && self === parent.expression);
- if (needs_parens) { output.print("("); }
- if (self.async) {
- output.print("async");
- output.space();
- }
- if (self.argnames.length === 1 && self.argnames[0] instanceof AST_Symbol) {
- self.argnames[0].print(output);
- } else {
- output.with_parens(function() {
- self.argnames.forEach(function(arg, i) {
- if (i) output.comma();
- arg.print(output);
- });
- });
- }
- output.space();
- output.print("=>");
- output.space();
- const first_statement = self.body[0];
- if (
- self.body.length === 1
- && first_statement instanceof AST_Return
- ) {
- const returned = first_statement.value;
- if (!returned) {
- output.print("{}");
- } else if (left_is_object(returned)) {
- output.print("(");
- returned.print(output);
- output.print(")");
- } else {
- returned.print(output);
- }
- } else {
- print_braced(self, output);
- }
- if (needs_parens) { output.print(")"); }
- output.gc_scope(self);
- });
- /* -----[ exits ]----- */
- AST_Exit.DEFMETHOD("_do_print", function(output, kind) {
- output.print(kind);
- if (this.value) {
- output.space();
- const comments = this.value.start.comments_before;
- if (comments && comments.length && !output.printed_comments.has(comments)) {
- output.print("(");
- this.value.print(output);
- output.print(")");
- } else {
- this.value.print(output);
- }
- }
- output.semicolon();
- });
- DEFPRINT(AST_Return, function(self, output) {
- self._do_print(output, "return");
- });
- DEFPRINT(AST_Throw, function(self, output) {
- self._do_print(output, "throw");
- });
- /* -----[ yield ]----- */
- DEFPRINT(AST_Yield, function(self, output) {
- var star = self.is_star ? "*" : "";
- output.print("yield" + star);
- if (self.expression) {
- output.space();
- self.expression.print(output);
- }
- });
- DEFPRINT(AST_Await, function(self, output) {
- output.print("await");
- output.space();
- var e = self.expression;
- var parens = !(
- e instanceof AST_Call
- || e instanceof AST_SymbolRef
- || e instanceof AST_PropAccess
- || e instanceof AST_Unary
- || e instanceof AST_Constant
- || e instanceof AST_Await
- || e instanceof AST_Object
- );
- if (parens) output.print("(");
- self.expression.print(output);
- if (parens) output.print(")");
- });
- /* -----[ loop control ]----- */
- AST_LoopControl.DEFMETHOD("_do_print", function(output, kind) {
- output.print(kind);
- if (this.label) {
- output.space();
- this.label.print(output);
- }
- output.semicolon();
- });
- DEFPRINT(AST_Break, function(self, output) {
- self._do_print(output, "break");
- });
- DEFPRINT(AST_Continue, function(self, output) {
- self._do_print(output, "continue");
- });
- /* -----[ if ]----- */
- function make_then(self, output) {
- var b = self.body;
- if (output.option("braces")
- || output.option("ie8") && b instanceof AST_Do)
- return make_block(b, output);
- // The squeezer replaces "block"-s that contain only a single
- // statement with the statement itself; technically, the AST
- // is correct, but this can create problems when we output an
- // IF having an ELSE clause where the THEN clause ends in an
- // IF *without* an ELSE block (then the outer ELSE would refer
- // to the inner IF). This function checks for this case and
- // adds the block braces if needed.
- if (!b) return output.force_semicolon();
- while (true) {
- if (b instanceof AST_If) {
- if (!b.alternative) {
- make_block(self.body, output);
- return;
- }
- b = b.alternative;
- } else if (b instanceof AST_StatementWithBody) {
- b = b.body;
- } else break;
- }
- print_maybe_braced_body(self.body, output);
- }
- DEFPRINT(AST_If, function(self, output) {
- output.print("if");
- output.space();
- output.with_parens(function() {
- self.condition.print(output);
- });
- output.space();
- if (self.alternative) {
- make_then(self, output);
- output.space();
- output.print("else");
- output.space();
- if (self.alternative instanceof AST_If)
- self.alternative.print(output);
- else
- print_maybe_braced_body(self.alternative, output);
- } else {
- self._do_print_body(output);
- }
- });
- /* -----[ switch ]----- */
- DEFPRINT(AST_Switch, function(self, output) {
- output.print("switch");
- output.space();
- output.with_parens(function() {
- self.expression.print(output);
- });
- output.space();
- var last = self.body.length - 1;
- if (last < 0) print_braced_empty(self, output);
- else output.with_block(function() {
- self.body.forEach(function(branch, i) {
- output.indent(true);
- branch.print(output);
- if (i < last && branch.body.length > 0)
- output.newline();
- });
- });
- });
- AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output) {
- output.newline();
- this.body.forEach(function(stmt) {
- output.indent();
- stmt.print(output);
- output.newline();
- });
- });
- DEFPRINT(AST_Default, function(self, output) {
- output.print("default:");
- self._do_print_body(output);
- });
- DEFPRINT(AST_Case, function(self, output) {
- output.print("case");
- output.space();
- self.expression.print(output);
- output.print(":");
- self._do_print_body(output);
- });
- /* -----[ exceptions ]----- */
- DEFPRINT(AST_Try, function(self, output) {
- output.print("try");
- output.space();
- self.body.print(output);
- if (self.bcatch) {
- output.space();
- self.bcatch.print(output);
- }
- if (self.bfinally) {
- output.space();
- self.bfinally.print(output);
- }
- });
- DEFPRINT(AST_TryBlock, function(self, output) {
- print_braced(self, output);
- });
- DEFPRINT(AST_Catch, function(self, output) {
- output.print("catch");
- if (self.argname) {
- output.space();
- output.with_parens(function() {
- self.argname.print(output);
- });
- }
- output.space();
- print_braced(self, output);
- });
- DEFPRINT(AST_Finally, function(self, output) {
- output.print("finally");
- output.space();
- print_braced(self, output);
- });
- /* -----[ var/const ]----- */
- AST_DefinitionsLike.DEFMETHOD("_do_print", function(output, kind) {
- output.print(kind);
- output.space();
- this.definitions.forEach(function(def, i) {
- if (i) output.comma();
- def.print(output);
- });
- var p = output.parent();
- var in_for = p instanceof AST_For || p instanceof AST_ForIn;
- var output_semicolon = !in_for || p && p.init !== this;
- if (output_semicolon)
- output.semicolon();
- });
- DEFPRINT(AST_Let, function(self, output) {
- self._do_print(output, "let");
- });
- DEFPRINT(AST_Var, function(self, output) {
- self._do_print(output, "var");
- });
- DEFPRINT(AST_Const, function(self, output) {
- self._do_print(output, "const");
- });
- DEFPRINT(AST_Using, function(self, output) {
- self._do_print(output, self.await ? "await using" : "using");
- });
- DEFPRINT(AST_Import, function(self, output) {
- output.print("import");
- output.space();
- if (self.phase) {
- output.print(self.phase);
- output.space();
- }
- if (self.imported_name) {
- self.imported_name.print(output);
- }
- if (self.imported_name && self.imported_names) {
- output.print(",");
- output.space();
- }
- if (self.imported_names) {
- if (self.imported_names.length === 1 &&
- self.imported_names[0].foreign_name.name === "*" &&
- !self.imported_names[0].foreign_name.quote) {
- self.imported_names[0].print(output);
- } else {
- output.print("{");
- self.imported_names.forEach(function (name_import, i) {
- output.space();
- name_import.print(output);
- if (i < self.imported_names.length - 1) {
- output.print(",");
- }
- });
- output.space();
- output.print("}");
- }
- }
- if (self.imported_name || self.imported_names) {
- output.space();
- output.print("from");
- output.space();
- }
- self.module_name.print(output);
- if (self.attributes) {
- output.print("with");
- self.attributes.print(output);
- }
- output.semicolon();
- });
- DEFPRINT(AST_ImportMeta, function(self, output) {
- output.print("import.meta");
- });
- DEFPRINT(AST_DynamicImport, function(self, output) {
- if (self.phase) output.print("import." + self.phase);
- else output.print("import");
- output.with_parens(function() {
- self.args.forEach(function(arg, i) {
- if (i) output.comma();
- arg.print(output);
- });
- });
- });
- DEFPRINT(AST_NameMapping, function(self, output) {
- var is_import = output.parent() instanceof AST_Import;
- var definition = self.name.definition();
- var foreign_name = self.foreign_name;
- var names_are_different =
- (definition && definition.mangled_name || self.name.name) !==
- foreign_name.name;
- if (!names_are_different &&
- foreign_name.name === "*" &&
- !!foreign_name.quote != !!self.name.quote) {
- // export * as "*"
- names_are_different = true;
- }
- var foreign_name_is_name = !foreign_name.quote;
- if (names_are_different) {
- if (is_import) {
- if (foreign_name_is_name) {
- output.print(foreign_name.name);
- } else {
- output.print_string(foreign_name.name, foreign_name.quote);
- }
- } else {
- if (!self.name.quote) {
- self.name.print(output);
- } else {
- output.print_string(self.name.name, self.name.quote);
- }
-
- }
- output.space();
- output.print("as");
- output.space();
- if (is_import) {
- self.name.print(output);
- } else {
- if (foreign_name_is_name) {
- output.print(foreign_name.name);
- } else {
- output.print_string(foreign_name.name, foreign_name.quote);
- }
- }
- } else {
- if (!self.name.quote) {
- self.name.print(output);
- } else {
- output.print_string(self.name.name, self.name.quote);
- }
- }
- });
- DEFPRINT(AST_Export, function(self, output) {
- output.print("export");
- output.space();
- if (self.is_default) {
- output.print("default");
- output.space();
- }
- if (self.exported_names) {
- if (self.exported_names.length === 1 &&
- self.exported_names[0].name.name === "*" &&
- !self.exported_names[0].name.quote) {
- self.exported_names[0].print(output);
- } else {
- output.print("{");
- self.exported_names.forEach(function(name_export, i) {
- output.space();
- name_export.print(output);
- if (i < self.exported_names.length - 1) {
- output.print(",");
- }
- });
- output.space();
- output.print("}");
- }
- } else if (self.exported_value) {
- self.exported_value.print(output);
- } else if (self.exported_definition) {
- self.exported_definition.print(output);
- if (self.exported_definition instanceof AST_Definitions) return;
- }
- if (self.module_name) {
- output.space();
- output.print("from");
- output.space();
- self.module_name.print(output);
- }
- if (self.attributes) {
- output.print("with");
- self.attributes.print(output);
- }
- if (self.exported_value
- && !(self.exported_value instanceof AST_Defun ||
- self.exported_value instanceof AST_Function ||
- self.exported_value instanceof AST_Class)
- || self.module_name
- || self.exported_names
- ) {
- output.semicolon();
- }
- });
- function parenthesize_for_noin(node, output, noin) {
- var parens = false;
- // need to take some precautions here:
- // https://github.com/mishoo/UglifyJS2/issues/60
- if (noin) {
- parens = walk(node, node => {
- // Don't go into scopes -- except arrow functions:
- // https://github.com/terser/terser/issues/1019#issuecomment-877642607
- if (node instanceof AST_Scope && !(node instanceof AST_Arrow)) {
- return true;
- }
- if (
- node instanceof AST_Binary && node.operator == "in"
- || node instanceof AST_PrivateIn
- ) {
- return walk_abort; // makes walk() return true
- }
- });
- }
- node.print(output, parens);
- }
- DEFPRINT(AST_VarDefLike, function(self, output) {
- self.name.print(output);
- if (self.value) {
- output.space();
- output.print("=");
- output.space();
- var p = output.parent(1);
- var noin = p instanceof AST_For || p instanceof AST_ForIn;
- parenthesize_for_noin(self.value, output, noin);
- }
- });
- /* -----[ other expressions ]----- */
- DEFPRINT(AST_Call, function(self, output) {
- self.expression.print(output);
- if (self instanceof AST_New && self.args.length === 0)
- return;
- if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
- output.add_mapping(self.start);
- }
- if (self.optional) output.print("?.");
- output.with_parens(function() {
- self.args.forEach(function(expr, i) {
- if (i) output.comma();
- expr.print(output);
- });
- });
- });
- DEFPRINT(AST_New, function(self, output) {
- output.print("new");
- output.space();
- AST_Call.prototype._codegen(self, output);
- });
- AST_Sequence.DEFMETHOD("_do_print", function(output) {
- this.expressions.forEach(function(node, index) {
- if (index > 0) {
- output.comma();
- if (output.should_break()) {
- output.newline();
- output.indent();
- }
- }
- node.print(output);
- });
- });
- DEFPRINT(AST_Sequence, function(self, output) {
- self._do_print(output);
- // var p = output.parent();
- // if (p instanceof AST_Statement) {
- // output.with_indent(output.next_indent(), function(){
- // self._do_print(output);
- // });
- // } else {
- // self._do_print(output);
- // }
- });
- DEFPRINT(AST_Dot, function(self, output) {
- var expr = self.expression;
- expr.print(output);
- var prop = self.property;
- var print_computed = ALL_RESERVED_WORDS.has(prop)
- ? output.option("ie8")
- : !is_identifier_string(
- prop,
- output.option("ecma") >= 2015 && !output.option("safari10")
- );
- if (self.optional) output.print("?.");
- if (print_computed) {
- output.print("[");
- output.add_mapping(self.end);
- output.print_string(prop);
- output.print("]");
- } else {
- if (expr instanceof AST_Number && expr.getValue() >= 0) {
- if (!/[xa-f.)]/i.test(output.last())) {
- output.print(".");
- }
- }
- if (!self.optional) output.print(".");
- // the name after dot would be mapped about here.
- output.add_mapping(self.end);
- output.print_name(prop);
- }
- });
- DEFPRINT(AST_DotHash, function(self, output) {
- var expr = self.expression;
- expr.print(output);
- var prop = self.property;
- if (self.optional) output.print("?");
- output.print(".#");
- output.add_mapping(self.end);
- output.print_name(prop);
- });
- DEFPRINT(AST_Sub, function(self, output) {
- self.expression.print(output);
- if (self.optional) output.print("?.");
- output.print("[");
- self.property.print(output);
- output.print("]");
- });
- DEFPRINT(AST_Chain, function(self, output) {
- self.expression.print(output);
- });
- DEFPRINT(AST_UnaryPrefix, function(self, output) {
- var op = self.operator;
- if (op === "--" && output.last().endsWith("!")) {
- // avoid printing "<!--"
- output.print(" ");
- }
- output.print(op);
- if (/^[a-z]/i.test(op)
- || (/[+-]$/.test(op)
- && self.expression instanceof AST_UnaryPrefix
- && /^[+-]/.test(self.expression.operator))) {
- output.space();
- }
- self.expression.print(output);
- });
- DEFPRINT(AST_UnaryPostfix, function(self, output) {
- self.expression.print(output);
- output.print(self.operator);
- });
- DEFPRINT(AST_Binary, function(self, output) {
- var op = self.operator;
- self.left.print(output);
- if (op[0] == ">" /* ">>" ">>>" ">" ">=" */
- && output.last().endsWith("--")) {
- // space is mandatory to avoid outputting -->
- output.print(" ");
- } else {
- // the space is optional depending on "beautify"
- output.space();
- }
- output.print(op);
- output.space();
- self.right.print(output);
- });
- DEFPRINT(AST_Conditional, function(self, output) {
- self.condition.print(output);
- output.space();
- output.print("?");
- output.space();
- self.consequent.print(output);
- output.space();
- output.colon();
- self.alternative.print(output);
- });
- /* -----[ literals ]----- */
- DEFPRINT(AST_Array, function(self, output) {
- output.with_square(function() {
- var a = self.elements, len = a.length;
- if (len > 0) output.space();
- a.forEach(function(exp, i) {
- if (i) output.comma();
- exp.print(output);
- // If the final element is a hole, we need to make sure it
- // doesn't look like a trailing comma, by inserting an actual
- // trailing comma.
- if (i === len - 1 && exp instanceof AST_Hole)
- output.comma();
- });
- if (len > 0) output.space();
- });
- });
- DEFPRINT(AST_Object, function(self, output) {
- if (self.properties.length > 0) output.with_block(function() {
- self.properties.forEach(function(prop, i) {
- if (i) {
- output.print(",");
- output.newline();
- }
- output.indent();
- prop.print(output);
- });
- output.newline();
- });
- else print_braced_empty(self, output);
- });
- DEFPRINT(AST_Class, function(self, output) {
- output.print("class");
- output.space();
- if (self.name) {
- self.name.print(output);
- output.space();
- }
- if (self.extends) {
- var parens = (
- !(self.extends instanceof AST_SymbolRef)
- && !(self.extends instanceof AST_PropAccess)
- && !(self.extends instanceof AST_ClassExpression)
- && !(self.extends instanceof AST_Function)
- );
- output.print("extends");
- if (parens) {
- output.print("(");
- } else {
- output.space();
- }
- self.extends.print(output);
- if (parens) {
- output.print(")");
- } else {
- output.space();
- }
- }
- if (self.properties.length > 0) output.with_block(function() {
- self.properties.forEach(function(prop, i) {
- if (i) {
- output.newline();
- }
- output.indent();
- prop.print(output);
- });
- output.newline();
- });
- else output.print("{}");
- });
- DEFPRINT(AST_NewTarget, function(self, output) {
- output.print("new.target");
- });
- /** Prints a prop name. Returns whether it can be used as a shorthand. */
- function print_property_name(key, quote, output) {
- if (output.option("quote_keys")) {
- output.print_string(key);
- return false;
- }
- if ("" + +key == key && key >= 0) {
- if (output.option("keep_numbers")) {
- output.print(key);
- return false;
- }
- output.print(make_num(key));
- return false;
- }
- var print_string = ALL_RESERVED_WORDS.has(key)
- ? output.option("ie8")
- : (
- output.option("ecma") < 2015 || output.option("safari10")
- ? !is_basic_identifier_string(key)
- : !is_identifier_string(key, true)
- );
- if (print_string || (quote && output.option("keep_quoted_props"))) {
- output.print_string(key, quote);
- return false;
- }
- output.print_name(key);
- return true;
- }
- DEFPRINT(AST_ObjectKeyVal, function(self, output) {
- function get_name(self) {
- var def = self.definition();
- return def ? def.mangled_name || def.name : self.name;
- }
- const try_shorthand = output.option("shorthand") && !(self.key instanceof AST_Node);
- if (
- try_shorthand
- && self.value instanceof AST_Symbol
- && get_name(self.value) === self.key
- && !ALL_RESERVED_WORDS.has(self.key)
- ) {
- const was_shorthand = print_property_name(self.key, self.quote, output);
- if (!was_shorthand) {
- output.colon();
- self.value.print(output);
- }
- } else if (
- try_shorthand
- && self.value instanceof AST_DefaultAssign
- && self.value.left instanceof AST_Symbol
- && get_name(self.value.left) === self.key
- ) {
- const was_shorthand = print_property_name(self.key, self.quote, output);
- if (!was_shorthand) {
- output.colon();
- self.value.left.print(output);
- }
- output.space();
- output.print("=");
- output.space();
- self.value.right.print(output);
- } else {
- if (!(self.key instanceof AST_Node)) {
- print_property_name(self.key, self.quote, output);
- } else {
- output.with_square(function() {
- self.key.print(output);
- });
- }
- output.colon();
- self.value.print(output);
- }
- });
- DEFPRINT(AST_ClassPrivateProperty, (self, output) => {
- if (self.static) {
- output.print("static");
- output.space();
- }
- output.print("#");
-
- print_property_name(self.key.name, undefined, output);
- if (self.value) {
- output.print("=");
- self.value.print(output);
- }
- output.semicolon();
- });
- DEFPRINT(AST_ClassProperty, (self, output) => {
- if (self.static) {
- output.print("static");
- output.space();
- }
- if (self.key instanceof AST_SymbolClassProperty) {
- print_property_name(self.key.name, self.quote, output);
- } else {
- output.print("[");
- self.key.print(output);
- output.print("]");
- }
- if (self.value) {
- output.print("=");
- self.value.print(output);
- }
- output.semicolon();
- });
- AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, is_private, output) {
- var self = this;
- if (self.static) {
- output.print("static");
- output.space();
- }
- if (type) {
- output.print(type);
- output.space();
- }
- if (self.key instanceof AST_SymbolMethod) {
- if (is_private) output.print("#");
- print_property_name(self.key.name, self.quote, output);
- self.key.add_source_map(output);
- } else {
- output.with_square(function() {
- self.key.print(output);
- });
- }
- self.value._do_print(output, true);
- });
- DEFPRINT(AST_ObjectSetter, function(self, output) {
- self._print_getter_setter("set", false, output);
- });
- DEFPRINT(AST_ObjectGetter, function(self, output) {
- self._print_getter_setter("get", false, output);
- });
- DEFPRINT(AST_PrivateSetter, function(self, output) {
- self._print_getter_setter("set", true, output);
- });
- DEFPRINT(AST_PrivateGetter, function(self, output) {
- self._print_getter_setter("get", true, output);
- });
- DEFPRINT(AST_ConciseMethod, function(self, output) {
- var type;
- if (self.value.is_generator && self.value.async) {
- type = "async*";
- } else if (self.value.is_generator) {
- type = "*";
- } else if (self.value.async) {
- type = "async";
- }
- self._print_getter_setter(type, false, output);
- });
- DEFPRINT(AST_PrivateMethod, function(self, output) {
- var type;
- if (self.value.is_generator && self.value.async) {
- type = "async*";
- } else if (self.value.is_generator) {
- type = "*";
- } else if (self.value.async) {
- type = "async";
- }
- self._print_getter_setter(type, true, output);
- });
- DEFPRINT(AST_PrivateIn, function(self, output) {
- self.key.print(output);
- output.space();
- output.print("in");
- output.space();
- self.value.print(output);
- });
- DEFPRINT(AST_SymbolPrivateProperty, function(self, output) {
- output.print("#" + self.name);
- });
- DEFPRINT(AST_ClassStaticBlock, function (self, output) {
- output.print("static");
- output.space();
- print_braced(self, output);
- });
- AST_Symbol.DEFMETHOD("_do_print", function(output) {
- var def = this.definition();
- output.print_name(def ? def.mangled_name || def.name : this.name);
- });
- DEFPRINT(AST_Symbol, function (self, output) {
- self._do_print(output);
- });
- DEFPRINT(AST_Hole, noop);
- DEFPRINT(AST_This, function(self, output) {
- output.print("this");
- });
- DEFPRINT(AST_Super, function(self, output) {
- output.print("super");
- });
- DEFPRINT(AST_Constant, function(self, output) {
- output.print(self.getValue());
- });
- DEFPRINT(AST_String, function(self, output) {
- output.print_string(self.getValue(), self.quote, output.in_directive);
- });
- DEFPRINT(AST_Number, function(self, output) {
- if ((output.option("keep_numbers") || output.use_asm) && self.raw) {
- output.print(self.raw);
- } else {
- output.print(make_num(self.getValue()));
- }
- });
- DEFPRINT(AST_BigInt, function(self, output) {
- if (output.option("keep_numbers") && self.raw) {
- output.print(self.raw);
- } else {
- output.print(self.getValue() + "n");
- }
- });
- const r_slash_script = /(<\s*\/\s*script)/i;
- const r_starts_with_script = /^\s*script/i;
- const slash_script_replace = (_, $1) => $1.replace("/", "\\/");
- DEFPRINT(AST_RegExp, function(self, output) {
- let { source, flags } = self.getValue();
- source = regexp_source_fix(source);
- flags = flags ? sort_regexp_flags(flags) : "";
- // Avoid outputting end of script tag
- source = source.replace(r_slash_script, slash_script_replace);
- if (r_starts_with_script.test(source) && output.last().endsWith("<")) {
- output.print(" ");
- }
- output.print(output.to_utf8(`/${source}/${flags}`, false, true));
- const parent = output.parent();
- if (
- parent instanceof AST_Binary
- && /^\w/.test(parent.operator)
- && parent.left === self
- ) {
- output.print(" ");
- }
- });
- /** if, for, while, may or may not have braces surrounding its body */
- function print_maybe_braced_body(stat, output) {
- if (output.option("braces")) {
- make_block(stat, output);
- } else {
- if (!stat || stat instanceof AST_EmptyStatement)
- output.force_semicolon();
- else if ((stat instanceof AST_DefinitionsLike && !(stat instanceof AST_Var)) || stat instanceof AST_Class)
- make_block(stat, output);
- else
- stat.print(output);
- }
- }
- function best_of(a) {
- var best = a[0], len = best.length;
- for (var i = 1; i < a.length; ++i) {
- if (a[i].length < len) {
- best = a[i];
- len = best.length;
- }
- }
- return best;
- }
- function make_num(num) {
- var str = num.toString(10).replace(/^0\./, ".").replace("e+", "e");
- var candidates = [ str ];
- if (Math.floor(num) === num) {
- if (num < 0) {
- candidates.push("-0x" + (-num).toString(16).toLowerCase());
- } else {
- candidates.push("0x" + num.toString(16).toLowerCase());
- }
- }
- var match, len, digits;
- if (match = /^\.0+/.exec(str)) {
- len = match[0].length;
- digits = str.slice(len);
- candidates.push(digits + "e-" + (digits.length + len - 1));
- } else if (match = /0+$/.exec(str)) {
- len = match[0].length;
- candidates.push(str.slice(0, -len) + "e" + len);
- } else if (match = /^(\d)\.(\d+)e(-?\d+)$/.exec(str)) {
- candidates.push(match[1] + match[2] + "e" + (match[3] - match[2].length));
- }
- return best_of(candidates);
- }
- function make_block(stmt, output) {
- if (!stmt || stmt instanceof AST_EmptyStatement)
- output.print("{}");
- else if (stmt instanceof AST_BlockStatement)
- stmt.print(output);
- else output.with_block(function() {
- output.indent();
- stmt.print(output);
- output.newline();
- });
- }
- /* -----[ source map generators ]----- */
- function DEFMAP(nodetype, generator) {
- nodetype.forEach(function(nodetype) {
- nodetype.DEFMETHOD("add_source_map", generator);
- });
- }
- DEFMAP([
- // We could easily add info for ALL nodes, but it seems to me that
- // would be quite wasteful, hence this noop in the base class.
- AST_Node,
- // since the label symbol will mark it
- AST_LabeledStatement,
- AST_Toplevel,
- ], noop);
- // XXX: I'm not exactly sure if we need it for all of these nodes,
- // or if we should add even more.
- DEFMAP([
- AST_Array,
- AST_BlockStatement,
- AST_Catch,
- AST_Class,
- AST_Constant,
- AST_Debugger,
- AST_DefinitionsLike,
- AST_Directive,
- AST_Finally,
- AST_Jump,
- AST_Lambda,
- AST_New,
- AST_Object,
- AST_StatementWithBody,
- AST_Symbol,
- AST_Switch,
- AST_SwitchBranch,
- AST_TemplateString,
- AST_TemplateSegment,
- AST_Try,
- ], function(output) {
- output.add_mapping(this.start);
- });
- DEFMAP([
- AST_ObjectGetter,
- AST_ObjectSetter,
- AST_PrivateGetter,
- AST_PrivateSetter,
- AST_ConciseMethod,
- AST_PrivateMethod,
- ], function(output) {
- output.add_mapping(this.start, false /*name handled below*/);
- });
- DEFMAP([
- AST_SymbolMethod,
- AST_SymbolPrivateProperty
- ], function(output) {
- const tok_type = this.end && this.end.type;
- if (tok_type === "name" || tok_type === "privatename") {
- output.add_mapping(this.end, this.name);
- } else {
- output.add_mapping(this.end);
- }
- });
- DEFMAP([ AST_ObjectProperty ], function(output) {
- output.add_mapping(this.start, this.key);
- });
- })();
- const shallow_cmp = (node1, node2) => {
- return (
- node1 === null && node2 === null
- || node1.TYPE === node2.TYPE && node1.shallow_cmp(node2)
- );
- };
- const equivalent_to = (tree1, tree2) => {
- if (!shallow_cmp(tree1, tree2)) return false;
- const walk_1_state = [tree1];
- const walk_2_state = [tree2];
- const walk_1_push = walk_1_state.push.bind(walk_1_state);
- const walk_2_push = walk_2_state.push.bind(walk_2_state);
- while (walk_1_state.length && walk_2_state.length) {
- const node_1 = walk_1_state.pop();
- const node_2 = walk_2_state.pop();
- if (!shallow_cmp(node_1, node_2)) return false;
- node_1._children_backwards(walk_1_push);
- node_2._children_backwards(walk_2_push);
- if (walk_1_state.length !== walk_2_state.length) {
- // Different number of children
- return false;
- }
- }
- return walk_1_state.length == 0 && walk_2_state.length == 0;
- };
- const pass_through = () => true;
- AST_Node.prototype.shallow_cmp = function () {
- throw new Error("did not find a shallow_cmp function for " + this.constructor.name);
- };
- AST_Debugger.prototype.shallow_cmp = pass_through;
- AST_Directive.prototype.shallow_cmp = function(other) {
- return this.value === other.value;
- };
- AST_SimpleStatement.prototype.shallow_cmp = pass_through;
- AST_Block.prototype.shallow_cmp = pass_through;
- AST_EmptyStatement.prototype.shallow_cmp = pass_through;
- AST_LabeledStatement.prototype.shallow_cmp = function(other) {
- return this.label.name === other.label.name;
- };
- AST_Do.prototype.shallow_cmp = pass_through;
- AST_While.prototype.shallow_cmp = pass_through;
- AST_For.prototype.shallow_cmp = function(other) {
- return (this.init == null ? other.init == null : this.init === other.init) && (this.condition == null ? other.condition == null : this.condition === other.condition) && (this.step == null ? other.step == null : this.step === other.step);
- };
- AST_ForIn.prototype.shallow_cmp = pass_through;
- AST_ForOf.prototype.shallow_cmp = pass_through;
- AST_With.prototype.shallow_cmp = pass_through;
- AST_Toplevel.prototype.shallow_cmp = pass_through;
- AST_Expansion.prototype.shallow_cmp = pass_through;
- AST_Lambda.prototype.shallow_cmp = function(other) {
- return this.is_generator === other.is_generator && this.async === other.async;
- };
- AST_Destructuring.prototype.shallow_cmp = function(other) {
- return this.is_array === other.is_array;
- };
- AST_PrefixedTemplateString.prototype.shallow_cmp = pass_through;
- AST_TemplateString.prototype.shallow_cmp = pass_through;
- AST_TemplateSegment.prototype.shallow_cmp = function(other) {
- return this.value === other.value;
- };
- AST_Jump.prototype.shallow_cmp = pass_through;
- AST_LoopControl.prototype.shallow_cmp = pass_through;
- AST_Await.prototype.shallow_cmp = pass_through;
- AST_Yield.prototype.shallow_cmp = function(other) {
- return this.is_star === other.is_star;
- };
- AST_If.prototype.shallow_cmp = function(other) {
- return this.alternative == null ? other.alternative == null : this.alternative === other.alternative;
- };
- AST_Switch.prototype.shallow_cmp = pass_through;
- AST_SwitchBranch.prototype.shallow_cmp = pass_through;
- AST_Try.prototype.shallow_cmp = function(other) {
- return (this.body === other.body) && (this.bcatch == null ? other.bcatch == null : this.bcatch === other.bcatch) && (this.bfinally == null ? other.bfinally == null : this.bfinally === other.bfinally);
- };
- AST_Catch.prototype.shallow_cmp = function(other) {
- return this.argname == null ? other.argname == null : this.argname === other.argname;
- };
- AST_Finally.prototype.shallow_cmp = pass_through;
- AST_DefinitionsLike.prototype.shallow_cmp = pass_through;
- AST_VarDefLike.prototype.shallow_cmp = function(other) {
- return this.value == null ? other.value == null : this.value === other.value;
- };
- AST_NameMapping.prototype.shallow_cmp = pass_through;
- AST_Import.prototype.shallow_cmp = function(other) {
- return (this.imported_name || null) === (other.imported_name || null)
- && (this.imported_names || null) === (other.imported_names || null)
- && (this.attributes || null) === (other.attributes || null)
- && (this.phase || null) === (other.phase || null);
- };
- AST_ImportMeta.prototype.shallow_cmp = pass_through;
- AST_DynamicImport.prototype.shallow_cmp = function(other) {
- return (this.phase || null) === (other.phase || null) && this.args.length === other.args.length;
- };
- AST_Export.prototype.shallow_cmp = function(other) {
- return (this.exported_definition == null ? other.exported_definition == null : this.exported_definition === other.exported_definition) && (this.exported_value == null ? other.exported_value == null : this.exported_value === other.exported_value) && (this.exported_names == null ? other.exported_names == null : this.exported_names === other.exported_names) && (this.attributes == null ? other.attributes == null : this.attributes === other.attributes) && this.module_name === other.module_name && this.is_default === other.is_default;
- };
- AST_Call.prototype.shallow_cmp = pass_through;
- AST_Sequence.prototype.shallow_cmp = pass_through;
- AST_PropAccess.prototype.shallow_cmp = pass_through;
- AST_Chain.prototype.shallow_cmp = pass_through;
- AST_Dot.prototype.shallow_cmp = function(other) {
- return (
- this.property === other.property
- && !!this.quote === !!other.quote
- );
- };
- AST_DotHash.prototype.shallow_cmp = function(other) {
- return this.property === other.property;
- };
- AST_Unary.prototype.shallow_cmp = function(other) {
- return this.operator === other.operator;
- };
- AST_Binary.prototype.shallow_cmp = function(other) {
- return this.operator === other.operator;
- };
- AST_PrivateIn.prototype.shallow_cmp = pass_through;
- AST_Conditional.prototype.shallow_cmp = pass_through;
- AST_Array.prototype.shallow_cmp = pass_through;
- AST_Object.prototype.shallow_cmp = pass_through;
- AST_ObjectProperty.prototype.shallow_cmp = pass_through;
- AST_ObjectKeyVal.prototype.shallow_cmp = function(other) {
- return this.key === other.key && this.quote === other.quote;
- };
- AST_ObjectSetter.prototype.shallow_cmp = function(other) {
- return this.static === other.static;
- };
- AST_ObjectGetter.prototype.shallow_cmp = function(other) {
- return this.static === other.static;
- };
- AST_ConciseMethod.prototype.shallow_cmp = function(other) {
- return this.static === other.static;
- };
- AST_PrivateMethod.prototype.shallow_cmp = function(other) {
- return this.static === other.static;
- };
- AST_Class.prototype.shallow_cmp = function(other) {
- return (this.name == null ? other.name == null : this.name === other.name) && (this.extends == null ? other.extends == null : this.extends === other.extends);
- };
- AST_ClassProperty.prototype.shallow_cmp = function(other) {
- return this.static === other.static
- && (typeof this.key === "string"
- ? this.key === other.key
- : true /* AST_Node handled elsewhere */);
- };
- AST_ClassPrivateProperty.prototype.shallow_cmp = function(other) {
- return this.static === other.static;
- };
- AST_Symbol.prototype.shallow_cmp = function(other) {
- return this.name === other.name;
- };
- AST_NewTarget.prototype.shallow_cmp = pass_through;
- AST_This.prototype.shallow_cmp = pass_through;
- AST_Super.prototype.shallow_cmp = pass_through;
- AST_String.prototype.shallow_cmp = function(other) {
- return this.value === other.value;
- };
- AST_Number.prototype.shallow_cmp = function(other) {
- return this.value === other.value;
- };
- AST_BigInt.prototype.shallow_cmp = function(other) {
- return this.value === other.value;
- };
- AST_RegExp.prototype.shallow_cmp = function (other) {
- return (
- this.value.flags === other.value.flags
- && this.value.source === other.value.source
- );
- };
- AST_Atom.prototype.shallow_cmp = pass_through;
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- const MASK_EXPORT_DONT_MANGLE = 1 << 0;
- const MASK_EXPORT_WANT_MANGLE = 1 << 1;
- let function_defs = null;
- let unmangleable_names = null;
- /**
- * When defined, there is a function declaration somewhere that's inside of a block.
- * See https://tc39.es/ecma262/multipage/additional-ecmascript-features-for-web-browsers.html#sec-block-level-function-declarations-web-legacy-compatibility-semantics
- */
- let scopes_with_block_defuns = null;
- class SymbolDef {
- constructor(scope, orig, init) {
- this.name = orig.name;
- this.orig = [ orig ];
- this.init = init;
- this.eliminated = 0;
- this.assignments = 0;
- this.scope = scope;
- this.replaced = 0;
- this.global = false;
- this.export = 0;
- this.mangled_name = null;
- this.undeclared = false;
- this.id = SymbolDef.next_id++;
- this.chained = false;
- this.direct_access = false;
- this.escaped = 0;
- this.recursive_refs = 0;
- this.references = [];
- this.should_replace = undefined;
- this.single_use = false;
- this.fixed = false;
- Object.seal(this);
- }
- fixed_value() {
- if (!this.fixed || this.fixed instanceof AST_Node) return this.fixed;
- return this.fixed();
- }
- unmangleable(options) {
- if (!options) options = {};
- if (
- function_defs &&
- function_defs.has(this.id) &&
- keep_name(options.keep_fnames, this.orig[0].name)
- ) return true;
- return this.global && !options.toplevel
- || (this.export & MASK_EXPORT_DONT_MANGLE)
- || this.undeclared
- || !options.eval && this.scope.pinned()
- || (this.orig[0] instanceof AST_SymbolLambda
- || this.orig[0] instanceof AST_SymbolDefun) && keep_name(options.keep_fnames, this.orig[0].name)
- || this.orig[0] instanceof AST_SymbolMethod
- || (this.orig[0] instanceof AST_SymbolClass
- || this.orig[0] instanceof AST_SymbolDefClass) && keep_name(options.keep_classnames, this.orig[0].name);
- }
- mangle(options) {
- const cache = options.cache && options.cache.props;
- if (this.global && cache && cache.has(this.name)) {
- this.mangled_name = cache.get(this.name);
- } else if (!this.mangled_name && !this.unmangleable(options)) {
- var s = this.scope;
- var sym = this.orig[0];
- if (options.ie8 && sym instanceof AST_SymbolLambda)
- s = s.parent_scope;
- const redefinition = redefined_catch_def(this);
- this.mangled_name = redefinition
- ? redefinition.mangled_name || redefinition.name
- : s.next_mangled(options, this);
- if (this.global && cache) {
- cache.set(this.name, this.mangled_name);
- }
- }
- }
- }
- SymbolDef.next_id = 1;
- function redefined_catch_def(def) {
- if (def.orig[0] instanceof AST_SymbolCatch
- && def.scope.is_block_scope()
- ) {
- return def.scope.get_defun_scope().variables.get(def.name);
- }
- }
- AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = undefined, toplevel = this } = {}) {
- options = defaults(options, {
- cache: null,
- ie8: false,
- safari10: false,
- module: false,
- });
- if (!(toplevel instanceof AST_Toplevel)) {
- throw new Error("Invalid toplevel scope");
- }
- // pass 1: setup scope chaining and handle definitions
- var scope = this.parent_scope = parent_scope;
- var labels = new Map();
- var defun = null;
- var in_destructuring = null;
- var for_scopes = [];
- var tw = new TreeWalker((node, descend) => {
- if (node.is_block_scope()) {
- const save_scope = scope;
- node.block_scope = scope = new AST_Scope(node);
- scope._block_scope = true;
- scope.init_scope_vars(save_scope);
- scope.uses_with = save_scope.uses_with;
- scope.uses_eval = save_scope.uses_eval;
- if (options.safari10) {
- if (node instanceof AST_For || node instanceof AST_ForIn || node instanceof AST_ForOf) {
- for_scopes.push(scope);
- }
- }
- if (node instanceof AST_Switch) {
- // XXX: HACK! Ensure the switch expression gets the correct scope (the parent scope) and the body gets the contained scope
- // AST_Switch has a scope within the body, but it itself "is a block scope"
- // This means the switched expression has to belong to the outer scope
- // while the body inside belongs to the switch itself.
- // This is pretty nasty and warrants an AST change
- const the_block_scope = scope;
- scope = save_scope;
- node.expression.walk(tw);
- scope = the_block_scope;
- for (let i = 0; i < node.body.length; i++) {
- node.body[i].walk(tw);
- }
- } else {
- descend();
- }
- scope = save_scope;
- return true;
- }
- if (node instanceof AST_Destructuring) {
- const save_destructuring = in_destructuring;
- in_destructuring = node;
- descend();
- in_destructuring = save_destructuring;
- return true;
- }
- if (node instanceof AST_Scope) {
- node.init_scope_vars(scope);
- var save_scope = scope;
- var save_defun = defun;
- var save_labels = labels;
- defun = scope = node;
- labels = new Map();
- descend();
- scope = save_scope;
- defun = save_defun;
- labels = save_labels;
- if (node instanceof AST_Lambda) {
- detect_screwy_argnames_scope(node, scope);
- }
- return true; // don't descend again in TreeWalker
- }
- if (node instanceof AST_LabeledStatement) {
- var l = node.label;
- if (labels.has(l.name)) {
- throw new Error(string_template("Label {name} defined twice", l));
- }
- labels.set(l.name, l);
- descend();
- labels.delete(l.name);
- return true; // no descend again
- }
- if (node instanceof AST_With) {
- for (var s = scope; s; s = s.parent_scope)
- s.uses_with = true;
- return;
- }
- if (node instanceof AST_Symbol) {
- node.scope = scope;
- }
- if (node instanceof AST_Label) {
- node.thedef = node;
- node.references = [];
- }
- if (node instanceof AST_SymbolLambda) {
- defun.def_function(node, node.name == "arguments" ? undefined : defun);
- } else if (node instanceof AST_SymbolDefun) {
- // Careful here, the scope where this should be defined is
- // the parent scope. The reason is that we enter a new
- // scope when we encounter the AST_Defun node (which is
- // instanceof AST_Scope) but we get to the symbol a bit
- // later.
- const closest_scope = defun.parent_scope;
- // In strict mode, function definitions are block-scoped
- node.scope = tw.directives["use strict"]
- ? closest_scope
- : closest_scope.get_defun_scope();
- mark_export(node.scope.def_function(node, defun), 1);
- } else if (node instanceof AST_SymbolClass) {
- mark_export(defun.def_variable(node, defun), 1);
- } else if (node instanceof AST_SymbolImport) {
- scope.def_variable(node);
- } else if (node instanceof AST_SymbolDefClass) {
- // This deals with the name of the class being available
- // inside the class.
- mark_export((node.scope = defun.parent_scope).def_function(node, defun), 1);
- } else if (
- node instanceof AST_SymbolVar
- || node instanceof AST_SymbolLet
- || node instanceof AST_SymbolConst
- || node instanceof AST_SymbolUsing
- || node instanceof AST_SymbolCatch
- ) {
- var def;
- if (node instanceof AST_SymbolBlockDeclaration) {
- def = scope.def_variable(node, null);
- } else {
- def = defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
- }
- if (!def.orig.every((sym) => {
- if (sym === node) return true;
- if (node instanceof AST_SymbolBlockDeclaration) {
- return sym instanceof AST_SymbolLambda;
- }
- return !(sym instanceof AST_SymbolLet || sym instanceof AST_SymbolConst || sym instanceof AST_SymbolUsing);
- })) {
- js_error(
- `"${node.name}" is redeclared`,
- node.start.file,
- node.start.line,
- node.start.col,
- node.start.pos
- );
- }
- if (!(node instanceof AST_SymbolFunarg)) mark_export(def, 2);
- if (defun !== scope) {
- node.mark_enclosed();
- var def = scope.find_variable(node);
- if (node.thedef !== def) {
- node.thedef = def;
- node.reference();
- }
- }
- } else if (node instanceof AST_LabelRef) {
- var sym = labels.get(node.name);
- if (!sym) throw new Error(string_template("Undefined label {name} [{line},{col}]", {
- name: node.name,
- line: node.start.line,
- col: node.start.col
- }));
- node.thedef = sym;
- }
- if (!(scope instanceof AST_Toplevel) && (node instanceof AST_Export || node instanceof AST_Import)) {
- js_error(
- `"${node.TYPE}" statement may only appear at the top level`,
- node.start.file,
- node.start.line,
- node.start.col,
- node.start.pos
- );
- }
- });
- if (options.module) {
- tw.directives["use strict"] = true;
- }
- this.walk(tw);
- function mark_export(def, level) {
- if (in_destructuring) {
- var i = 0;
- do {
- level++;
- } while (tw.parent(i++) !== in_destructuring);
- }
- var node = tw.parent(level);
- if (def.export = node instanceof AST_Export ? MASK_EXPORT_DONT_MANGLE : 0) {
- var exported = node.exported_definition;
- if ((exported instanceof AST_Defun || exported instanceof AST_DefClass) && node.is_default) {
- def.export = MASK_EXPORT_WANT_MANGLE;
- }
- }
- }
- // pass 2: find back references and eval
- const is_toplevel = this instanceof AST_Toplevel;
- if (is_toplevel) {
- this.globals = new Map();
- }
- var tw = new TreeWalker(node => {
- if (node instanceof AST_LoopControl && node.label) {
- node.label.thedef.references.push(node);
- return true;
- }
- if (node instanceof AST_SymbolRef) {
- var name = node.name;
- if (name == "eval" && tw.parent() instanceof AST_Call) {
- for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) {
- s.uses_eval = true;
- }
- }
- var sym;
- if (tw.parent() instanceof AST_NameMapping && tw.parent(1).module_name
- || !(sym = node.scope.find_variable(name))) {
- sym = toplevel.def_global(node);
- if (node instanceof AST_SymbolExport) sym.export = MASK_EXPORT_DONT_MANGLE;
- } else if (sym.scope instanceof AST_Lambda && name == "arguments") {
- sym.scope.get_defun_scope().uses_arguments = true;
- }
- node.thedef = sym;
- node.reference();
- if (node.scope.is_block_scope()
- && !(sym.orig[0] instanceof AST_SymbolBlockDeclaration)) {
- node.scope = node.scope.get_defun_scope();
- }
- return true;
- }
- // ensure mangling works if catch reuses a scope variable
- var def;
- if (node instanceof AST_SymbolCatch && (def = redefined_catch_def(node.definition()))) {
- var s = node.scope;
- while (s) {
- push_uniq(s.enclosed, def);
- if (s === def.scope) break;
- s = s.parent_scope;
- }
- }
- });
- this.walk(tw);
- // pass 3: work around IE8 and Safari catch scope bugs
- if (options.ie8 || options.safari10) {
- walk(this, node => {
- if (node instanceof AST_SymbolCatch) {
- var name = node.name;
- var refs = node.thedef.references;
- var scope = node.scope.get_defun_scope();
- var def = scope.find_variable(name)
- || toplevel.globals.get(name)
- || scope.def_variable(node);
- refs.forEach(function(ref) {
- ref.thedef = def;
- ref.reference();
- });
- node.thedef = def;
- node.reference();
- return true;
- }
- });
- }
- // pass 4: add symbol definitions to loop scopes
- // Safari/Webkit bug workaround - loop init let variable shadowing argument.
- // https://github.com/mishoo/UglifyJS2/issues/1753
- // https://bugs.webkit.org/show_bug.cgi?id=171041
- if (options.safari10) {
- for (const scope of for_scopes) {
- scope.parent_scope.variables.forEach(function(def) {
- push_uniq(scope.enclosed, def);
- });
- }
- }
- // Arguments have their own scope, different from the scope of `var`.
- // This is apparent when default args are used.
- function detect_screwy_argnames_scope(lambda, parent_scope) {
- let cached_argnames;
- for (const arg of lambda.argnames) {
- walk(arg, sym => {
- if (sym instanceof AST_SymbolRef) {
- const in_lambda = lambda.variables.get(sym.name);
- if (!in_lambda) return;
- // In funargs and also a `var` inside
- // (sym, x = sym) => { var sym }
- if (in_lambda.orig.length > 1 && find_name_in_arg_names(sym.name)) {
- mark_screwy(sym.definition());
- }
- // Outside and in a `var`
- // var sym = ...; (x = sym) => { var sym }
- const outside_lambda = parent_scope.find_variable(sym.name);
- if (outside_lambda) {
- mark_screwy(sym.definition());
- mark_screwy(outside_lambda);
- }
- }
- });
- }
- function find_name_in_arg_names(name) {
- if (!cached_argnames) cached_argnames = lambda.args_as_names();
- return cached_argnames.some(s => s.name === name);
- }
- function mark_screwy(def) {
- if (def) def.scope.screwy_argnames_scope = true;
- lambda.screwy_argnames_scope = true;
- }
- }
- });
- AST_Toplevel.DEFMETHOD("def_global", function(node) {
- var globals = this.globals, name = node.name;
- if (globals.has(name)) {
- return globals.get(name);
- } else {
- var g = new SymbolDef(this, node);
- g.undeclared = true;
- g.global = true;
- globals.set(name, g);
- return g;
- }
- });
- AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) {
- this.variables = new Map(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
- this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
- this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
- this.screwy_argnames_scope = false;
- this.parent_scope = parent_scope; // the parent scope
- this.enclosed = []; // a list of variables from this or outer scope(s) that are referenced from this or inner scopes
- this.cname = -1; // the current index for mangling functions/variables
- });
- AST_Scope.DEFMETHOD("conflicting_def", function (name) {
- return (
- this.enclosed.find(def => def.name === name)
- || this.variables.has(name)
- || (this.parent_scope && this.parent_scope.conflicting_def(name))
- );
- });
- AST_Scope.DEFMETHOD("conflicting_def_shallow", function (name) {
- return (
- this.enclosed.find(def => def.name === name)
- || this.variables.has(name)
- );
- });
- AST_Scope.DEFMETHOD("add_child_scope", function (scope) {
- // `scope` is going to be moved into `this` right now.
- // Update the required scopes' information
- if (scope.parent_scope === this) return;
- scope.parent_scope = this;
- // Propagate to this.uses_arguments from arrow functions
- if ((scope instanceof AST_Arrow) && (this instanceof AST_Lambda && !this.uses_arguments)) {
- this.uses_arguments = walk(scope, node => {
- if (
- node instanceof AST_SymbolRef
- && node.scope instanceof AST_Lambda
- && node.name === "arguments"
- ) {
- return walk_abort;
- }
- if (node instanceof AST_Lambda && !(node instanceof AST_Arrow)) {
- return true;
- }
- });
- }
- this.uses_with = this.uses_with || scope.uses_with;
- this.uses_eval = this.uses_eval || scope.uses_eval;
- const scope_ancestry = (() => {
- const ancestry = [];
- let cur = this;
- do {
- ancestry.push(cur);
- } while ((cur = cur.parent_scope));
- ancestry.reverse();
- return ancestry;
- })();
- const new_scope_enclosed_set = new Set(scope.enclosed);
- const to_enclose = [];
- for (const scope_topdown of scope_ancestry) {
- to_enclose.forEach(e => push_uniq(scope_topdown.enclosed, e));
- for (const def of scope_topdown.variables.values()) {
- if (new_scope_enclosed_set.has(def)) {
- push_uniq(to_enclose, def);
- push_uniq(scope_topdown.enclosed, def);
- }
- }
- }
- });
- function find_scopes_visible_from(scopes) {
- const found_scopes = new Set();
- for (const scope of new Set(scopes)) {
- (function bubble_up(scope) {
- if (scope == null || found_scopes.has(scope)) return;
- found_scopes.add(scope);
- bubble_up(scope.parent_scope);
- })(scope);
- }
- return [...found_scopes];
- }
- // Creates a symbol during compression
- AST_Scope.DEFMETHOD("create_symbol", function(SymClass, {
- source,
- tentative_name,
- scope,
- conflict_scopes = [scope],
- init = null
- } = {}) {
- let symbol_name;
- conflict_scopes = find_scopes_visible_from(conflict_scopes);
- if (tentative_name) {
- // Implement hygiene (no new names are conflicting with existing names)
- tentative_name =
- symbol_name =
- tentative_name.replace(/(?:^[^a-z_$]|[^a-z0-9_$])/ig, "_");
- let i = 0;
- while (conflict_scopes.find(s => s.conflicting_def_shallow(symbol_name))) {
- symbol_name = tentative_name + "$" + i++;
- }
- }
- if (!symbol_name) {
- throw new Error("No symbol name could be generated in create_symbol()");
- }
- const symbol = make_node(SymClass, source, {
- name: symbol_name,
- scope
- });
- this.def_variable(symbol, init || null);
- symbol.mark_enclosed();
- return symbol;
- });
- AST_Node.DEFMETHOD("is_block_scope", return_false);
- AST_Class.DEFMETHOD("is_block_scope", return_false);
- AST_Lambda.DEFMETHOD("is_block_scope", return_false);
- AST_Toplevel.DEFMETHOD("is_block_scope", return_false);
- AST_SwitchBranch.DEFMETHOD("is_block_scope", return_false);
- AST_Block.DEFMETHOD("is_block_scope", return_true);
- AST_Scope.DEFMETHOD("is_block_scope", function () {
- return this._block_scope || false;
- });
- AST_IterationStatement.DEFMETHOD("is_block_scope", return_true);
- AST_Lambda.DEFMETHOD("init_scope_vars", function() {
- AST_Scope.prototype.init_scope_vars.apply(this, arguments);
- this.uses_arguments = false;
- this.def_variable(new AST_SymbolFunarg({
- name: "arguments",
- start: this.start,
- end: this.end
- }));
- });
- AST_Arrow.DEFMETHOD("init_scope_vars", function() {
- AST_Scope.prototype.init_scope_vars.apply(this, arguments);
- this.uses_arguments = false;
- });
- AST_Symbol.DEFMETHOD("mark_enclosed", function() {
- var def = this.definition();
- var s = this.scope;
- while (s) {
- push_uniq(s.enclosed, def);
- if (s === def.scope) break;
- s = s.parent_scope;
- }
- });
- AST_Symbol.DEFMETHOD("reference", function() {
- this.definition().references.push(this);
- this.mark_enclosed();
- });
- AST_Scope.DEFMETHOD("find_variable", function(name) {
- if (name instanceof AST_Symbol) name = name.name;
- return this.variables.get(name)
- || (this.parent_scope && this.parent_scope.find_variable(name));
- });
- AST_Scope.DEFMETHOD("def_function", function(symbol, init) {
- var def = this.def_variable(symbol, init);
- if (!def.init || def.init instanceof AST_Defun) def.init = init;
- return def;
- });
- AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
- var def = this.variables.get(symbol.name);
- if (def) {
- def.orig.push(symbol);
- if (def.init && (def.scope !== symbol.scope || def.init instanceof AST_Function)) {
- def.init = init;
- }
- } else {
- def = new SymbolDef(this, symbol, init);
- this.variables.set(symbol.name, def);
- def.global = !this.parent_scope;
- }
- return symbol.thedef = def;
- });
- function next_mangled(scope, options) {
- let defun_scope;
- if (
- scopes_with_block_defuns
- && (defun_scope = scope.get_defun_scope())
- && scopes_with_block_defuns.has(defun_scope)
- ) {
- scope = defun_scope;
- }
- var ext = scope.enclosed;
- var nth_identifier = options.nth_identifier;
- out: while (true) {
- var m = nth_identifier.get(++scope.cname);
- if (ALL_RESERVED_WORDS.has(m)) continue; // skip over "do"
- // https://github.com/mishoo/UglifyJS2/issues/242 -- do not
- // shadow a name reserved from mangling.
- if (options.reserved.has(m)) continue;
- // Functions with short names might collide with base54 output
- // and therefore cause collisions when keep_fnames is true.
- if (unmangleable_names && unmangleable_names.has(m)) continue out;
- // we must ensure that the mangled name does not shadow a name
- // from some parent scope that is referenced in this or in
- // inner scopes.
- for (let i = ext.length; --i >= 0;) {
- const def = ext[i];
- const name = def.mangled_name || (def.unmangleable(options) && def.name);
- if (m == name) continue out;
- }
- return m;
- }
- }
- AST_Scope.DEFMETHOD("next_mangled", function(options) {
- return next_mangled(this, options);
- });
- AST_Toplevel.DEFMETHOD("next_mangled", function(options) {
- let name;
- const mangled_names = this.mangled_names;
- do {
- name = next_mangled(this, options);
- } while (mangled_names.has(name));
- return name;
- });
- AST_Function.DEFMETHOD("next_mangled", function(options, def) {
- // #179, #326
- // in Safari strict mode, something like (function x(x){...}) is a syntax error;
- // a function expression's argument cannot shadow the function expression's name
- var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition();
- // the function's mangled_name is null when keep_fnames is true
- var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
- while (true) {
- var name = next_mangled(this, options);
- if (!tricky_name || tricky_name != name)
- return name;
- }
- });
- AST_Symbol.DEFMETHOD("unmangleable", function(options) {
- var def = this.definition();
- return !def || def.unmangleable(options);
- });
- // labels are always mangleable
- AST_Label.DEFMETHOD("unmangleable", return_false);
- AST_Symbol.DEFMETHOD("unreferenced", function() {
- return !this.definition().references.length && !this.scope.pinned();
- });
- AST_Symbol.DEFMETHOD("definition", function() {
- return this.thedef;
- });
- AST_Symbol.DEFMETHOD("global", function() {
- return this.thedef.global;
- });
- /**
- * Format the mangler options (if any) into their appropriate types
- */
- function format_mangler_options(options) {
- options = defaults(options, {
- eval : false,
- nth_identifier : base54,
- ie8 : false,
- keep_classnames: false,
- keep_fnames : false,
- module : false,
- reserved : [],
- toplevel : false,
- });
- if (options.module) options.toplevel = true;
- if (!Array.isArray(options.reserved)
- && !(options.reserved instanceof Set)
- ) {
- options.reserved = [];
- }
- options.reserved = new Set(options.reserved);
- // Never mangle arguments
- options.reserved.add("arguments");
- return options;
- }
- AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
- options = format_mangler_options(options);
- var nth_identifier = options.nth_identifier;
- // We only need to mangle declaration nodes. Special logic wired
- // into the code generator will display the mangled name if it's
- // present (and for AST_SymbolRef-s it'll use the mangled name of
- // the AST_SymbolDeclaration that it points to).
- var lname = -1;
- var to_mangle = [];
- if (options.keep_fnames) {
- function_defs = new Set();
- }
- const mangled_names = this.mangled_names = new Set();
- unmangleable_names = new Set();
- if (options.cache) {
- this.globals.forEach(collect);
- if (options.cache.props) {
- options.cache.props.forEach(function(mangled_name) {
- mangled_names.add(mangled_name);
- });
- }
- }
- var tw = new TreeWalker(function(node, descend) {
- if (node instanceof AST_LabeledStatement) {
- // lname is incremented when we get to the AST_Label
- var save_nesting = lname;
- descend();
- lname = save_nesting;
- return true; // don't descend again in TreeWalker
- }
- if (
- node instanceof AST_Defun
- && !(tw.parent() instanceof AST_Scope)
- ) {
- scopes_with_block_defuns = scopes_with_block_defuns || new Set();
- scopes_with_block_defuns.add(node.parent_scope.get_defun_scope());
- }
- if (node instanceof AST_Scope) {
- node.variables.forEach(collect);
- return;
- }
- if (node.is_block_scope()) {
- node.block_scope.variables.forEach(collect);
- return;
- }
- if (
- function_defs
- && node instanceof AST_VarDef
- && node.name instanceof AST_Symbol
- && node.value instanceof AST_Lambda
- && !node.value.name
- && keep_name(options.keep_fnames, node.name.name)
- ) {
- function_defs.add(node.name.definition().id);
- return;
- }
- if (node instanceof AST_Label) {
- let name;
- do {
- name = nth_identifier.get(++lname);
- } while (ALL_RESERVED_WORDS.has(name));
- node.mangled_name = name;
- return true;
- }
- if (!(options.ie8 || options.safari10) && node instanceof AST_SymbolCatch) {
- to_mangle.push(node.definition());
- return;
- }
- });
- this.walk(tw);
- if (options.keep_fnames || options.keep_classnames) {
- // Collect a set of short names which are unmangleable,
- // for use in avoiding collisions in next_mangled.
- to_mangle.forEach(def => {
- if (def.name.length < 6 && def.unmangleable(options)) {
- unmangleable_names.add(def.name);
- }
- });
- }
- to_mangle.forEach(def => { def.mangle(options); });
- function_defs = null;
- unmangleable_names = null;
- scopes_with_block_defuns = null;
- function collect(symbol) {
- if (symbol.export & MASK_EXPORT_DONT_MANGLE) {
- unmangleable_names.add(symbol.name);
- } else if (!options.reserved.has(symbol.name)) {
- to_mangle.push(symbol);
- }
- }
- });
- AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
- const cache = options.cache && options.cache.props;
- const avoid = new Set();
- options.reserved.forEach(to_avoid);
- this.globals.forEach(add_def);
- this.walk(new TreeWalker(function(node) {
- if (node instanceof AST_Scope) node.variables.forEach(add_def);
- if (node instanceof AST_SymbolCatch) add_def(node.definition());
- }));
- return avoid;
- function to_avoid(name) {
- avoid.add(name);
- }
- function add_def(def) {
- var name = def.name;
- if (def.global && cache && cache.has(name)) name = cache.get(name);
- else if (!def.unmangleable(options)) return;
- to_avoid(name);
- }
- });
- AST_Toplevel.DEFMETHOD("expand_names", function(options) {
- options = format_mangler_options(options);
- var nth_identifier = options.nth_identifier;
- if (nth_identifier.reset && nth_identifier.sort) {
- nth_identifier.reset();
- nth_identifier.sort();
- }
- var avoid = this.find_colliding_names(options);
- var cname = 0;
- this.globals.forEach(rename);
- this.walk(new TreeWalker(function(node) {
- if (node instanceof AST_Scope) node.variables.forEach(rename);
- if (node instanceof AST_SymbolCatch) rename(node.definition());
- }));
- function next_name() {
- var name;
- do {
- name = nth_identifier.get(cname++);
- } while (avoid.has(name) || ALL_RESERVED_WORDS.has(name));
- return name;
- }
- function rename(def) {
- if (def.global && options.cache) return;
- if (def.unmangleable(options)) return;
- if (options.reserved.has(def.name)) return;
- const redefinition = redefined_catch_def(def);
- const name = def.name = redefinition ? redefinition.name : next_name();
- def.orig.forEach(function(sym) {
- sym.name = name;
- });
- def.references.forEach(function(sym) {
- sym.name = name;
- });
- }
- });
- AST_Node.DEFMETHOD("tail_node", return_this);
- AST_Sequence.DEFMETHOD("tail_node", function() {
- return this.expressions[this.expressions.length - 1];
- });
- AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) {
- options = format_mangler_options(options);
- var nth_identifier = options.nth_identifier;
- if (!nth_identifier.reset || !nth_identifier.consider || !nth_identifier.sort) {
- // If the identifier mangler is invariant, skip computing character frequency.
- return;
- }
- nth_identifier.reset();
- try {
- AST_Node.prototype.print = function(stream, force_parens) {
- this._print(stream, force_parens);
- if (this instanceof AST_Symbol && !this.unmangleable(options)) {
- nth_identifier.consider(this.name, -1);
- } else if (options.properties) {
- if (this instanceof AST_DotHash) {
- nth_identifier.consider("#" + this.property, -1);
- } else if (this instanceof AST_Dot) {
- nth_identifier.consider(this.property, -1);
- } else if (this instanceof AST_Sub) {
- skip_string(this.property);
- }
- }
- };
- nth_identifier.consider(this.print_to_string(), 1);
- } finally {
- AST_Node.prototype.print = AST_Node.prototype._print;
- }
- nth_identifier.sort();
- function skip_string(node) {
- if (node instanceof AST_String) {
- nth_identifier.consider(node.value, -1);
- } else if (node instanceof AST_Conditional) {
- skip_string(node.consequent);
- skip_string(node.alternative);
- } else if (node instanceof AST_Sequence) {
- skip_string(node.tail_node());
- }
- }
- });
- const base54 = (() => {
- const leading = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_".split("");
- const digits = "0123456789".split("");
- let chars;
- let frequency;
- function reset() {
- frequency = new Map();
- leading.forEach(function(ch) {
- frequency.set(ch, 0);
- });
- digits.forEach(function(ch) {
- frequency.set(ch, 0);
- });
- }
- function consider(str, delta) {
- for (var i = str.length; --i >= 0;) {
- frequency.set(str[i], frequency.get(str[i]) + delta);
- }
- }
- function compare(a, b) {
- return frequency.get(b) - frequency.get(a);
- }
- function sort() {
- chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
- }
- // Ensure this is in a usable initial state.
- reset();
- sort();
- function base54(num) {
- var ret = "", base = 54;
- num++;
- do {
- num--;
- ret += chars[num % base];
- num = Math.floor(num / base);
- base = 64;
- } while (num > 0);
- return ret;
- }
- return {
- get: base54,
- consider,
- reset,
- sort
- };
- })();
- let mangle_options = undefined;
- AST_Node.prototype.size = function (compressor, stack) {
- mangle_options = compressor && compressor._mangle_options;
- let size = 0;
- walk_parent(this, (node, info) => {
- size += node._size(info);
- // Braceless arrow functions have fake "return" statements
- if (node instanceof AST_Arrow && node.is_braceless()) {
- size += node.body[0].value._size(info);
- return true;
- }
- }, stack || (compressor && compressor.stack));
- // just to save a bit of memory
- mangle_options = undefined;
- return size;
- };
- AST_Node.prototype._size = () => 0;
- AST_Debugger.prototype._size = () => 8;
- AST_Directive.prototype._size = function () {
- // TODO string encoding stuff
- return 2 + this.value.length;
- };
- /** Count commas/semicolons necessary to show a list of expressions/statements */
- const list_overhead = (array) => array.length && array.length - 1;
- AST_Block.prototype._size = function () {
- return 2 + list_overhead(this.body);
- };
- AST_Toplevel.prototype._size = function() {
- return list_overhead(this.body);
- };
- AST_EmptyStatement.prototype._size = () => 1;
- AST_LabeledStatement.prototype._size = () => 2; // x:
- AST_Do.prototype._size = () => 9;
- AST_While.prototype._size = () => 7;
- AST_For.prototype._size = () => 8;
- AST_ForIn.prototype._size = () => 8;
- // AST_ForOf inherits ^
- AST_With.prototype._size = () => 6;
- AST_Expansion.prototype._size = () => 3;
- const lambda_modifiers = func =>
- (func.is_generator ? 1 : 0) + (func.async ? 6 : 0);
- AST_Accessor.prototype._size = function () {
- return lambda_modifiers(this) + 4 + list_overhead(this.argnames) + list_overhead(this.body);
- };
- AST_Function.prototype._size = function (info) {
- const first = !!first_in_statement(info);
- return (first * 2) + lambda_modifiers(this) + 12 + list_overhead(this.argnames) + list_overhead(this.body);
- };
- AST_Defun.prototype._size = function () {
- return lambda_modifiers(this) + 13 + list_overhead(this.argnames) + list_overhead(this.body);
- };
- AST_Arrow.prototype._size = function () {
- let args_and_arrow = 2 + list_overhead(this.argnames);
- if (
- !(
- this.argnames.length === 1
- && this.argnames[0] instanceof AST_Symbol
- )
- ) {
- args_and_arrow += 2; // parens around the args
- }
- const body_overhead = this.is_braceless() ? 0 : list_overhead(this.body) + 2;
- return lambda_modifiers(this) + args_and_arrow + body_overhead;
- };
- AST_Destructuring.prototype._size = () => 2;
- AST_TemplateString.prototype._size = function () {
- return 2 + (Math.floor(this.segments.length / 2) * 3); /* "${}" */
- };
- AST_TemplateSegment.prototype._size = function () {
- return this.value.length;
- };
- AST_Return.prototype._size = function () {
- return this.value ? 7 : 6;
- };
- AST_Throw.prototype._size = () => 6;
- AST_Break.prototype._size = function () {
- return this.label ? 6 : 5;
- };
- AST_Continue.prototype._size = function () {
- return this.label ? 9 : 8;
- };
- AST_If.prototype._size = () => 4;
- AST_Switch.prototype._size = function () {
- return 8 + list_overhead(this.body);
- };
- AST_Case.prototype._size = function () {
- return 5 + list_overhead(this.body);
- };
- AST_Default.prototype._size = function () {
- return 8 + list_overhead(this.body);
- };
- AST_Try.prototype._size = () => 3;
- AST_Catch.prototype._size = function () {
- let size = 7 + list_overhead(this.body);
- if (this.argname) {
- size += 2;
- }
- return size;
- };
- AST_Finally.prototype._size = function () {
- return 7 + list_overhead(this.body);
- };
- AST_Var.prototype._size = function () {
- return 4 + list_overhead(this.definitions);
- };
- AST_Let.prototype._size = function () {
- return 4 + list_overhead(this.definitions);
- };
- AST_Const.prototype._size = function () {
- return 6 + list_overhead(this.definitions);
- };
- AST_Using.prototype._size = function () {
- const await_size = this.await ? 6 : 0;
- return await_size + 6 + list_overhead(this.definitions);
- };
- AST_VarDefLike.prototype._size = function () {
- return this.value ? 1 : 0;
- };
- AST_NameMapping.prototype._size = function () {
- // foreign name isn't mangled
- return this.name ? 4 : 0;
- };
- AST_Import.prototype._size = function () {
- // import
- let size = 6;
- if (this.imported_name) size += 1;
- // from
- if (this.imported_name || this.imported_names) size += 5;
- // braces, and the commas
- if (this.imported_names) {
- size += 2 + list_overhead(this.imported_names);
- }
- return size;
- };
- AST_ImportMeta.prototype._size = () => 11;
- AST_DynamicImport.prototype._size = function () {
- // `import.` + phase + `()` + arg overhead
- if (this.phase) {
- return 9 + this.phase.length + list_overhead(this.args);
- } else {
- return 8 + list_overhead(this.args);
- }
- };
- AST_Export.prototype._size = function () {
- let size = 7 + (this.is_default ? 8 : 0);
- if (this.exported_value) {
- size += this.exported_value._size();
- }
- if (this.exported_names) {
- // Braces and commas
- size += 2 + list_overhead(this.exported_names);
- }
- if (this.module_name) {
- // "from "
- size += 5;
- }
- return size;
- };
- AST_Call.prototype._size = function () {
- if (this.optional) {
- return 4 + list_overhead(this.args);
- }
- return 2 + list_overhead(this.args);
- };
- AST_New.prototype._size = function () {
- return 6 + list_overhead(this.args);
- };
- AST_Sequence.prototype._size = function () {
- return list_overhead(this.expressions);
- };
- AST_Dot.prototype._size = function () {
- if (this.optional) {
- return this.property.length + 2;
- }
- return this.property.length + 1;
- };
- AST_DotHash.prototype._size = function () {
- if (this.optional) {
- return this.property.length + 3;
- }
- return this.property.length + 2;
- };
- AST_Sub.prototype._size = function () {
- return this.optional ? 4 : 2;
- };
- AST_Unary.prototype._size = function () {
- if (this.operator === "typeof") return 7;
- if (this.operator === "void") return 5;
- return this.operator.length;
- };
- AST_Binary.prototype._size = function (info) {
- if (this.operator === "in") return 4;
- let size = this.operator.length;
- if (
- (this.operator === "+" || this.operator === "-")
- && this.right instanceof AST_Unary && this.right.operator === this.operator
- ) {
- // 1+ +a > needs space between the +
- size += 1;
- }
- if (this.needs_parens(info)) {
- size += 2;
- }
- return size;
- };
- AST_Conditional.prototype._size = () => 3;
- AST_Array.prototype._size = function () {
- return 2 + list_overhead(this.elements);
- };
- AST_Object.prototype._size = function (info) {
- let base = 2;
- if (first_in_statement(info)) {
- base += 2; // parens
- }
- return base + list_overhead(this.properties);
- };
- /*#__INLINE__*/
- const key_size = key =>
- typeof key === "string" ? key.length : 0;
- AST_ObjectKeyVal.prototype._size = function () {
- return key_size(this.key) + 1;
- };
- /*#__INLINE__*/
- const static_size = is_static => is_static ? 7 : 0;
- AST_ObjectGetter.prototype._size = function () {
- return 5 + static_size(this.static) + key_size(this.key);
- };
- AST_ObjectSetter.prototype._size = function () {
- return 5 + static_size(this.static) + key_size(this.key);
- };
- AST_ConciseMethod.prototype._size = function () {
- return static_size(this.static) + key_size(this.key);
- };
- AST_PrivateMethod.prototype._size = function () {
- return AST_ConciseMethod.prototype._size.call(this) + 1;
- };
- AST_PrivateGetter.prototype._size = function () {
- return AST_ConciseMethod.prototype._size.call(this) + 4;
- };
- AST_PrivateSetter.prototype._size = function () {
- return AST_ConciseMethod.prototype._size.call(this) + 4;
- };
- AST_PrivateIn.prototype._size = function () {
- return 5; // "#", and " in "
- };
- AST_Class.prototype._size = function () {
- return (
- (this.name ? 8 : 7)
- + (this.extends ? 8 : 0)
- );
- };
- AST_ClassStaticBlock.prototype._size = function () {
- // "static{}" + semicolons
- return 8 + list_overhead(this.body);
- };
- AST_ClassProperty.prototype._size = function () {
- return (
- static_size(this.static)
- + (typeof this.key === "string" ? this.key.length + 2 : 0)
- + (this.value ? 1 : 0)
- );
- };
- AST_ClassPrivateProperty.prototype._size = function () {
- return AST_ClassProperty.prototype._size.call(this) + 1;
- };
- AST_Symbol.prototype._size = function () {
- if (!(mangle_options && this.thedef && !this.thedef.unmangleable(mangle_options))) {
- return this.name.length;
- } else {
- return 1;
- }
- };
- // TODO take propmangle into account
- AST_SymbolClassProperty.prototype._size = function () {
- return this.name.length;
- };
- AST_SymbolRef.prototype._size = AST_SymbolDeclaration.prototype._size = function () {
- if (this.name === "arguments") return 9;
- return AST_Symbol.prototype._size.call(this);
- };
- AST_NewTarget.prototype._size = () => 10;
- AST_SymbolImportForeign.prototype._size = function () {
- return this.name.length;
- };
- AST_SymbolExportForeign.prototype._size = function () {
- return this.name.length;
- };
- AST_This.prototype._size = () => 4;
- AST_Super.prototype._size = () => 5;
- AST_String.prototype._size = function () {
- return this.value.length + 2;
- };
- AST_Number.prototype._size = function () {
- const { value } = this;
- if (value === 0) return 1;
- if (value > 0 && Math.floor(value) === value) {
- return Math.floor(Math.log10(value) + 1);
- }
- return value.toString().length;
- };
- AST_BigInt.prototype._size = function () {
- return this.value.length;
- };
- AST_RegExp.prototype._size = function () {
- return this.value.toString().length;
- };
- AST_Null.prototype._size = () => 4;
- AST_NaN.prototype._size = () => 3;
- AST_Undefined.prototype._size = () => 6; // "void 0"
- AST_Hole.prototype._size = () => 0; // comma is taken into account by list_overhead()
- AST_Infinity.prototype._size = () => 8;
- AST_True.prototype._size = () => 4;
- AST_False.prototype._size = () => 5;
- AST_Await.prototype._size = () => 6;
- AST_Yield.prototype._size = () => 6;
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- // bitfield flags to be stored in node.flags.
- // These are set and unset during compression, and store information in the node without requiring multiple fields.
- const UNUSED = 0b00000001;
- const TRUTHY = 0b00000010;
- const FALSY = 0b00000100;
- const UNDEFINED = 0b00001000;
- const INLINED = 0b00010000;
- // Nodes to which values are ever written. Used when keep_assign is part of the unused option string.
- const WRITE_ONLY = 0b00100000;
- // information specific to a single compression pass
- const SQUEEZED = 0b0000000100000000;
- const OPTIMIZED = 0b0000001000000000;
- const TOP = 0b0000010000000000;
- const CLEAR_BETWEEN_PASSES = SQUEEZED | OPTIMIZED | TOP;
- const has_flag = (node, flag) => node.flags & flag;
- const set_flag = (node, flag) => { node.flags |= flag; };
- const clear_flag = (node, flag) => { node.flags &= ~flag; };
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- function merge_sequence(array, node) {
- if (node instanceof AST_Sequence) {
- array.push(...node.expressions);
- } else {
- array.push(node);
- }
- return array;
- }
- function make_sequence(orig, expressions) {
- if (expressions.length == 1) return expressions[0];
- if (expressions.length == 0) throw new Error("trying to create a sequence with length zero!");
- return make_node(AST_Sequence, orig, {
- expressions: expressions.reduce(merge_sequence, [])
- });
- }
- function make_empty_function(self) {
- return make_node(AST_Function, self, {
- uses_arguments: false,
- argnames: [],
- body: [],
- is_generator: false,
- async: false,
- variables: new Map(),
- uses_with: false,
- uses_eval: false,
- parent_scope: null,
- enclosed: [],
- cname: 0,
- block_scope: undefined,
- });
- }
- function make_node_from_constant(val, orig) {
- switch (typeof val) {
- case "string":
- return make_node(AST_String, orig, {
- value: val
- });
- case "number":
- if (isNaN(val)) return make_node(AST_NaN, orig);
- if (isFinite(val)) {
- return 1 / val < 0 ? make_node(AST_UnaryPrefix, orig, {
- operator: "-",
- expression: make_node(AST_Number, orig, { value: -val })
- }) : make_node(AST_Number, orig, { value: val });
- }
- return val < 0 ? make_node(AST_UnaryPrefix, orig, {
- operator: "-",
- expression: make_node(AST_Infinity, orig)
- }) : make_node(AST_Infinity, orig);
- case "bigint":
- return make_node(AST_BigInt, orig, { value: val.toString() });
- case "boolean":
- return make_node(val ? AST_True : AST_False, orig);
- case "undefined":
- return make_void_0(orig);
- default:
- if (val === null) {
- return make_node(AST_Null, orig, { value: null });
- }
- if (val instanceof RegExp) {
- return make_node(AST_RegExp, orig, {
- value: {
- source: regexp_source_fix(val.source),
- flags: val.flags
- }
- });
- }
- throw new Error(string_template("Can't handle constant of type: {type}", {
- type: typeof val
- }));
- }
- }
- function best_of_expression(ast1, ast2) {
- return ast1.size() > ast2.size() ? ast2 : ast1;
- }
- function best_of_statement(ast1, ast2) {
- return best_of_expression(
- make_node(AST_SimpleStatement, ast1, {
- body: ast1
- }),
- make_node(AST_SimpleStatement, ast2, {
- body: ast2
- })
- ).body;
- }
- /** Find which node is smaller, and return that */
- function best_of(compressor, ast1, ast2) {
- if (first_in_statement(compressor)) {
- return best_of_statement(ast1, ast2);
- } else {
- return best_of_expression(ast1, ast2);
- }
- }
- /** Simplify an object property's key, if possible */
- function get_simple_key(key) {
- if (key instanceof AST_Constant) {
- return key.getValue();
- }
- if (key instanceof AST_UnaryPrefix
- && key.operator == "void"
- && key.expression instanceof AST_Constant) {
- return undefined;
- }
- return key;
- }
- function read_property(obj, key) {
- key = get_simple_key(key);
- if (key instanceof AST_Node) return;
- var value;
- if (obj instanceof AST_Array) {
- var elements = obj.elements;
- if (key == "length") return make_node_from_constant(elements.length, obj);
- if (typeof key == "number" && key in elements) value = elements[key];
- } else if (obj instanceof AST_Object) {
- key = "" + key;
- var props = obj.properties;
- for (var i = props.length; --i >= 0;) {
- var prop = props[i];
- if (!(prop instanceof AST_ObjectKeyVal)) return;
- if (!value && props[i].key === key) value = props[i].value;
- }
- }
- return value instanceof AST_SymbolRef && value.fixed_value() || value;
- }
- function has_break_or_continue(loop, parent) {
- var found = false;
- var tw = new TreeWalker(function(node) {
- if (found || node instanceof AST_Scope) return true;
- if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === loop) {
- return found = true;
- }
- });
- if (parent instanceof AST_LabeledStatement) tw.push(parent);
- tw.push(loop);
- loop.body.walk(tw);
- return found;
- }
- // we shouldn't compress (1,func)(something) to
- // func(something) because that changes the meaning of
- // the func (becomes lexical instead of global).
- function maintain_this_binding(parent, orig, val) {
- if (requires_sequence_to_maintain_binding(parent, orig, val)) {
- const zero = make_node(AST_Number, orig, { value: 0 });
- return make_sequence(orig, [ zero, val ]);
- } else {
- return val;
- }
- }
- /** Detect (1, x.noThis)(), (0, eval)(), which need sequences */
- function requires_sequence_to_maintain_binding(parent, orig, val) {
- return (
- parent instanceof AST_UnaryPrefix && parent.operator == "delete"
- || parent instanceof AST_Call && parent.expression === orig
- && (
- val instanceof AST_Chain
- || val instanceof AST_PropAccess
- || val instanceof AST_SymbolRef && val.name == "eval"
- )
- );
- }
- function is_func_expr(node) {
- return node instanceof AST_Arrow || node instanceof AST_Function;
- }
- /**
- * Used to determine whether the node can benefit from negation.
- * Not the case with arrow functions (you need an extra set of parens). */
- function is_iife_call(node) {
- if (node.TYPE != "Call") return false;
- return node.expression instanceof AST_Function || is_iife_call(node.expression);
- }
- function is_empty(thing) {
- if (thing === null) return true;
- if (thing instanceof AST_EmptyStatement) return true;
- if (thing instanceof AST_BlockStatement) return thing.body.length == 0;
- return false;
- }
- const identifier_atom = makePredicate("Infinity NaN undefined");
- function is_identifier_atom(node) {
- return node instanceof AST_Infinity
- || node instanceof AST_NaN
- || node instanceof AST_Undefined;
- }
- /** Check if this is a SymbolRef node which has one def of a certain AST type */
- function is_ref_of(ref, type) {
- if (!(ref instanceof AST_SymbolRef)) return false;
- var orig = ref.definition().orig;
- for (var i = orig.length; --i >= 0;) {
- if (orig[i] instanceof type) return true;
- }
- }
- /**Can we turn { block contents... } into just the block contents ?
- * Not if one of these is inside.
- **/
- function can_be_evicted_from_block(node) {
- return !(
- node instanceof AST_DefClass ||
- node instanceof AST_Defun ||
- node instanceof AST_Let ||
- node instanceof AST_Const ||
- node instanceof AST_Using ||
- node instanceof AST_Export ||
- node instanceof AST_Import
- );
- }
- function as_statement_array(thing) {
- if (thing === null) return [];
- if (thing instanceof AST_BlockStatement) return thing.body;
- if (thing instanceof AST_EmptyStatement) return [];
- if (thing instanceof AST_Statement) return [ thing ];
- throw new Error("Can't convert thing to statement array");
- }
- function is_reachable(scope_node, defs) {
- const find_ref = node => {
- if (node instanceof AST_SymbolRef && defs.includes(node.definition())) {
- return walk_abort;
- }
- };
- return walk_parent(scope_node, (node, info) => {
- if (node instanceof AST_Scope && node !== scope_node) {
- var parent = info.parent();
- if (
- parent instanceof AST_Call
- && parent.expression === node
- // Async/Generators aren't guaranteed to sync evaluate all of
- // their body steps, so it's possible they close over the variable.
- && !(node.async || node.is_generator)
- ) {
- return;
- }
- if (walk(node, find_ref)) return walk_abort;
- return true;
- }
- });
- }
- /** Check if a ref refers to the name of a function/class it's defined within */
- function is_recursive_ref(tw, def) {
- var node;
- for (var i = 0; node = tw.parent(i); i++) {
- if (node instanceof AST_Lambda || node instanceof AST_Class) {
- var name = node.name;
- if (name && name.definition() === def) {
- return true;
- }
- }
- }
- return false;
- }
- // TODO this only works with AST_Defun, shouldn't it work for other ways of defining functions?
- function retain_top_func(fn, compressor) {
- return compressor.top_retain
- && fn instanceof AST_Defun
- && has_flag(fn, TOP)
- && fn.name
- && compressor.top_retain(fn.name.definition());
- }
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- // Lists of native methods, useful for `unsafe` option which assumes they exist.
- // Note: Lots of methods and functions are missing here, in case they aren't pure
- // or not available in all JS environments.
- const make_nested_lookup = (feature_callback) => (compressor) => {
- const obj = feature_callback(feature_variables(compressor));
- const out = new Map();
- for (var key of Object.keys(obj)) {
- if (obj[key]) {
- out.set(key, makePredicate(remove_false(obj[key])));
- }
- }
- const does_have = (global_name, fname) => {
- const inner_map = out.get(global_name);
- return inner_map != null && inner_map.has(fname);
- };
- return does_have;
- };
- const make_lookup = (feature_callback) => (compressor) => {
- const obj = feature_callback(feature_variables(compressor));
- const predicate = makePredicate(remove_false(obj));
- const does_have = (global_name) => {
- return predicate.has(global_name);
- };
- return does_have;
- };
- function remove_false(arr) {
- for (let i = 0; i < arr.length; i++) {
- if (arr[i] === false) {
- arr.splice(i, 1);
- i--;
- }
- }
- return arr;
- }
- /** Generate the object with arguments seen below */
- function feature_variables(compressor) {
- return {
- sloppy: compressor.option("unsafe"),
- es: compressor.option("builtins_ecma"),
- };
- }
- // eslint-disable-next-line no-unused-vars
- const pure_access_globals = make_lookup(({ sloppy, es }) => [
- "Array",
- "Boolean",
- "clearInterval",
- "clearTimeout",
- "console",
- "Date",
- "decodeURI",
- "decodeURIComponent",
- "encodeURI",
- "encodeURIComponent",
- "Error",
- "escape",
- "eval",
- "EvalError",
- "Function",
- es >= 2020 && "globalThis",
- "isFinite",
- "isNaN",
- "JSON",
- "Math",
- "Number",
- "parseFloat",
- "parseInt",
- "RangeError",
- "ReferenceError",
- "RegExp",
- "Object",
- "setInterval",
- "setTimeout",
- "String",
- "SyntaxError",
- "TypeError",
- "unescape",
- "URIError",
- ]);
- // Objects which are safe to access without throwing or causing a side effect.
- // Usually we'd check the `unsafe` option first but these are way too common for that
- const pure_prop_access_globals = new Set([
- "Number",
- "String",
- "Array",
- "Object",
- "Function",
- "Promise",
- ]);
- // eslint-disable-next-line no-unused-vars
- const is_pure_native_fn = make_lookup(({ sloppy, es }) => [
- sloppy && es >= 2021 && "AggregateError",
- "Array",
- "ArrayBuffer",
- es >= 2020 && "BigInt",
- es >= 2020 && "BigInt64Array",
- es >= 2020 && "BigUint64Array",
- "Boolean",
- "Date",
- sloppy && "decodeURI",
- sloppy && "decodeURIComponent",
- sloppy && "encodeURI",
- sloppy && "encodeURIComponent",
- "Error",
- "escape",
- "EvalError",
- es >= 2021 && "FinalizationRegistry",
- es >= 2026 && "Float16Array",
- "Float32Array",
- "Float64Array",
- "Int16Array",
- "Int32Array",
- "Int8Array",
- "isFinite",
- "isNaN",
- es >= 2026 && "Iterator",
- es >= 2015 && "Map",
- "Number",
- "parseFloat",
- "parseInt",
- es >= 2015 && "Promise",
- es >= 2015 && "Proxy",
- "RangeError",
- "ReferenceError",
- sloppy && "RegExp",
- es >= 2015 && "Set",
- "String",
- es >= 2015 && "Symbol",
- "SyntaxError",
- "TypeError",
- "Uint16Array",
- "Uint32Array",
- "Uint8Array",
- "Uint8ClampedArray",
- sloppy && "unescape",
- "URIError",
- sloppy && es >= 2015 && "WeakMap",
- sloppy && es >= 2021 && "WeakRef",
- sloppy && es >= 2015 && "WeakSet",
- ]);
- const arg1_is_iterable = new Set([
- "Map",
- "Set",
- "WeakMap",
- "WeakSet",
- ]);
- const arg1_is_range_or_iterable = new Set([
- "ArrayBuffer",
- "Float32Array",
- "Float64Array",
- "Int16Array",
- "Int32Array",
- "Int8Array",
- "Uint16Array",
- "Uint32Array",
- "Uint8Array",
- "Uint8ClampedArray",
- ]);
- const lone_arg_is_range = new Set(["Array"]);
- const object_methods = [
- "constructor",
- "toString",
- "valueOf",
- ];
- // eslint-disable-next-line no-unused-vars
- const is_pure_native_method = make_nested_lookup(({ sloppy, es }) => ({
- Array: [
- es >= 2022 && "at",
- es >= 2019 && "flat",
- es >= 2016 && "includes",
- "indexOf",
- "join",
- "lastIndexOf",
- "slice",
- ...object_methods,
- ],
- Boolean: object_methods,
- Function: object_methods,
- Number: [
- "toExponential",
- "toFixed",
- "toPrecision",
- ...object_methods,
- ],
- Object: object_methods,
- RegExp: [
- "test",
- ...object_methods,
- ],
- String: [
- es >= 2022 && "at",
- "charAt",
- "charCodeAt",
- es >= 2015 && "codePointAt",
- "concat",
- es >= 2025 && "endsWith",
- es >= 2015 && "includes",
- "indexOf",
- "italics",
- "lastIndexOf",
- es >= 2020 && "localeCompare",
- "match",
- es >= 2020 && "matchAll",
- es >= 2015 && "normalize",
- es >= 2017 && "padStart",
- es >= 2017 && "padEnd",
- es >= 2015 && sloppy && "repeat",
- "replace",
- es >= 2021 && "replaceAll",
- "search",
- "slice",
- "split",
- es >= 2015 && "startsWith",
- "substr",
- "substring",
- es >= 2015 && "repeat",
- "toLocaleLowerCase",
- "toLocaleUpperCase",
- "toLowerCase",
- "toUpperCase",
- "trim",
- es >= 2019 && "trimEnd",
- es >= 2019 && "trimStart",
- es >= 2019 && "trimLeft",
- es >= 2019 && "trimRight",
- ...object_methods,
- ],
- }));
- // eslint-disable-next-line no-unused-vars
- const is_pure_native_static_fn = make_nested_lookup(({ sloppy, es }) => ({
- Array: [
- "isArray",
- es >= 2015 && "of",
- ],
- ArrayBuffer: [
- "isView",
- ],
- BigInt: es >= 2020 && [
- sloppy && "asIntN",
- sloppy && "asUintN",
- ],
- BigInt64Array: sloppy && es >= 2020 && ["of"],
- BigUint64Array: sloppy && es >= 2020 && ["of"],
- Date: [
- "now",
- "parse",
- "UTC",
- ],
- Error: [
- es >= 2026 && "isError",
- ],
- Float16Array: sloppy && es >= 2026 && ["of"],
- Float32Array: sloppy && ["of"],
- Float64Array: sloppy && ["of"],
- Int16Array: sloppy && ["of"],
- Int32Array: sloppy && ["of"],
- Int8Array: sloppy && ["of"],
- Math: [
- "abs",
- "acos",
- es >= 2015 && "acosh",
- "asin",
- es >= 2015 && "asinh",
- "atan",
- "atan2",
- es >= 2015 && "atanh",
- es >= 2015 && "cbrt",
- "ceil",
- es >= 2015 && "clz32",
- "cos",
- es >= 2015 && "cosh",
- "exp",
- es >= 2015 && "expm1",
- "floor",
- es >= 2026 && "f16round",
- es >= 2015 && "fround",
- es >= 2015 && "hypot",
- es >= 2015 && "imul",
- "log",
- es >= 2015 && "log10",
- es >= 2015 && "log1p",
- es >= 2015 && "log2",
- "max",
- "min",
- "pow",
- "round",
- es >= 2015 && "sign",
- "sin",
- es >= 2015 && "sinh",
- "sqrt",
- "tan",
- es >= 2015 && "tanh",
- es >= 2015 && "trunc",
- ],
- Number: [
- es >= 2015 && "isFinite",
- es >= 2015 && "isInteger",
- es >= 2015 && "isSafeInteger",
- es >= 2015 && "isNaN",
- es >= 2015 && "parseFloat",
- es >= 2015 && "parseInt",
- ],
- Object: [
- sloppy && "create",
- sloppy && "getOwnPropertyDescriptor",
- es >= 2017 && sloppy && "getOwnPropertyDescriptors",
- sloppy && "getOwnPropertyNames",
- es >= 2015 && sloppy && "getOwnPropertySymbols",
- sloppy && "getPrototypeOf",
- es >= 2022 && sloppy && "hasOwn",
- es >= 2015 && "is",
- "isExtensible",
- "isFrozen",
- "isSealed",
- es >= 2015 && sloppy && "keys",
- ],
- Promise: es >= 2015 && [
- es >= 2024 && "withResolvers",
- ],
- Proxy: es >= 2015 && [
- sloppy && "revocable",
- ],
- Reflect: es >= 2015 && [
- sloppy && "has",
- sloppy && "isExtensible",
- sloppy && "ownKeys",
- ],
- RegExp: [
- es >= 2026 && sloppy && "escape",
- ],
- String: [
- "fromCharCode",
- sloppy && es >= 2025 && "fromCodePoint",
- ],
- Uint16Array: ["of"],
- Uint32Array: ["of"],
- Uint8Array: ["of"],
- Uint8ClampedArray: ["of"],
- }));
- // Known numeric values which come with JS environments
- // eslint-disable-next-line no-unused-vars
- const is_pure_native_static_property = make_nested_lookup(({ sloppy, es }) => ({
- Math: [
- "E",
- "LN10",
- "LN2",
- "LOG2E",
- "LOG10E",
- "PI",
- "SQRT1_2",
- "SQRT2",
- ],
- Number: [
- es >= 2015 && "EPSILON",
- es >= 2015 && "MAX_SAFE_VALUE",
- "MAX_VALUE",
- es >= 2015 && "MIN_SAFE_VALUE",
- "MIN_VALUE",
- "NaN",
- "NEGATIVE_INFINITY",
- "POSITIVE_INFINITY",
- ],
- RegExp: [
- "$_",
- "$0",
- "$1",
- "$2",
- "$3",
- "$4",
- "$5",
- "$6",
- "$7",
- "$8",
- "$9",
- "input",
- "lastMatch",
- "lastParen",
- "leftContext",
- "rightContext",
- ],
- }));
- const re_uppercase_first_letter = /^[A-Z]/;
- function is_pure_builtin_call(compressor, call) {
- let builtin = "";
- let method = "";
- let exp = call.expression;
- if (is_undeclared_ref(exp)) {
- builtin = exp.name;
- } else if (exp instanceof AST_Dot) {
- method = exp.property;
- exp = exp.expression;
- if (is_undeclared_ref(exp)) {
- if (
- // globalThis.pureFunc()
- exp.name === "globalThis"
- && compressor.option("builtins_ecma") >= 2020
- ) {
- builtin = method;
- method = "";
- } else {
- // SomeBuiltin.pureFunc()
- builtin = exp.name;
- }
- } else if (exp instanceof AST_Dot) {
- if (
- is_undeclared_ref(exp.expression)
- && exp.expression.name === "globalThis"
- && compressor.option("builtins_ecma") >= 2020
- ) {
- // globalThis.SomeBuiltin.pureFunc()
- builtin = exp.property;
- } else {
- return false;
- }
- } else {
- return false;
- }
- } else {
- return false;
- }
- if (!method) {
- if (compressor.is_pure_native_fn(builtin)) {
- // some require `new`, others throw if you use it
- const is_new = call instanceof AST_New;
- const should_be_new = re_uppercase_first_letter.test(builtin); // true of all `is_pure_native_fn`
- if (is_new !== should_be_new) return false;
- if (!is_builtin_pure_with_these_args(builtin, call.args)) {
- return false;
- }
- return true;
- }
- return false;
- } else {
- return compressor.is_pure_native_static_fn(builtin, method);
- }
- }
- /** Some builtins are listed above but their purity is subject to some conditions */
- function is_builtin_pure_with_these_args(builtin, args) {
- // all the builtins we deal with here are ok with getting 0 args
- if (args.length === 0) return true;
- let arg1 = args[0];
- if (arg1 instanceof AST_SymbolRef) {
- arg1 = arg1.fixed_value();
- }
- if (lone_arg_is_range.has(builtin)) { // new Array(number)
- const arg_valid = args.length > 1
- || arg1 instanceof AST_Number
- && arg1.value >= 0 && arg1.value <= 0xffffffff;
- // TODO: or, we are asked to ignore TypeError
- if (!arg_valid) return false;
- }
- if (arg1_is_range_or_iterable.has(builtin)) { // new Float32Array(number | Array)
- const arg_valid = args.length === 0
- || arg1 instanceof AST_Array
- || arg1 instanceof AST_Number
- && arg1.value >= 0 && arg1.value <= 0xffffffff;
- if (!arg_valid) return false;
- }
- if (arg1_is_iterable.has(builtin)) { // new Set(iterable)
- const arg_valid = args.length === 0 || arg1 instanceof AST_Array;
- if (!arg_valid) return false;
- }
- return true;
- }
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- // Functions and methods to infer certain facts about expressions
- // It's not always possible to be 100% sure about something just by static analysis,
- // so `true` means yes, and `false` means maybe
- const is_undeclared_ref = (node) =>
- node instanceof AST_SymbolRef && node.definition().undeclared;
- const bitwise_binop = makePredicate("<<< >> << & | ^ ~");
- const lazy_op = makePredicate("&& || ??");
- const unary_side_effects = makePredicate("delete ++ --");
- // methods to determine whether an expression has a boolean result type
- (function(def_is_boolean) {
- const unary_bool = makePredicate("! delete");
- const binary_bool = makePredicate("in instanceof == != === !== < <= >= >");
- def_is_boolean(AST_Node, return_false);
- def_is_boolean(AST_UnaryPrefix, function() {
- return unary_bool.has(this.operator);
- });
- def_is_boolean(AST_Binary, function() {
- return binary_bool.has(this.operator)
- || lazy_op.has(this.operator)
- && this.left.is_boolean()
- && this.right.is_boolean();
- });
- def_is_boolean(AST_Conditional, function() {
- return this.consequent.is_boolean() && this.alternative.is_boolean();
- });
- def_is_boolean(AST_Assign, function() {
- return this.operator == "=" && this.right.is_boolean();
- });
- def_is_boolean(AST_Sequence, function() {
- return this.tail_node().is_boolean();
- });
- def_is_boolean(AST_True, return_true);
- def_is_boolean(AST_False, return_true);
- })(function(node, func) {
- node.DEFMETHOD("is_boolean", func);
- });
- // methods to determine if an expression has a numeric result type
- (function(def_is_number) {
- def_is_number(AST_Node, return_false);
- def_is_number(AST_Number, return_true);
- const unary = makePredicate("+ - ~ ++ --");
- def_is_number(AST_Unary, function(compressor) {
- return unary.has(this.operator) && this.expression.is_number(compressor);
- });
- const numeric_ops = makePredicate("- * / % & | ^ << >> >>>");
- def_is_number(AST_Binary, function(compressor) {
- if (this.operator === "+") {
- // Both sides need to be `number`. Or one is a `number` and the other is number-ish.
- return this.left.is_number(compressor) && this.right.is_number_or_bigint(compressor)
- || this.right.is_number(compressor) && this.left.is_number_or_bigint(compressor);
- } else if (numeric_ops.has(this.operator)) {
- return this.left.is_number(compressor) || this.right.is_number(compressor);
- } else {
- return false;
- }
- });
- def_is_number(AST_Assign, function(compressor) {
- return (this.operator === "=" || numeric_ops.has(this.operator.slice(0, -1)))
- && this.right.is_number(compressor);
- });
- def_is_number(AST_Sequence, function(compressor) {
- return this.tail_node().is_number(compressor);
- });
- def_is_number(AST_Conditional, function(compressor) {
- return this.consequent.is_number(compressor) && this.alternative.is_number(compressor);
- });
- })(function(node, func) {
- node.DEFMETHOD("is_number", func);
- });
- // methods to determine if an expression returns a BigInt
- (function(def_is_bigint) {
- def_is_bigint(AST_Node, return_false);
- def_is_bigint(AST_BigInt, return_true);
- const unary = makePredicate("+ - ~ ++ --");
- def_is_bigint(AST_Unary, function(compressor) {
- return unary.has(this.operator) && this.expression.is_bigint(compressor);
- });
- const numeric_ops = makePredicate("- * / % & | ^ << >>");
- def_is_bigint(AST_Binary, function(compressor) {
- if (this.operator === "+") {
- return this.left.is_bigint(compressor) && this.right.is_number_or_bigint(compressor)
- || this.right.is_bigint(compressor) && this.left.is_number_or_bigint(compressor);
- } else if (numeric_ops.has(this.operator)) {
- return this.left.is_bigint(compressor) || this.right.is_bigint(compressor);
- } else {
- return false;
- }
- });
- def_is_bigint(AST_Assign, function(compressor) {
- return (numeric_ops.has(this.operator.slice(0, -1)) || this.operator == "=")
- && this.right.is_bigint(compressor);
- });
- def_is_bigint(AST_Sequence, function(compressor) {
- return this.tail_node().is_bigint(compressor);
- });
- def_is_bigint(AST_Conditional, function(compressor) {
- return this.consequent.is_bigint(compressor) && this.alternative.is_bigint(compressor);
- });
- })(function(node, func) {
- node.DEFMETHOD("is_bigint", func);
- });
- // methods to determine if an expression is a number or a bigint
- (function(def_is_number_or_bigint) {
- def_is_number_or_bigint(AST_Node, return_false);
- def_is_number_or_bigint(AST_Number, return_true);
- def_is_number_or_bigint(AST_BigInt, return_true);
- const numeric_unary_ops = makePredicate("+ - ~ ++ --");
- def_is_number_or_bigint(AST_Unary, function(_compressor) {
- return numeric_unary_ops.has(this.operator);
- });
- const numeric_ops = makePredicate("- * / % & | ^ << >>");
- def_is_number_or_bigint(AST_Binary, function(compressor) {
- return this.operator === "+"
- ? this.left.is_number_or_bigint(compressor) && this.right.is_number_or_bigint(compressor)
- : numeric_ops.has(this.operator);
- });
- def_is_number_or_bigint(AST_Assign, function(compressor) {
- return numeric_ops.has(this.operator.slice(0, -1))
- || this.operator == "=" && this.right.is_number_or_bigint(compressor);
- });
- def_is_number_or_bigint(AST_Sequence, function(compressor) {
- return this.tail_node().is_number_or_bigint(compressor);
- });
- def_is_number_or_bigint(AST_Conditional, function(compressor) {
- return this.consequent.is_number_or_bigint(compressor) && this.alternative.is_number_or_bigint(compressor);
- });
- }(function (node, func) {
- node.DEFMETHOD("is_number_or_bigint", func);
- }));
- // methods to determine if an expression is a 32 bit integer (IE results from bitwise ops, or is an integer constant fitting in that size
- (function(def_is_32_bit_integer) {
- def_is_32_bit_integer(AST_Node, return_false);
- def_is_32_bit_integer(AST_Number, function(_compressor) {
- return this.value === (this.value | 0);
- });
- def_is_32_bit_integer(AST_UnaryPrefix, function(compressor) {
- return this.operator == "~" ? this.expression.is_number(compressor)
- : this.operator === "+" ? this.expression.is_32_bit_integer(compressor)
- : false;
- });
- def_is_32_bit_integer(AST_Binary, function(compressor) {
- return bitwise_binop.has(this.operator)
- && (this.left.is_number(compressor) || this.right.is_number(compressor));
- });
- }(function (node, func) {
- node.DEFMETHOD("is_32_bit_integer", func);
- }));
- // methods to determine if an expression has a string result type
- (function(def_is_string) {
- def_is_string(AST_Node, return_false);
- def_is_string(AST_String, return_true);
- def_is_string(AST_TemplateString, return_true);
- def_is_string(AST_UnaryPrefix, function() {
- return this.operator == "typeof";
- });
- def_is_string(AST_Binary, function(compressor) {
- return this.operator == "+" &&
- (this.left.is_string(compressor) || this.right.is_string(compressor));
- });
- def_is_string(AST_Assign, function(compressor) {
- return (this.operator == "=" || this.operator == "+=") && this.right.is_string(compressor);
- });
- def_is_string(AST_Sequence, function(compressor) {
- return this.tail_node().is_string(compressor);
- });
- def_is_string(AST_Conditional, function(compressor) {
- return this.consequent.is_string(compressor) && this.alternative.is_string(compressor);
- });
- })(function(node, func) {
- node.DEFMETHOD("is_string", func);
- });
- function is_undefined(node, compressor) {
- return (
- has_flag(node, UNDEFINED)
- || node instanceof AST_Undefined
- || node instanceof AST_UnaryPrefix
- && node.operator == "void"
- && !node.expression.has_side_effects(compressor)
- );
- }
- // Is the node explicitly null or undefined.
- function is_null_or_undefined(node, compressor) {
- let fixed;
- return (
- node instanceof AST_Null
- || is_undefined(node, compressor)
- || (
- node instanceof AST_SymbolRef
- && (fixed = node.definition().fixed) instanceof AST_Node
- && is_nullish(fixed, compressor)
- )
- );
- }
- // Find out if this expression is optionally chained from a base-point that we
- // can statically analyze as null or undefined.
- function is_nullish_shortcircuited(node, compressor) {
- if (node instanceof AST_PropAccess || node instanceof AST_Call) {
- return (
- (node.optional && is_null_or_undefined(node.expression, compressor))
- || is_nullish_shortcircuited(node.expression, compressor)
- );
- }
- if (node instanceof AST_Chain) return is_nullish_shortcircuited(node.expression, compressor);
- return false;
- }
- // Find out if something is == null, or can short circuit into nullish.
- // Used to optimize ?. and ??
- function is_nullish(node, compressor) {
- if (is_null_or_undefined(node, compressor)) return true;
- return is_nullish_shortcircuited(node, compressor);
- }
- // Determine if expression might cause side effects
- // If there's a possibility that a node may change something when it's executed, this returns true
- (function(def_has_side_effects) {
- def_has_side_effects(AST_Node, return_true);
- def_has_side_effects(AST_EmptyStatement, return_false);
- def_has_side_effects(AST_Constant, return_false);
- def_has_side_effects(AST_This, return_false);
- function any(list, compressor) {
- for (var i = list.length; --i >= 0;)
- if (list[i].has_side_effects(compressor))
- return true;
- return false;
- }
- def_has_side_effects(AST_Block, function(compressor) {
- return any(this.body, compressor);
- });
- def_has_side_effects(AST_Call, function(compressor) {
- if (
- !this.is_callee_pure(compressor)
- && (!this.expression.is_call_pure(compressor)
- || this.expression.has_side_effects(compressor))
- ) {
- return true;
- }
- return any(this.args, compressor);
- });
- def_has_side_effects(AST_Switch, function(compressor) {
- return this.expression.has_side_effects(compressor)
- || any(this.body, compressor);
- });
- def_has_side_effects(AST_Case, function(compressor) {
- return this.expression.has_side_effects(compressor)
- || any(this.body, compressor);
- });
- def_has_side_effects(AST_Try, function(compressor) {
- return this.body.has_side_effects(compressor)
- || this.bcatch && this.bcatch.has_side_effects(compressor)
- || this.bfinally && this.bfinally.has_side_effects(compressor);
- });
- def_has_side_effects(AST_If, function(compressor) {
- return this.condition.has_side_effects(compressor)
- || this.body && this.body.has_side_effects(compressor)
- || this.alternative && this.alternative.has_side_effects(compressor);
- });
- def_has_side_effects(AST_ImportMeta, return_false);
- def_has_side_effects(AST_DynamicImport, function() {
- // `import.source(x)` only compiles the module, which is side-effect free
- return this.phase !== "source";
- });
- def_has_side_effects(AST_LabeledStatement, function(compressor) {
- return this.body.has_side_effects(compressor);
- });
- def_has_side_effects(AST_SimpleStatement, function(compressor) {
- return this.body.has_side_effects(compressor);
- });
- def_has_side_effects(AST_Lambda, return_false);
- def_has_side_effects(AST_Class, function (compressor) {
- if (this.extends && this.extends.has_side_effects(compressor)) {
- return true;
- }
- return any(this.properties, compressor);
- });
- def_has_side_effects(AST_ClassStaticBlock, function(compressor) {
- return any(this.body, compressor);
- });
- def_has_side_effects(AST_Binary, function(compressor) {
- return this.left.has_side_effects(compressor)
- || this.right.has_side_effects(compressor);
- });
- def_has_side_effects(AST_Assign, return_true);
- def_has_side_effects(AST_Conditional, function(compressor) {
- return this.condition.has_side_effects(compressor)
- || this.consequent.has_side_effects(compressor)
- || this.alternative.has_side_effects(compressor);
- });
- def_has_side_effects(AST_Unary, function(compressor) {
- return unary_side_effects.has(this.operator)
- || this.expression.has_side_effects(compressor);
- });
- def_has_side_effects(AST_SymbolRef, function(compressor) {
- return !this.is_declared(compressor) && !pure_prop_access_globals.has(this.name);
- });
- def_has_side_effects(AST_SymbolClassProperty, return_false);
- def_has_side_effects(AST_SymbolDeclaration, return_false);
- def_has_side_effects(AST_Object, function(compressor) {
- return any(this.properties, compressor);
- });
- def_has_side_effects(AST_ObjectKeyVal, function(compressor) {
- return (
- this.computed_key() && this.key.has_side_effects(compressor)
- || this.value && this.value.has_side_effects(compressor)
- );
- });
- def_has_side_effects([
- AST_ClassProperty,
- AST_ClassPrivateProperty,
- ], function(compressor) {
- return (
- this.computed_key() && this.key.has_side_effects(compressor)
- || this.static && this.value && this.value.has_side_effects(compressor)
- );
- });
- def_has_side_effects([
- AST_PrivateMethod,
- AST_PrivateGetter,
- AST_PrivateSetter,
- AST_ConciseMethod,
- AST_ObjectGetter,
- AST_ObjectSetter,
- ], function(compressor) {
- return this.computed_key() && this.key.has_side_effects(compressor);
- });
- def_has_side_effects(AST_Array, function(compressor) {
- return any(this.elements, compressor);
- });
- def_has_side_effects(AST_Dot, function(compressor) {
- if (is_nullish(this, compressor)) {
- return this.expression.has_side_effects(compressor);
- }
- if (!this.optional && this.expression.may_throw_on_access(compressor)) {
- return true;
- }
- return this.expression.has_side_effects(compressor);
- });
- def_has_side_effects(AST_Sub, function(compressor) {
- if (is_nullish(this, compressor)) {
- return this.expression.has_side_effects(compressor);
- }
- if (!this.optional && this.expression.may_throw_on_access(compressor)) {
- return true;
- }
- var property = this.property.has_side_effects(compressor);
- if (property && this.optional) return true; // "?." is a condition
- return property || this.expression.has_side_effects(compressor);
- });
- def_has_side_effects(AST_Chain, function (compressor) {
- return this.expression.has_side_effects(compressor);
- });
- def_has_side_effects(AST_Sequence, function(compressor) {
- return any(this.expressions, compressor);
- });
- def_has_side_effects(AST_Definitions, function(compressor) {
- return any(this.definitions, compressor);
- });
- def_has_side_effects(AST_VarDef, function() {
- return this.value != null;
- });
- def_has_side_effects(AST_TemplateSegment, return_false);
- def_has_side_effects(AST_TemplateString, function(compressor) {
- return any(this.segments, compressor);
- });
- })(function(node_or_nodes, func) {
- for (const node of [].concat(node_or_nodes)) {
- node.DEFMETHOD("has_side_effects", func);
- }
- });
- // determine if expression may throw
- (function(def_may_throw) {
- def_may_throw(AST_Node, return_true);
- def_may_throw(AST_Constant, return_false);
- def_may_throw(AST_EmptyStatement, return_false);
- def_may_throw(AST_Lambda, return_false);
- def_may_throw(AST_SymbolDeclaration, return_false);
- def_may_throw(AST_This, return_false);
- def_may_throw(AST_ImportMeta, return_false);
- function any(list, compressor) {
- for (var i = list.length; --i >= 0;)
- if (list[i].may_throw(compressor))
- return true;
- return false;
- }
- def_may_throw(AST_Class, function(compressor) {
- if (this.extends && this.extends.may_throw(compressor)) return true;
- return any(this.properties, compressor);
- });
- def_may_throw(AST_ClassStaticBlock, function (compressor) {
- return any(this.body, compressor);
- });
- def_may_throw(AST_Array, function(compressor) {
- return any(this.elements, compressor);
- });
- def_may_throw(AST_Assign, function(compressor) {
- if (this.right.may_throw(compressor)) return true;
- if (!compressor.has_directive("use strict")
- && this.operator == "="
- && this.left instanceof AST_SymbolRef) {
- return false;
- }
- return this.left.may_throw(compressor);
- });
- def_may_throw(AST_Binary, function(compressor) {
- return this.left.may_throw(compressor)
- || this.right.may_throw(compressor);
- });
- def_may_throw(AST_Block, function(compressor) {
- return any(this.body, compressor);
- });
- def_may_throw(AST_Call, function(compressor) {
- if (is_nullish(this, compressor)) return false;
- if (any(this.args, compressor)) return true;
- if (this.is_callee_pure(compressor)) return false;
- if (this.expression.may_throw(compressor)) return true;
- return !(this.expression instanceof AST_Lambda)
- || any(this.expression.body, compressor);
- });
- def_may_throw(AST_Case, function(compressor) {
- return this.expression.may_throw(compressor)
- || any(this.body, compressor);
- });
- def_may_throw(AST_Conditional, function(compressor) {
- return this.condition.may_throw(compressor)
- || this.consequent.may_throw(compressor)
- || this.alternative.may_throw(compressor);
- });
- def_may_throw(AST_Definitions, function(compressor) {
- return any(this.definitions, compressor);
- });
- def_may_throw(AST_If, function(compressor) {
- return this.condition.may_throw(compressor)
- || this.body && this.body.may_throw(compressor)
- || this.alternative && this.alternative.may_throw(compressor);
- });
- def_may_throw(AST_LabeledStatement, function(compressor) {
- return this.body.may_throw(compressor);
- });
- def_may_throw(AST_Object, function(compressor) {
- return any(this.properties, compressor);
- });
- def_may_throw(AST_ObjectKeyVal, function(compressor) {
- return (
- this.computed_key() && this.key.may_throw(compressor)
- || this.value ? this.value.may_throw(compressor) : false
- );
- });
- def_may_throw([
- AST_ClassProperty,
- AST_ClassPrivateProperty,
- ], function(compressor) {
- return (
- this.computed_key() && this.key.may_throw(compressor)
- || this.static && this.value && this.value.may_throw(compressor)
- );
- });
- def_may_throw([
- AST_ConciseMethod,
- AST_ObjectGetter,
- AST_ObjectSetter,
- ], function(compressor) {
- return this.computed_key() && this.key.may_throw(compressor);
- });
- def_may_throw([
- AST_PrivateMethod,
- AST_PrivateGetter,
- AST_PrivateSetter,
- ], return_false);
- def_may_throw(AST_Return, function(compressor) {
- return this.value && this.value.may_throw(compressor);
- });
- def_may_throw(AST_Sequence, function(compressor) {
- return any(this.expressions, compressor);
- });
- def_may_throw(AST_SimpleStatement, function(compressor) {
- return this.body.may_throw(compressor);
- });
- def_may_throw(AST_Dot, function(compressor) {
- if (is_nullish(this, compressor)) return false;
- return !this.optional && this.expression.may_throw_on_access(compressor)
- || this.expression.may_throw(compressor);
- });
- def_may_throw(AST_Sub, function(compressor) {
- if (is_nullish(this, compressor)) return false;
- return !this.optional && this.expression.may_throw_on_access(compressor)
- || this.expression.may_throw(compressor)
- || this.property.may_throw(compressor);
- });
- def_may_throw(AST_Chain, function(compressor) {
- return this.expression.may_throw(compressor);
- });
- def_may_throw(AST_Switch, function(compressor) {
- return this.expression.may_throw(compressor)
- || any(this.body, compressor);
- });
- def_may_throw(AST_SymbolRef, function(compressor) {
- return !this.is_declared(compressor) && !pure_prop_access_globals.has(this.name);
- });
- def_may_throw(AST_SymbolClassProperty, return_false);
- def_may_throw(AST_Try, function(compressor) {
- return this.bcatch ? this.bcatch.may_throw(compressor) : this.body.may_throw(compressor)
- || this.bfinally && this.bfinally.may_throw(compressor);
- });
- def_may_throw(AST_Unary, function(compressor) {
- if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef)
- return false;
- return this.expression.may_throw(compressor);
- });
- def_may_throw(AST_VarDef, function(compressor) {
- if (!this.value) return false;
- return this.value.may_throw(compressor);
- });
- })(function(node_or_nodes, func) {
- for (const node of [].concat(node_or_nodes)) {
- node.DEFMETHOD("may_throw", func);
- }
- });
- // determine if expression is constant
- (function(def_is_constant_expression) {
- function all_refs_local(scope) {
- let result = true;
- walk(this, node => {
- if (node instanceof AST_SymbolRef) {
- if (has_flag(this, INLINED)) {
- result = false;
- return walk_abort;
- }
- var def = node.definition();
- if (
- member(def, this.enclosed)
- && !this.variables.has(def.name)
- ) {
- if (scope) {
- var scope_def = scope.find_variable(node);
- if (def.undeclared ? !scope_def : scope_def === def) {
- result = "f";
- return true;
- }
- }
- result = false;
- return walk_abort;
- }
- return true;
- }
- if (node instanceof AST_This && this instanceof AST_Arrow) {
- result = false;
- return walk_abort;
- }
- });
- return result;
- }
- def_is_constant_expression(AST_Node, return_false);
- def_is_constant_expression(AST_Constant, return_true);
- def_is_constant_expression(AST_Class, function(scope) {
- if (this.extends && !this.extends.is_constant_expression(scope)) {
- return false;
- }
- for (const prop of this.properties) {
- if (prop.computed_key() && !prop.key.is_constant_expression(scope)) {
- return false;
- }
- if (prop.static && prop.value && !prop.value.is_constant_expression(scope)) {
- return false;
- }
- if (prop instanceof AST_ClassStaticBlock) {
- return false;
- }
- }
- return all_refs_local.call(this, scope);
- });
- def_is_constant_expression(AST_Lambda, all_refs_local);
- def_is_constant_expression(AST_Unary, function() {
- return this.expression.is_constant_expression();
- });
- def_is_constant_expression(AST_Binary, function() {
- return this.left.is_constant_expression()
- && this.right.is_constant_expression();
- });
- def_is_constant_expression(AST_Array, function() {
- return this.elements.every((l) => l.is_constant_expression());
- });
- def_is_constant_expression(AST_Object, function() {
- return this.properties.every((l) => l.is_constant_expression());
- });
- def_is_constant_expression(AST_ObjectProperty, function() {
- return !!(!(this.key instanceof AST_Node) && this.value && this.value.is_constant_expression());
- });
- })(function(node, func) {
- node.DEFMETHOD("is_constant_expression", func);
- });
- // may_throw_on_access()
- // returns true if this node may be null, undefined or contain `AST_Accessor`
- (function(def_may_throw_on_access) {
- AST_Node.DEFMETHOD("may_throw_on_access", function(compressor) {
- return !compressor.option("pure_getters")
- || this._dot_throw(compressor);
- });
- function is_strict(compressor) {
- return /strict/.test(compressor.option("pure_getters"));
- }
- def_may_throw_on_access(AST_Node, is_strict);
- def_may_throw_on_access(AST_Null, return_true);
- def_may_throw_on_access(AST_Undefined, return_true);
- def_may_throw_on_access(AST_Constant, return_false);
- def_may_throw_on_access(AST_Array, return_false);
- def_may_throw_on_access(AST_Object, function(compressor) {
- if (!is_strict(compressor)) return false;
- for (var i = this.properties.length; --i >=0;)
- if (this.properties[i]._dot_throw(compressor)) return true;
- return false;
- });
- // Do not be as strict with classes as we are with objects.
- // Hopefully the community is not going to abuse static getters and setters.
- // https://github.com/terser/terser/issues/724#issuecomment-643655656
- def_may_throw_on_access(AST_Class, return_false);
- def_may_throw_on_access(AST_ObjectProperty, return_false);
- def_may_throw_on_access(AST_ObjectGetter, return_true);
- def_may_throw_on_access(AST_Expansion, function(compressor) {
- return this.expression._dot_throw(compressor);
- });
- def_may_throw_on_access(AST_Function, return_false);
- def_may_throw_on_access(AST_Arrow, return_false);
- def_may_throw_on_access(AST_UnaryPostfix, return_false);
- def_may_throw_on_access(AST_UnaryPrefix, function() {
- return this.operator == "void";
- });
- def_may_throw_on_access(AST_Binary, function(compressor) {
- return (this.operator == "&&" || this.operator == "||" || this.operator == "??")
- && (this.left._dot_throw(compressor) || this.right._dot_throw(compressor));
- });
- def_may_throw_on_access(AST_Assign, function(compressor) {
- if (this.logical) return true;
- return this.operator == "="
- && this.right._dot_throw(compressor);
- });
- def_may_throw_on_access(AST_Conditional, function(compressor) {
- return this.consequent._dot_throw(compressor)
- || this.alternative._dot_throw(compressor);
- });
- def_may_throw_on_access(AST_Dot, function(compressor) {
- if (!is_strict(compressor)) return false;
- if (this.property == "prototype") {
- return !(
- this.expression instanceof AST_Function
- || this.expression instanceof AST_Class
- );
- }
- return true;
- });
- def_may_throw_on_access(AST_Chain, function(compressor) {
- return this.expression._dot_throw(compressor);
- });
- def_may_throw_on_access(AST_Sequence, function(compressor) {
- return this.tail_node()._dot_throw(compressor);
- });
- def_may_throw_on_access(AST_SymbolRef, function(compressor) {
- if (this.name === "arguments" && this.scope instanceof AST_Lambda) return false;
- if (has_flag(this, UNDEFINED)) return true;
- if (!is_strict(compressor)) return false;
- if (is_undeclared_ref(this) && this.is_declared(compressor)) return false;
- if (this.is_immutable()) return false;
- var fixed = this.fixed_value();
- return !fixed || fixed._dot_throw(compressor);
- });
- })(function(node, func) {
- node.DEFMETHOD("_dot_throw", func);
- });
- function is_lhs(node, parent) {
- if (parent instanceof AST_Unary && unary_side_effects.has(parent.operator)) return parent.expression;
- if (parent instanceof AST_Assign && parent.left === node) return node;
- if (parent instanceof AST_ForIn && parent.init === node) return node;
- }
- // method to negate an expression
- (function(def_negate) {
- function basic_negation(exp) {
- return make_node(AST_UnaryPrefix, exp, {
- operator: "!",
- expression: exp
- });
- }
- function best(orig, alt, first_in_statement) {
- var negated = basic_negation(orig);
- if (first_in_statement) {
- var stat = make_node(AST_SimpleStatement, alt, {
- body: alt
- });
- return best_of_expression(negated, stat) === stat ? alt : negated;
- }
- return best_of_expression(negated, alt);
- }
- def_negate(AST_Node, function() {
- return basic_negation(this);
- });
- def_negate(AST_Statement, function() {
- throw new Error("Cannot negate a statement");
- });
- def_negate(AST_Function, function() {
- return basic_negation(this);
- });
- def_negate(AST_Class, function() {
- return basic_negation(this);
- });
- def_negate(AST_Arrow, function() {
- return basic_negation(this);
- });
- def_negate(AST_UnaryPrefix, function() {
- if (this.operator == "!")
- return this.expression;
- return basic_negation(this);
- });
- def_negate(AST_Sequence, function(compressor) {
- var expressions = this.expressions.slice();
- expressions.push(expressions.pop().negate(compressor));
- return make_sequence(this, expressions);
- });
- def_negate(AST_Conditional, function(compressor, first_in_statement) {
- var self = this.clone();
- self.consequent = self.consequent.negate(compressor);
- self.alternative = self.alternative.negate(compressor);
- return best(this, self, first_in_statement);
- });
- def_negate(AST_Binary, function(compressor, first_in_statement) {
- var self = this.clone(), op = this.operator;
- if (compressor.option("unsafe_comps")) {
- switch (op) {
- case "<=" : self.operator = ">" ; return self;
- case "<" : self.operator = ">=" ; return self;
- case ">=" : self.operator = "<" ; return self;
- case ">" : self.operator = "<=" ; return self;
- }
- }
- switch (op) {
- case "==" : self.operator = "!="; return self;
- case "!=" : self.operator = "=="; return self;
- case "===": self.operator = "!=="; return self;
- case "!==": self.operator = "==="; return self;
- case "&&":
- self.operator = "||";
- self.left = self.left.negate(compressor, first_in_statement);
- self.right = self.right.negate(compressor);
- return best(this, self, first_in_statement);
- case "||":
- self.operator = "&&";
- self.left = self.left.negate(compressor, first_in_statement);
- self.right = self.right.negate(compressor);
- return best(this, self, first_in_statement);
- }
- return basic_negation(this);
- });
- })(function(node, func) {
- node.DEFMETHOD("negate", function(compressor, first_in_statement) {
- return func.call(this, compressor, first_in_statement);
- });
- });
- (function (def_bitwise_negate) {
- function basic_bitwise_negation(exp) {
- return make_node(AST_UnaryPrefix, exp, {
- operator: "~",
- expression: exp
- });
- }
- def_bitwise_negate(AST_Node, function(_compressor) {
- return basic_bitwise_negation(this);
- });
- def_bitwise_negate(AST_Number, function(_compressor) {
- const neg = ~this.value;
- if (neg.toString().length > this.value.toString().length) {
- return basic_bitwise_negation(this);
- }
- return make_node(AST_Number, this, { value: neg });
- });
- def_bitwise_negate(AST_UnaryPrefix, function(compressor, in_32_bit_context) {
- if (
- this.operator == "~"
- && (
- this.expression.is_32_bit_integer(compressor) ||
- (in_32_bit_context != null ? in_32_bit_context : compressor.in_32_bit_context())
- )
- ) {
- return this.expression;
- } else {
- return basic_bitwise_negation(this);
- }
- });
- })(function (node, func) {
- node.DEFMETHOD("bitwise_negate", func);
- });
- // Is the callee of this function pure?
- var global_pure_fns = makePredicate("Boolean decodeURI decodeURIComponent Date encodeURI encodeURIComponent Error escape EvalError isFinite isNaN Number Object parseFloat parseInt RangeError ReferenceError String SyntaxError TypeError unescape URIError");
- AST_Call.DEFMETHOD("is_callee_pure", function(compressor) {
- if (compressor.option("unsafe")) {
- var expr = this.expression;
- var first_arg;
- if (
- expr.expression && expr.expression.name === "hasOwnProperty" &&
- (
- (first_arg = (this.args && this.args[0] && this.args[0].evaluate(compressor))) == null
- || first_arg.thedef && first_arg.thedef.undeclared
- )
- ) {
- return false;
- }
- if (is_undeclared_ref(expr) && global_pure_fns.has(expr.name)) return true;
- if (is_pure_builtin_call(compressor, this)) return true;
- } else if (compressor.option("builtins_pure")) {
- if (is_pure_builtin_call(compressor, this)) return true;
- }
- if ((this instanceof AST_New) && compressor.option("pure_new")) {
- return true;
- }
- if (compressor.option("side_effects") && has_annotation(this, _PURE)) {
- return true;
- }
- return !compressor.pure_funcs(this);
- });
- // If I call this, is it a pure function?
- AST_Node.DEFMETHOD("is_call_pure", return_false);
- AST_Dot.DEFMETHOD("is_call_pure", function(compressor) {
- if (!compressor.option("unsafe")) return;
- const expr = this.expression;
- let native_obj;
- if (expr instanceof AST_Array) {
- native_obj = "Array";
- } else if (expr.is_boolean()) {
- native_obj = "Boolean";
- } else if (expr.is_number(compressor)) {
- native_obj = "Number";
- } else if (expr instanceof AST_RegExp) {
- native_obj = "RegExp";
- } else if (expr.is_string(compressor)) {
- native_obj = "String";
- } else if (!this.may_throw_on_access(compressor)) {
- native_obj = "Object";
- }
- return native_obj != null && compressor.is_pure_native_method(native_obj, this.property);
- });
- // tell me if a statement aborts
- const aborts = (thing) => thing && thing.aborts();
- (function(def_aborts) {
- def_aborts(AST_Statement, return_null);
- def_aborts(AST_Jump, return_this);
- function block_aborts() {
- for (var i = 0; i < this.body.length; i++) {
- if (aborts(this.body[i])) {
- return this.body[i];
- }
- }
- return null;
- }
- def_aborts(AST_Import, return_null);
- def_aborts(AST_BlockStatement, block_aborts);
- def_aborts(AST_SwitchBranch, block_aborts);
- def_aborts(AST_DefClass, function () {
- for (const prop of this.properties) {
- if (prop instanceof AST_ClassStaticBlock) {
- if (prop.aborts()) return prop;
- }
- }
- return null;
- });
- def_aborts(AST_ClassStaticBlock, block_aborts);
- def_aborts(AST_If, function() {
- return this.alternative && aborts(this.body) && aborts(this.alternative) && this;
- });
- })(function(node, func) {
- node.DEFMETHOD("aborts", func);
- });
- AST_Node.DEFMETHOD("contains_this", function() {
- return walk(this, node => {
- if (node instanceof AST_This) return walk_abort;
- if (
- node !== this
- && node instanceof AST_Scope
- && !(node instanceof AST_Arrow)
- ) {
- return true;
- }
- });
- });
- function is_modified(compressor, tw, node, value, level, immutable) {
- var parent = tw.parent(level);
- var lhs = is_lhs(node, parent);
- if (lhs) return lhs;
- if (!immutable
- && parent instanceof AST_Call
- && parent.expression === node
- && !(value instanceof AST_Arrow)
- && !(value instanceof AST_Class)
- && !parent.is_callee_pure(compressor)
- && (!(value instanceof AST_Function)
- || !(parent instanceof AST_New) && value.contains_this())) {
- return true;
- }
- if (parent instanceof AST_Array) {
- return is_modified(compressor, tw, parent, parent, level + 1);
- }
- if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
- var obj = tw.parent(level + 1);
- return is_modified(compressor, tw, obj, obj, level + 2);
- }
- if (parent instanceof AST_PropAccess && parent.expression === node) {
- var prop = read_property(value, parent.property);
- return !immutable && is_modified(compressor, tw, parent, prop, level + 1);
- }
- }
- /**
- * Check if a node may be used by the expression it's in
- * void (0, 1, {node}, 2) -> false
- * console.log(0, {node}) -> true
- */
- function is_used_in_expression(tw) {
- for (let p = -1, node, parent; node = tw.parent(p), parent = tw.parent(p + 1); p++) {
- if (parent instanceof AST_Sequence) {
- const nth_expression = parent.expressions.indexOf(node);
- if (nth_expression !== parent.expressions.length - 1) {
- // Detect (0, x.noThis)() constructs
- const grandparent = tw.parent(p + 2);
- if (
- parent.expressions.length > 2
- || parent.expressions.length === 1
- || !requires_sequence_to_maintain_binding(grandparent, parent, parent.expressions[1])
- ) {
- return false;
- }
- return true;
- } else {
- continue;
- }
- }
- if (parent instanceof AST_Unary) {
- const op = parent.operator;
- if (op === "void") {
- return false;
- }
- if (op === "typeof" || op === "+" || op === "-" || op === "!" || op === "~") {
- continue;
- }
- }
- if (
- parent instanceof AST_SimpleStatement
- || parent instanceof AST_LabeledStatement
- ) {
- return false;
- }
- if (parent instanceof AST_Scope) {
- return false;
- }
- return true;
- }
- return true;
- }
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- // methods to evaluate a constant expression
- function def_eval(node, func) {
- node.DEFMETHOD("_eval", func);
- }
- // Used to propagate a nullish short-circuit signal upwards through the chain.
- const nullish = Symbol("This AST_Chain is nullish");
- // If the node has been successfully reduced to a constant,
- // then its value is returned; otherwise the element itself
- // is returned.
- // They can be distinguished as constant value is never a
- // descendant of AST_Node.
- AST_Node.DEFMETHOD("evaluate", function (compressor) {
- if (!compressor.option("evaluate"))
- return this;
- var val = this._eval(compressor, 1);
- if (!val || val instanceof RegExp)
- return val;
- if (typeof val == "function" || typeof val == "object" || val == nullish)
- return this;
- // Evaluated strings can be larger than the original expression
- if (typeof val === "string") {
- const unevaluated_size = this.size(compressor);
- if (val.length + 2 > unevaluated_size) return this;
- }
- return val;
- });
- var unaryPrefix = makePredicate("! ~ - + void");
- AST_Node.DEFMETHOD("is_constant", function () {
- // Accomodate when compress option evaluate=false
- // as well as the common constant expressions !0 and -1
- if (this instanceof AST_Constant) {
- return !(this instanceof AST_RegExp);
- } else {
- return this instanceof AST_UnaryPrefix
- && unaryPrefix.has(this.operator)
- && (
- // `this.expression` may be an `AST_RegExp`,
- // so not only `.is_constant()`.
- this.expression instanceof AST_Constant
- || this.expression.is_constant()
- );
- }
- });
- def_eval(AST_Statement, function () {
- throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start));
- });
- def_eval(AST_Lambda, return_this);
- def_eval(AST_Class, return_this);
- def_eval(AST_Node, return_this);
- def_eval(AST_Constant, function () {
- return this.getValue();
- });
- const supports_bigint = typeof BigInt === "function";
- def_eval(AST_BigInt, function () {
- if (supports_bigint) {
- return BigInt(this.value);
- } else {
- return this;
- }
- });
- def_eval(AST_RegExp, function (compressor) {
- let evaluated = compressor.evaluated_regexps.get(this.value);
- if (evaluated === undefined && regexp_is_safe(this.value.source)) {
- try {
- const { source, flags } = this.value;
- evaluated = new RegExp(source, flags);
- } catch (e) {
- evaluated = null;
- }
- compressor.evaluated_regexps.set(this.value, evaluated);
- }
- return evaluated || this;
- });
- def_eval(AST_TemplateString, function () {
- if (this.segments.length !== 1) return this;
- return this.segments[0].value;
- });
- def_eval(AST_Function, function (compressor) {
- if (compressor.option("unsafe")) {
- var fn = function () { };
- fn.node = this;
- fn.toString = () => this.print_to_string();
- return fn;
- }
- return this;
- });
- def_eval(AST_Array, function (compressor, depth) {
- if (compressor.option("unsafe")) {
- var elements = [];
- for (var i = 0, len = this.elements.length; i < len; i++) {
- var element = this.elements[i];
- var value = element._eval(compressor, depth);
- if (element === value)
- return this;
- elements.push(value);
- }
- return elements;
- }
- return this;
- });
- def_eval(AST_Object, function (compressor, depth) {
- if (compressor.option("unsafe")) {
- var val = {};
- for (var i = 0, len = this.properties.length; i < len; i++) {
- var prop = this.properties[i];
- if (prop instanceof AST_Expansion)
- return this;
- var key = prop.key;
- if (key instanceof AST_Symbol) {
- key = key.name;
- } else if (key instanceof AST_Node) {
- key = key._eval(compressor, depth);
- if (key === prop.key)
- return this;
- }
- if (typeof Object.prototype[key] === "function") {
- return this;
- }
- if (prop.value instanceof AST_Function)
- continue;
- val[key] = prop.value._eval(compressor, depth);
- if (val[key] === prop.value)
- return this;
- }
- return val;
- }
- return this;
- });
- var non_converting_unary = makePredicate("! typeof void");
- def_eval(AST_UnaryPrefix, function (compressor, depth) {
- var e = this.expression;
- if (compressor.option("typeofs")
- && this.operator == "typeof") {
- // Function would be evaluated to an array and so typeof would
- // incorrectly return 'object'. Hence making is a special case.
- if (e instanceof AST_Lambda
- || e instanceof AST_SymbolRef
- && e.fixed_value() instanceof AST_Lambda) {
- return typeof function () { };
- }
- if (
- (e instanceof AST_Object
- || e instanceof AST_Array
- || (e instanceof AST_SymbolRef
- && (e.fixed_value() instanceof AST_Object
- || e.fixed_value() instanceof AST_Array)))
- && !e.has_side_effects(compressor)
- ) {
- return typeof {};
- }
- }
- if (!non_converting_unary.has(this.operator))
- depth++;
- e = e._eval(compressor, depth);
- if (e === this.expression)
- return this;
- switch (this.operator) {
- case "!": return !e;
- case "typeof":
- // typeof <RegExp> returns "object" or "function" on different platforms
- // so cannot evaluate reliably
- if (e instanceof RegExp)
- return this;
- return typeof e;
- case "void": return void e;
- case "~": return ~e;
- case "-": return -e;
- case "+": return +e;
- }
- return this;
- });
- var non_converting_binary = makePredicate("&& || ?? === !==");
- const identity_comparison = makePredicate("== != === !==");
- const has_identity = value => typeof value === "object"
- || typeof value === "function"
- || typeof value === "symbol";
- def_eval(AST_Binary, function (compressor, depth) {
- if (!non_converting_binary.has(this.operator))
- depth++;
- var left = this.left._eval(compressor, depth);
- if (left === this.left)
- return this;
- var right = this.right._eval(compressor, depth);
- if (right === this.right)
- return this;
- if (left != null
- && right != null
- && identity_comparison.has(this.operator)
- && has_identity(left)
- && has_identity(right)
- && typeof left === typeof right) {
- // Do not compare by reference
- return this;
- }
- // Do not mix BigInt and Number
- // Don't use `>>>` on BigInt or `/ 0n` (error)
- // Don't use `**` on BigInt (slow)
- if (
- (typeof left === "bigint") !== (typeof right === "bigint")
- || typeof left === "bigint"
- && (this.operator === "/" && Number(right) === 0
- || this.operator === ">>>"
- || this.operator === "**")
- ) {
- return this;
- }
- var result;
- switch (this.operator) {
- case "&&": result = left && right; break;
- case "||": result = left || right; break;
- case "??": result = left != null ? left : right; break;
- case "|": result = left | right; break;
- case "&": result = left & right; break;
- case "^": result = left ^ right; break;
- case "+": result = left + right; break;
- case "*": result = left * right; break;
- case "**": result = left ** right; break;
- case "/": result = left / right; break;
- case "%": result = left % right; break;
- case "-": result = left - right; break;
- case "<<": result = left << right; break;
- case ">>": result = left >> right; break;
- case ">>>": result = left >>> right; break;
- case "==": result = left == right; break;
- case "===": result = left === right; break;
- case "!=": result = left != right; break;
- case "!==": result = left !== right; break;
- case "<": result = left < right; break;
- case "<=": result = left <= right; break;
- case ">": result = left > right; break;
- case ">=": result = left >= right; break;
- default:
- return this;
- }
- if (typeof result === "number" && isNaN(result) && compressor.find_parent(AST_With)) {
- // leave original expression as is
- return this;
- }
- return result;
- });
- def_eval(AST_Conditional, function (compressor, depth) {
- var condition = this.condition._eval(compressor, depth);
- if (condition === this.condition)
- return this;
- var node = condition ? this.consequent : this.alternative;
- var value = node._eval(compressor, depth);
- return value === node ? this : value;
- });
- // Set of AST_SymbolRef which are currently being evaluated.
- // Avoids infinite recursion of ._eval()
- const reentrant_ref_eval = new Set();
- def_eval(AST_SymbolRef, function (compressor, depth) {
- if (reentrant_ref_eval.has(this))
- return this;
- var fixed = this.fixed_value();
- if (!fixed)
- return this;
- reentrant_ref_eval.add(this);
- const value = fixed._eval(compressor, depth);
- reentrant_ref_eval.delete(this);
- if (value === fixed)
- return this;
- if (value && typeof value == "object") {
- var escaped = this.definition().escaped;
- if (escaped && depth > escaped)
- return this;
- }
- return value;
- });
- def_eval(AST_Chain, function (compressor, depth) {
- const evaluated = this.expression._eval(compressor, depth, /*ast_chain=*/true);
- return evaluated === nullish
- ? undefined
- : evaluated === this.expression
- ? this
- : evaluated;
- });
- const global_objs = { Array, Math, Number, Object, String };
- const regexp_flags = new Set([
- "dotAll",
- "global",
- "ignoreCase",
- "multiline",
- "sticky",
- "unicode",
- ]);
- def_eval(AST_PropAccess, function (compressor, depth, ast_chain) {
- let obj = (ast_chain || this.property === "length" || compressor.option("unsafe"))
- && this.expression._eval(compressor, depth + 1, ast_chain);
- if (ast_chain) {
- if (obj === nullish || (this.optional && obj == null)) return nullish;
- }
- // `.length` of strings and arrays is always safe
- if (this.property === "length") {
- if (typeof obj === "string") {
- return obj.length;
- }
- const is_spreadless_array =
- obj instanceof AST_Array
- && obj.elements.every(el => !(el instanceof AST_Expansion));
- if (
- is_spreadless_array
- && obj.elements.every(el => !el.has_side_effects(compressor))
- ) {
- return obj.elements.length;
- }
- }
- if (compressor.option("unsafe")) {
- var key = this.property;
- if (key instanceof AST_Node) {
- key = key._eval(compressor, depth);
- if (key === this.property)
- return this;
- }
- var exp = this.expression;
- if (is_undeclared_ref(exp)) {
- var aa;
- var first_arg = exp.name === "hasOwnProperty"
- && key === "call"
- && (aa = compressor.parent() && compressor.parent().args)
- && (aa && aa[0]
- && aa[0].evaluate(compressor));
- first_arg = first_arg instanceof AST_Dot ? first_arg.expression : first_arg;
- if (first_arg == null || first_arg.thedef && first_arg.thedef.undeclared) {
- return this.clone();
- }
- if (!compressor.is_pure_native_static_property(exp.name, key))
- return this;
- obj = global_objs[exp.name];
- } else {
- if (obj instanceof RegExp) {
- if (key == "source") {
- return regexp_source_fix(obj.source);
- } else if (key == "flags" || regexp_flags.has(key)) {
- return obj[key];
- }
- }
- if (!obj || obj === exp || !HOP(obj, key))
- return this;
- if (typeof obj == "function")
- switch (key) {
- case "name":
- return obj.node.name ? obj.node.name.name : "";
- case "length":
- return obj.node.length_property();
- default:
- return this;
- }
- }
- return obj[key];
- }
- return this;
- });
- def_eval(AST_Call, function (compressor, depth, ast_chain) {
- var exp = this.expression;
- if (ast_chain) {
- const callee = exp._eval(compressor, depth, ast_chain);
- if (callee === nullish || (this.optional && callee == null)) return nullish;
- }
- if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
- var key = exp.property;
- if (key instanceof AST_Node) {
- key = key._eval(compressor, depth);
- if (typeof key !== "string" && typeof key !== "number")
- return this;
- }
- var val;
- var e = exp.expression;
- if (is_undeclared_ref(e)) {
- var first_arg = e.name === "hasOwnProperty" &&
- key === "call" &&
- (this.args[0] && this.args[0].evaluate(compressor));
- first_arg = first_arg instanceof AST_Dot ? first_arg.expression : first_arg;
- if ((first_arg == null || first_arg.thedef && first_arg.thedef.undeclared)) {
- return this.clone();
- }
- if (!compressor.is_pure_native_static_fn(e.name, key)) return this;
- val = global_objs[e.name];
- } else {
- val = e._eval(compressor, depth + 1, /* don't pass ast_chain (exponential work) */);
- if (val === e || !val)
- return this;
- if (!compressor.is_pure_native_method(val.constructor.name, key))
- return this;
- }
- var args = [];
- for (var i = 0, len = this.args.length; i < len; i++) {
- var arg = this.args[i];
- var value = arg._eval(compressor, depth);
- if (arg === value)
- return this;
- if (arg instanceof AST_Lambda)
- return this;
- args.push(value);
- }
- try {
- return val[key].apply(val, args);
- } catch (ex) {
- // We don't really care
- }
- }
- return this;
- });
- // Also a subclass of AST_Call
- def_eval(AST_New, return_this);
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- // AST_Node#drop_side_effect_free() gets called when we don't care about the value,
- // only about side effects. We'll be defining this method for each node type in this module
- //
- // Examples:
- // foo++ -> foo++
- // 1 + func() -> func()
- // 10 -> (nothing)
- // knownPureFunc(foo++) -> foo++
- function def_drop_side_effect_free(node_or_nodes, func) {
- for (const node of [].concat(node_or_nodes)) {
- node.DEFMETHOD("drop_side_effect_free", func);
- }
- }
- // Drop side-effect-free elements from an array of expressions.
- // Returns an array of expressions with side-effects or null
- // if all elements were dropped. Note: original array may be
- // returned if nothing changed.
- function trim(nodes, compressor, first_in_statement) {
- var len = nodes.length;
- if (!len) return null;
- var ret = [], changed = false;
- for (var i = 0; i < len; i++) {
- var node = nodes[i].drop_side_effect_free(compressor, first_in_statement);
- changed |= node !== nodes[i];
- if (node) {
- ret.push(node);
- first_in_statement = false;
- }
- }
- return changed ? ret.length ? ret : null : nodes;
- }
- def_drop_side_effect_free(AST_Node, return_this);
- def_drop_side_effect_free(AST_Constant, return_null);
- def_drop_side_effect_free(AST_This, return_null);
- def_drop_side_effect_free(AST_Call, function (compressor, first_in_statement) {
- if (is_nullish_shortcircuited(this, compressor)) {
- return this.expression.drop_side_effect_free(compressor, first_in_statement);
- }
- if (!this.is_callee_pure(compressor)) {
- if (this.expression.is_call_pure(compressor)) {
- var exprs = this.args.slice();
- exprs.unshift(this.expression.expression);
- exprs = trim(exprs, compressor, first_in_statement);
- return exprs && make_sequence(this, exprs);
- }
- if (is_func_expr(this.expression)
- && (!this.expression.name || !this.expression.name.definition().references.length)) {
- var node = this.clone();
- node.expression.process_expression(false, compressor);
- return node;
- }
- return this;
- }
- var args = trim(this.args, compressor, first_in_statement);
- return args && make_sequence(this, args);
- });
- def_drop_side_effect_free(AST_DynamicImport, function (compressor, first_in_statement) {
- if (this.phase !== "source") return this;
- var args = trim(this.args, compressor, first_in_statement);
- return args && make_sequence(this, args);
- });
- def_drop_side_effect_free(AST_Accessor, return_null);
- def_drop_side_effect_free(AST_Function, return_null);
- def_drop_side_effect_free(AST_Arrow, return_null);
- def_drop_side_effect_free(AST_Class, function (compressor) {
- const with_effects = [];
- if (this.is_self_referential() && this.has_side_effects(compressor)) {
- return this;
- }
- const trimmed_extends = this.extends && this.extends.drop_side_effect_free(compressor);
- if (trimmed_extends) with_effects.push(trimmed_extends);
- for (const prop of this.properties) {
- if (prop instanceof AST_ClassStaticBlock) {
- if (prop.has_side_effects(compressor)) {
- return this; // Be cautious about these
- }
- } else {
- const trimmed_prop = prop.drop_side_effect_free(compressor);
- if (trimmed_prop) with_effects.push(trimmed_prop);
- }
- }
- if (!with_effects.length)
- return null;
- const exprs = make_sequence(this, with_effects);
- if (this instanceof AST_DefClass) {
- // We want a statement
- return make_node(AST_SimpleStatement, this, { body: exprs });
- } else {
- return exprs;
- }
- });
- def_drop_side_effect_free([
- AST_ClassProperty,
- AST_ClassPrivateProperty,
- ], function (compressor) {
- const key = this.computed_key() && this.key.drop_side_effect_free(compressor);
- const value = this.static && this.value
- && this.value.drop_side_effect_free(compressor);
- if (key && value)
- return make_sequence(this, [key, value]);
- return key || value || null;
- });
- def_drop_side_effect_free(AST_Binary, function (compressor, first_in_statement) {
- var right = this.right.drop_side_effect_free(compressor);
- if (!right)
- return this.left.drop_side_effect_free(compressor, first_in_statement);
- if (lazy_op.has(this.operator)) {
- if (right === this.right)
- return this;
- var node = this.clone();
- node.right = right;
- return node;
- } else {
- var left = this.left.drop_side_effect_free(compressor, first_in_statement);
- if (!left)
- return this.right.drop_side_effect_free(compressor, first_in_statement);
- return make_sequence(this, [left, right]);
- }
- });
- def_drop_side_effect_free(AST_Assign, function (compressor) {
- if (this.logical)
- return this;
- var left = this.left;
- if (left.has_side_effects(compressor)
- || compressor.has_directive("use strict")
- && left instanceof AST_PropAccess
- && left.expression.is_constant()) {
- return this;
- }
- set_flag(this, WRITE_ONLY);
- while (left instanceof AST_PropAccess) {
- left = left.expression;
- }
- if (left.is_constant_expression(compressor.find_parent(AST_Scope))) {
- return this.right.drop_side_effect_free(compressor);
- }
- return this;
- });
- def_drop_side_effect_free(AST_Conditional, function (compressor) {
- var consequent = this.consequent.drop_side_effect_free(compressor);
- var alternative = this.alternative.drop_side_effect_free(compressor);
- if (consequent === this.consequent && alternative === this.alternative)
- return this;
- if (!consequent)
- return alternative ? make_node(AST_Binary, this, {
- operator: "||",
- left: this.condition,
- right: alternative
- }) : this.condition.drop_side_effect_free(compressor);
- if (!alternative)
- return make_node(AST_Binary, this, {
- operator: "&&",
- left: this.condition,
- right: consequent
- });
- var node = this.clone();
- node.consequent = consequent;
- node.alternative = alternative;
- return node;
- });
- def_drop_side_effect_free(AST_Unary, function (compressor, first_in_statement) {
- if (unary_side_effects.has(this.operator)) {
- if (!this.expression.has_side_effects(compressor)) {
- set_flag(this, WRITE_ONLY);
- } else {
- clear_flag(this, WRITE_ONLY);
- }
- return this;
- }
- if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef)
- return null;
- var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
- if (first_in_statement && expression && is_iife_call(expression)) {
- if (expression === this.expression && this.operator == "!")
- return this;
- return expression.negate(compressor, first_in_statement);
- }
- return expression;
- });
- def_drop_side_effect_free(AST_SymbolRef, function (compressor) {
- const safe_access = this.is_declared(compressor)
- || pure_prop_access_globals.has(this.name);
- return safe_access ? null : this;
- });
- def_drop_side_effect_free(AST_Object, function (compressor, first_in_statement) {
- var values = trim(this.properties, compressor, first_in_statement);
- return values && make_sequence(this, values);
- });
- def_drop_side_effect_free(AST_ObjectKeyVal, function (compressor, first_in_statement) {
- const computed_key = this.key instanceof AST_Node;
- const key = computed_key && this.key.drop_side_effect_free(compressor, first_in_statement);
- const value = this.value.drop_side_effect_free(compressor, first_in_statement);
- if (key && value) {
- return make_sequence(this, [key, value]);
- }
- return key || value;
- });
- def_drop_side_effect_free([
- AST_ConciseMethod,
- AST_ObjectGetter,
- AST_ObjectSetter,
- ], function (compressor, first_in_statement) {
- return this.computed_key() ? this.key.drop_side_effect_free(compressor, first_in_statement) : null;
- });
- def_drop_side_effect_free([
- AST_PrivateMethod,
- AST_PrivateGetter,
- AST_PrivateSetter,
- ], function () {
- return null;
- });
- def_drop_side_effect_free(AST_Array, function (compressor, first_in_statement) {
- var values = trim(this.elements, compressor, first_in_statement);
- return values && make_sequence(this, values);
- });
- def_drop_side_effect_free(AST_Dot, function (compressor, first_in_statement) {
- if (is_nullish_shortcircuited(this, compressor)) {
- return this.expression.drop_side_effect_free(compressor, first_in_statement);
- }
- if (!this.optional && this.expression.may_throw_on_access(compressor)) {
- return this;
- }
- return this.expression.drop_side_effect_free(compressor, first_in_statement);
- });
- def_drop_side_effect_free(AST_Sub, function (compressor, first_in_statement) {
- if (is_nullish_shortcircuited(this, compressor)) {
- return this.expression.drop_side_effect_free(compressor, first_in_statement);
- }
- if (!this.optional && this.expression.may_throw_on_access(compressor)) {
- return this;
- }
- var property = this.property.drop_side_effect_free(compressor);
- if (property && this.optional) return this;
- var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
- if (expression && property) return make_sequence(this, [expression, property]);
- return expression || property;
- });
- def_drop_side_effect_free(AST_Chain, function (compressor, first_in_statement) {
- return this.expression.drop_side_effect_free(compressor, first_in_statement);
- });
- def_drop_side_effect_free(AST_Sequence, function (compressor) {
- var last = this.tail_node();
- var expr = last.drop_side_effect_free(compressor);
- if (expr === last)
- return this;
- var expressions = this.expressions.slice(0, -1);
- if (expr)
- expressions.push(expr);
- if (!expressions.length) {
- return make_node(AST_Number, this, { value: 0 });
- }
- return make_sequence(this, expressions);
- });
- def_drop_side_effect_free(AST_Expansion, function (compressor, first_in_statement) {
- return this.expression.drop_side_effect_free(compressor, first_in_statement);
- });
- def_drop_side_effect_free(AST_TemplateSegment, return_null);
- def_drop_side_effect_free(AST_TemplateString, function (compressor) {
- var values = trim(this.segments, compressor, first_in_statement);
- return values && make_sequence(this, values);
- });
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- const r_keep_assign = /keep_assign/;
- /** Drop unused variables from this scope */
- AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
- if (!compressor.option("unused")) return;
- if (compressor.has_directive("use asm")) return;
- if (!this.variables) return; // not really a scope (eg: AST_Class)
- var self = this;
- if (self.pinned()) return;
- var drop_funcs = !(self instanceof AST_Toplevel) || compressor.toplevel.funcs;
- var drop_vars = !(self instanceof AST_Toplevel) || compressor.toplevel.vars;
- const assign_as_unused = r_keep_assign.test(compressor.option("unused")) ? return_false : function(node) {
- if (node instanceof AST_Assign
- && !node.logical
- && (has_flag(node, WRITE_ONLY) || node.operator == "=")
- ) {
- return node.left;
- }
- if (node instanceof AST_Unary && has_flag(node, WRITE_ONLY)) {
- return node.expression;
- }
- };
- var in_use_ids = new Map();
- var fixed_ids = new Map();
- if (self instanceof AST_Toplevel && compressor.top_retain) {
- self.variables.forEach(function(def) {
- if (compressor.top_retain(def)) {
- in_use_ids.set(def.id, def);
- }
- });
- }
- var var_defs_by_id = new Map();
- var initializations = new Map();
- // pass 1: find out which symbols are directly used in
- // this scope (not in nested scopes).
- var scope = this;
- var tw = new TreeWalker(function(node, descend) {
- if (node instanceof AST_Lambda && node.uses_arguments && !tw.has_directive("use strict")) {
- node.argnames.forEach(function(argname) {
- if (!(argname instanceof AST_SymbolDeclaration)) return;
- var def = argname.definition();
- in_use_ids.set(def.id, def);
- });
- }
- if (node === self) return;
- if (node instanceof AST_Class && node.has_side_effects(compressor)) {
- if (node.is_self_referential()) {
- descend();
- } else {
- node.visit_nondeferred_class_parts(tw);
- }
- }
- if (node instanceof AST_Defun || node instanceof AST_DefClass) {
- var node_def = node.name.definition();
- const in_export = tw.parent() instanceof AST_Export;
- if (in_export || !drop_funcs && scope === self) {
- if (node_def.global) {
- in_use_ids.set(node_def.id, node_def);
- }
- }
- map_add(initializations, node_def.id, node);
- return true; // don't go in nested scopes
- }
- // In the root scope, we drop things. In inner scopes, we just check for uses.
- const in_root_scope = scope === self;
- if (node instanceof AST_SymbolFunarg && in_root_scope) {
- map_add(var_defs_by_id, node.definition().id, node);
- }
- if (node instanceof AST_Definitions && in_root_scope) {
- const in_export = tw.parent() instanceof AST_Export;
- node.definitions.forEach(function(def) {
- if (def.name instanceof AST_SymbolVar) {
- map_add(var_defs_by_id, def.name.definition().id, def);
- }
- if (in_export || !drop_vars) {
- walk(def.name, node => {
- if (node instanceof AST_SymbolDeclaration) {
- const def = node.definition();
- if (def.global) {
- in_use_ids.set(def.id, def);
- }
- }
- });
- }
- if (def.name instanceof AST_Destructuring) {
- def.walk(tw);
- }
- if (def.name instanceof AST_SymbolDeclaration && def.value) {
- var node_def = def.name.definition();
- map_add(initializations, node_def.id, def.value);
- if (!node_def.chained && def.name.fixed_value() === def.value) {
- fixed_ids.set(node_def.id, def);
- }
- if (def.value.has_side_effects(compressor)) {
- def.value.walk(tw);
- }
- }
- });
- return true;
- }
- return scan_ref_scoped(node, descend);
- });
- self.walk(tw);
- // pass 2: for every used symbol we need to walk its
- // initialization code to figure out if it uses other
- // symbols (that may not be in_use).
- tw = new TreeWalker(scan_ref_scoped);
- in_use_ids.forEach(function (def) {
- var init = initializations.get(def.id);
- if (init) init.forEach(function(init) {
- init.walk(tw);
- });
- });
- // pass 3: we should drop declarations not in_use
- var tt = new TreeTransformer(
- function before(node, descend, in_list) {
- var parent = tt.parent();
- if (drop_vars) {
- const sym = assign_as_unused(node);
- if (sym instanceof AST_SymbolRef) {
- var def = sym.definition();
- var in_use = in_use_ids.has(def.id);
- if (node instanceof AST_Assign) {
- if (!in_use || fixed_ids.has(def.id) && fixed_ids.get(def.id) !== node) {
- const assignee = node.right.transform(tt);
- if (!in_use && !assignee.has_side_effects(compressor) && !is_used_in_expression(tt)) {
- return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
- }
- return maintain_this_binding(parent, node, assignee);
- }
- } else if (!in_use) {
- return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
- }
- }
- }
- if (scope !== self) return;
- var def;
- if (node.name
- && (node instanceof AST_ClassExpression
- && !keep_name(compressor.option("keep_classnames"), (def = node.name.definition()).name)
- || node instanceof AST_Function
- && !keep_name(compressor.option("keep_fnames"), (def = node.name.definition()).name))) {
- // any declarations with same name will overshadow
- // name of this anonymous function and can therefore
- // never be used anywhere
- if (!in_use_ids.has(def.id) || def.orig.length > 1) node.name = null;
- }
- if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) {
- var trim =
- !compressor.option("keep_fargs")
- // Is this an IIFE that won't refer to its name?
- || parent instanceof AST_Call
- && parent.expression === node
- && !node.pinned()
- && (!node.name || node.name.unreferenced());
- for (var a = node.argnames, i = a.length; --i >= 0;) {
- var sym = a[i];
- if (sym instanceof AST_Expansion) {
- sym = sym.expression;
- }
- if (sym instanceof AST_DefaultAssign) {
- sym = sym.left;
- }
- // Do not drop destructuring arguments.
- // They constitute a type assertion of sorts
- if (
- !(sym instanceof AST_Destructuring)
- && !in_use_ids.has(sym.definition().id)
- ) {
- set_flag(sym, UNUSED);
- if (trim) {
- a.pop();
- }
- } else {
- trim = false;
- }
- }
- }
- if (node instanceof AST_DefClass && node !== self) {
- const def = node.name.definition();
- descend(node, this);
- const keep_class = def.global && !drop_funcs || in_use_ids.has(def.id);
- if (!keep_class) {
- const kept = node.drop_side_effect_free(compressor);
- if (kept == null) {
- def.eliminated++;
- return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
- }
- return kept;
- }
- return node;
- }
- if (node instanceof AST_Defun && node !== self) {
- const def = node.name.definition();
- const keep = def.global && !drop_funcs || in_use_ids.has(def.id);
- if (!keep) {
- def.eliminated++;
- return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
- }
- }
- if (node instanceof AST_Definitions && !(parent instanceof AST_ForIn && parent.init === node)) {
- var drop_block = !(parent instanceof AST_Toplevel) && !(node instanceof AST_Var);
- // place uninitialized names at the start
- var body = [], head = [], tail = [];
- // for unused names whose initialization has
- // side effects, we can cascade the init. code
- // into the next one, or next statement.
- var side_effects = [];
- node.definitions.forEach(function(def) {
- if (def.value) def.value = def.value.transform(tt);
- var is_destructure = def.name instanceof AST_Destructuring;
- var sym = is_destructure
- ? new SymbolDef(null, { name: "<destructure>" }) /* fake SymbolDef */
- : def.name.definition();
- if (drop_block && sym.global) return tail.push(def);
- if (!(drop_vars || drop_block)
- || is_destructure
- && (def.name.names.length
- || def.name.is_array
- || compressor.option("pure_getters") != true)
- || in_use_ids.has(sym.id)
- ) {
- if (def.value && fixed_ids.has(sym.id) && fixed_ids.get(sym.id) !== def) {
- def.value = def.value.drop_side_effect_free(compressor);
- }
- if (def.name instanceof AST_SymbolVar) {
- var var_defs = var_defs_by_id.get(sym.id);
- if (var_defs.length > 1 && (!def.value || sym.orig.indexOf(def.name) > sym.eliminated)) {
- if (def.value) {
- var ref = make_node(AST_SymbolRef, def.name, def.name);
- sym.references.push(ref);
- var assign = make_node(AST_Assign, def, {
- operator: "=",
- logical: false,
- left: ref,
- right: def.value
- });
- if (fixed_ids.get(sym.id) === def) {
- fixed_ids.set(sym.id, assign);
- }
- side_effects.push(assign.transform(tt));
- }
- remove(var_defs, def);
- sym.eliminated++;
- return;
- }
- }
- if (def.value) {
- if (side_effects.length > 0) {
- if (tail.length > 0) {
- side_effects.push(def.value);
- def.value = make_sequence(def.value, side_effects);
- } else {
- body.push(make_node(AST_SimpleStatement, node, {
- body: make_sequence(node, side_effects)
- }));
- }
- side_effects = [];
- }
- tail.push(def);
- } else {
- head.push(def);
- }
- } else if (sym.orig[0] instanceof AST_SymbolCatch) {
- var value = def.value && def.value.drop_side_effect_free(compressor);
- if (value) side_effects.push(value);
- def.value = null;
- head.push(def);
- } else {
- var value = def.value && def.value.drop_side_effect_free(compressor);
- if (value) {
- side_effects.push(value);
- }
- sym.eliminated++;
- }
- });
- if (head.length > 0 || tail.length > 0) {
- node.definitions = head.concat(tail);
- body.push(node);
- }
- if (side_effects.length > 0) {
- body.push(make_node(AST_SimpleStatement, node, {
- body: make_sequence(node, side_effects)
- }));
- }
- switch (body.length) {
- case 0:
- return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
- case 1:
- return body[0];
- default:
- return in_list ? MAP.splice(body) : make_node(AST_BlockStatement, node, { body });
- }
- }
- // certain combination of unused name + side effect leads to:
- // https://github.com/mishoo/UglifyJS2/issues/44
- // https://github.com/mishoo/UglifyJS2/issues/1830
- // https://github.com/mishoo/UglifyJS2/issues/1838
- // that's an invalid AST.
- // We fix it at this stage by moving the `var` outside the `for`.
- if (node instanceof AST_For) {
- descend(node, this);
- var block;
- if (node.init instanceof AST_BlockStatement) {
- block = node.init;
- node.init = block.body.pop();
- block.body.push(node);
- }
- if (node.init instanceof AST_SimpleStatement) {
- node.init = node.init.body;
- } else if (is_empty(node.init)) {
- node.init = null;
- }
- return !block ? node : in_list ? MAP.splice(block.body) : block;
- }
- if (node instanceof AST_LabeledStatement
- && node.body instanceof AST_For
- ) {
- descend(node, this);
- if (node.body instanceof AST_BlockStatement) {
- var block = node.body;
- node.body = block.body.pop();
- block.body.push(node);
- return in_list ? MAP.splice(block.body) : block;
- }
- return node;
- }
- if (node instanceof AST_BlockStatement) {
- descend(node, this);
- if (in_list && node.body.every(can_be_evicted_from_block)) {
- return MAP.splice(node.body);
- }
- return node;
- }
- if (node instanceof AST_Scope && !(node instanceof AST_ClassStaticBlock)) {
- const save_scope = scope;
- scope = node;
- descend(node, this);
- scope = save_scope;
- return node;
- }
- },
- function after(node, in_list) {
- if (node instanceof AST_Sequence) {
- switch (node.expressions.length) {
- case 0: return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
- case 1: return node.expressions[0];
- }
- }
- }
- );
- self.transform(tt);
- function scan_ref_scoped(node, descend) {
- var node_def;
- const sym = assign_as_unused(node);
- if (sym instanceof AST_SymbolRef
- && !is_ref_of(node.left, AST_SymbolBlockDeclaration)
- && self.variables.get(sym.name) === (node_def = sym.definition())
- ) {
- if (node instanceof AST_Assign) {
- node.right.walk(tw);
- if (!node_def.chained && node.left.fixed_value() === node.right) {
- fixed_ids.set(node_def.id, node);
- }
- }
- return true;
- }
- if (node instanceof AST_SymbolRef) {
- node_def = node.definition();
- if (!in_use_ids.has(node_def.id)) {
- in_use_ids.set(node_def.id, node_def);
- if (node_def.orig[0] instanceof AST_SymbolCatch) {
- const redef = node_def.scope.is_block_scope()
- && node_def.scope.get_defun_scope().variables.get(node_def.name);
- if (redef) in_use_ids.set(redef.id, redef);
- }
- }
- return true;
- }
- if (node instanceof AST_Class) {
- descend();
- return true;
- }
- if (node instanceof AST_Scope && !(node instanceof AST_ClassStaticBlock)) {
- var save_scope = scope;
- scope = node;
- descend();
- scope = save_scope;
- return true;
- }
- }
- });
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- /**
- * Define the method AST_Node#reduce_vars, which goes through the AST in
- * execution order to perform basic flow analysis
- */
- function def_reduce_vars(node, func) {
- node.DEFMETHOD("reduce_vars", func);
- }
- def_reduce_vars(AST_Node, noop);
- /** Clear definition properties */
- function reset_def(compressor, def) {
- def.assignments = 0;
- def.chained = false;
- def.direct_access = false;
- def.escaped = 0;
- def.recursive_refs = 0;
- def.references = [];
- def.single_use = undefined;
- if (
- def.scope.pinned()
- || (def.orig[0] instanceof AST_SymbolFunarg && def.scope.uses_arguments)
- ) {
- def.fixed = false;
- } else if (def.orig[0] instanceof AST_SymbolConst || !compressor.exposed(def)) {
- def.fixed = def.init;
- } else {
- def.fixed = false;
- }
- }
- function reset_variables(tw, compressor, node) {
- node.variables.forEach(function(def) {
- reset_def(compressor, def);
- if (def.fixed === null) {
- tw.defs_to_safe_ids.set(def.id, tw.safe_ids);
- mark(tw, def, true);
- } else if (def.fixed) {
- tw.loop_ids.set(def.id, tw.in_loop);
- mark(tw, def, true);
- }
- });
- }
- function reset_block_variables(compressor, node) {
- if (node.block_scope) node.block_scope.variables.forEach((def) => {
- reset_def(compressor, def);
- });
- }
- function push(tw) {
- tw.safe_ids = Object.create(tw.safe_ids);
- }
- function pop(tw) {
- tw.safe_ids = Object.getPrototypeOf(tw.safe_ids);
- }
- function mark(tw, def, safe) {
- tw.safe_ids[def.id] = safe;
- }
- function safe_to_read(tw, def) {
- if (def.single_use == "m") return false;
- if (tw.safe_ids[def.id]) {
- if (def.fixed == null) {
- var orig = def.orig[0];
- if (orig instanceof AST_SymbolFunarg || orig.name == "arguments") return false;
- def.fixed = make_void_0(orig);
- }
- return true;
- }
- return def.fixed instanceof AST_Defun;
- }
- function safe_to_assign(tw, def, scope, value) {
- if (def.fixed === undefined) return true;
- let def_safe_ids;
- if (def.fixed === null
- && (def_safe_ids = tw.defs_to_safe_ids.get(def.id))
- ) {
- def_safe_ids[def.id] = false;
- tw.defs_to_safe_ids.delete(def.id);
- return true;
- }
- if (!HOP(tw.safe_ids, def.id)) return false;
- if (!safe_to_read(tw, def)) return false;
- if (def.fixed === false) return false;
- if (def.fixed != null && (!value || def.references.length > def.assignments)) return false;
- if (def.fixed instanceof AST_Defun) {
- return value instanceof AST_Node && def.fixed.parent_scope === scope;
- }
- return def.orig.every((sym) => {
- return !(sym instanceof AST_SymbolConst
- || sym instanceof AST_SymbolDefun
- || sym instanceof AST_SymbolLambda);
- });
- }
- function ref_once(tw, compressor, def) {
- return compressor.option("unused")
- && !def.scope.pinned()
- && def.references.length - def.recursive_refs == 1
- && tw.loop_ids.get(def.id) === tw.in_loop;
- }
- function is_immutable(value) {
- if (!value) return false;
- return value.is_constant()
- || value instanceof AST_Lambda
- || value instanceof AST_This;
- }
- // A definition "escapes" when its value can leave the point of use.
- // Example: `a = b || c`
- // In this example, "b" and "c" are escaping, because they're going into "a"
- //
- // def.escaped is != 0 when it escapes.
- //
- // When greater than 1, it means that N chained properties will be read off
- // of that def before an escape occurs. This is useful for evaluating
- // property accesses, where you need to know when to stop.
- function mark_escaped(tw, d, scope, node, value, level = 0, depth = 1) {
- var parent = tw.parent(level);
- if (value) {
- if (value.is_constant()) return;
- if (value instanceof AST_ClassExpression) return;
- }
- if (
- parent instanceof AST_Assign && (parent.operator === "=" || parent.logical) && node === parent.right
- || parent instanceof AST_Call && (node !== parent.expression || parent instanceof AST_New)
- || parent instanceof AST_Exit && node === parent.value && node.scope !== d.scope
- || parent instanceof AST_VarDefLike && node === parent.value
- || parent instanceof AST_Yield && node === parent.value && node.scope !== d.scope
- ) {
- if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1;
- if (!d.escaped || d.escaped > depth) d.escaped = depth;
- return;
- } else if (
- parent instanceof AST_Array
- || parent instanceof AST_Await
- || parent instanceof AST_Binary && lazy_op.has(parent.operator)
- || parent instanceof AST_Conditional && node !== parent.condition
- || parent instanceof AST_Expansion
- || parent instanceof AST_Sequence && node === parent.tail_node()
- ) {
- mark_escaped(tw, d, scope, parent, parent, level + 1, depth);
- } else if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
- var obj = tw.parent(level + 1);
- mark_escaped(tw, d, scope, obj, obj, level + 2, depth);
- } else if (parent instanceof AST_PropAccess && node === parent.expression) {
- value = read_property(value, parent.property);
- mark_escaped(tw, d, scope, parent, value, level + 1, depth + 1);
- if (value) return;
- }
- if (level > 0) return;
- if (parent instanceof AST_Sequence && node !== parent.tail_node()) return;
- if (parent instanceof AST_SimpleStatement) return;
- d.direct_access = true;
- }
- const suppress = node => walk(node, node => {
- if (!(node instanceof AST_Symbol)) return;
- var d = node.definition();
- if (!d) return;
- if (node instanceof AST_SymbolRef) d.references.push(node);
- d.fixed = false;
- });
- def_reduce_vars(AST_Accessor, function(tw, descend, compressor) {
- push(tw);
- reset_variables(tw, compressor, this);
- descend();
- pop(tw);
- return true;
- });
- def_reduce_vars(AST_Assign, function(tw, descend, compressor) {
- var node = this;
- if (node.left instanceof AST_Destructuring) {
- suppress(node.left);
- return;
- }
- const finish_walk = () => {
- if (node.logical) {
- node.left.walk(tw);
- push(tw);
- node.right.walk(tw);
- pop(tw);
- return true;
- }
- };
- var sym = node.left;
- if (!(sym instanceof AST_SymbolRef)) return finish_walk();
- var def = sym.definition();
- var safe = safe_to_assign(tw, def, sym.scope, node.right);
- def.assignments++;
- if (!safe) return finish_walk();
- var fixed = def.fixed;
- if (!fixed && node.operator != "=" && !node.logical) return finish_walk();
- var eq = node.operator == "=";
- var value = eq ? node.right : node;
- if (is_modified(compressor, tw, node, value, 0)) return finish_walk();
- def.references.push(sym);
- if (!node.logical) {
- if (!eq) def.chained = true;
- def.fixed = eq ? function() {
- return node.right;
- } : function() {
- return make_node(AST_Binary, node, {
- operator: node.operator.slice(0, -1),
- left: fixed instanceof AST_Node ? fixed : fixed(),
- right: node.right
- });
- };
- }
- if (node.logical) {
- mark(tw, def, false);
- push(tw);
- node.right.walk(tw);
- pop(tw);
- return true;
- }
- mark(tw, def, false);
- node.right.walk(tw);
- mark(tw, def, true);
- mark_escaped(tw, def, sym.scope, node, value, 0, 1);
- return true;
- });
- def_reduce_vars(AST_Binary, function(tw) {
- if (!lazy_op.has(this.operator)) return;
- this.left.walk(tw);
- push(tw);
- this.right.walk(tw);
- pop(tw);
- return true;
- });
- def_reduce_vars(AST_Block, function(tw, descend, compressor) {
- reset_block_variables(compressor, this);
- });
- def_reduce_vars(AST_Case, function(tw) {
- push(tw);
- this.expression.walk(tw);
- pop(tw);
- push(tw);
- walk_body(this, tw);
- pop(tw);
- return true;
- });
- def_reduce_vars(AST_Class, function(tw, descend) {
- clear_flag(this, INLINED);
- push(tw);
- descend();
- pop(tw);
- return true;
- });
- def_reduce_vars(AST_ClassStaticBlock, function(tw, descend, compressor) {
- reset_block_variables(compressor, this);
- });
- def_reduce_vars(AST_Conditional, function(tw) {
- this.condition.walk(tw);
- push(tw);
- this.consequent.walk(tw);
- pop(tw);
- push(tw);
- this.alternative.walk(tw);
- pop(tw);
- return true;
- });
- def_reduce_vars(AST_Chain, function(tw, descend) {
- // Chains' conditions apply left-to-right, cumulatively.
- // If we walk normally we don't go in that order because we would pop before pushing again
- // Solution: AST_PropAccess and AST_Call push when they are optional, and never pop.
- // Then we pop everything when they are done being walked.
- const safe_ids = tw.safe_ids;
- descend();
- // Unroll back to start
- tw.safe_ids = safe_ids;
- return true;
- });
- def_reduce_vars(AST_Call, function (tw) {
- this.expression.walk(tw);
- if (this.optional) {
- // Never pop -- it's popped at AST_Chain above
- push(tw);
- }
- for (const arg of this.args) arg.walk(tw);
- return true;
- });
- def_reduce_vars(AST_PropAccess, function (tw) {
- if (!this.optional) return;
- this.expression.walk(tw);
- // Never pop -- it's popped at AST_Chain above
- push(tw);
- if (this.property instanceof AST_Node) this.property.walk(tw);
- return true;
- });
- def_reduce_vars(AST_Default, function(tw, descend) {
- push(tw);
- descend();
- pop(tw);
- return true;
- });
- function mark_lambda(tw, descend, compressor) {
- clear_flag(this, INLINED);
- push(tw);
- reset_variables(tw, compressor, this);
- var iife;
- if (!this.name
- && !this.uses_arguments
- && !this.pinned()
- && (iife = tw.parent()) instanceof AST_Call
- && iife.expression === this
- && !iife.args.some(arg => arg instanceof AST_Expansion)
- && this.argnames.every(arg_name => arg_name instanceof AST_Symbol)
- ) {
- // Virtually turn IIFE parameters into variable definitions:
- // (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})()
- // So existing transformation rules can work on them.
- this.argnames.forEach((arg, i) => {
- if (!arg.definition) return;
- var d = arg.definition();
- // Avoid setting fixed when there's more than one origin for a variable value
- if (d.orig.length > 1) return;
- if (d.fixed === undefined && (!this.uses_arguments || tw.has_directive("use strict"))) {
- d.fixed = function() {
- return iife.args[i] || make_void_0(iife);
- };
- tw.loop_ids.set(d.id, tw.in_loop);
- mark(tw, d, true);
- } else {
- d.fixed = false;
- }
- });
- }
- descend();
- pop(tw);
- handle_defined_after_hoist(this);
- return true;
- }
- /**
- * It's possible for a hoisted function to use something that's not defined yet. Example:
- *
- * hoisted();
- * var defined_after = true;
- * function hoisted() {
- * // use defined_after
- * }
- *
- * Or even indirectly:
- *
- * B();
- * var defined_after = true;
- * function A() {
- * // use defined_after
- * }
- * function B() {
- * A();
- * }
- *
- * Access a variable before declaration will either throw a ReferenceError
- * (if the variable is declared with `let` or `const`),
- * or get an `undefined` (if the variable is declared with `var`).
- *
- * If the variable is inlined into the function, the behavior will change.
- *
- * This function is called on the parent to disallow inlining of such variables,
- */
- function handle_defined_after_hoist(parent) {
- const defuns = [];
- walk(parent, node => {
- if (node === parent) return;
- if (node instanceof AST_Defun) {
- defuns.push(node);
- return true;
- }
- if (
- node instanceof AST_Scope
- || node instanceof AST_SimpleStatement
- ) return true;
- });
- // `defun` id to array of `defun` it uses
- const defun_dependencies_map = new Map();
- // `defun` id to array of enclosing `def` that are used by the function
- const dependencies_map = new Map();
- // all symbol ids that will be tracked for read/write
- const symbols_of_interest = new Set();
- const defuns_of_interest = new Set();
- for (const defun of defuns) {
- const fname_def = defun.name.definition();
- const enclosing_defs = [];
- for (const def of defun.enclosed) {
- if (
- def.fixed === false
- || def === fname_def
- || def.scope.get_defun_scope() !== parent
- ) {
- continue;
- }
- symbols_of_interest.add(def.id);
- // found a reference to another function
- if (
- def.assignments === 0
- && def.orig.length === 1
- && def.orig[0] instanceof AST_SymbolDefun
- ) {
- defuns_of_interest.add(def.id);
- symbols_of_interest.add(def.id);
- defuns_of_interest.add(fname_def.id);
- symbols_of_interest.add(fname_def.id);
- if (!defun_dependencies_map.has(fname_def.id)) {
- defun_dependencies_map.set(fname_def.id, []);
- }
- defun_dependencies_map.get(fname_def.id).push(def.id);
- continue;
- }
- enclosing_defs.push(def);
- }
- if (enclosing_defs.length) {
- dependencies_map.set(fname_def.id, enclosing_defs);
- defuns_of_interest.add(fname_def.id);
- symbols_of_interest.add(fname_def.id);
- }
- }
- // No defuns use outside constants
- if (!dependencies_map.size) {
- return;
- }
- // Increment to count "symbols of interest" (defuns or defs) that we found.
- // These are tracked in AST order so we can check which is after which.
- let symbol_index = 1;
- // Map a defun ID to its first read (a `symbol_index`)
- const defun_first_read_map = new Map();
- // Map a symbol ID to its last write (a `symbol_index`)
- const symbol_last_write_map = new Map();
- walk_parent(parent, (node, walk_info) => {
- if (node instanceof AST_Symbol && node.thedef) {
- const id = node.definition().id;
- symbol_index++;
- // Track last-writes to symbols
- if (symbols_of_interest.has(id)) {
- if (node instanceof AST_SymbolDeclaration || is_lhs(node, walk_info.parent())) {
- symbol_last_write_map.set(id, symbol_index);
- }
- }
- // Track first-reads of defuns (refined later)
- if (defuns_of_interest.has(id)) {
- if (!defun_first_read_map.has(id) && !is_recursive_ref(walk_info, id)) {
- defun_first_read_map.set(id, symbol_index);
- }
- }
- }
- });
- // Refine `defun_first_read_map` to be as high as possible
- for (const [defun, defun_first_read] of defun_first_read_map) {
- // Update all dependencies of `defun`
- const queue = new Set(defun_dependencies_map.get(defun));
- for (const enclosed_defun of queue) {
- let enclosed_defun_first_read = defun_first_read_map.get(enclosed_defun);
- if (enclosed_defun_first_read != null && enclosed_defun_first_read < defun_first_read) {
- continue;
- }
- defun_first_read_map.set(enclosed_defun, defun_first_read);
- for (const enclosed_enclosed_defun of defun_dependencies_map.get(enclosed_defun) || []) {
- queue.add(enclosed_enclosed_defun);
- }
- }
- }
- // ensure write-then-read order, otherwise clear `fixed`
- // This is safe because last-writes (found_symbol_writes) are assumed to be as late as possible, and first-reads (defun_first_read_map) are assumed to be as early as possible.
- for (const [defun, defs] of dependencies_map) {
- const defun_first_read = defun_first_read_map.get(defun);
- if (defun_first_read === undefined) {
- continue;
- }
- for (const def of defs) {
- if (def.fixed === false) {
- continue;
- }
- let def_last_write = symbol_last_write_map.get(def.id) || 0;
- if (defun_first_read < def_last_write) {
- def.fixed = false;
- }
- }
- }
- }
- def_reduce_vars(AST_Lambda, mark_lambda);
- def_reduce_vars(AST_Do, function(tw, descend, compressor) {
- reset_block_variables(compressor, this);
- const saved_loop = tw.in_loop;
- tw.in_loop = this;
- push(tw);
- this.body.walk(tw);
- if (has_break_or_continue(this)) {
- pop(tw);
- push(tw);
- }
- this.condition.walk(tw);
- pop(tw);
- tw.in_loop = saved_loop;
- return true;
- });
- def_reduce_vars(AST_For, function(tw, descend, compressor) {
- reset_block_variables(compressor, this);
- if (this.init) this.init.walk(tw);
- const saved_loop = tw.in_loop;
- tw.in_loop = this;
- push(tw);
- if (this.condition) this.condition.walk(tw);
- this.body.walk(tw);
- if (this.step) {
- if (has_break_or_continue(this)) {
- pop(tw);
- push(tw);
- }
- this.step.walk(tw);
- }
- pop(tw);
- tw.in_loop = saved_loop;
- return true;
- });
- def_reduce_vars(AST_ForIn, function(tw, descend, compressor) {
- reset_block_variables(compressor, this);
- suppress(this.init);
- this.object.walk(tw);
- const saved_loop = tw.in_loop;
- tw.in_loop = this;
- push(tw);
- this.body.walk(tw);
- pop(tw);
- tw.in_loop = saved_loop;
- return true;
- });
- def_reduce_vars(AST_If, function(tw) {
- this.condition.walk(tw);
- push(tw);
- this.body.walk(tw);
- pop(tw);
- if (this.alternative) {
- push(tw);
- this.alternative.walk(tw);
- pop(tw);
- }
- return true;
- });
- def_reduce_vars(AST_LabeledStatement, function(tw) {
- push(tw);
- this.body.walk(tw);
- pop(tw);
- return true;
- });
- def_reduce_vars(AST_SymbolCatch, function() {
- this.definition().fixed = false;
- });
- def_reduce_vars(AST_SymbolRef, function(tw, descend, compressor) {
- var d = this.definition();
- d.references.push(this);
- if (d.references.length == 1
- && !d.fixed
- && d.orig[0] instanceof AST_SymbolDefun) {
- tw.loop_ids.set(d.id, tw.in_loop);
- }
- var fixed_value;
- if (d.fixed === undefined || !safe_to_read(tw, d)) {
- d.fixed = false;
- } else if (d.fixed) {
- fixed_value = this.fixed_value();
- if (
- fixed_value instanceof AST_Lambda
- && is_recursive_ref(tw, d)
- ) {
- d.recursive_refs++;
- } else if (fixed_value
- && !compressor.exposed(d)
- && ref_once(tw, compressor, d)
- ) {
- d.single_use =
- fixed_value instanceof AST_Lambda && !fixed_value.pinned()
- || fixed_value instanceof AST_Class
- || d.scope === this.scope && fixed_value.is_constant_expression();
- } else {
- d.single_use = false;
- }
- if (is_modified(compressor, tw, this, fixed_value, 0, is_immutable(fixed_value))) {
- if (d.single_use) {
- d.single_use = "m";
- } else {
- d.fixed = false;
- }
- }
- }
- mark_escaped(tw, d, this.scope, this, fixed_value, 0, 1);
- });
- def_reduce_vars(AST_Toplevel, function(tw, descend, compressor) {
- this.globals.forEach(function(def) {
- reset_def(compressor, def);
- });
- reset_variables(tw, compressor, this);
- descend();
- handle_defined_after_hoist(this);
- return true;
- });
- def_reduce_vars(AST_Try, function(tw, descend, compressor) {
- reset_block_variables(compressor, this);
- push(tw);
- this.body.walk(tw);
- pop(tw);
- if (this.bcatch) {
- push(tw);
- this.bcatch.walk(tw);
- pop(tw);
- }
- if (this.bfinally) this.bfinally.walk(tw);
- return true;
- });
- def_reduce_vars(AST_Unary, function(tw) {
- var node = this;
- if (node.operator !== "++" && node.operator !== "--") return;
- var exp = node.expression;
- if (!(exp instanceof AST_SymbolRef)) return;
- var def = exp.definition();
- var safe = safe_to_assign(tw, def, exp.scope, true);
- def.assignments++;
- if (!safe) return;
- var fixed = def.fixed;
- if (!fixed) return;
- def.references.push(exp);
- def.chained = true;
- def.fixed = function() {
- return make_node(AST_Binary, node, {
- operator: node.operator.slice(0, -1),
- left: make_node(AST_UnaryPrefix, node, {
- operator: "+",
- expression: fixed instanceof AST_Node ? fixed : fixed()
- }),
- right: make_node(AST_Number, node, {
- value: 1
- })
- });
- };
- mark(tw, def, true);
- return true;
- });
- def_reduce_vars(AST_VarDef, function(tw, descend) {
- var node = this;
- if (node.name instanceof AST_Destructuring) {
- suppress(node.name);
- return;
- }
- var d = node.name.definition();
- if (node.value) {
- if (safe_to_assign(tw, d, node.name.scope, node.value)) {
- d.fixed = function() {
- return node.value;
- };
- tw.loop_ids.set(d.id, tw.in_loop);
- mark(tw, d, false);
- descend();
- mark(tw, d, true);
- return true;
- } else {
- d.fixed = false;
- }
- }
- });
- def_reduce_vars(AST_UsingDef, function() {
- suppress(this.name);
- });
- def_reduce_vars(AST_While, function(tw, descend, compressor) {
- reset_block_variables(compressor, this);
- const saved_loop = tw.in_loop;
- tw.in_loop = this;
- push(tw);
- descend();
- pop(tw);
- tw.in_loop = saved_loop;
- return true;
- });
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- function loop_body(x) {
- if (x instanceof AST_IterationStatement) {
- return x.body instanceof AST_BlockStatement ? x.body : x;
- }
- return x;
- }
- function is_lhs_read_only(lhs) {
- if (lhs instanceof AST_This) return true;
- if (lhs instanceof AST_SymbolRef) return lhs.definition().orig[0] instanceof AST_SymbolLambda;
- if (lhs instanceof AST_PropAccess) {
- lhs = lhs.expression;
- if (lhs instanceof AST_SymbolRef) {
- if (lhs.is_immutable()) return false;
- lhs = lhs.fixed_value();
- }
- if (!lhs) return true;
- if (lhs instanceof AST_RegExp) return false;
- if (lhs instanceof AST_Constant) return true;
- return is_lhs_read_only(lhs);
- }
- return false;
- }
- /** var a = 1 --> var a*/
- function remove_initializers(var_statement) {
- var decls = [];
- var_statement.definitions.forEach(function(def) {
- if (def.name instanceof AST_SymbolDeclaration) {
- def.value = null;
- decls.push(def);
- } else {
- def.declarations_as_names().forEach(name => {
- decls.push(make_node(AST_VarDef, def, {
- name,
- value: null
- }));
- });
- }
- });
- return decls.length ? make_node(AST_Var, var_statement, { definitions: decls }) : null;
- }
- /** Called on code which won't be executed but has an effect outside of itself: `var`, `function` statements, `export`, `import`. */
- function extract_from_unreachable_code(compressor, stat, target) {
- walk(stat, node => {
- if (node instanceof AST_Var) {
- const no_initializers = remove_initializers(node);
- if (no_initializers) target.push(no_initializers);
- return true;
- }
- if (
- node instanceof AST_Defun
- && (node === stat || !compressor.has_directive("use strict"))
- ) {
- target.push(node === stat ? node : make_node(AST_Var, node, {
- definitions: [
- make_node(AST_VarDef, node, {
- name: make_node(AST_SymbolVar, node.name, node.name),
- value: null
- })
- ]
- }));
- return true;
- }
- if (node instanceof AST_Export || node instanceof AST_Import) {
- target.push(node);
- return true;
- }
- if (node instanceof AST_Scope || node instanceof AST_Class) {
- // Do not go into nested scopes
- return true;
- }
- });
- }
- /** Tighten a bunch of statements together, and perform statement-level optimization. */
- function tighten_body(statements, compressor) {
- const nearest_scope = compressor.find_scope();
- const defun_scope = nearest_scope.get_defun_scope();
- const { in_loop, in_try } = find_loop_scope_try();
- var CHANGED, max_iter = 10;
- do {
- CHANGED = false;
- eliminate_spurious_blocks(statements);
- if (compressor.option("dead_code")) {
- eliminate_dead_code(statements, compressor);
- }
- if (compressor.option("if_return")) {
- handle_if_return(statements, compressor);
- }
- if (compressor.sequences_limit > 0) {
- sequencesize(statements, compressor);
- sequencesize_2(statements, compressor);
- }
- if (compressor.option("join_vars")) {
- join_consecutive_vars(statements);
- }
- if (compressor.option("collapse_vars")) {
- collapse(statements, compressor);
- }
- } while (CHANGED && max_iter-- > 0);
- function find_loop_scope_try() {
- var node = compressor.self(), level = 0, in_loop = false, in_try = false;
- do {
- if (node instanceof AST_IterationStatement) {
- in_loop = true;
- } else if (node instanceof AST_Scope) {
- break;
- } else if (node instanceof AST_TryBlock) {
- in_try = true;
- }
- } while (node = compressor.parent(level++));
- return { in_loop, in_try };
- }
- // Search from right to left for assignment-like expressions:
- // - `var a = x;`
- // - `a = x;`
- // - `++a`
- // For each candidate, scan from left to right for first usage, then try
- // to fold assignment into the site for compression.
- // Will not attempt to collapse assignments into or past code blocks
- // which are not sequentially executed, e.g. loops and conditionals.
- function collapse(statements, compressor) {
- if (nearest_scope.pinned() || defun_scope.pinned())
- return statements;
- var args;
- var candidates = [];
- var stat_index = statements.length;
- var scanner = new TreeTransformer(function (node) {
- if (abort)
- return node;
- // Skip nodes before `candidate` as quickly as possible
- if (!hit) {
- if (node !== hit_stack[hit_index])
- return node;
- hit_index++;
- if (hit_index < hit_stack.length)
- return handle_custom_scan_order(node);
- hit = true;
- stop_after = find_stop(node, 0);
- if (stop_after === node)
- abort = true;
- return node;
- }
- // Stop immediately if these node types are encountered
- var parent = scanner.parent();
- if (node instanceof AST_Assign
- && (node.logical || node.operator != "=" && lhs.equivalent_to(node.left))
- || node instanceof AST_Await
- || node instanceof AST_Using
- || node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression)
- ||
- (node instanceof AST_Call || node instanceof AST_PropAccess)
- && node.optional
- || node instanceof AST_Debugger
- || node instanceof AST_Destructuring
- || node instanceof AST_Expansion
- && node.expression instanceof AST_Symbol
- && (
- node.expression instanceof AST_This
- || node.expression.definition().references.length > 1
- )
- || node instanceof AST_IterationStatement && !(node instanceof AST_For)
- || node instanceof AST_LoopControl
- || node instanceof AST_Try
- || node instanceof AST_With
- || node instanceof AST_Yield
- || node instanceof AST_Export
- || node instanceof AST_Class
- || parent instanceof AST_For && node !== parent.init
- || !replace_all
- && (
- node instanceof AST_SymbolRef
- && !node.is_declared(compressor)
- && !pure_prop_access_globals.has(node)
- )
- || node instanceof AST_SymbolRef
- && parent instanceof AST_Call
- && has_annotation(parent, _NOINLINE)
- || node instanceof AST_ObjectProperty && node.key instanceof AST_Node
- ) {
- abort = true;
- return node;
- }
- // Stop only if candidate is found within conditional branches
- if (!stop_if_hit && (!lhs_local || !replace_all)
- && (parent instanceof AST_Binary && lazy_op.has(parent.operator) && parent.left !== node
- || parent instanceof AST_Conditional && parent.condition !== node
- || parent instanceof AST_If && parent.condition !== node)) {
- stop_if_hit = parent;
- }
- // Replace variable with assignment when found
- if (
- can_replace
- && !(node instanceof AST_SymbolDeclaration)
- && lhs.equivalent_to(node)
- && !shadows(scanner.find_scope() || nearest_scope, lvalues)
- ) {
- if (stop_if_hit) {
- abort = true;
- return node;
- }
- if (is_lhs(node, parent)) {
- if (value_def)
- replaced++;
- return node;
- } else {
- replaced++;
- if (value_def && candidate instanceof AST_VarDef)
- return node;
- }
- CHANGED = abort = true;
- if (candidate instanceof AST_UnaryPostfix) {
- return make_node(AST_UnaryPrefix, candidate, candidate);
- }
- if (candidate instanceof AST_VarDef) {
- var def = candidate.name.definition();
- var value = candidate.value;
- if (def.references.length - def.replaced == 1 && !compressor.exposed(def)) {
- def.replaced++;
- if (funarg && is_identifier_atom(value)) {
- return value.transform(compressor);
- } else {
- return maintain_this_binding(parent, node, value);
- }
- }
- return make_node(AST_Assign, candidate, {
- operator: "=",
- logical: false,
- left: make_node(AST_SymbolRef, candidate.name, candidate.name),
- right: value
- });
- }
- clear_flag(candidate, WRITE_ONLY);
- return candidate;
- }
- // These node types have child nodes that execute sequentially,
- // but are otherwise not safe to scan into or beyond them.
- var sym;
- if (node instanceof AST_Call
- || node instanceof AST_Exit
- && (side_effects || lhs instanceof AST_PropAccess || may_modify(lhs))
- || node instanceof AST_PropAccess
- && (side_effects || node.expression.may_throw_on_access(compressor))
- || node instanceof AST_SymbolRef
- && ((lvalues.has(node.name) && lvalues.get(node.name).modified) || side_effects && may_modify(node))
- || node instanceof AST_VarDef && node.value
- && (lvalues.has(node.name.name) || side_effects && may_modify(node.name))
- || node instanceof AST_Using
- || (sym = is_lhs(node.left, node))
- && (sym instanceof AST_PropAccess || lvalues.has(sym.name))
- || may_throw
- && (in_try ? node.has_side_effects(compressor) : side_effects_external(node))) {
- stop_after = node;
- if (node instanceof AST_Scope)
- abort = true;
- }
- return handle_custom_scan_order(node);
- }, function (node) {
- if (abort)
- return;
- if (stop_after === node)
- abort = true;
- if (stop_if_hit === node)
- stop_if_hit = null;
- });
- var multi_replacer = new TreeTransformer(function (node) {
- if (abort)
- return node;
- // Skip nodes before `candidate` as quickly as possible
- if (!hit) {
- if (node !== hit_stack[hit_index])
- return node;
- hit_index++;
- if (hit_index < hit_stack.length)
- return;
- hit = true;
- return node;
- }
- // Replace variable when found
- if (node instanceof AST_SymbolRef
- && node.name == def.name) {
- if (!--replaced)
- abort = true;
- if (is_lhs(node, multi_replacer.parent()))
- return node;
- def.replaced++;
- value_def.replaced--;
- return candidate.value;
- }
- // Skip (non-executed) functions and (leading) default case in switch statements
- if (node instanceof AST_Default || node instanceof AST_Scope)
- return node;
- });
- while (--stat_index >= 0) {
- // Treat parameters as collapsible in IIFE, i.e.
- // function(a, b){ ... }(x());
- // would be translated into equivalent assignments:
- // var a = x(), b = undefined;
- if (stat_index == 0 && compressor.option("unused"))
- extract_args();
- // Find collapsible assignments
- var hit_stack = [];
- extract_candidates(statements[stat_index]);
- while (candidates.length > 0) {
- hit_stack = candidates.pop();
- var hit_index = 0;
- var candidate = hit_stack[hit_stack.length - 1];
- var value_def = null;
- var stop_after = null;
- var stop_if_hit = null;
- var lhs = get_lhs(candidate);
- if (!lhs || is_lhs_read_only(lhs) || lhs.has_side_effects(compressor))
- continue;
- // Locate symbols which may execute code outside of scanning range
- var lvalues = get_lvalues(candidate);
- var lhs_local = is_lhs_local(lhs);
- if (lhs instanceof AST_SymbolRef) {
- lvalues.set(lhs.name, { def: lhs.definition(), modified: false });
- }
- var side_effects = value_has_side_effects(candidate);
- var replace_all = replace_all_symbols();
- var may_throw = candidate.may_throw(compressor);
- var funarg = candidate.name instanceof AST_SymbolFunarg;
- var hit = funarg;
- var abort = false, replaced = 0, can_replace = !args || !hit;
- if (!can_replace) {
- for (
- let j = compressor.self().argnames.lastIndexOf(candidate.name) + 1;
- !abort && j < args.length;
- j++
- ) {
- args[j].transform(scanner);
- }
- can_replace = true;
- }
- for (var i = stat_index; !abort && i < statements.length; i++) {
- statements[i].transform(scanner);
- }
- if (value_def) {
- var def = candidate.name.definition();
- if (abort && def.references.length - def.replaced > replaced)
- replaced = false;
- else {
- abort = false;
- hit_index = 0;
- hit = funarg;
- for (var i = stat_index; !abort && i < statements.length; i++) {
- statements[i].transform(multi_replacer);
- }
- value_def.single_use = false;
- }
- }
- if (replaced && !remove_candidate(candidate))
- statements.splice(stat_index, 1);
- }
- }
- function handle_custom_scan_order(node) {
- // Skip (non-executed) functions
- if (node instanceof AST_Scope)
- return node;
- // Scan case expressions first in a switch statement
- if (node instanceof AST_Switch) {
- node.expression = node.expression.transform(scanner);
- for (var i = 0, len = node.body.length; !abort && i < len; i++) {
- var branch = node.body[i];
- if (branch instanceof AST_Case) {
- if (!hit) {
- if (branch !== hit_stack[hit_index])
- continue;
- hit_index++;
- }
- branch.expression = branch.expression.transform(scanner);
- if (!replace_all)
- break;
- }
- }
- abort = true;
- return node;
- }
- }
- function redefined_within_scope(def, scope) {
- if (def.global)
- return false;
- let cur_scope = def.scope;
- while (cur_scope && cur_scope !== scope) {
- if (cur_scope.variables.has(def.name)) {
- return true;
- }
- cur_scope = cur_scope.parent_scope;
- }
- return false;
- }
- function has_overlapping_symbol(fn, arg, fn_strict) {
- var found = false, scan_this = !(fn instanceof AST_Arrow);
- arg.walk(new TreeWalker(function (node, descend) {
- if (found)
- return true;
- if (node instanceof AST_SymbolRef && (fn.variables.has(node.name) || redefined_within_scope(node.definition(), fn))) {
- var s = node.definition().scope;
- if (s !== defun_scope)
- while (s = s.parent_scope) {
- if (s === defun_scope)
- return true;
- }
- return found = true;
- }
- if ((fn_strict || scan_this) && node instanceof AST_This) {
- return found = true;
- }
- if (node instanceof AST_Scope && !(node instanceof AST_Arrow)) {
- var prev = scan_this;
- scan_this = false;
- descend();
- scan_this = prev;
- return true;
- }
- }));
- return found;
- }
- function arg_is_injectable(arg) {
- if (arg instanceof AST_Expansion) return false;
- const contains_await = walk(arg, (node) => {
- if (node instanceof AST_Await) return walk_abort;
- });
- if (contains_await) return false;
- return true;
- }
- function extract_args() {
- var iife, fn = compressor.self();
- if (is_func_expr(fn)
- && !fn.name
- && !fn.uses_arguments
- && !fn.pinned()
- && (iife = compressor.parent()) instanceof AST_Call
- && iife.expression === fn
- && iife.args.every(arg_is_injectable)
- ) {
- var fn_strict = compressor.has_directive("use strict");
- if (fn_strict && !member(fn_strict, fn.body))
- fn_strict = false;
- var len = fn.argnames.length;
- args = iife.args.slice(len);
- var names = new Set();
- for (var i = len; --i >= 0;) {
- var sym = fn.argnames[i];
- var arg = iife.args[i];
- // The following two line fix is a duplicate of the fix at
- // https://github.com/terser/terser/commit/011d3eb08cefe6922c7d1bdfa113fc4aeaca1b75
- // This might mean that these two pieces of code (one here in collapse_vars and another in reduce_vars
- // Might be doing the exact same thing.
- const def = sym.definition && sym.definition();
- const is_reassigned = def && def.orig.length > 1;
- if (is_reassigned)
- continue;
- args.unshift(make_node(AST_VarDef, sym, {
- name: sym,
- value: arg
- }));
- if (names.has(sym.name))
- continue;
- names.add(sym.name);
- if (sym instanceof AST_Expansion) {
- var elements = iife.args.slice(i);
- if (elements.every((arg) => !has_overlapping_symbol(fn, arg, fn_strict)
- )) {
- candidates.unshift([make_node(AST_VarDef, sym, {
- name: sym.expression,
- value: make_node(AST_Array, iife, {
- elements: elements
- })
- })]);
- }
- } else {
- if (!arg) {
- arg = make_void_0(sym).transform(compressor);
- } else if (arg instanceof AST_Lambda && arg.pinned()
- || has_overlapping_symbol(fn, arg, fn_strict)) {
- arg = null;
- }
- if (arg)
- candidates.unshift([make_node(AST_VarDef, sym, {
- name: sym,
- value: arg
- })]);
- }
- }
- }
- }
- function extract_candidates(expr) {
- hit_stack.push(expr);
- if (expr instanceof AST_Assign) {
- if (!expr.left.has_side_effects(compressor)
- && !(expr.right instanceof AST_Chain)) {
- candidates.push(hit_stack.slice());
- }
- extract_candidates(expr.right);
- } else if (expr instanceof AST_Binary) {
- extract_candidates(expr.left);
- extract_candidates(expr.right);
- } else if (expr instanceof AST_Call && !has_annotation(expr, _NOINLINE)) {
- extract_candidates(expr.expression);
- expr.args.forEach(extract_candidates);
- } else if (expr instanceof AST_Case) {
- extract_candidates(expr.expression);
- } else if (expr instanceof AST_Conditional) {
- extract_candidates(expr.condition);
- extract_candidates(expr.consequent);
- extract_candidates(expr.alternative);
- } else if (expr instanceof AST_Definitions) {
- var len = expr.definitions.length;
- // limit number of trailing variable definitions for consideration
- var i = len - 200;
- if (i < 0)
- i = 0;
- for (; i < len; i++) {
- extract_candidates(expr.definitions[i]);
- }
- } else if (expr instanceof AST_DWLoop) {
- extract_candidates(expr.condition);
- if (!(expr.body instanceof AST_Block)) {
- extract_candidates(expr.body);
- }
- } else if (expr instanceof AST_Exit) {
- if (expr.value)
- extract_candidates(expr.value);
- } else if (expr instanceof AST_For) {
- if (expr.init)
- extract_candidates(expr.init);
- if (expr.condition)
- extract_candidates(expr.condition);
- if (expr.step)
- extract_candidates(expr.step);
- if (!(expr.body instanceof AST_Block)) {
- extract_candidates(expr.body);
- }
- } else if (expr instanceof AST_ForIn) {
- extract_candidates(expr.object);
- if (!(expr.body instanceof AST_Block)) {
- extract_candidates(expr.body);
- }
- } else if (expr instanceof AST_If) {
- extract_candidates(expr.condition);
- if (!(expr.body instanceof AST_Block)) {
- extract_candidates(expr.body);
- }
- if (expr.alternative && !(expr.alternative instanceof AST_Block)) {
- extract_candidates(expr.alternative);
- }
- } else if (expr instanceof AST_Sequence) {
- expr.expressions.forEach(extract_candidates);
- } else if (expr instanceof AST_SimpleStatement) {
- extract_candidates(expr.body);
- } else if (expr instanceof AST_Switch) {
- extract_candidates(expr.expression);
- expr.body.forEach(extract_candidates);
- } else if (expr instanceof AST_Unary) {
- if (expr.operator == "++" || expr.operator == "--") {
- candidates.push(hit_stack.slice());
- }
- } else if (expr instanceof AST_VarDef) {
- if (expr.value && !(expr.value instanceof AST_Chain)) {
- candidates.push(hit_stack.slice());
- extract_candidates(expr.value);
- }
- }
- hit_stack.pop();
- }
- function find_stop(node, level, write_only) {
- var parent = scanner.parent(level);
- if (parent instanceof AST_Assign) {
- if (write_only
- && !parent.logical
- && !(parent.left instanceof AST_PropAccess
- || lvalues.has(parent.left.name))) {
- return find_stop(parent, level + 1, write_only);
- }
- return node;
- }
- if (parent instanceof AST_Binary) {
- if (write_only && (!lazy_op.has(parent.operator) || parent.left === node)) {
- return find_stop(parent, level + 1, write_only);
- }
- return node;
- }
- if (parent instanceof AST_Call)
- return node;
- if (parent instanceof AST_Case)
- return node;
- if (parent instanceof AST_Conditional) {
- if (write_only && parent.condition === node) {
- return find_stop(parent, level + 1, write_only);
- }
- return node;
- }
- if (parent instanceof AST_Definitions) {
- return find_stop(parent, level + 1, true);
- }
- if (parent instanceof AST_Exit) {
- return write_only ? find_stop(parent, level + 1, write_only) : node;
- }
- if (parent instanceof AST_If) {
- if (write_only && parent.condition === node) {
- return find_stop(parent, level + 1, write_only);
- }
- return node;
- }
- if (parent instanceof AST_IterationStatement)
- return node;
- if (parent instanceof AST_Sequence) {
- return find_stop(parent, level + 1, parent.tail_node() !== node);
- }
- if (parent instanceof AST_SimpleStatement) {
- return find_stop(parent, level + 1, true);
- }
- if (parent instanceof AST_Switch)
- return node;
- if (parent instanceof AST_VarDef)
- return node;
- return null;
- }
- function mangleable_var(var_def) {
- var value = var_def.value;
- if (!(value instanceof AST_SymbolRef))
- return;
- if (value.name == "arguments")
- return;
- var def = value.definition();
- if (def.undeclared)
- return;
- return value_def = def;
- }
- function get_lhs(expr) {
- if (expr instanceof AST_Assign && expr.logical) {
- return false;
- } else if (expr instanceof AST_VarDef && expr.name instanceof AST_SymbolDeclaration) {
- var def = expr.name.definition();
- if (!member(expr.name, def.orig))
- return;
- var referenced = def.references.length - def.replaced;
- if (!referenced)
- return;
- var declared = def.orig.length - def.eliminated;
- if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)
- || (referenced > 1 ? mangleable_var(expr) : !compressor.exposed(def))) {
- return make_node(AST_SymbolRef, expr.name, expr.name);
- }
- } else {
- const lhs = expr instanceof AST_Assign
- ? expr.left
- : expr.expression;
- return !is_ref_of(lhs, AST_SymbolConst)
- && !is_ref_of(lhs, AST_SymbolLet)
- && !is_ref_of(lhs, AST_SymbolUsing)
- && lhs;
- }
- }
- function get_rvalue(expr) {
- if (expr instanceof AST_Assign) {
- return expr.right;
- } else {
- return expr.value;
- }
- }
- function get_lvalues(expr) {
- var lvalues = new Map();
- if (expr instanceof AST_Unary)
- return lvalues;
- var tw = new TreeWalker(function (node) {
- var sym = node;
- while (sym instanceof AST_PropAccess)
- sym = sym.expression;
- if (sym instanceof AST_SymbolRef) {
- const prev = lvalues.get(sym.name);
- if (!prev || !prev.modified) {
- lvalues.set(sym.name, {
- def: sym.definition(),
- modified: is_modified(compressor, tw, node, node, 0)
- });
- }
- }
- });
- get_rvalue(expr).walk(tw);
- return lvalues;
- }
- function remove_candidate(expr) {
- if (expr.name instanceof AST_SymbolFunarg) {
- var iife = compressor.parent(), argnames = compressor.self().argnames;
- var index = argnames.indexOf(expr.name);
- if (index < 0) {
- iife.args.length = Math.min(iife.args.length, argnames.length - 1);
- } else {
- var args = iife.args;
- if (args[index])
- args[index] = make_node(AST_Number, args[index], {
- value: 0
- });
- }
- return true;
- }
- var found = false;
- return statements[stat_index].transform(new TreeTransformer(function (node, descend, in_list) {
- if (found)
- return node;
- if (node === expr || node.body === expr) {
- found = true;
- if (node instanceof AST_VarDef) {
- node.value = node.name instanceof AST_SymbolConst
- ? make_void_0(node.value) // `const` always needs value.
- : null;
- return node;
- }
- return in_list ? MAP.skip : null;
- }
- }, function (node) {
- if (node instanceof AST_Sequence)
- switch (node.expressions.length) {
- case 0: return null;
- case 1: return node.expressions[0];
- }
- }));
- }
- function is_lhs_local(lhs) {
- while (lhs instanceof AST_PropAccess)
- lhs = lhs.expression;
- return lhs instanceof AST_SymbolRef
- && lhs.definition().scope.get_defun_scope() === defun_scope
- && !(in_loop
- && (lvalues.has(lhs.name)
- || candidate instanceof AST_Unary
- || (candidate instanceof AST_Assign
- && !candidate.logical
- && candidate.operator != "=")));
- }
- function value_has_side_effects(expr) {
- if (expr instanceof AST_Unary)
- return unary_side_effects.has(expr.operator);
- return get_rvalue(expr).has_side_effects(compressor);
- }
- function replace_all_symbols() {
- if (side_effects)
- return false;
- if (value_def)
- return true;
- if (lhs instanceof AST_SymbolRef) {
- var def = lhs.definition();
- if (def.references.length - def.replaced == (candidate instanceof AST_VarDef ? 1 : 2)) {
- return true;
- }
- }
- return false;
- }
- function may_modify(sym) {
- if (!sym.definition)
- return true; // AST_Destructuring
- var def = sym.definition();
- if (def.orig.length == 1 && def.orig[0] instanceof AST_SymbolDefun)
- return false;
- if (def.scope.get_defun_scope() !== defun_scope)
- return true;
- return def.references.some((ref) =>
- ref.scope.get_defun_scope() !== defun_scope
- );
- }
- function side_effects_external(node, lhs) {
- if (node instanceof AST_Assign)
- return side_effects_external(node.left, true);
- if (node instanceof AST_Unary)
- return side_effects_external(node.expression, true);
- if (node instanceof AST_VarDef)
- return node.value && side_effects_external(node.value);
- if (lhs) {
- if (node instanceof AST_Dot)
- return side_effects_external(node.expression, true);
- if (node instanceof AST_Sub)
- return side_effects_external(node.expression, true);
- if (node instanceof AST_SymbolRef)
- return node.definition().scope.get_defun_scope() !== defun_scope;
- }
- return false;
- }
- /**
- * Will any of the pulled-in lvalues shadow a variable in newScope or parents?
- * similar to scope_encloses_variables_in_this_scope */
- function shadows(my_scope, lvalues) {
- for (const { def } of lvalues.values()) {
- const looked_up = my_scope.find_variable(def.name);
- if (looked_up) {
- if (looked_up === def) continue;
- return true;
- }
- }
- return false;
- }
- }
- function eliminate_spurious_blocks(statements) {
- var seen_dirs = [];
- for (var i = 0; i < statements.length;) {
- var stat = statements[i];
- if (stat instanceof AST_BlockStatement && stat.body.every(can_be_evicted_from_block)) {
- CHANGED = true;
- eliminate_spurious_blocks(stat.body);
- statements.splice(i, 1, ...stat.body);
- i += stat.body.length;
- } else if (stat instanceof AST_EmptyStatement) {
- CHANGED = true;
- statements.splice(i, 1);
- } else if (stat instanceof AST_Directive) {
- if (seen_dirs.indexOf(stat.value) < 0) {
- i++;
- seen_dirs.push(stat.value);
- } else {
- CHANGED = true;
- statements.splice(i, 1);
- }
- } else
- i++;
- }
- }
- function handle_if_return(statements, compressor) {
- var self = compressor.self();
- var multiple_if_returns = has_multiple_if_returns(statements);
- var in_lambda = self instanceof AST_Lambda;
- // Prevent extremely deep nesting
- // https://github.com/terser/terser/issues/1432
- // https://github.com/webpack/webpack/issues/17548
- const iteration_start = Math.min(statements.length, 500);
- for (var i = iteration_start; --i >= 0;) {
- var stat = statements[i];
- var j = next_index(i);
- var next = statements[j];
- if (in_lambda && !next && stat instanceof AST_Return) {
- if (!stat.value) {
- CHANGED = true;
- statements.splice(i, 1);
- continue;
- }
- if (stat.value instanceof AST_UnaryPrefix && stat.value.operator == "void") {
- CHANGED = true;
- statements[i] = make_node(AST_SimpleStatement, stat, {
- body: stat.value.expression
- });
- continue;
- }
- }
- if (stat instanceof AST_If) {
- let ab, new_else;
- ab = aborts(stat.body);
- if (
- can_merge_flow(ab)
- && (new_else = as_statement_array_with_return(stat.body, ab))
- ) {
- if (ab.label) {
- remove(ab.label.thedef.references, ab);
- }
- CHANGED = true;
- stat = stat.clone();
- stat.condition = stat.condition.negate(compressor);
- stat.body = make_node(AST_BlockStatement, stat, {
- body: as_statement_array(stat.alternative).concat(extract_defuns())
- });
- stat.alternative = make_node(AST_BlockStatement, stat, {
- body: new_else
- });
- statements[i] = stat.transform(compressor);
- continue;
- }
- ab = aborts(stat.alternative);
- if (
- can_merge_flow(ab)
- && (new_else = as_statement_array_with_return(stat.alternative, ab))
- ) {
- if (ab.label) {
- remove(ab.label.thedef.references, ab);
- }
- CHANGED = true;
- stat = stat.clone();
- stat.body = make_node(AST_BlockStatement, stat.body, {
- body: as_statement_array(stat.body).concat(extract_defuns())
- });
- stat.alternative = make_node(AST_BlockStatement, stat.alternative, {
- body: new_else
- });
- statements[i] = stat.transform(compressor);
- continue;
- }
- }
- if (stat instanceof AST_If && stat.body instanceof AST_Return) {
- var value = stat.body.value;
- //---
- // pretty silly case, but:
- // if (foo()) return; return; ==> foo(); return;
- if (!value && !stat.alternative
- && (in_lambda && !next || next instanceof AST_Return && !next.value)) {
- CHANGED = true;
- statements[i] = make_node(AST_SimpleStatement, stat.condition, {
- body: stat.condition
- });
- continue;
- }
- //---
- // if (foo()) return x; return y; ==> return foo() ? x : y;
- if (value && !stat.alternative && next instanceof AST_Return && next.value) {
- CHANGED = true;
- stat = stat.clone();
- stat.alternative = next;
- statements[i] = stat.transform(compressor);
- statements.splice(j, 1);
- continue;
- }
- //---
- // if (foo()) return x; [ return ; ] ==> return foo() ? x : undefined;
- if (value && !stat.alternative
- && (!next && in_lambda && multiple_if_returns
- || next instanceof AST_Return)) {
- CHANGED = true;
- stat = stat.clone();
- stat.alternative = next || make_node(AST_Return, stat, {
- value: null
- });
- statements[i] = stat.transform(compressor);
- if (next)
- statements.splice(j, 1);
- continue;
- }
- //---
- // if (a) return b; if (c) return d; e; ==> return a ? b : c ? d : void e;
- //
- // if sequences is not enabled, this can lead to an endless loop (issue #866).
- // however, with sequences on this helps producing slightly better output for
- // the example code.
- var prev = statements[prev_index(i)];
- if (compressor.option("sequences") && in_lambda && !stat.alternative
- && prev instanceof AST_If && prev.body instanceof AST_Return
- && next_index(j) == statements.length && next instanceof AST_SimpleStatement) {
- CHANGED = true;
- stat = stat.clone();
- stat.alternative = make_node(AST_BlockStatement, next, {
- body: [
- next,
- make_node(AST_Return, next, {
- value: null
- })
- ]
- });
- statements[i] = stat.transform(compressor);
- statements.splice(j, 1);
- continue;
- }
- }
- }
- function has_multiple_if_returns(statements) {
- var n = 0;
- for (var i = statements.length; --i >= 0;) {
- var stat = statements[i];
- if (stat instanceof AST_If && stat.body instanceof AST_Return) {
- if (++n > 1)
- return true;
- }
- }
- return false;
- }
- function is_return_void(value) {
- return !value || value instanceof AST_UnaryPrefix && value.operator == "void";
- }
- function can_merge_flow(ab) {
- if (!ab)
- return false;
- for (var j = i + 1, len = statements.length; j < len; j++) {
- var stat = statements[j];
- if (stat instanceof AST_DefinitionsLike && !(stat instanceof AST_Var))
- return false;
- }
- var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab) : null;
- return ab instanceof AST_Return && in_lambda && is_return_void(ab.value)
- || ab instanceof AST_Continue && self === loop_body(lct)
- || ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct;
- }
- function extract_defuns() {
- var tail = statements.slice(i + 1);
- statements.length = i + 1;
- return tail.filter(function (stat) {
- if (stat instanceof AST_Defun) {
- statements.push(stat);
- return false;
- }
- return true;
- });
- }
- function as_statement_array_with_return(node, ab) {
- var body = as_statement_array(node);
- if (ab !== body[body.length - 1]) {
- return undefined;
- }
- body = body.slice(0, -1);
- if (!body.every(stat => can_be_evicted_from_block(stat))) {
- return undefined;
- }
- if (ab.value) {
- body.push(make_node(AST_SimpleStatement, ab.value, {
- body: ab.value.expression
- }));
- }
- return body;
- }
- function next_index(i) {
- for (var j = i + 1, len = statements.length; j < len; j++) {
- var stat = statements[j];
- if (!(stat instanceof AST_Var && declarations_only(stat))) {
- break;
- }
- }
- return j;
- }
- function prev_index(i) {
- for (var j = i; --j >= 0;) {
- var stat = statements[j];
- if (!(stat instanceof AST_Var && declarations_only(stat))) {
- break;
- }
- }
- return j;
- }
- }
- function eliminate_dead_code(statements, compressor) {
- var has_quit;
- var self = compressor.self();
- for (var i = 0, n = 0, len = statements.length; i < len; i++) {
- var stat = statements[i];
- if (stat instanceof AST_LoopControl) {
- var lct = compressor.loopcontrol_target(stat);
- if (stat instanceof AST_Break
- && !(lct instanceof AST_IterationStatement)
- && loop_body(lct) === self
- || stat instanceof AST_Continue
- && loop_body(lct) === self) {
- if (stat.label) {
- remove(stat.label.thedef.references, stat);
- }
- } else {
- statements[n++] = stat;
- }
- } else {
- statements[n++] = stat;
- }
- if (aborts(stat)) {
- has_quit = statements.slice(i + 1);
- break;
- }
- }
- statements.length = n;
- CHANGED = n != len;
- if (has_quit)
- has_quit.forEach(function (stat) {
- extract_from_unreachable_code(compressor, stat, statements);
- });
- }
- function declarations_only(node) {
- return node.definitions.every((var_def) => !var_def.value);
- }
- function sequencesize(statements, compressor) {
- if (statements.length < 2)
- return;
- var seq = [], n = 0;
- function push_seq() {
- if (!seq.length)
- return;
- var body = make_sequence(seq[0], seq);
- statements[n++] = make_node(AST_SimpleStatement, body, { body: body });
- seq = [];
- }
- for (var i = 0, len = statements.length; i < len; i++) {
- var stat = statements[i];
- if (stat instanceof AST_SimpleStatement) {
- if (seq.length >= compressor.sequences_limit)
- push_seq();
- var body = stat.body;
- if (seq.length > 0)
- body = body.drop_side_effect_free(compressor);
- if (body)
- merge_sequence(seq, body);
- } else if (stat instanceof AST_Definitions && declarations_only(stat)
- || stat instanceof AST_Defun) {
- statements[n++] = stat;
- } else {
- push_seq();
- statements[n++] = stat;
- }
- }
- push_seq();
- statements.length = n;
- if (n != len)
- CHANGED = true;
- }
- function to_simple_statement(block, decls) {
- if (!(block instanceof AST_BlockStatement))
- return block;
- var stat = null;
- for (var i = 0, len = block.body.length; i < len; i++) {
- var line = block.body[i];
- if (line instanceof AST_Var && declarations_only(line)) {
- decls.push(line);
- } else if (stat || line instanceof AST_DefinitionsLike && !(line instanceof AST_Var)) {
- return false;
- } else {
- stat = line;
- }
- }
- return stat;
- }
- function sequencesize_2(statements, compressor) {
- function cons_seq(right) {
- n--;
- CHANGED = true;
- var left = prev.body;
- return make_sequence(left, [left, right]).transform(compressor);
- }
- var n = 0, prev;
- for (var i = 0; i < statements.length; i++) {
- var stat = statements[i];
- if (prev) {
- if (stat instanceof AST_Exit) {
- stat.value = cons_seq(stat.value || make_void_0(stat).transform(compressor));
- } else if (stat instanceof AST_For) {
- if (!(stat.init instanceof AST_DefinitionsLike)) {
- const abort = walk(prev.body, node => {
- if (node instanceof AST_Scope)
- return true;
- if (node instanceof AST_Binary
- && node.operator === "in") {
- return walk_abort;
- }
- });
- if (!abort) {
- if (stat.init)
- stat.init = cons_seq(stat.init);
- else {
- stat.init = prev.body;
- n--;
- CHANGED = true;
- }
- }
- }
- } else if (stat instanceof AST_ForIn) {
- if (!(stat.init instanceof AST_DefinitionsLike) || stat.init instanceof AST_Var) {
- stat.object = cons_seq(stat.object);
- }
- } else if (stat instanceof AST_If) {
- stat.condition = cons_seq(stat.condition);
- } else if (stat instanceof AST_Switch) {
- stat.expression = cons_seq(stat.expression);
- } else if (stat instanceof AST_With) {
- stat.expression = cons_seq(stat.expression);
- }
- }
- if (compressor.option("conditionals") && stat instanceof AST_If) {
- var decls = [];
- var body = to_simple_statement(stat.body, decls);
- var alt = to_simple_statement(stat.alternative, decls);
- if (body !== false && alt !== false && decls.length > 0) {
- var len = decls.length;
- decls.push(make_node(AST_If, stat, {
- condition: stat.condition,
- body: body || make_node(AST_EmptyStatement, stat.body),
- alternative: alt
- }));
- decls.unshift(n, 1);
- [].splice.apply(statements, decls);
- i += len;
- n += len + 1;
- prev = null;
- CHANGED = true;
- continue;
- }
- }
- statements[n++] = stat;
- prev = stat instanceof AST_SimpleStatement ? stat : null;
- }
- statements.length = n;
- }
- function join_object_assignments(defn, body) {
- if (!(defn instanceof AST_Definitions))
- return;
- var def = defn.definitions[defn.definitions.length - 1];
- if (!(def.value instanceof AST_Object))
- return;
- var exprs;
- if (body instanceof AST_Assign && !body.logical) {
- exprs = [body];
- } else if (body instanceof AST_Sequence) {
- exprs = body.expressions.slice();
- }
- if (!exprs)
- return;
- var trimmed = false;
- do {
- var node = exprs[0];
- if (!(node instanceof AST_Assign))
- break;
- if (node.operator != "=")
- break;
- if (!(node.left instanceof AST_PropAccess))
- break;
- var sym = node.left.expression;
- if (!(sym instanceof AST_SymbolRef))
- break;
- if (def.name.name != sym.name)
- break;
- if (!node.right.is_constant_expression(nearest_scope))
- break;
- var prop = node.left.property;
- if (prop instanceof AST_Node) {
- prop = prop.evaluate(compressor);
- }
- if (prop instanceof AST_Node)
- break;
- prop = "" + prop;
- var diff = compressor.option("ecma") < 2015
- && compressor.has_directive("use strict") ? function (node) {
- return node.key != prop && (node.key && node.key.name != prop);
- } : function (node) {
- return node.key && node.key.name != prop;
- };
- if (!def.value.properties.every(diff))
- break;
- var p = def.value.properties.filter(function (p) { return p.key === prop; })[0];
- if (!p) {
- def.value.properties.push(make_node(AST_ObjectKeyVal, node, {
- key: prop,
- value: node.right
- }));
- } else {
- p.value = new AST_Sequence({
- start: p.start,
- expressions: [p.value.clone(), node.right.clone()],
- end: p.end
- });
- }
- exprs.shift();
- trimmed = true;
- } while (exprs.length);
- return trimmed && exprs;
- }
- function join_consecutive_vars(statements) {
- var defs;
- for (var i = 0, j = -1, len = statements.length; i < len; i++) {
- var stat = statements[i];
- var prev = statements[j];
- if (stat instanceof AST_Definitions) {
- if (prev && prev.TYPE == stat.TYPE) {
- prev.definitions = prev.definitions.concat(stat.definitions);
- CHANGED = true;
- } else if (defs && defs.TYPE == stat.TYPE && declarations_only(stat)) {
- defs.definitions = defs.definitions.concat(stat.definitions);
- CHANGED = true;
- } else {
- statements[++j] = stat;
- defs = stat;
- }
- } else if (
- stat instanceof AST_Using
- && prev instanceof AST_Using
- && prev.await === stat.await
- ) {
- prev.definitions = prev.definitions.concat(stat.definitions);
- } else if (stat instanceof AST_Exit) {
- stat.value = extract_object_assignments(stat.value);
- } else if (stat instanceof AST_For) {
- var exprs = join_object_assignments(prev, stat.init);
- if (exprs) {
- CHANGED = true;
- stat.init = exprs.length ? make_sequence(stat.init, exprs) : null;
- statements[++j] = stat;
- } else if (
- prev instanceof AST_Var
- && (!stat.init || stat.init.TYPE == prev.TYPE)
- ) {
- if (stat.init) {
- prev.definitions = prev.definitions.concat(stat.init.definitions);
- }
- stat.init = prev;
- statements[j] = stat;
- CHANGED = true;
- } else if (
- defs instanceof AST_Var
- && stat.init instanceof AST_Var
- && declarations_only(stat.init)
- ) {
- defs.definitions = defs.definitions.concat(stat.init.definitions);
- stat.init = null;
- statements[++j] = stat;
- CHANGED = true;
- } else {
- statements[++j] = stat;
- }
- } else if (stat instanceof AST_ForIn) {
- stat.object = extract_object_assignments(stat.object);
- } else if (stat instanceof AST_If) {
- stat.condition = extract_object_assignments(stat.condition);
- } else if (stat instanceof AST_SimpleStatement) {
- var exprs = join_object_assignments(prev, stat.body);
- if (exprs) {
- CHANGED = true;
- if (!exprs.length)
- continue;
- stat.body = make_sequence(stat.body, exprs);
- }
- statements[++j] = stat;
- } else if (stat instanceof AST_Switch) {
- stat.expression = extract_object_assignments(stat.expression);
- } else if (stat instanceof AST_With) {
- stat.expression = extract_object_assignments(stat.expression);
- } else {
- statements[++j] = stat;
- }
- }
- statements.length = j + 1;
- function extract_object_assignments(value) {
- statements[++j] = stat;
- var exprs = join_object_assignments(prev, value);
- if (exprs) {
- CHANGED = true;
- if (exprs.length) {
- return make_sequence(value, exprs);
- } else if (value instanceof AST_Sequence) {
- return value.tail_node().left;
- } else {
- return value.left;
- }
- }
- return value;
- }
- }
- }
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- /**
- * Module that contains the inlining logic.
- *
- * @module
- *
- * The stars of the show are `inline_into_symbolref` and `inline_into_call`.
- */
- function within_array_or_object_literal(compressor) {
- var node, level = 0;
- while (node = compressor.parent(level++)) {
- if (node instanceof AST_Statement) return false;
- if (node instanceof AST_Array
- || node instanceof AST_ObjectKeyVal
- || node instanceof AST_Object) {
- return true;
- }
- }
- return false;
- }
- function scope_encloses_variables_in_this_scope(scope, pulled_scope) {
- for (const enclosed of pulled_scope.enclosed) {
- if (pulled_scope.variables.has(enclosed.name)) {
- continue;
- }
- const looked_up = scope.find_variable(enclosed.name);
- if (looked_up) {
- if (looked_up === enclosed) continue;
- return true;
- }
- }
- return false;
- }
- /**
- * An extra check function for `top_retain` option, compare the length of const identifier
- * and init value length and return true if init value is longer than identifier. for example:
- * ```
- * // top_retain: ["example"]
- * const example = 100
- * ```
- * it will return false because length of "100" is short than identifier "example".
- */
- function is_const_symbol_short_than_init_value(def, fixed_value) {
- if (def.orig.length === 1 && fixed_value) {
- const init_value_length = fixed_value.size();
- const identifer_length = def.name.length;
- return init_value_length > identifer_length;
- }
- return true;
- }
- function inline_into_symbolref(self, compressor) {
- if (compressor.in_computed_key()) return self;
- const parent = compressor.parent();
- const def = self.definition();
- const nearest_scope = compressor.find_scope();
- let fixed = self.fixed_value();
- if (
- compressor.top_retain &&
- def.global &&
- compressor.top_retain(def) &&
- // when identifier is in top_retain option dose not mean we can always inline it.
- // if identifier name is longer then init value, we can replace it.
- is_const_symbol_short_than_init_value(def, fixed)
- ) {
- // keep it
- def.fixed = false;
- def.single_use = false;
- return self;
- }
- if (dont_inline_lambda_in_loop(compressor, fixed)) return self;
- let single_use = def.single_use
- && !(parent instanceof AST_Call
- && (parent.is_callee_pure(compressor))
- || has_annotation(parent, _NOINLINE))
- && !(parent instanceof AST_Export
- && fixed instanceof AST_Lambda
- && fixed.name);
- if (single_use && fixed instanceof AST_Node) {
- single_use =
- !fixed.has_side_effects(compressor)
- && !fixed.may_throw(compressor);
- }
- if (fixed instanceof AST_Class && def.scope !== self.scope) {
- return self;
- }
- if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
- if (retain_top_func(fixed, compressor)) {
- single_use = false;
- } else if (def.scope !== self.scope
- && (def.escaped == 1
- || has_flag(fixed, INLINED)
- || within_array_or_object_literal(compressor)
- || !compressor.option("reduce_funcs"))) {
- single_use = false;
- } else if (is_recursive_ref(compressor, def)) {
- single_use = false;
- } else if (def.scope !== self.scope || def.orig[0] instanceof AST_SymbolFunarg) {
- single_use = fixed.is_constant_expression(self.scope);
- if (single_use == "f") {
- var scope = self.scope;
- do {
- if (scope instanceof AST_Defun || is_func_expr(scope)) {
- set_flag(scope, INLINED);
- }
- } while (scope = scope.parent_scope);
- }
- }
- }
- if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
- single_use =
- def.scope === self.scope
- && !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
- || parent instanceof AST_Call
- && parent.expression === self
- && !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
- && !(fixed.name && fixed.name.definition().recursive_refs > 0);
- }
- if (single_use && fixed) {
- if (fixed instanceof AST_DefClass) {
- set_flag(fixed, SQUEEZED);
- fixed = make_node(AST_ClassExpression, fixed, fixed);
- }
- if (fixed instanceof AST_Defun) {
- set_flag(fixed, SQUEEZED);
- fixed = make_node(AST_Function, fixed, fixed);
- }
- if (def.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) {
- const defun_def = fixed.name.definition();
- let lambda_def = fixed.variables.get(fixed.name.name);
- let name = lambda_def && lambda_def.orig[0];
- if (!(name instanceof AST_SymbolLambda)) {
- name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
- name.scope = fixed;
- fixed.name = name;
- lambda_def = fixed.def_function(name);
- }
- walk(fixed, node => {
- if (node instanceof AST_SymbolRef && node.definition() === defun_def) {
- node.thedef = lambda_def;
- lambda_def.references.push(node);
- }
- });
- }
- if (
- (fixed instanceof AST_Lambda || fixed instanceof AST_Class)
- && fixed.parent_scope !== nearest_scope
- ) {
- fixed = fixed.clone(true, compressor.get_toplevel());
- nearest_scope.add_child_scope(fixed);
- }
- return fixed.optimize(compressor);
- }
- // multiple uses
- if (fixed) {
- let replace;
- if (fixed instanceof AST_This) {
- if (!(def.orig[0] instanceof AST_SymbolFunarg)
- && def.references.every((ref) =>
- def.scope === ref.scope
- )) {
- replace = fixed;
- }
- } else {
- var ev = fixed.evaluate(compressor);
- if (
- ev !== fixed
- && (compressor.option("unsafe_regexp") || !(ev instanceof RegExp))
- ) {
- replace = make_node_from_constant(ev, fixed);
- }
- }
- if (replace) {
- const name_length = self.size(compressor);
- const replace_size = replace.size(compressor);
- let overhead = 0;
- if (compressor.option("unused") && !compressor.exposed(def)) {
- overhead =
- (name_length + 2 + fixed.size(compressor)) /
- (def.references.length - def.assignments);
- }
- if (replace_size <= name_length + overhead) {
- return replace;
- }
- }
- }
- return self;
- }
- function inline_into_call(self, compressor) {
- if (compressor.in_computed_key()) return self;
- var exp = self.expression;
- var fn = exp;
- var simple_args = self.args.every((arg) => !(arg instanceof AST_Expansion));
- if (compressor.option("reduce_vars")
- && fn instanceof AST_SymbolRef
- && !has_annotation(self, _NOINLINE)
- ) {
- const fixed = fn.fixed_value();
- if (
- retain_top_func(fixed, compressor)
- || !compressor.toplevel.funcs && exp.definition().global
- ) {
- return self;
- }
- fn = fixed;
- }
- if (
- dont_inline_lambda_in_loop(compressor, fn)
- && !has_annotation(self, _INLINE)
- ) return self;
- var is_func = fn instanceof AST_Lambda;
- var stat = is_func && fn.body[0];
- var is_regular_func = is_func && !fn.is_generator && !fn.async;
- var can_inline = is_regular_func && compressor.option("inline") && !self.is_callee_pure(compressor);
- if (can_inline && stat instanceof AST_Return) {
- let returned = stat.value;
- if (!returned || returned.is_constant_expression()) {
- if (returned) {
- returned = returned.clone(true);
- } else {
- returned = make_void_0(self);
- }
- const args = self.args.concat(returned);
- return make_sequence(self, args).optimize(compressor);
- }
- // optimize identity function
- if (
- fn.argnames.length === 1
- && (fn.argnames[0] instanceof AST_SymbolFunarg)
- && self.args.length < 2
- && !(self.args[0] instanceof AST_Expansion)
- && returned instanceof AST_SymbolRef
- && returned.name === fn.argnames[0].name
- ) {
- const replacement =
- (self.args[0] || make_void_0()).optimize(compressor);
- let parent;
- if (
- replacement instanceof AST_PropAccess
- && (parent = compressor.parent()) instanceof AST_Call
- && parent.expression === self
- ) {
- // identity function was being used to remove `this`, like in
- //
- // id(bag.no_this)(...)
- //
- // Replace with a larger but more effish (0, bag.no_this) wrapper.
- return make_sequence(self, [
- make_node(AST_Number, self, { value: 0 }),
- replacement
- ]);
- }
- // replace call with first argument or undefined if none passed
- return replacement;
- }
- }
- if (can_inline) {
- var scope, in_loop, level = -1;
- let def;
- let returned_value;
- let nearest_scope;
- if (simple_args
- && !fn.uses_arguments
- && !(compressor.parent() instanceof AST_Class)
- && !(fn.name && fn instanceof AST_Function)
- && (returned_value = can_flatten_body(stat))
- && (exp === fn
- || has_annotation(self, _INLINE)
- || compressor.option("unused")
- && (def = exp.definition()).references.length == 1
- && !is_recursive_ref(compressor, def)
- && fn.is_constant_expression(exp.scope))
- && !has_annotation(self, _PURE | _NOINLINE)
- && !fn.contains_this()
- && can_inject_symbols()
- && (nearest_scope = compressor.find_scope())
- && !scope_encloses_variables_in_this_scope(nearest_scope, fn)
- && !(function in_default_assign() {
- // Due to the fact function parameters have their own scope
- // which can't use `var something` in the function body within,
- // we simply don't inline into DefaultAssign.
- let i = 0;
- let p;
- while ((p = compressor.parent(i++))) {
- if (p instanceof AST_DefaultAssign) return true;
- if (p instanceof AST_Block) break;
- }
- return false;
- })()
- && !(scope instanceof AST_Class)
- ) {
- set_flag(fn, SQUEEZED);
- nearest_scope.add_child_scope(fn);
- return make_sequence(self, flatten_fn(returned_value)).optimize(compressor);
- }
- }
- if (can_inline && has_annotation(self, _INLINE)) {
- set_flag(fn, SQUEEZED);
- fn = make_node(fn.CTOR === AST_Defun ? AST_Function : fn.CTOR, fn, fn);
- fn = fn.clone(true);
- fn.figure_out_scope({}, {
- parent_scope: compressor.find_scope(),
- toplevel: compressor.get_toplevel()
- });
- return make_node(AST_Call, self, {
- expression: fn,
- args: self.args,
- }).optimize(compressor);
- }
- const can_drop_this_call = is_regular_func && compressor.option("side_effects") && fn.body.every(is_empty);
- if (can_drop_this_call) {
- var args = self.args.concat(make_void_0(self));
- return make_sequence(self, args).optimize(compressor);
- }
- if (compressor.option("negate_iife")
- && compressor.parent() instanceof AST_SimpleStatement
- && is_iife_call(self)) {
- return self.negate(compressor, true);
- }
- var ev = self.evaluate(compressor);
- if (ev !== self) {
- ev = make_node_from_constant(ev, self).optimize(compressor);
- return best_of(compressor, ev, self);
- }
- return self;
- function return_value(stat) {
- if (!stat) return make_void_0(self);
- if (stat instanceof AST_Return) {
- if (!stat.value) return make_void_0(self);
- return stat.value.clone(true);
- }
- if (stat instanceof AST_SimpleStatement) {
- return make_node(AST_UnaryPrefix, stat, {
- operator: "void",
- expression: stat.body.clone(true)
- });
- }
- }
- function can_flatten_body(stat) {
- var body = fn.body;
- var len = body.length;
- if (compressor.option("inline") < 3) {
- return len == 1 && return_value(stat);
- }
- stat = null;
- for (var i = 0; i < len; i++) {
- var line = body[i];
- if (line instanceof AST_Var) {
- if (stat && !line.definitions.every((var_def) =>
- !var_def.value
- )) {
- return false;
- }
- } else if (stat) {
- return false;
- } else if (!(line instanceof AST_EmptyStatement)) {
- stat = line;
- }
- }
- return return_value(stat);
- }
- function can_inject_args(block_scoped, safe_to_inject) {
- for (var i = 0, len = fn.argnames.length; i < len; i++) {
- var arg = fn.argnames[i];
- if (arg instanceof AST_DefaultAssign) {
- if (has_flag(arg.left, UNUSED)) continue;
- return false;
- }
- if (arg instanceof AST_Destructuring) return false;
- if (arg instanceof AST_Expansion) {
- if (has_flag(arg.expression, UNUSED)) continue;
- return false;
- }
- if (has_flag(arg, UNUSED)) continue;
- if (!safe_to_inject
- || block_scoped.has(arg.name)
- || identifier_atom.has(arg.name)
- || scope.conflicting_def(arg.name)) {
- return false;
- }
- if (in_loop) in_loop.push(arg.definition());
- }
- return true;
- }
- function can_inject_vars(block_scoped, safe_to_inject) {
- var len = fn.body.length;
- for (var i = 0; i < len; i++) {
- var stat = fn.body[i];
- if (!(stat instanceof AST_Var)) continue;
- if (!safe_to_inject) return false;
- for (var j = stat.definitions.length; --j >= 0;) {
- var name = stat.definitions[j].name;
- if (name instanceof AST_Destructuring
- || block_scoped.has(name.name)
- || identifier_atom.has(name.name)
- || scope.conflicting_def(name.name)) {
- return false;
- }
- if (in_loop) in_loop.push(name.definition());
- }
- }
- return true;
- }
- function can_inject_symbols() {
- var block_scoped = new Set();
- do {
- scope = compressor.parent(++level);
- if (scope.is_block_scope() && scope.block_scope) {
- // TODO this is sometimes undefined during compression.
- // But it should always have a value!
- scope.block_scope.variables.forEach(function (variable) {
- block_scoped.add(variable.name);
- });
- }
- if (scope instanceof AST_Catch) {
- // TODO can we delete? AST_Catch is a block scope.
- if (scope.argname) {
- block_scoped.add(scope.argname.name);
- }
- } else if (scope instanceof AST_IterationStatement) {
- in_loop = [];
- } else if (scope instanceof AST_SymbolRef) {
- if (scope.fixed_value() instanceof AST_Scope) return false;
- }
- } while (!(scope instanceof AST_Scope));
- var safe_to_inject = !(scope instanceof AST_Toplevel) || compressor.toplevel.vars;
- var inline = compressor.option("inline");
- if (!can_inject_vars(block_scoped, inline >= 3 && safe_to_inject)) return false;
- if (!can_inject_args(block_scoped, inline >= 2 && safe_to_inject)) return false;
- return !in_loop || in_loop.length == 0 || !is_reachable(fn, in_loop);
- }
- function append_var(decls, expressions, name, value) {
- var def = name.definition();
- // Name already exists, only when a function argument had the same name
- const already_appended = scope.variables.has(name.name);
- if (!already_appended) {
- scope.variables.set(name.name, def);
- scope.enclosed.push(def);
- decls.push(make_node(AST_VarDef, name, {
- name: name,
- value: null
- }));
- }
- var sym = make_node(AST_SymbolRef, name, name);
- def.references.push(sym);
- if (value) expressions.push(make_node(AST_Assign, self, {
- operator: "=",
- logical: false,
- left: sym,
- right: value.clone()
- }));
- }
- function flatten_args(decls, expressions) {
- var len = fn.argnames.length;
- for (var i = self.args.length; --i >= len;) {
- expressions.push(self.args[i]);
- }
- for (i = len; --i >= 0;) {
- var name = fn.argnames[i];
- var value = self.args[i];
- if (has_flag(name, UNUSED) || !name.name || scope.conflicting_def(name.name)) {
- if (value) expressions.push(value);
- } else {
- var symbol = make_node(AST_SymbolVar, name, name);
- name.definition().orig.push(symbol);
- if (!value && in_loop) value = make_void_0(self);
- append_var(decls, expressions, symbol, value);
- }
- }
- decls.reverse();
- expressions.reverse();
- }
- function flatten_vars(decls, expressions) {
- var pos = expressions.length;
- for (var i = 0, lines = fn.body.length; i < lines; i++) {
- var stat = fn.body[i];
- if (!(stat instanceof AST_Var)) continue;
- for (var j = 0, defs = stat.definitions.length; j < defs; j++) {
- var var_def = stat.definitions[j];
- var name = var_def.name;
- append_var(decls, expressions, name, var_def.value);
- if (in_loop && fn.argnames.every((argname) =>
- argname.name != name.name
- )) {
- var def = fn.variables.get(name.name);
- var sym = make_node(AST_SymbolRef, name, name);
- def.references.push(sym);
- expressions.splice(pos++, 0, make_node(AST_Assign, var_def, {
- operator: "=",
- logical: false,
- left: sym,
- right: make_void_0(name),
- }));
- }
- }
- }
- }
- function flatten_fn(returned_value) {
- var decls = [];
- var expressions = [];
- flatten_args(decls, expressions);
- flatten_vars(decls, expressions);
- expressions.push(returned_value);
- if (decls.length) {
- const i = scope.body.indexOf(compressor.parent(level - 1)) + 1;
- scope.body.splice(i, 0, make_node(AST_Var, fn, {
- definitions: decls
- }));
- }
- return expressions.map(exp => exp.clone(true));
- }
- }
- /** prevent inlining functions into loops, for performance reasons */
- function dont_inline_lambda_in_loop(compressor, maybe_lambda) {
- return (
- (maybe_lambda instanceof AST_Lambda || maybe_lambda instanceof AST_Class)
- && !!compressor.is_within_loop()
- );
- }
- (function(def_find_defs) {
- function to_node(value, orig) {
- if (value instanceof AST_Node) {
- if (!(value instanceof AST_Constant)) {
- // Value may be a function, an array including functions and even a complex assign / block expression,
- // so it should never be shared in different places.
- // Otherwise wrong information may be used in the compression phase
- value = value.clone(true);
- }
- return make_node(value.CTOR, orig, value);
- }
- if (Array.isArray(value)) return make_node(AST_Array, orig, {
- elements: value.map(function(value) {
- return to_node(value, orig);
- })
- });
- if (value && typeof value == "object") {
- var props = [];
- for (var key in value) if (HOP(value, key)) {
- props.push(make_node(AST_ObjectKeyVal, orig, {
- key: key,
- value: to_node(value[key], orig)
- }));
- }
- return make_node(AST_Object, orig, {
- properties: props
- });
- }
- return make_node_from_constant(value, orig);
- }
- AST_Toplevel.DEFMETHOD("resolve_defines", function(compressor) {
- if (!compressor.option("global_defs")) return this;
- this.figure_out_scope({ ie8: compressor.option("ie8") });
- return this.transform(new TreeTransformer(function(node) {
- var def = node._find_defs(compressor, "");
- if (!def) return;
- var level = 0, child = node, parent;
- while (parent = this.parent(level++)) {
- if (!(parent instanceof AST_PropAccess)) break;
- if (parent.expression !== child) break;
- child = parent;
- }
- if (is_lhs(child, parent)) {
- return;
- }
- return def;
- }));
- });
- def_find_defs(AST_Node, noop);
- def_find_defs(AST_Chain, function(compressor, suffix) {
- return this.expression._find_defs(compressor, suffix);
- });
- def_find_defs(AST_Dot, function(compressor, suffix) {
- return this.expression._find_defs(compressor, "." + this.property + suffix);
- });
- def_find_defs(AST_SymbolDeclaration, function() {
- if (!this.global()) return;
- });
- def_find_defs(AST_SymbolRef, function(compressor, suffix) {
- if (!this.global()) return;
- var defines = compressor.option("global_defs");
- var name = this.name + suffix;
- if (HOP(defines, name)) return to_node(defines[name], this);
- });
- def_find_defs(AST_ImportMeta, function(compressor, suffix) {
- var defines = compressor.option("global_defs");
- var name = "import.meta" + suffix;
- if (HOP(defines, name)) return to_node(defines[name], this);
- });
- })(function(node, func) {
- node.DEFMETHOD("_find_defs", func);
- });
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- class Compressor extends TreeWalker {
- constructor(options, { false_by_default = false, mangle_options = false }) {
- super();
- if (options.defaults !== undefined && !options.defaults) false_by_default = true;
- this.options = defaults(options, {
- arguments : false,
- arrows : !false_by_default,
- booleans : !false_by_default,
- booleans_as_integers : false,
- collapse_vars : !false_by_default,
- comparisons : !false_by_default,
- computed_props: !false_by_default,
- conditionals : !false_by_default,
- dead_code : !false_by_default,
- defaults : true,
- directives : !false_by_default,
- drop_console : false,
- drop_debugger : !false_by_default,
- ecma : 5,
- builtins_ecma : 5,
- builtins_pure : false,
- evaluate : !false_by_default,
- expression : false,
- global_defs : false,
- hoist_funs : false,
- hoist_props : !false_by_default,
- hoist_vars : false,
- ie8 : false,
- if_return : !false_by_default,
- inline : !false_by_default,
- join_vars : !false_by_default,
- keep_classnames: false,
- keep_fargs : true,
- keep_fnames : false,
- keep_infinity : false,
- lhs_constants : !false_by_default,
- loops : !false_by_default,
- module : false,
- negate_iife : !false_by_default,
- passes : 1,
- properties : !false_by_default,
- pure_getters : !false_by_default && "strict",
- pure_funcs : null,
- pure_new : false,
- reduce_funcs : !false_by_default,
- reduce_vars : !false_by_default,
- sequences : !false_by_default,
- side_effects : !false_by_default,
- switches : !false_by_default,
- top_retain : null,
- toplevel : !!(options && options["top_retain"]),
- typeofs : !false_by_default,
- unsafe : false,
- unsafe_arrows : false,
- unsafe_comps : false,
- unsafe_Function: false,
- unsafe_math : false,
- unsafe_symbols: false,
- unsafe_methods: false,
- unsafe_proto : false,
- unsafe_regexp : false,
- unsafe_undefined: false,
- unused : !false_by_default,
- warnings : false // legacy
- }, true);
- var global_defs = this.options["global_defs"];
- if (typeof global_defs == "object") for (var key in global_defs) {
- if (key[0] === "@" && HOP(global_defs, key)) {
- global_defs[key.slice(1)] = parse(global_defs[key], {
- expression: true
- });
- }
- }
- if (this.options["inline"] === true) this.options["inline"] = 3;
- var pure_funcs = this.options["pure_funcs"];
- if (typeof pure_funcs == "function") {
- this.pure_funcs = pure_funcs;
- } else {
- this.pure_funcs = pure_funcs ? function(node) {
- return !pure_funcs.includes(node.expression.print_to_string());
- } : return_true;
- }
- var top_retain = this.options["top_retain"];
- if (top_retain instanceof RegExp) {
- this.top_retain = function(def) {
- return top_retain.test(def.name);
- };
- } else if (typeof top_retain == "function") {
- this.top_retain = top_retain;
- } else if (top_retain) {
- if (typeof top_retain == "string") {
- top_retain = top_retain.split(/,/);
- }
- this.top_retain = function(def) {
- return top_retain.includes(def.name);
- };
- }
- if (this.options["module"]) {
- this.directives["use strict"] = true;
- this.options["toplevel"] = true;
- }
- var toplevel = this.options["toplevel"];
- this.toplevel = typeof toplevel == "string" ? {
- funcs: /funcs/.test(toplevel),
- vars: /vars/.test(toplevel)
- } : {
- funcs: toplevel,
- vars: toplevel
- };
- var sequences = this.options["sequences"];
- this.sequences_limit = sequences == 1 ? 800 : sequences | 0;
- this.evaluated_regexps = new Map();
- this._toplevel = undefined;
- this._mangle_options = mangle_options
- ? format_mangler_options(mangle_options)
- : mangle_options;
- this.pure_access_globals = pure_access_globals(this);
- this.is_pure_native_fn = is_pure_native_fn(this);
- this.is_pure_native_method = is_pure_native_method(this);
- this.is_pure_native_static_fn = is_pure_native_static_fn(this);
- this.is_pure_native_static_property = is_pure_native_static_property(this);
- }
- mangle_options() {
- var nth_identifier = this._mangle_options && this._mangle_options.nth_identifier || base54;
- var module = this._mangle_options && this._mangle_options.module || this.option("module");
- return { ie8: this.option("ie8"), nth_identifier, module };
- }
- option(key) {
- return this.options[key];
- }
- exposed(def) {
- if (def.export) return true;
- if (def.global) for (var i = 0, len = def.orig.length; i < len; i++)
- if (!this.toplevel[def.orig[i] instanceof AST_SymbolDefun ? "funcs" : "vars"])
- return true;
- return false;
- }
- in_boolean_context() {
- if (!this.option("booleans")) return false;
- var self = this.self();
- for (var i = 0, p; p = this.parent(i); i++) {
- if (p instanceof AST_SimpleStatement
- || p instanceof AST_Conditional && p.condition === self
- || p instanceof AST_DWLoop && p.condition === self
- || p instanceof AST_For && p.condition === self
- || p instanceof AST_If && p.condition === self
- || p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self) {
- return true;
- }
- if (
- p instanceof AST_Binary && (
- p.operator == "&&" || p.operator == "||"
- )
- || p instanceof AST_Conditional
- || p.tail_node() === self
- ) {
- self = p;
- } else {
- return false;
- }
- }
- }
- /** True if compressor.self()'s result will be turned into a 32-bit integer.
- * ex:
- * ~{expr}
- * (1, 2, {expr}) | 0
- **/
- in_32_bit_context(other_operand_must_be_number) {
- if (!this.option("evaluate")) return false;
- var self = this.self();
- for (var i = 0, p; p = this.parent(i); i++) {
- if (p instanceof AST_Binary && bitwise_binop.has(p.operator)) {
- if (other_operand_must_be_number) {
- return (self === p.left ? p.right : p.left).is_number(this);
- } else {
- return true;
- }
- }
- if (p instanceof AST_UnaryPrefix) {
- return p.operator === "~";
- }
- if (
- p instanceof AST_Binary
- && (
- // Don't talk about p.left. Can change branch taken
- p.operator == "&&" && p.right === self
- || p.operator == "||" && p.right === self
- || p.operator == "??" && p.right === self
- )
- || p instanceof AST_Conditional && p.condition !== self
- || p.tail_node() === self
- ) {
- self = p;
- } else {
- return false;
- }
- }
- }
- in_computed_key() {
- if (!this.option("evaluate")) return false;
- var self = this.self();
- for (var i = 0, p; p = this.parent(i); i++) {
- if (p instanceof AST_ObjectProperty && p.key === self) {
- return true;
- }
- }
- return false;
- }
- get_toplevel() {
- return this._toplevel;
- }
- compress(toplevel) {
- toplevel = toplevel.resolve_defines(this);
- this._toplevel = toplevel;
- if (this.option("expression")) {
- this._toplevel.process_expression(true);
- }
- var passes = +this.options.passes || 1;
- var min_count = 1 / 0;
- var stopping = false;
- var mangle = this.mangle_options();
- for (var pass = 0; pass < passes; pass++) {
- this._toplevel.figure_out_scope(mangle);
- if (pass === 0 && this.option("drop_console")) {
- // must be run before reduce_vars and compress pass
- this._toplevel = this._toplevel.drop_console(this.option("drop_console"));
- }
- if (pass > 0 || this.option("reduce_vars")) {
- this._toplevel.reset_opt_flags(this);
- }
- this._toplevel = this._toplevel.transform(this);
- if (passes > 1) {
- let count = 0;
- walk(this._toplevel, () => { count++; });
- if (count < min_count) {
- min_count = count;
- stopping = false;
- } else if (stopping) {
- break;
- } else {
- stopping = true;
- }
- }
- }
- if (this.option("expression")) {
- this._toplevel.process_expression(false);
- }
- toplevel = this._toplevel;
- this._toplevel = undefined;
- return toplevel;
- }
- before(node, descend) {
- if (has_flag(node, SQUEEZED)) return node;
- var was_scope = false;
- if (node instanceof AST_Scope) {
- node = node.hoist_properties(this);
- node = node.hoist_declarations(this);
- was_scope = true;
- }
- // Before https://github.com/mishoo/UglifyJS2/pull/1602 AST_Node.optimize()
- // would call AST_Node.transform() if a different instance of AST_Node is
- // produced after def_optimize().
- // This corrupts TreeWalker.stack, which cause AST look-ups to malfunction.
- // Migrate and defer all children's AST_Node.transform() to below, which
- // will now happen after this parent AST_Node has been properly substituted
- // thus gives a consistent AST snapshot.
- descend(node, this);
- // Existing code relies on how AST_Node.optimize() worked, and omitting the
- // following replacement call would result in degraded efficiency of both
- // output and performance.
- descend(node, this);
- var opt = node.optimize(this);
- if (was_scope && opt instanceof AST_Scope) {
- opt.drop_unused(this);
- descend(opt, this);
- }
- if (opt === node) set_flag(opt, SQUEEZED);
- return opt;
- }
- /** Alternative to plain is_lhs() which doesn't work within .optimize() */
- is_lhs() {
- const self = this.stack[this.stack.length - 1];
- const parent = this.stack[this.stack.length - 2];
- return is_lhs(self, parent);
- }
- }
- function def_optimize(node, optimizer) {
- node.DEFMETHOD("optimize", function(compressor) {
- var self = this;
- if (has_flag(self, OPTIMIZED)) return self;
- if (compressor.has_directive("use asm")) return self;
- var opt = optimizer(self, compressor);
- set_flag(opt, OPTIMIZED);
- return opt;
- });
- }
- def_optimize(AST_Node, function(self) {
- return self;
- });
- AST_Toplevel.DEFMETHOD("drop_console", function(options) {
- const isArray = Array.isArray(options);
- const tt = new TreeTransformer(function(self) {
- if (self.TYPE !== "Call") {
- return;
- }
- var exp = self.expression;
- if (!(exp instanceof AST_PropAccess)) {
- return;
- }
- var name = exp.expression;
- var property = exp.property;
- var depth = 2;
- while (name.expression) {
- property = name.property;
- name = name.expression;
- depth++;
- }
- if (isArray && !options.includes(property)) {
- return;
- }
- if (is_undeclared_ref(name) && name.name == "console") {
- if (
- depth === 3
- && !["call", "apply"].includes(exp.property)
- && is_used_in_expression(tt)
- ) {
- // a (used) call to Function.prototype methods (eg: console.log.bind(console))
- // but not .call and .apply which would also return undefined.
- exp.expression = make_empty_function(self);
- set_flag(exp.expression, SQUEEZED);
- self.args = [];
- } else {
- return make_void_0(self);
- }
- }
- });
- return this.transform(tt);
- });
- AST_Node.DEFMETHOD("equivalent_to", function(node) {
- return equivalent_to(this, node);
- });
- AST_Scope.DEFMETHOD("process_expression", function(insert, compressor) {
- var self = this;
- var tt = new TreeTransformer(function(node) {
- if (insert && node instanceof AST_SimpleStatement) {
- return make_node(AST_Return, node, {
- value: node.body
- });
- }
- if (!insert && node instanceof AST_Return) {
- if (compressor) {
- var value = node.value && node.value.drop_side_effect_free(compressor, true);
- return value
- ? make_node(AST_SimpleStatement, node, { body: value })
- : make_node(AST_EmptyStatement, node);
- }
- return make_node(AST_SimpleStatement, node, {
- body: node.value || make_void_0(node)
- });
- }
- if (node instanceof AST_Class || node instanceof AST_Lambda && node !== self) {
- return node;
- }
- if (node instanceof AST_Block) {
- var index = node.body.length - 1;
- if (index >= 0) {
- node.body[index] = node.body[index].transform(tt);
- }
- } else if (node instanceof AST_If) {
- node.body = node.body.transform(tt);
- if (node.alternative) {
- node.alternative = node.alternative.transform(tt);
- }
- } else if (node instanceof AST_With) {
- node.body = node.body.transform(tt);
- }
- return node;
- });
- self.transform(tt);
- });
- AST_Toplevel.DEFMETHOD("reset_opt_flags", function(compressor) {
- const self = this;
- const reduce_vars = compressor.option("reduce_vars");
- const preparation = new TreeWalker(function(node, descend) {
- clear_flag(node, CLEAR_BETWEEN_PASSES);
- if (reduce_vars) {
- if (compressor.top_retain
- && node instanceof AST_Defun // Only functions are retained
- && preparation.parent() === self
- ) {
- set_flag(node, TOP);
- }
- return node.reduce_vars(preparation, descend, compressor);
- }
- });
- // Stack of look-up tables to keep track of whether a `SymbolDef` has been
- // properly assigned before use:
- // - `push()` & `pop()` when visiting conditional branches
- preparation.safe_ids = Object.create(null);
- preparation.in_loop = null;
- preparation.loop_ids = new Map();
- preparation.defs_to_safe_ids = new Map();
- self.walk(preparation);
- });
- AST_Symbol.DEFMETHOD("fixed_value", function() {
- var fixed = this.thedef.fixed;
- if (!fixed || fixed instanceof AST_Node) return fixed;
- return fixed();
- });
- AST_SymbolRef.DEFMETHOD("is_immutable", function() {
- var orig = this.definition().orig;
- return orig.length == 1 && orig[0] instanceof AST_SymbolLambda;
- });
- function find_variable(compressor, name) {
- var scope, i = 0;
- while (scope = compressor.parent(i++)) {
- if (scope instanceof AST_Scope) break;
- if (scope instanceof AST_Catch && scope.argname) {
- scope = scope.argname.definition().scope;
- break;
- }
- }
- return scope.find_variable(name);
- }
- AST_SymbolRef.DEFMETHOD("is_declared", function(compressor) {
- return !this.definition().undeclared
- || (compressor.option("unsafe") || compressor.option("builtins_pure")) && compressor.pure_access_globals(this.name);
- });
- /* -----[ optimizers ]----- */
- var directives = new Set(["use asm", "use strict"]);
- def_optimize(AST_Directive, function(self, compressor) {
- if (compressor.option("directives")
- && (!directives.has(self.value) || compressor.has_directive(self.value) !== self)) {
- return make_node(AST_EmptyStatement, self);
- }
- return self;
- });
- def_optimize(AST_Debugger, function(self, compressor) {
- if (compressor.option("drop_debugger"))
- return make_node(AST_EmptyStatement, self);
- return self;
- });
- def_optimize(AST_LabeledStatement, function(self, compressor) {
- if (self.body instanceof AST_Break
- && compressor.loopcontrol_target(self.body) === self.body) {
- return make_node(AST_EmptyStatement, self);
- }
- return self.label.references.length == 0 ? self.body : self;
- });
- def_optimize(AST_Block, function(self, compressor) {
- tighten_body(self.body, compressor);
- return self;
- });
- function can_be_extracted_from_if_block(node) {
- return !(
- node instanceof AST_Const
- || node instanceof AST_Let
- || node instanceof AST_Using
- || node instanceof AST_Class
- );
- }
- def_optimize(AST_BlockStatement, function(self, compressor) {
- tighten_body(self.body, compressor);
- switch (self.body.length) {
- case 1:
- if (!compressor.has_directive("use strict")
- && compressor.parent() instanceof AST_If
- && can_be_extracted_from_if_block(self.body[0])
- || can_be_evicted_from_block(self.body[0])) {
- return self.body[0];
- }
- break;
- case 0: return make_node(AST_EmptyStatement, self);
- }
- return self;
- });
- function opt_AST_Lambda(self, compressor) {
- tighten_body(self.body, compressor);
- if (compressor.option("side_effects")
- && self.body.length == 1
- && self.body[0] === compressor.has_directive("use strict")) {
- self.body.length = 0;
- }
- return self;
- }
- def_optimize(AST_Lambda, opt_AST_Lambda);
- AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) {
- var self = this;
- if (compressor.has_directive("use asm")) return self;
- var hoist_funs = compressor.option("hoist_funs");
- var hoist_vars = compressor.option("hoist_vars");
- if (hoist_funs || hoist_vars) {
- var dirs = [];
- var hoisted = [];
- var vars = new Map(), vars_found = 0, var_decl = 0;
- // let's count var_decl first, we seem to waste a lot of
- // space if we hoist `var` when there's only one.
- walk(self, node => {
- if (node instanceof AST_Scope && node !== self)
- return true;
- if (node instanceof AST_Var) {
- ++var_decl;
- return true;
- }
- });
- hoist_vars = hoist_vars && var_decl > 1;
- var tt = new TreeTransformer(
- function before(node) {
- if (node !== self) {
- if (node instanceof AST_Directive) {
- dirs.push(node);
- return make_node(AST_EmptyStatement, node);
- }
- if (hoist_funs && node instanceof AST_Defun
- && !(tt.parent() instanceof AST_Export)
- && tt.parent() === self) {
- hoisted.push(node);
- return make_node(AST_EmptyStatement, node);
- }
- if (
- hoist_vars
- && node instanceof AST_Var
- && !node.definitions.some(def => def.name instanceof AST_Destructuring)
- ) {
- node.definitions.forEach(function(def) {
- vars.set(def.name.name, def);
- ++vars_found;
- });
- var seq = node.to_assignments(compressor);
- var p = tt.parent();
- if (p instanceof AST_ForIn && p.init === node) {
- if (seq == null) {
- var def = node.definitions[0].name;
- return make_node(AST_SymbolRef, def, def);
- }
- return seq;
- }
- if (p instanceof AST_For && p.init === node) {
- return seq;
- }
- if (!seq) return make_node(AST_EmptyStatement, node);
- return make_node(AST_SimpleStatement, node, {
- body: seq
- });
- }
- if (node instanceof AST_Scope)
- return node; // to avoid descending in nested scopes
- }
- }
- );
- self = self.transform(tt);
- if (vars_found > 0) {
- // collect only vars which don't show up in self's arguments list
- var defs = [];
- const is_lambda = self instanceof AST_Lambda;
- const args_as_names = is_lambda ? self.args_as_names() : null;
- vars.forEach((def, name) => {
- if (is_lambda && args_as_names.some((x) => x.name === def.name.name)) {
- vars.delete(name);
- } else {
- def = def.clone();
- def.value = null;
- defs.push(def);
- vars.set(name, def);
- }
- });
- if (defs.length > 0) {
- // try to merge in assignments
- for (var i = 0; i < self.body.length;) {
- if (self.body[i] instanceof AST_SimpleStatement) {
- var expr = self.body[i].body, sym, assign;
- if (expr instanceof AST_Assign
- && expr.operator == "="
- && (sym = expr.left) instanceof AST_Symbol
- && vars.has(sym.name)
- ) {
- var def = vars.get(sym.name);
- if (def.value) break;
- def.value = expr.right;
- remove(defs, def);
- defs.push(def);
- self.body.splice(i, 1);
- continue;
- }
- if (expr instanceof AST_Sequence
- && (assign = expr.expressions[0]) instanceof AST_Assign
- && assign.operator == "="
- && (sym = assign.left) instanceof AST_Symbol
- && vars.has(sym.name)
- ) {
- var def = vars.get(sym.name);
- if (def.value) break;
- def.value = assign.right;
- remove(defs, def);
- defs.push(def);
- self.body[i].body = make_sequence(expr, expr.expressions.slice(1));
- continue;
- }
- }
- if (self.body[i] instanceof AST_EmptyStatement) {
- self.body.splice(i, 1);
- continue;
- }
- if (self.body[i] instanceof AST_BlockStatement) {
- self.body.splice(i, 1, ...self.body[i].body);
- continue;
- }
- break;
- }
- defs = make_node(AST_Var, self, {
- definitions: defs
- });
- hoisted.push(defs);
- }
- }
- self.body = dirs.concat(hoisted, self.body);
- }
- return self;
- });
- AST_Scope.DEFMETHOD("hoist_properties", function(compressor) {
- var self = this;
- if (!compressor.option("hoist_props") || compressor.has_directive("use asm")) return self;
- var top_retain = self instanceof AST_Toplevel && compressor.top_retain || return_false;
- var defs_by_id = new Map();
- var hoister = new TreeTransformer(function(node, descend) {
- if (node instanceof AST_VarDef) {
- const sym = node.name;
- let def;
- let value;
- if (sym.scope === self
- && !(sym instanceof AST_SymbolUsing)
- && (def = sym.definition()).escaped != 1
- && !def.assignments
- && !def.direct_access
- && !def.single_use
- && !compressor.exposed(def)
- && !top_retain(def)
- && (value = sym.fixed_value()) === node.value
- && value instanceof AST_Object
- && !value.properties.some(prop =>
- prop instanceof AST_Expansion || prop.computed_key()
- )
- ) {
- descend(node, this);
- const defs = new Map();
- const assignments = [];
- value.properties.forEach(({ key, value }) => {
- const scope = hoister.find_scope();
- const symbol = self.create_symbol(sym.CTOR, {
- source: sym,
- scope,
- conflict_scopes: new Set([
- scope,
- ...sym.definition().references.map(ref => ref.scope)
- ]),
- tentative_name: sym.name + "_" + key
- });
- defs.set(String(key), symbol.definition());
- assignments.push(make_node(AST_VarDef, node, {
- name: symbol,
- value
- }));
- });
- defs_by_id.set(def.id, defs);
- return MAP.splice(assignments);
- }
- } else if (node instanceof AST_PropAccess
- && node.expression instanceof AST_SymbolRef
- ) {
- const defs = defs_by_id.get(node.expression.definition().id);
- if (defs) {
- const def = defs.get(String(get_simple_key(node.property)));
- const sym = make_node(AST_SymbolRef, node, {
- name: def.name,
- scope: node.expression.scope,
- thedef: def
- });
- sym.reference({});
- return sym;
- }
- }
- });
- return self.transform(hoister);
- });
- def_optimize(AST_SimpleStatement, function(self, compressor) {
- if (compressor.option("side_effects")) {
- var body = self.body;
- var node = body.drop_side_effect_free(compressor, true);
- if (!node) {
- return make_node(AST_EmptyStatement, self);
- }
- if (node !== body) {
- return make_node(AST_SimpleStatement, self, { body: node });
- }
- }
- return self;
- });
- def_optimize(AST_While, function(self, compressor) {
- return compressor.option("loops") ? make_node(AST_For, self, self).optimize(compressor) : self;
- });
- def_optimize(AST_Do, function(self, compressor) {
- if (!compressor.option("loops")) return self;
- var cond = self.condition.tail_node().evaluate(compressor);
- if (!(cond instanceof AST_Node)) {
- if (cond) return make_node(AST_For, self, {
- body: make_node(AST_BlockStatement, self.body, {
- body: [
- self.body,
- make_node(AST_SimpleStatement, self.condition, {
- body: self.condition
- })
- ]
- })
- }).optimize(compressor);
- if (!has_break_or_continue(self, compressor.parent())) {
- return make_node(AST_BlockStatement, self.body, {
- body: [
- self.body,
- make_node(AST_SimpleStatement, self.condition, {
- body: self.condition
- })
- ]
- }).optimize(compressor);
- }
- }
- return self;
- });
- function if_break_in_loop(self, compressor) {
- var first = self.body instanceof AST_BlockStatement ? self.body.body[0] : self.body;
- if (compressor.option("dead_code") && is_break(first)) {
- var body = [];
- if (self.init instanceof AST_Statement) {
- body.push(self.init);
- } else if (self.init) {
- body.push(make_node(AST_SimpleStatement, self.init, {
- body: self.init
- }));
- }
- if (self.condition) {
- body.push(make_node(AST_SimpleStatement, self.condition, {
- body: self.condition
- }));
- }
- extract_from_unreachable_code(compressor, self.body, body);
- return make_node(AST_BlockStatement, self, {
- body: body
- });
- }
- if (first instanceof AST_If) {
- if (is_break(first.body)) {
- if (self.condition) {
- self.condition = make_node(AST_Binary, self.condition, {
- left: self.condition,
- operator: "&&",
- right: first.condition.negate(compressor),
- });
- } else {
- self.condition = first.condition.negate(compressor);
- }
- drop_it(first.alternative);
- } else if (is_break(first.alternative)) {
- if (self.condition) {
- self.condition = make_node(AST_Binary, self.condition, {
- left: self.condition,
- operator: "&&",
- right: first.condition,
- });
- } else {
- self.condition = first.condition;
- }
- drop_it(first.body);
- }
- }
- return self;
- function is_break(node) {
- return node instanceof AST_Break
- && compressor.loopcontrol_target(node) === compressor.self();
- }
- function drop_it(rest) {
- rest = as_statement_array(rest);
- if (self.body instanceof AST_BlockStatement) {
- self.body = self.body.clone();
- self.body.body = rest.concat(self.body.body.slice(1));
- self.body = self.body.transform(compressor);
- } else {
- self.body = make_node(AST_BlockStatement, self.body, {
- body: rest
- }).transform(compressor);
- }
- self = if_break_in_loop(self, compressor);
- }
- }
- def_optimize(AST_For, function(self, compressor) {
- if (!compressor.option("loops")) return self;
- if (compressor.option("side_effects") && self.init) {
- self.init = self.init.drop_side_effect_free(compressor);
- }
- if (self.condition) {
- var cond = self.condition.evaluate(compressor);
- if (!(cond instanceof AST_Node)) {
- if (cond) self.condition = null;
- else if (!compressor.option("dead_code")) {
- var orig = self.condition;
- self.condition = make_node_from_constant(cond, self.condition);
- self.condition = best_of_expression(self.condition.transform(compressor), orig);
- }
- }
- if (compressor.option("dead_code")) {
- if (cond instanceof AST_Node) cond = self.condition.tail_node().evaluate(compressor);
- if (!cond) {
- var body = [];
- extract_from_unreachable_code(compressor, self.body, body);
- if (self.init instanceof AST_Statement) {
- body.push(self.init);
- } else if (self.init) {
- body.push(make_node(AST_SimpleStatement, self.init, {
- body: self.init
- }));
- }
- body.push(make_node(AST_SimpleStatement, self.condition, {
- body: self.condition
- }));
- return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
- }
- }
- }
- return if_break_in_loop(self, compressor);
- });
- def_optimize(AST_If, function(self, compressor) {
- if (is_empty(self.alternative)) self.alternative = null;
- if (!compressor.option("conditionals")) return self;
- // if condition can be statically determined, drop
- // one of the blocks. note, statically determined implies
- // “has no side effects”; also it doesn't work for cases like
- // `x && true`, though it probably should.
- var cond = self.condition.evaluate(compressor);
- if (!compressor.option("dead_code") && !(cond instanceof AST_Node)) {
- var orig = self.condition;
- self.condition = make_node_from_constant(cond, orig);
- self.condition = best_of_expression(self.condition.transform(compressor), orig);
- }
- if (compressor.option("dead_code")) {
- if (cond instanceof AST_Node) cond = self.condition.tail_node().evaluate(compressor);
- if (!cond) {
- var body = [];
- extract_from_unreachable_code(compressor, self.body, body);
- body.push(make_node(AST_SimpleStatement, self.condition, {
- body: self.condition
- }));
- if (self.alternative) body.push(self.alternative);
- return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
- } else if (!(cond instanceof AST_Node)) {
- var body = [];
- body.push(make_node(AST_SimpleStatement, self.condition, {
- body: self.condition
- }));
- body.push(self.body);
- if (self.alternative) {
- extract_from_unreachable_code(compressor, self.alternative, body);
- }
- return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
- }
- }
- var negated = self.condition.negate(compressor);
- var self_condition_length = self.condition.size();
- var negated_length = negated.size();
- var negated_is_best = negated_length < self_condition_length;
- if (self.alternative && negated_is_best) {
- negated_is_best = false; // because we already do the switch here.
- // no need to swap values of self_condition_length and negated_length
- // here because they are only used in an equality comparison later on.
- self.condition = negated;
- var tmp = self.body;
- self.body = self.alternative || make_node(AST_EmptyStatement, self);
- self.alternative = tmp;
- }
- if (is_empty(self.body) && is_empty(self.alternative)) {
- return make_node(AST_SimpleStatement, self.condition, {
- body: self.condition.clone()
- }).optimize(compressor);
- }
- if (self.body instanceof AST_SimpleStatement
- && self.alternative instanceof AST_SimpleStatement) {
- return make_node(AST_SimpleStatement, self, {
- body: make_node(AST_Conditional, self, {
- condition : self.condition,
- consequent : self.body.body,
- alternative : self.alternative.body
- })
- }).optimize(compressor);
- }
- if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) {
- if (self_condition_length === negated_length && !negated_is_best
- && self.condition instanceof AST_Binary && self.condition.operator == "||") {
- // although the code length of self.condition and negated are the same,
- // negated does not require additional surrounding parentheses.
- // see https://github.com/mishoo/UglifyJS2/issues/979
- negated_is_best = true;
- }
- if (negated_is_best) return make_node(AST_SimpleStatement, self, {
- body: make_node(AST_Binary, self, {
- operator : "||",
- left : negated,
- right : self.body.body
- })
- }).optimize(compressor);
- return make_node(AST_SimpleStatement, self, {
- body: make_node(AST_Binary, self, {
- operator : "&&",
- left : self.condition,
- right : self.body.body
- })
- }).optimize(compressor);
- }
- if (self.body instanceof AST_EmptyStatement
- && self.alternative instanceof AST_SimpleStatement) {
- return make_node(AST_SimpleStatement, self, {
- body: make_node(AST_Binary, self, {
- operator : "||",
- left : self.condition,
- right : self.alternative.body
- })
- }).optimize(compressor);
- }
- if (self.body instanceof AST_Exit
- && self.alternative instanceof AST_Exit
- && self.body.TYPE == self.alternative.TYPE) {
- return make_node(self.body.CTOR, self, {
- value: make_node(AST_Conditional, self, {
- condition : self.condition,
- consequent : self.body.value || make_void_0(self.body),
- alternative : self.alternative.value || make_void_0(self.alternative),
- }).transform(compressor)
- }).optimize(compressor);
- }
- if (self.body instanceof AST_If
- && !self.body.alternative
- && !self.alternative) {
- self = make_node(AST_If, self, {
- condition: make_node(AST_Binary, self.condition, {
- operator: "&&",
- left: self.condition,
- right: self.body.condition
- }),
- body: self.body.body,
- alternative: null
- });
- }
- if (aborts(self.body)) {
- if (self.alternative) {
- var alt = self.alternative;
- self.alternative = null;
- return make_node(AST_BlockStatement, self, {
- body: [ self, alt ]
- }).optimize(compressor);
- }
- }
- if (aborts(self.alternative)) {
- var body = self.body;
- self.body = self.alternative;
- self.condition = negated_is_best ? negated : self.condition.negate(compressor);
- self.alternative = null;
- return make_node(AST_BlockStatement, self, {
- body: [ self, body ]
- }).optimize(compressor);
- }
- return self;
- });
- def_optimize(AST_Switch, function(self, compressor) {
- if (!compressor.option("switches")) return self;
- var branch;
- var value = self.expression.evaluate(compressor);
- if (!(value instanceof AST_Node)) {
- var orig = self.expression;
- self.expression = make_node_from_constant(value, orig);
- self.expression = best_of_expression(self.expression.transform(compressor), orig);
- }
- if (!compressor.option("dead_code")) return self;
- if (value instanceof AST_Node) {
- value = self.expression.tail_node().evaluate(compressor);
- }
- var decl = [];
- var body = [];
- var default_branch;
- var exact_match;
- // - compress self.body into `body`
- // - find and deduplicate default branch
- // - find the exact match (`case 1234` inside `switch(1234)`)
- for (var i = 0, len = self.body.length; i < len && !exact_match; i++) {
- branch = self.body[i];
- if (branch instanceof AST_Default) {
- if (!default_branch) {
- default_branch = branch;
- } else {
- eliminate_branch(branch, body[body.length - 1]);
- }
- } else if (!(value instanceof AST_Node)) {
- var exp = branch.expression.evaluate(compressor);
- if (!(exp instanceof AST_Node) && exp !== value) {
- eliminate_branch(branch, body[body.length - 1]);
- continue;
- }
- if (exp instanceof AST_Node && !exp.has_side_effects(compressor)) {
- exp = branch.expression.tail_node().evaluate(compressor);
- }
- if (exp === value) {
- exact_match = branch;
- if (default_branch) {
- var default_index = body.indexOf(default_branch);
- body.splice(default_index, 1);
- eliminate_branch(default_branch, body[default_index - 1]);
- default_branch = null;
- }
- }
- }
- body.push(branch);
- }
- // i < len if we found an exact_match. eliminate the rest
- while (i < len) eliminate_branch(self.body[i++], body[body.length - 1]);
- self.body = body;
- let default_or_exact = default_branch || exact_match;
- default_branch = null;
- exact_match = null;
- // group equivalent branches so they will be located next to each other,
- // that way the next micro-optimization will merge them.
- // ** bail micro-optimization if not a simple switch case with breaks
- if (body.every((branch, i) =>
- (branch === default_or_exact || branch.expression instanceof AST_Constant)
- && (branch.body.length === 0 || aborts(branch) || body.length - 1 === i))
- ) {
- for (let i = 0; i < body.length; i++) {
- const branch = body[i];
- for (let j = i + 1; j < body.length; j++) {
- const next = body[j];
- if (next.body.length === 0) continue;
- const last_branch = j === (body.length - 1);
- const equivalentBranch = branches_equivalent(next, branch, false);
- if (equivalentBranch || (last_branch && branches_equivalent(next, branch, true))) {
- if (!equivalentBranch && last_branch) {
- next.body.push(make_node(AST_Break));
- }
- // let's find previous siblings with inert fallthrough...
- let x = j - 1;
- let fallthroughDepth = 0;
- while (x > i) {
- if (is_inert_body(body[x--])) {
- fallthroughDepth++;
- } else {
- break;
- }
- }
- const plucked = body.splice(j - fallthroughDepth, 1 + fallthroughDepth);
- body.splice(i + 1, 0, ...plucked);
- i += plucked.length;
- }
- }
- }
- }
- // merge equivalent branches in a row
- for (let i = 0; i < body.length; i++) {
- let branch = body[i];
- if (branch.body.length === 0) continue;
- if (!aborts(branch)) continue;
- for (let j = i + 1; j < body.length; i++, j++) {
- let next = body[j];
- if (next.body.length === 0) continue;
- if (
- branches_equivalent(next, branch, false)
- || (j === body.length - 1 && branches_equivalent(next, branch, true))
- ) {
- branch.body = [];
- branch = next;
- continue;
- }
- break;
- }
- }
- // Prune any empty branches at the end of the switch statement.
- {
- let i = body.length - 1;
- for (; i >= 0; i--) {
- let bbody = body[i].body;
- while (is_break(bbody[bbody.length - 1], compressor)) bbody.pop();
- if (!is_inert_body(body[i])) break;
- }
- // i now points to the index of a branch that contains a body. By incrementing, it's
- // pointing to the first branch that's empty.
- i++;
- if (!default_or_exact || body.indexOf(default_or_exact) >= i) {
- // The default behavior is to do nothing. We can take advantage of that to
- // remove all case expressions that are side-effect free that also do
- // nothing, since they'll default to doing nothing. But we can't remove any
- // case expressions before one that would side-effect, since they may cause
- // the side-effect to be skipped.
- for (let j = body.length - 1; j >= i; j--) {
- let branch = body[j];
- if (branch === default_or_exact) {
- default_or_exact = null;
- eliminate_branch(body.pop());
- } else if (!branch.expression.has_side_effects(compressor)) {
- eliminate_branch(body.pop());
- } else {
- break;
- }
- }
- }
- }
- // Prune side-effect free branches that fall into default.
- DEFAULT: if (default_or_exact) {
- let default_index = body.indexOf(default_or_exact);
- let default_body_index = default_index;
- for (; default_body_index < body.length - 1; default_body_index++) {
- if (!is_inert_body(body[default_body_index])) break;
- }
- if (default_body_index < body.length - 1) {
- break DEFAULT;
- }
- let side_effect_index = body.length - 1;
- for (; side_effect_index >= 0; side_effect_index--) {
- let branch = body[side_effect_index];
- if (branch === default_or_exact) continue;
- if (branch.expression.has_side_effects(compressor)) break;
- }
- // If the default behavior comes after any side-effect case expressions,
- // then we can fold all side-effect free cases into the default branch.
- // If the side-effect case is after the default, then any side-effect
- // free cases could prevent the side-effect from occurring.
- if (default_body_index > side_effect_index) {
- let prev_body_index = default_index - 1;
- for (; prev_body_index >= 0; prev_body_index--) {
- if (!is_inert_body(body[prev_body_index])) break;
- }
- let before = Math.max(side_effect_index, prev_body_index) + 1;
- let after = default_index;
- if (side_effect_index > default_index) {
- // If the default falls into the same body as a side-effect
- // case, then we need preserve that case and only prune the
- // cases after it.
- after = side_effect_index;
- body[side_effect_index].body = body[default_body_index].body;
- } else {
- // The default will be the last branch.
- default_or_exact.body = body[default_body_index].body;
- }
- // Prune everything after the default (or last side-effect case)
- // until the next case with a body.
- body.splice(after + 1, default_body_index - after);
- // Prune everything before the default that falls into it.
- body.splice(before, default_index - before);
- }
- }
- // See if we can remove the switch entirely if all cases (the default) fall into the same case body.
- DEFAULT: if (default_or_exact) {
- let i = body.findIndex(branch => !is_inert_body(branch));
- let caseBody;
- // `i` is equal to one of the following:
- // - `-1`, there is no body in the switch statement.
- // - `body.length - 1`, all cases fall into the same body.
- // - anything else, there are multiple bodies in the switch.
- if (i === body.length - 1) {
- // All cases fall into the case body.
- let branch = body[i];
- if (has_nested_break(self)) break DEFAULT;
- // This is the last case body, and we've already pruned any breaks, so it's
- // safe to hoist.
- caseBody = make_node(AST_BlockStatement, branch, {
- body: branch.body
- });
- branch.body = [];
- } else if (i !== -1) {
- // If there are multiple bodies, then we cannot optimize anything.
- break DEFAULT;
- }
- let sideEffect = body.find(
- branch => branch !== default_or_exact && branch.expression.has_side_effects(compressor)
- );
- // If no cases cause a side-effect, we can eliminate the switch entirely.
- if (!sideEffect) {
- return make_node(AST_BlockStatement, self, {
- body: decl.concat(
- statement(self.expression),
- default_or_exact.expression ? statement(default_or_exact.expression) : [],
- caseBody || []
- )
- }).optimize(compressor);
- }
- // If we're this far, either there was no body or all cases fell into the same body.
- // If there was no body, then we don't need a default branch (because the default is
- // do nothing). If there was a body, we'll extract it to after the switch, so the
- // switch's new default is to do nothing and we can still prune it.
- const default_index = body.indexOf(default_or_exact);
- body.splice(default_index, 1);
- default_or_exact = null;
- if (caseBody) {
- // Recurse into switch statement one more time so that we can append the case body
- // outside of the switch. This recursion will only happen once since we've pruned
- // the default case.
- return make_node(AST_BlockStatement, self, {
- body: decl.concat(self, caseBody)
- }).optimize(compressor);
- }
- // If we fall here, there is a default branch somewhere, there are no case bodies,
- // and there's a side-effect somewhere. Just let the below paths take care of it.
- }
- // Reintegrate `decl` (var statements)
- if (body.length > 0) {
- body[0].body = decl.concat(body[0].body);
- }
- if (body.length == 0) {
- return make_node(AST_BlockStatement, self, {
- body: decl.concat(statement(self.expression))
- }).optimize(compressor);
- }
- if (body.length == 1 && !has_nested_break(self)) {
- // This is the last case body, and we've already pruned any breaks, so it's
- // safe to hoist.
- let branch = body[0];
- return make_node(AST_If, self, {
- condition: make_node(AST_Binary, self, {
- operator: "===",
- left: self.expression,
- right: branch.expression,
- }),
- body: make_node(AST_BlockStatement, branch, {
- body: branch.body
- }),
- alternative: null
- }).optimize(compressor);
- }
- if (body.length === 2 && default_or_exact && !has_nested_break(self)) {
- let branch = body[0] === default_or_exact ? body[1] : body[0];
- let exact_exp = default_or_exact.expression && statement(default_or_exact.expression);
- if (aborts(body[0])) {
- // Only the first branch body could have a break (at the last statement)
- let first = body[0];
- if (is_break(first.body[first.body.length - 1], compressor)) {
- first.body.pop();
- }
- return make_node(AST_If, self, {
- condition: make_node(AST_Binary, self, {
- operator: "===",
- left: self.expression,
- right: branch.expression,
- }),
- body: make_node(AST_BlockStatement, branch, {
- body: branch.body
- }),
- alternative: make_node(AST_BlockStatement, default_or_exact, {
- body: [].concat(
- exact_exp || [],
- default_or_exact.body
- )
- })
- }).optimize(compressor);
- }
- let operator = "===";
- let consequent = make_node(AST_BlockStatement, branch, {
- body: branch.body,
- });
- let always = make_node(AST_BlockStatement, default_or_exact, {
- body: [].concat(
- exact_exp || [],
- default_or_exact.body
- )
- });
- if (body[0] === default_or_exact) {
- operator = "!==";
- let tmp = always;
- always = consequent;
- consequent = tmp;
- }
- return make_node(AST_BlockStatement, self, {
- body: [
- make_node(AST_If, self, {
- condition: make_node(AST_Binary, self, {
- operator: operator,
- left: self.expression,
- right: branch.expression,
- }),
- body: consequent,
- alternative: null,
- }),
- always,
- ],
- }).optimize(compressor);
- }
- return self;
- function eliminate_branch(branch, prev) {
- if (prev && !aborts(prev)) {
- prev.body = prev.body.concat(branch.body);
- } else {
- extract_from_unreachable_code(compressor, branch, decl);
- }
- }
- function branches_equivalent(branch, prev, insertBreak) {
- let bbody = branch.body;
- let pbody = prev.body;
- if (insertBreak) {
- bbody = bbody.concat(make_node(AST_Break));
- }
- if (bbody.length !== pbody.length) return false;
- let bblock = make_node(AST_BlockStatement, branch, { body: bbody });
- let pblock = make_node(AST_BlockStatement, prev, { body: pbody });
- return bblock.equivalent_to(pblock);
- }
- function statement(body) {
- return make_node(AST_SimpleStatement, body, { body });
- }
- function has_nested_break(root) {
- let has_break = false;
- let tw = new TreeWalker(node => {
- if (has_break) return true;
- if (node instanceof AST_Lambda) return true;
- if (node instanceof AST_SimpleStatement) return true;
- if (!is_break(node, tw)) return;
- let parent = tw.parent();
- if (
- parent instanceof AST_SwitchBranch
- && parent.body[parent.body.length - 1] === node
- ) {
- return;
- }
- has_break = true;
- });
- root.walk(tw);
- return has_break;
- }
- function is_break(node, stack) {
- return node instanceof AST_Break
- && stack.loopcontrol_target(node) === self;
- }
- function is_inert_body(branch) {
- return !aborts(branch) && !make_node(AST_BlockStatement, branch, {
- body: branch.body
- }).has_side_effects(compressor);
- }
- });
- def_optimize(AST_Try, function(self, compressor) {
- if (self.bcatch && self.bfinally && self.bfinally.body.every(is_empty)) self.bfinally = null;
- if (compressor.option("dead_code") && self.body.body.every(is_empty)) {
- var body = [];
- if (self.bcatch) {
- extract_from_unreachable_code(compressor, self.bcatch, body);
- }
- if (self.bfinally) body.push(...self.bfinally.body);
- return make_node(AST_BlockStatement, self, {
- body: body
- }).optimize(compressor);
- }
- return self;
- });
- AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
- var reduce_vars = compressor.option("reduce_vars");
- var assignments = [];
- for (const def of this.definitions) {
- if (def.value) {
- var name = make_node(AST_SymbolRef, def.name, def.name);
- assignments.push(make_node(AST_Assign, def, {
- operator : "=",
- logical: false,
- left : name,
- right : def.value
- }));
- if (reduce_vars) name.definition().fixed = false;
- }
- const thedef = def.name.definition();
- thedef.eliminated++;
- thedef.replaced--;
- }
- if (assignments.length == 0) return null;
- return make_sequence(this, assignments);
- });
- def_optimize(AST_Definitions, function(self) {
- if (self.definitions.length == 0) {
- return make_node(AST_EmptyStatement, self);
- }
- return self;
- });
- def_optimize(AST_VarDef, function(self, compressor) {
- if (
- self.name instanceof AST_SymbolLet
- && self.value != null
- && is_undefined(self.value, compressor)
- ) {
- self.value = null;
- }
- return self;
- });
- def_optimize(AST_Import, function(self) {
- return self;
- });
- def_optimize(AST_Call, function(self, compressor) {
- var exp = self.expression;
- var fn = exp;
- inline_array_like_spread(self.args);
- var simple_args = self.args.every((arg) => !(arg instanceof AST_Expansion));
- if (compressor.option("reduce_vars") && fn instanceof AST_SymbolRef) {
- fn = fn.fixed_value();
- }
- var is_func = fn instanceof AST_Lambda;
- if (is_func && fn.pinned()) return self;
- if (compressor.option("unused")
- && simple_args
- && is_func
- && !fn.uses_arguments) {
- var pos = 0, last = 0;
- for (var i = 0, len = self.args.length; i < len; i++) {
- if (fn.argnames[i] instanceof AST_Expansion) {
- if (has_flag(fn.argnames[i].expression, UNUSED)) while (i < len) {
- var node = self.args[i++].drop_side_effect_free(compressor);
- if (node) {
- self.args[pos++] = node;
- }
- } else while (i < len) {
- self.args[pos++] = self.args[i++];
- }
- last = pos;
- break;
- }
- var trim = i >= fn.argnames.length;
- if (trim || has_flag(fn.argnames[i], UNUSED)) {
- var node = self.args[i].drop_side_effect_free(compressor);
- if (node) {
- self.args[pos++] = node;
- } else if (!trim) {
- self.args[pos++] = make_node(AST_Number, self.args[i], {
- value: 0
- });
- continue;
- }
- } else {
- self.args[pos++] = self.args[i];
- }
- last = pos;
- }
- self.args.length = last;
- }
- if (
- exp instanceof AST_Dot
- && exp.expression instanceof AST_SymbolRef
- && exp.expression.name === "console"
- && exp.expression.definition().undeclared
- && exp.property === "assert"
- ) {
- const condition = self.args[0];
- if (condition) {
- const value = condition.evaluate(compressor);
-
- if (value === 1 || value === true) {
- return make_void_0(self).optimize(compressor);
- }
- }
- }
- if (compressor.option("unsafe") && !exp.contains_optional()) {
- if (exp instanceof AST_Dot && exp.start.value === "Array" && exp.property === "from" && self.args.length === 1) {
- const [argument] = self.args;
- if (argument instanceof AST_Array) {
- return make_node(AST_Array, argument, {
- elements: argument.elements
- }).optimize(compressor);
- }
- }
- if (is_undeclared_ref(exp)) switch (exp.name) {
- case "Array":
- if (self.args.length != 1) {
- return make_node(AST_Array, self, {
- elements: self.args
- }).optimize(compressor);
- } else if (self.args[0] instanceof AST_Number && self.args[0].value <= 11) {
- const elements = [];
- for (let i = 0; i < self.args[0].value; i++) elements.push(new AST_Hole);
- return new AST_Array({ elements });
- }
- break;
- case "Object":
- if (self.args.length == 0) {
- return make_node(AST_Object, self, {
- properties: []
- });
- }
- break;
- case "String":
- if (self.args.length == 0) return make_node(AST_String, self, {
- value: ""
- });
- if (self.args.length <= 1) return make_node(AST_Binary, self, {
- left: self.args[0],
- operator: "+",
- right: make_node(AST_String, self, { value: "" })
- }).optimize(compressor);
- break;
- case "Number":
- if (self.args.length == 0) return make_node(AST_Number, self, {
- value: 0
- });
- if (self.args.length == 1 && compressor.option("unsafe_math")) {
- return make_node(AST_UnaryPrefix, self, {
- expression: self.args[0],
- operator: "+"
- }).optimize(compressor);
- }
- break;
- case "Symbol":
- if (self.args.length == 1 && self.args[0] instanceof AST_String && compressor.option("unsafe_symbols"))
- self.args.length = 0;
- break;
- case "Boolean":
- if (self.args.length == 0) return make_node(AST_False, self);
- if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, {
- expression: make_node(AST_UnaryPrefix, self, {
- expression: self.args[0],
- operator: "!"
- }),
- operator: "!"
- }).optimize(compressor);
- break;
- case "RegExp":
- var params = [];
- if (self.args.length >= 1
- && self.args.length <= 2
- && self.args.every((arg) => {
- var value = arg.evaluate(compressor);
- params.push(value);
- return arg !== value;
- })
- && regexp_is_safe(params[0])
- ) {
- let [ source, flags ] = params;
- source = regexp_source_fix(new RegExp(source).source);
- const rx = make_node(AST_RegExp, self, {
- value: { source, flags }
- });
- if (rx._eval(compressor) !== rx) {
- return rx;
- }
- }
- break;
- } else if (exp instanceof AST_Dot) switch(exp.property) {
- case "toString":
- if (self.args.length == 0 && !exp.expression.may_throw_on_access(compressor)) {
- return make_node(AST_Binary, self, {
- left: make_node(AST_String, self, { value: "" }),
- operator: "+",
- right: exp.expression
- }).optimize(compressor);
- }
- break;
- case "join":
- if (exp.expression instanceof AST_Array) EXIT: {
- var separator;
- if (self.args.length > 0) {
- separator = self.args[0].evaluate(compressor);
- if (separator === self.args[0]) break EXIT; // not a constant
- }
- var elements = [];
- var consts = [];
- for (var i = 0, len = exp.expression.elements.length; i < len; i++) {
- var el = exp.expression.elements[i];
- if (el instanceof AST_Expansion) break EXIT;
- var value = el.evaluate(compressor);
- if (value !== el) {
- consts.push(value);
- } else {
- if (consts.length > 0) {
- elements.push(make_node(AST_String, self, {
- value: consts.join(separator)
- }));
- consts.length = 0;
- }
- elements.push(el);
- }
- }
- if (consts.length > 0) {
- elements.push(make_node(AST_String, self, {
- value: consts.join(separator)
- }));
- }
- if (elements.length == 0) return make_node(AST_String, self, { value: "" });
- if (elements.length == 1) {
- if (elements[0].is_string(compressor)) {
- return elements[0];
- }
- return make_node(AST_Binary, elements[0], {
- operator : "+",
- left : make_node(AST_String, self, { value: "" }),
- right : elements[0]
- });
- }
- if (separator == "") {
- var first;
- if (elements[0].is_string(compressor)
- || elements[1].is_string(compressor)) {
- first = elements.shift();
- } else {
- first = make_node(AST_String, self, { value: "" });
- }
- return elements.reduce(function(prev, el) {
- return make_node(AST_Binary, el, {
- operator : "+",
- left : prev,
- right : el
- });
- }, first).optimize(compressor);
- }
- // need this awkward cloning to not affect original element
- // best_of will decide which one to get through.
- var node = self.clone();
- node.expression = node.expression.clone();
- node.expression.expression = node.expression.expression.clone();
- node.expression.expression.elements = elements;
- return best_of(compressor, self, node);
- }
- break;
- case "charAt":
- if (exp.expression.is_string(compressor)) {
- var arg = self.args[0];
- var index = arg ? arg.evaluate(compressor) : 0;
- if (index !== arg) {
- return make_node(AST_Sub, exp, {
- expression: exp.expression,
- property: make_node_from_constant(index | 0, arg || exp)
- }).optimize(compressor);
- }
- }
- break;
- case "apply":
- if (self.args.length == 2 && self.args[1] instanceof AST_Array) {
- var args = self.args[1].elements.slice();
- args.unshift(self.args[0]);
- return make_node(AST_Call, self, {
- expression: make_node(AST_Dot, exp, {
- expression: exp.expression,
- optional: false,
- property: "call"
- }),
- args: args
- }).optimize(compressor);
- }
- break;
- case "call":
- var func = exp.expression;
- if (func instanceof AST_SymbolRef) {
- func = func.fixed_value();
- }
- if (func instanceof AST_Lambda && !func.contains_this()) {
- return (self.args.length ? make_sequence(this, [
- self.args[0],
- make_node(AST_Call, self, {
- expression: exp.expression,
- args: self.args.slice(1)
- })
- ]) : make_node(AST_Call, self, {
- expression: exp.expression,
- args: []
- })).optimize(compressor);
- }
- break;
- }
- }
- if (compressor.option("unsafe_Function")
- && is_undeclared_ref(exp)
- && exp.name == "Function") {
- // new Function() => function(){}
- if (self.args.length == 0) return make_empty_function(self).optimize(compressor);
- if (self.args.every((x) => x instanceof AST_String)) {
- // quite a corner-case, but we can handle it:
- // https://github.com/mishoo/UglifyJS2/issues/203
- // if the code argument is a constant, then we can minify it.
- try {
- var code = "n(function(" + self.args.slice(0, -1).map(function(arg) {
- return arg.value;
- }).join(",") + "){" + self.args[self.args.length - 1].value + "})";
- var ast = parse(code);
- var mangle = compressor.mangle_options();
- ast.figure_out_scope(mangle);
- var comp = new Compressor(compressor.options, {
- mangle_options: compressor._mangle_options
- });
- ast = ast.transform(comp);
- ast.figure_out_scope(mangle);
- ast.compute_char_frequency(mangle);
- ast.mangle_names(mangle);
- var fun;
- walk(ast, node => {
- if (is_func_expr(node)) {
- fun = node;
- return walk_abort;
- }
- });
- var code = OutputStream();
- AST_BlockStatement.prototype._codegen.call(fun, fun, code);
- self.args = [
- make_node(AST_String, self, {
- value: fun.argnames.map(function(arg) {
- return arg.print_to_string();
- }).join(",")
- }),
- make_node(AST_String, self.args[self.args.length - 1], {
- value: code.get().replace(/^{|}$/g, "")
- })
- ];
- return self;
- } catch (ex) {
- if (!(ex instanceof JS_Parse_Error)) {
- throw ex;
- }
- // Otherwise, it crashes at runtime. Or maybe it's nonstandard syntax.
- }
- }
- }
- return inline_into_call(self, compressor);
- });
- /** Does this node contain optional property access or optional call? */
- AST_Node.DEFMETHOD("contains_optional", function() {
- if (
- this instanceof AST_PropAccess
- || this instanceof AST_Call
- || this instanceof AST_Chain
- ) {
- if (this.optional) {
- return true;
- } else {
- return this.expression.contains_optional();
- }
- } else {
- return false;
- }
- });
- def_optimize(AST_New, function(self, compressor) {
- if (
- compressor.option("unsafe") &&
- is_undeclared_ref(self.expression) &&
- ["Object", "RegExp", "Function", "Error", "Array"].includes(self.expression.name)
- ) return make_node(AST_Call, self, self).transform(compressor);
- return self;
- });
- def_optimize(AST_Sequence, function(self, compressor) {
- if (!compressor.option("side_effects")) return self;
- var expressions = [];
- filter_for_side_effects();
- var end = expressions.length - 1;
- trim_right_for_undefined();
- if (end == 0) {
- self = maintain_this_binding(compressor.parent(), compressor.self(), expressions[0]);
- if (!(self instanceof AST_Sequence)) self = self.optimize(compressor);
- return self;
- }
- self.expressions = expressions;
- return self;
- function filter_for_side_effects() {
- var first = first_in_statement(compressor);
- var last = self.expressions.length - 1;
- self.expressions.forEach(function(expr, index) {
- if (index < last) expr = expr.drop_side_effect_free(compressor, first);
- if (expr) {
- merge_sequence(expressions, expr);
- first = false;
- }
- });
- }
- function trim_right_for_undefined() {
- while (end > 0 && is_undefined(expressions[end], compressor)) end--;
- if (end < expressions.length - 1) {
- expressions[end] = make_node(AST_UnaryPrefix, self, {
- operator : "void",
- expression : expressions[end]
- });
- expressions.length = end + 1;
- }
- }
- });
- AST_Unary.DEFMETHOD("lift_sequences", function(compressor) {
- if (compressor.option("sequences")) {
- if (this.expression instanceof AST_Sequence) {
- var x = this.expression.expressions.slice();
- var e = this.clone();
- e.expression = x.pop();
- x.push(e);
- return make_sequence(this, x).optimize(compressor);
- }
- }
- return this;
- });
- def_optimize(AST_UnaryPostfix, function(self, compressor) {
- return self.lift_sequences(compressor);
- });
- def_optimize(AST_UnaryPrefix, function(self, compressor) {
- var e = self.expression;
- if (
- self.operator == "delete" &&
- !(
- e instanceof AST_SymbolRef ||
- e instanceof AST_PropAccess ||
- e instanceof AST_Chain ||
- is_identifier_atom(e)
- )
- ) {
- return make_sequence(self, [e, make_node(AST_True, self)]).optimize(compressor);
- }
- // Short-circuit common `void 0`
- if (self.operator === "void" && e instanceof AST_Number && e.value === 0) {
- return unsafe_undefined_ref(self, compressor) || self;
- }
- var seq = self.lift_sequences(compressor);
- if (seq !== self) {
- return seq;
- }
- if (compressor.option("side_effects") && self.operator == "void") {
- e = e.drop_side_effect_free(compressor);
- if (e) {
- self.expression = e;
- return self;
- } else {
- return make_void_0(self).optimize(compressor);
- }
- }
- if (compressor.in_boolean_context()) {
- switch (self.operator) {
- case "!":
- if (e instanceof AST_UnaryPrefix && e.operator == "!") {
- // !!foo ==> foo, if we're in boolean context
- return e.expression;
- }
- if (e instanceof AST_Binary) {
- self = best_of(compressor, self, e.negate(compressor, first_in_statement(compressor)));
- }
- break;
- case "typeof":
- // typeof always returns a non-empty string, thus it's
- // always true in booleans
- // And we don't need to check if it's undeclared, because in typeof, that's OK
- return (e instanceof AST_SymbolRef ? make_node(AST_True, self) : make_sequence(self, [
- e,
- make_node(AST_True, self)
- ])).optimize(compressor);
- }
- }
- if (self.operator == "-" && e instanceof AST_Infinity) {
- e = e.transform(compressor);
- }
- if (e instanceof AST_Binary
- && (self.operator == "+" || self.operator == "-")
- && (e.operator == "*" || e.operator == "/" || e.operator == "%")) {
- return make_node(AST_Binary, self, {
- operator: e.operator,
- left: make_node(AST_UnaryPrefix, e.left, {
- operator: self.operator,
- expression: e.left
- }),
- right: e.right
- });
- }
- if (compressor.option("evaluate")) {
- // ~~x => x (in 32-bit context)
- // ~~{32 bit integer} => {32 bit integer}
- if (
- self.operator === "~"
- && self.expression instanceof AST_UnaryPrefix
- && self.expression.operator === "~"
- && (compressor.in_32_bit_context(false) || self.expression.expression.is_32_bit_integer(compressor))
- ) {
- return self.expression.expression;
- }
- // ~(x ^ y) => x ^ ~y
- if (
- self.operator === "~"
- && e instanceof AST_Binary
- && e.operator === "^"
- ) {
- if (e.left instanceof AST_UnaryPrefix && e.left.operator === "~") {
- // ~(~x ^ y) => x ^ y
- e.left = e.left.bitwise_negate(compressor, true);
- } else {
- e.right = e.right.bitwise_negate(compressor, true);
- }
- return e;
- }
- }
- if (
- self.operator != "-"
- // avoid infinite recursion of numerals
- || !(e instanceof AST_Number || e instanceof AST_Infinity || e instanceof AST_BigInt)
- ) {
- var ev = self.evaluate(compressor);
- if (ev !== self) {
- ev = make_node_from_constant(ev, self).optimize(compressor);
- return best_of(compressor, ev, self);
- }
- }
- return self;
- });
- AST_Binary.DEFMETHOD("lift_sequences", function(compressor) {
- if (compressor.option("sequences")) {
- if (this.left instanceof AST_Sequence) {
- var x = this.left.expressions.slice();
- var e = this.clone();
- e.left = x.pop();
- x.push(e);
- return make_sequence(this, x).optimize(compressor);
- }
- if (this.right instanceof AST_Sequence && !this.left.has_side_effects(compressor)) {
- var assign = this.operator == "=" && this.left instanceof AST_SymbolRef;
- var x = this.right.expressions;
- var last = x.length - 1;
- for (var i = 0; i < last; i++) {
- if (!assign && x[i].has_side_effects(compressor)) break;
- }
- if (i == last) {
- x = x.slice();
- var e = this.clone();
- e.right = x.pop();
- x.push(e);
- return make_sequence(this, x).optimize(compressor);
- } else if (i > 0) {
- var e = this.clone();
- e.right = make_sequence(this.right, x.slice(i));
- x = x.slice(0, i);
- x.push(e);
- return make_sequence(this, x).optimize(compressor);
- }
- }
- }
- return this;
- });
- var commutativeOperators = makePredicate("== === != !== * & | ^");
- function is_object(node) {
- return node instanceof AST_Array
- || node instanceof AST_Lambda
- || node instanceof AST_Object
- || node instanceof AST_Class;
- }
- def_optimize(AST_Binary, function(self, compressor) {
- function reversible() {
- return self.left.is_constant()
- || self.right.is_constant()
- || !self.left.has_side_effects(compressor)
- && !self.right.has_side_effects(compressor);
- }
- function reverse(op) {
- if (reversible()) {
- if (op) self.operator = op;
- var tmp = self.left;
- self.left = self.right;
- self.right = tmp;
- }
- }
- if (compressor.option("lhs_constants") && commutativeOperators.has(self.operator)) {
- if (self.right.is_constant()
- && !self.left.is_constant()) {
- // if right is a constant, whatever side effects the
- // left side might have could not influence the
- // result. hence, force switch.
- if (!(self.left instanceof AST_Binary
- && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) {
- reverse();
- }
- }
- }
- self = self.lift_sequences(compressor);
- if (compressor.option("comparisons")) switch (self.operator) {
- case "===":
- case "!==":
- var is_strict_comparison = true;
- if (
- (self.left.is_string(compressor) && self.right.is_string(compressor)) ||
- (self.left.is_number(compressor) && self.right.is_number(compressor)) ||
- (self.left.is_bigint(compressor) && self.right.is_bigint(compressor)) ||
- (self.left.is_boolean() && self.right.is_boolean()) ||
- self.left.equivalent_to(self.right)
- ) {
- self.operator = self.operator.substr(0, 2);
- }
- // XXX: intentionally falling down to the next case
- case "==":
- case "!=":
- // void 0 == x => null == x
- if (!is_strict_comparison && is_undefined(self.left, compressor)) {
- self.left = make_node(AST_Null, self.left);
- // x == void 0 => x == null
- } else if (!is_strict_comparison && is_undefined(self.right, compressor)) {
- self.right = make_node(AST_Null, self.right);
- } else if (compressor.option("typeofs")
- // "undefined" == typeof x => undefined === x
- && self.left instanceof AST_String
- && self.left.value == "undefined"
- && self.right instanceof AST_UnaryPrefix
- && self.right.operator == "typeof") {
- var expr = self.right.expression;
- if (expr instanceof AST_SymbolRef ? expr.is_declared(compressor)
- : !(expr instanceof AST_PropAccess && compressor.option("ie8"))) {
- self.right = expr;
- self.left = make_void_0(self.left).optimize(compressor);
- if (self.operator.length == 2) self.operator += "=";
- }
- } else if (compressor.option("typeofs")
- // typeof x === "undefined" => x === undefined
- && self.left instanceof AST_UnaryPrefix
- && self.left.operator == "typeof"
- && self.right instanceof AST_String
- && self.right.value == "undefined") {
- var expr = self.left.expression;
- if (expr instanceof AST_SymbolRef ? expr.is_declared(compressor)
- : !(expr instanceof AST_PropAccess && compressor.option("ie8"))) {
- self.left = expr;
- self.right = make_void_0(self.right).optimize(compressor);
- if (self.operator.length == 2) self.operator += "=";
- }
- } else if (self.left instanceof AST_SymbolRef
- // obj !== obj => false
- && self.right instanceof AST_SymbolRef
- && self.left.definition() === self.right.definition()
- && is_object(self.left.fixed_value())) {
- return make_node(self.operator[0] == "=" ? AST_True : AST_False, self);
- } else if (self.left.is_32_bit_integer(compressor) && self.right.is_32_bit_integer(compressor)) {
- const not = node => make_node(AST_UnaryPrefix, node, {
- operator: "!",
- expression: node
- });
- const booleanify = (node, truthy) => {
- if (truthy) {
- return compressor.in_boolean_context()
- ? node
- : not(not(node));
- } else {
- return not(node);
- }
- };
- // The only falsy 32-bit integer is 0
- if (self.left instanceof AST_Number && self.left.value === 0) {
- return booleanify(self.right, self.operator[0] === "!");
- }
- if (self.right instanceof AST_Number && self.right.value === 0) {
- return booleanify(self.left, self.operator[0] === "!");
- }
- // Mask all-bits check
- // (x & 0xFF) != 0xFF => !(~x & 0xFF)
- let and_op, x, mask;
- if (
- (and_op =
- self.left instanceof AST_Binary ? self.left
- : self.right instanceof AST_Binary ? self.right : null)
- && (mask = and_op === self.left ? self.right : self.left)
- && and_op.operator === "&"
- && mask instanceof AST_Number
- && mask.is_32_bit_integer(compressor)
- && (x =
- and_op.left.equivalent_to(mask) ? and_op.right
- : and_op.right.equivalent_to(mask) ? and_op.left : null)
- ) {
- let optimized = booleanify(make_node(AST_Binary, self, {
- operator: "&",
- left: mask,
- right: make_node(AST_UnaryPrefix, self, {
- operator: "~",
- expression: x
- })
- }), self.operator[0] === "!");
- return best_of(compressor, optimized, self);
- }
- }
- break;
- case "&&":
- case "||":
- var lhs = self.left;
- if (lhs.operator == self.operator) {
- lhs = lhs.right;
- }
- if (lhs instanceof AST_Binary
- && lhs.operator == (self.operator == "&&" ? "!==" : "===")
- && self.right instanceof AST_Binary
- && lhs.operator == self.right.operator
- && (is_undefined(lhs.left, compressor) && self.right.left instanceof AST_Null
- || lhs.left instanceof AST_Null && is_undefined(self.right.left, compressor))
- && !lhs.right.has_side_effects(compressor)
- && lhs.right.equivalent_to(self.right.right)) {
- var combined = make_node(AST_Binary, self, {
- operator: lhs.operator.slice(0, -1),
- left: make_node(AST_Null, self),
- right: lhs.right
- });
- if (lhs !== self.left) {
- combined = make_node(AST_Binary, self, {
- operator: self.operator,
- left: self.left.left,
- right: combined
- });
- }
- return combined;
- }
- break;
- }
- if (self.operator == "+" && compressor.in_boolean_context()) {
- var ll = self.left.evaluate(compressor);
- var rr = self.right.evaluate(compressor);
- if (ll && typeof ll == "string") {
- return make_sequence(self, [
- self.right,
- make_node(AST_True, self)
- ]).optimize(compressor);
- }
- if (rr && typeof rr == "string") {
- return make_sequence(self, [
- self.left,
- make_node(AST_True, self)
- ]).optimize(compressor);
- }
- }
- if (compressor.option("comparisons") && self.is_boolean()) {
- if (!(compressor.parent() instanceof AST_Binary)
- || compressor.parent() instanceof AST_Assign) {
- var negated = make_node(AST_UnaryPrefix, self, {
- operator: "!",
- expression: self.negate(compressor, first_in_statement(compressor))
- });
- self = best_of(compressor, self, negated);
- }
- if (compressor.option("unsafe_comps")) {
- switch (self.operator) {
- case "<": reverse(">"); break;
- case "<=": reverse(">="); break;
- }
- }
- }
- if (self.operator == "+") {
- if (self.right instanceof AST_String
- && self.right.getValue() == ""
- && self.left.is_string(compressor)) {
- return self.left;
- }
- if (self.left instanceof AST_String
- && self.left.getValue() == ""
- && self.right.is_string(compressor)) {
- return self.right;
- }
- if (self.left instanceof AST_Binary
- && self.left.operator == "+"
- && self.left.left instanceof AST_String
- && self.left.left.getValue() == ""
- && self.right.is_string(compressor)) {
- self.left = self.left.right;
- return self;
- }
- }
- if (compressor.option("evaluate")) {
- switch (self.operator) {
- case "&&":
- var ll = has_flag(self.left, TRUTHY)
- ? true
- : has_flag(self.left, FALSY)
- ? false
- : self.left.evaluate(compressor);
- if (!ll) {
- return maintain_this_binding(compressor.parent(), compressor.self(), self.left).optimize(compressor);
- } else if (!(ll instanceof AST_Node)) {
- return make_sequence(self, [ self.left, self.right ]).optimize(compressor);
- }
- var rr = self.right.evaluate(compressor);
- if (!rr) {
- if (compressor.in_boolean_context()) {
- return make_sequence(self, [
- self.left,
- make_node(AST_False, self)
- ]).optimize(compressor);
- } else {
- set_flag(self, FALSY);
- }
- } else if (!(rr instanceof AST_Node)) {
- var parent = compressor.parent();
- if (parent.operator == "&&" && parent.left === compressor.self() || compressor.in_boolean_context()) {
- return self.left.optimize(compressor);
- }
- }
- // x || false && y ---> x ? y : false
- if (self.left.operator == "||") {
- var lr = self.left.right.evaluate(compressor);
- if (!lr) return make_node(AST_Conditional, self, {
- condition: self.left.left,
- consequent: self.right,
- alternative: self.left.right
- }).optimize(compressor);
- }
- break;
- case "||":
- var ll = has_flag(self.left, TRUTHY)
- ? true
- : has_flag(self.left, FALSY)
- ? false
- : self.left.evaluate(compressor);
- if (!ll) {
- return make_sequence(self, [ self.left, self.right ]).optimize(compressor);
- } else if (!(ll instanceof AST_Node)) {
- return maintain_this_binding(compressor.parent(), compressor.self(), self.left).optimize(compressor);
- }
- var rr = self.right.evaluate(compressor);
- if (!rr) {
- var parent = compressor.parent();
- if (parent.operator == "||" && parent.left === compressor.self() || compressor.in_boolean_context()) {
- return self.left.optimize(compressor);
- }
- } else if (!(rr instanceof AST_Node)) {
- if (compressor.in_boolean_context()) {
- return make_sequence(self, [
- self.left,
- make_node(AST_True, self)
- ]).optimize(compressor);
- } else {
- set_flag(self, TRUTHY);
- }
- }
- if (self.left.operator == "&&") {
- var lr = self.left.right.evaluate(compressor);
- if (lr && !(lr instanceof AST_Node)) return make_node(AST_Conditional, self, {
- condition: self.left.left,
- consequent: self.left.right,
- alternative: self.right
- }).optimize(compressor);
- }
- break;
- case "??":
- if (is_nullish(self.left, compressor)) {
- return self.right;
- }
- var ll = self.left.evaluate(compressor);
- if (!(ll instanceof AST_Node)) {
- // if we know the value for sure we can simply compute right away.
- return ll == null ? self.right : self.left;
- }
- if (compressor.in_boolean_context()) {
- const rr = self.right.evaluate(compressor);
- if (!(rr instanceof AST_Node) && !rr) {
- return self.left;
- }
- }
- }
- var associative = true;
- switch (self.operator) {
- case "+":
- // (x + "foo") + "bar" => x + "foobar"
- if (self.right instanceof AST_Constant
- && self.left instanceof AST_Binary
- && self.left.operator == "+"
- && self.left.is_string(compressor)) {
- var binary = make_node(AST_Binary, self, {
- operator: "+",
- left: self.left.right,
- right: self.right,
- });
- var r = binary.optimize(compressor);
- if (binary !== r) {
- self = make_node(AST_Binary, self, {
- operator: "+",
- left: self.left.left,
- right: r
- });
- }
- }
- // (x + "foo") + ("bar" + y) => (x + "foobar") + y
- if (self.left instanceof AST_Binary
- && self.left.operator == "+"
- && self.left.is_string(compressor)
- && self.right instanceof AST_Binary
- && self.right.operator == "+"
- && self.right.is_string(compressor)) {
- var binary = make_node(AST_Binary, self, {
- operator: "+",
- left: self.left.right,
- right: self.right.left,
- });
- var m = binary.optimize(compressor);
- if (binary !== m) {
- self = make_node(AST_Binary, self, {
- operator: "+",
- left: make_node(AST_Binary, self.left, {
- operator: "+",
- left: self.left.left,
- right: m
- }),
- right: self.right.right
- });
- }
- }
- // a + -b => a - b
- if (self.right instanceof AST_UnaryPrefix
- && self.right.operator == "-"
- && self.left.is_number_or_bigint(compressor)) {
- self = make_node(AST_Binary, self, {
- operator: "-",
- left: self.left,
- right: self.right.expression
- });
- break;
- }
- // -a + b => b - a
- if (self.left instanceof AST_UnaryPrefix
- && self.left.operator == "-"
- && reversible()
- && self.right.is_number_or_bigint(compressor)) {
- self = make_node(AST_Binary, self, {
- operator: "-",
- left: self.right,
- right: self.left.expression
- });
- break;
- }
- // `foo${bar}baz` + 1 => `foo${bar}baz1`
- if (self.left instanceof AST_TemplateString) {
- var l = self.left;
- var r = self.right.evaluate(compressor);
- if (r != self.right) {
- l.segments[l.segments.length - 1].value += String(r);
- return l;
- }
- }
- // 1 + `foo${bar}baz` => `1foo${bar}baz`
- if (self.right instanceof AST_TemplateString) {
- var r = self.right;
- var l = self.left.evaluate(compressor);
- if (l != self.left) {
- r.segments[0].value = String(l) + r.segments[0].value;
- return r;
- }
- }
- // `1${bar}2` + `foo${bar}baz` => `1${bar}2foo${bar}baz`
- if (self.left instanceof AST_TemplateString
- && self.right instanceof AST_TemplateString) {
- var l = self.left;
- var segments = l.segments;
- var r = self.right;
- segments[segments.length - 1].value += r.segments[0].value;
- for (var i = 1; i < r.segments.length; i++) {
- segments.push(r.segments[i]);
- }
- return l;
- }
- case "*":
- associative = compressor.option("unsafe_math");
- case "&":
- case "|":
- case "^":
- // a + +b => +b + a
- if (
- self.left.is_number_or_bigint(compressor)
- && self.right.is_number_or_bigint(compressor)
- && reversible()
- && !(self.left instanceof AST_Binary
- && self.left.operator != self.operator
- && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) {
- var reversed = make_node(AST_Binary, self, {
- operator: self.operator,
- left: self.right,
- right: self.left
- });
- if (self.right instanceof AST_Constant
- && !(self.left instanceof AST_Constant)) {
- self = best_of(compressor, reversed, self);
- } else {
- self = best_of(compressor, self, reversed);
- }
- }
- if (associative && self.is_number_or_bigint(compressor)) {
- // a + (b + c) => (a + b) + c
- if (self.right instanceof AST_Binary
- && self.right.operator == self.operator) {
- self = make_node(AST_Binary, self, {
- operator: self.operator,
- left: make_node(AST_Binary, self.left, {
- operator: self.operator,
- left: self.left,
- right: self.right.left,
- start: self.left.start,
- end: self.right.left.end
- }),
- right: self.right.right
- });
- }
- // (n + 2) + 3 => 5 + n
- // (2 * n) * 3 => 6 + n
- if (self.right instanceof AST_Constant
- && self.left instanceof AST_Binary
- && self.left.operator == self.operator) {
- if (self.left.left instanceof AST_Constant) {
- self = make_node(AST_Binary, self, {
- operator: self.operator,
- left: make_node(AST_Binary, self.left, {
- operator: self.operator,
- left: self.left.left,
- right: self.right,
- start: self.left.left.start,
- end: self.right.end
- }),
- right: self.left.right
- });
- } else if (self.left.right instanceof AST_Constant) {
- self = make_node(AST_Binary, self, {
- operator: self.operator,
- left: make_node(AST_Binary, self.left, {
- operator: self.operator,
- left: self.left.right,
- right: self.right,
- start: self.left.right.start,
- end: self.right.end
- }),
- right: self.left.left
- });
- }
- }
- // (a | 1) | (2 | d) => (3 | a) | b
- if (self.left instanceof AST_Binary
- && self.left.operator == self.operator
- && self.left.right instanceof AST_Constant
- && self.right instanceof AST_Binary
- && self.right.operator == self.operator
- && self.right.left instanceof AST_Constant) {
- self = make_node(AST_Binary, self, {
- operator: self.operator,
- left: make_node(AST_Binary, self.left, {
- operator: self.operator,
- left: make_node(AST_Binary, self.left.left, {
- operator: self.operator,
- left: self.left.right,
- right: self.right.left,
- start: self.left.right.start,
- end: self.right.left.end
- }),
- right: self.left.left
- }),
- right: self.right.right
- });
- }
- }
- }
- // bitwise ops
- if (bitwise_binop.has(self.operator)) {
- // Use De Morgan's laws
- // z & (X | y)
- // => z & X (given y & z === 0)
- // => z & X | {y & z} (given y & z !== 0)
- let y, z, x_node, y_node, z_node = self.left;
- if (
- self.operator === "&"
- && self.right instanceof AST_Binary
- && self.right.operator === "|"
- && typeof (z = self.left.evaluate(compressor)) === "number"
- ) {
- if (typeof (y = self.right.right.evaluate(compressor)) === "number") {
- // z & (X | y)
- x_node = self.right.left;
- y_node = self.right.right;
- } else if (typeof (y = self.right.left.evaluate(compressor)) === "number") {
- // z & (y | X)
- x_node = self.right.right;
- y_node = self.right.left;
- }
- if (x_node && y_node) {
- if ((y & z) === 0) {
- self = make_node(AST_Binary, self, {
- operator: self.operator,
- left: z_node,
- right: x_node
- });
- } else {
- const reordered_ops = make_node(AST_Binary, self, {
- operator: "|",
- left: make_node(AST_Binary, self, {
- operator: "&",
- left: x_node,
- right: z_node
- }),
- right: make_node_from_constant(y & z, y_node),
- });
- self = best_of(compressor, self, reordered_ops);
- }
- }
- }
- // x | x => 0 | x
- // x & x => 0 | x
- if (
- (self.operator === "|" || self.operator === "&")
- && self.left.equivalent_to(self.right)
- && !self.left.has_side_effects(compressor)
- && compressor.in_32_bit_context(true)
- ) {
- self.left = make_node(AST_Number, self, { value: 0 });
- self.operator = "|";
- }
- // ~x ^ ~y => x ^ y
- if (
- self.operator === "^"
- && self.left instanceof AST_UnaryPrefix
- && self.left.operator === "~"
- && self.right instanceof AST_UnaryPrefix
- && self.right.operator === "~"
- ) {
- self = make_node(AST_Binary, self, {
- operator: "^",
- left: self.left.expression,
- right: self.right.expression
- });
- }
- // Shifts that do nothing
- // {anything} >> 0 => {anything} | 0
- // {anything} << 0 => {anything} | 0
- if (
- (self.operator === "<<" || self.operator === ">>")
- && self.right instanceof AST_Number && self.right.value === 0
- ) {
- self.operator = "|";
- }
- // Find useless to-bitwise conversions
- // {32 bit integer} | 0 => {32 bit integer}
- // {32 bit integer} ^ 0 => {32 bit integer}
- const zero_side = self.right instanceof AST_Number && self.right.value === 0 ? self.right
- : self.left instanceof AST_Number && self.left.value === 0 ? self.left
- : null;
- const non_zero_side = zero_side && (zero_side === self.right ? self.left : self.right);
- if (
- zero_side
- && (self.operator === "|" || self.operator === "^")
- && (non_zero_side.is_32_bit_integer(compressor) || compressor.in_32_bit_context(true))
- ) {
- return non_zero_side;
- }
- // {anything} & 0 => 0
- if (
- zero_side
- && self.operator === "&"
- && !non_zero_side.has_side_effects(compressor)
- && non_zero_side.is_32_bit_integer(compressor)
- ) {
- return zero_side;
- }
- // ~0 is all ones, as well as -1.
- // We can ellide some operations with it.
- const is_full_mask = (node) =>
- node instanceof AST_Number && node.value === -1
- ||
- node instanceof AST_UnaryPrefix
- && node.operator === "-"
- && node.expression instanceof AST_Number
- && node.expression.value === 1;
- const full_mask = is_full_mask(self.right) ? self.right
- : is_full_mask(self.left) ? self.left
- : null;
- const other_side = (full_mask === self.right ? self.left : self.right);
- // {32 bit integer} & -1 => {32 bit integer}
- if (
- full_mask
- && self.operator === "&"
- && (
- other_side.is_32_bit_integer(compressor)
- || compressor.in_32_bit_context(true)
- )
- ) {
- return other_side;
- }
- // {anything} ^ -1 => ~{anything}
- if (
- full_mask
- && self.operator === "^"
- && (
- other_side.is_32_bit_integer(compressor)
- || compressor.in_32_bit_context(true)
- )
- ) {
- return other_side.bitwise_negate(compressor);
- }
- }
- }
- // x && (y && z) ==> x && y && z
- // x || (y || z) ==> x || y || z
- // x + ("y" + z) ==> x + "y" + z
- // "x" + (y + "z")==> "x" + y + "z"
- if (self.right instanceof AST_Binary
- && self.right.operator == self.operator
- && (lazy_op.has(self.operator)
- || (self.operator == "+"
- && (self.right.left.is_string(compressor)
- || (self.left.is_string(compressor)
- && self.right.right.is_string(compressor)))))
- ) {
- self.left = make_node(AST_Binary, self.left, {
- operator : self.operator,
- left : self.left.transform(compressor),
- right : self.right.left.transform(compressor)
- });
- self.right = self.right.right.transform(compressor);
- return self.transform(compressor);
- }
- var ev = self.evaluate(compressor);
- if (ev !== self) {
- ev = make_node_from_constant(ev, self).optimize(compressor);
- return best_of(compressor, ev, self);
- }
- return self;
- });
- def_optimize(AST_SymbolExport, function(self) {
- return self;
- });
- def_optimize(AST_SymbolRef, function(self, compressor) {
- if (
- !compressor.option("ie8")
- && is_undeclared_ref(self)
- && !compressor.find_parent(AST_With)
- ) {
- switch (self.name) {
- case "undefined":
- return make_node(AST_Undefined, self).optimize(compressor);
- case "NaN":
- return make_node(AST_NaN, self).optimize(compressor);
- case "Infinity":
- return make_node(AST_Infinity, self).optimize(compressor);
- }
- }
- if (compressor.option("reduce_vars") && !compressor.is_lhs()) {
- return inline_into_symbolref(self, compressor);
- } else {
- return self;
- }
- });
- function is_atomic(lhs, self) {
- return lhs instanceof AST_SymbolRef || lhs.TYPE === self.TYPE;
- }
- /** Apply the `unsafe_undefined` option: find a variable called `undefined` and turn `self` into a reference to it. */
- function unsafe_undefined_ref(self, compressor) {
- if (compressor.option("unsafe_undefined")) {
- var undef = find_variable(compressor, "undefined");
- if (undef) {
- var ref = make_node(AST_SymbolRef, self, {
- name : "undefined",
- scope : undef.scope,
- thedef : undef
- });
- set_flag(ref, UNDEFINED);
- return ref;
- }
- }
- return null;
- }
- def_optimize(AST_Undefined, function(self, compressor) {
- var symbolref = unsafe_undefined_ref(self, compressor);
- if (symbolref) return symbolref;
- var lhs = compressor.is_lhs();
- if (lhs && is_atomic(lhs, self)) return self;
- return make_void_0(self);
- });
- def_optimize(AST_Infinity, function(self, compressor) {
- var lhs = compressor.is_lhs();
- if (lhs && is_atomic(lhs, self)) return self;
- if (
- compressor.option("keep_infinity")
- && !(lhs && !is_atomic(lhs, self))
- && !find_variable(compressor, "Infinity")
- ) {
- return self;
- }
- return make_node(AST_Binary, self, {
- operator: "/",
- left: make_node(AST_Number, self, {
- value: 1
- }),
- right: make_node(AST_Number, self, {
- value: 0
- })
- });
- });
- def_optimize(AST_NaN, function(self, compressor) {
- var lhs = compressor.is_lhs();
- if (lhs && !is_atomic(lhs, self)
- || find_variable(compressor, "NaN")) {
- return make_node(AST_Binary, self, {
- operator: "/",
- left: make_node(AST_Number, self, {
- value: 0
- }),
- right: make_node(AST_Number, self, {
- value: 0
- })
- });
- }
- return self;
- });
- const ASSIGN_OPS = makePredicate("+ - / * % >> << >>> | ^ &");
- const ASSIGN_OPS_COMMUTATIVE = makePredicate("* | ^ &");
- def_optimize(AST_Assign, function(self, compressor) {
- if (self.logical) {
- return self.lift_sequences(compressor);
- }
- var def;
- // x = x ---> x
- if (
- self.operator === "="
- && self.left instanceof AST_SymbolRef
- && self.left.name !== "arguments"
- && !(def = self.left.definition()).undeclared
- && self.right.equivalent_to(self.left)
- ) {
- return self.right;
- }
- if (compressor.option("dead_code")
- && self.left instanceof AST_SymbolRef
- && (def = self.left.definition()).scope === compressor.find_parent(AST_Lambda)) {
- var level = 0, node, parent = self;
- do {
- node = parent;
- parent = compressor.parent(level++);
- if (parent instanceof AST_Exit) {
- if (in_try(level, parent)) break;
- if (is_reachable(def.scope, [ def ])) break;
- if (self.operator == "=") return self.right;
- def.fixed = false;
- return make_node(AST_Binary, self, {
- operator: self.operator.slice(0, -1),
- left: self.left,
- right: self.right
- }).optimize(compressor);
- }
- } while (parent instanceof AST_Binary && parent.right === node
- || parent instanceof AST_Sequence && parent.tail_node() === node);
- }
- self = self.lift_sequences(compressor);
- if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary) {
- // x = expr1 OP expr2
- if (self.right.left instanceof AST_SymbolRef
- && self.right.left.name == self.left.name
- && ASSIGN_OPS.has(self.right.operator)) {
- // x = x - 2 ---> x -= 2
- self.operator = self.right.operator + "=";
- self.right = self.right.right;
- } else if (self.right.right instanceof AST_SymbolRef
- && self.right.right.name == self.left.name
- && ASSIGN_OPS_COMMUTATIVE.has(self.right.operator)
- && !self.right.left.has_side_effects(compressor)) {
- // x = 2 & x ---> x &= 2
- self.operator = self.right.operator + "=";
- self.right = self.right.left;
- }
- }
- return self;
- function in_try(level, node) {
- function may_assignment_throw() {
- const right = self.right;
- self.right = make_node(AST_Null, right);
- const may_throw = node.may_throw(compressor);
- self.right = right;
- return may_throw;
- }
- var stop_at = self.left.definition().scope.get_defun_scope();
- var parent;
- while ((parent = compressor.parent(level++)) !== stop_at) {
- if (parent instanceof AST_Try) {
- if (parent.bfinally) return true;
- if (parent.bcatch && may_assignment_throw()) return true;
- }
- }
- }
- });
- def_optimize(AST_DefaultAssign, function(self, compressor) {
- if (!compressor.option("evaluate")) {
- return self;
- }
- var evaluateRight = self.right.evaluate(compressor);
- // `[x = undefined] = foo` ---> `[x] = foo`
- // `(arg = undefined) => ...` ---> `(arg) => ...` (unless `keep_fargs`)
- // `((arg = undefined) => ...)()` ---> `((arg) => ...)()`
- let lambda, iife;
- if (evaluateRight === undefined) {
- if (
- (lambda = compressor.parent()) instanceof AST_Lambda
- ? (
- compressor.option("keep_fargs") === false
- || (iife = compressor.parent(1)).TYPE === "Call"
- && iife.expression === lambda
- )
- : true
- ) {
- self = self.left;
- }
- } else if (evaluateRight !== self.right) {
- evaluateRight = make_node_from_constant(evaluateRight, self.right);
- self.right = best_of_expression(evaluateRight, self.right);
- }
- return self;
- });
- function is_nullish_check(check, check_subject, compressor) {
- if (check_subject.may_throw(compressor)) return false;
- let nullish_side;
- // foo == null
- if (
- check instanceof AST_Binary
- && check.operator === "=="
- // which side is nullish?
- && (
- (nullish_side = is_nullish(check.left, compressor) && check.left)
- || (nullish_side = is_nullish(check.right, compressor) && check.right)
- )
- // is the other side the same as the check_subject
- && (
- nullish_side === check.left
- ? check.right
- : check.left
- ).equivalent_to(check_subject)
- ) {
- return true;
- }
- // foo === null || foo === undefined
- if (check instanceof AST_Binary && check.operator === "||") {
- let null_cmp;
- let undefined_cmp;
- const find_comparison = cmp => {
- if (!(
- cmp instanceof AST_Binary
- && (cmp.operator === "===" || cmp.operator === "==")
- )) {
- return false;
- }
- let found = 0;
- let defined_side;
- if (cmp.left instanceof AST_Null) {
- found++;
- null_cmp = cmp;
- defined_side = cmp.right;
- }
- if (cmp.right instanceof AST_Null) {
- found++;
- null_cmp = cmp;
- defined_side = cmp.left;
- }
- if (is_undefined(cmp.left, compressor)) {
- found++;
- undefined_cmp = cmp;
- defined_side = cmp.right;
- }
- if (is_undefined(cmp.right, compressor)) {
- found++;
- undefined_cmp = cmp;
- defined_side = cmp.left;
- }
- if (found !== 1) {
- return false;
- }
- if (!defined_side.equivalent_to(check_subject)) {
- return false;
- }
- return true;
- };
- if (!find_comparison(check.left)) return false;
- if (!find_comparison(check.right)) return false;
- if (null_cmp && undefined_cmp && null_cmp !== undefined_cmp) {
- return true;
- }
- }
- return false;
- }
- def_optimize(AST_Conditional, function(self, compressor) {
- if (!compressor.option("conditionals")) return self;
- // This looks like lift_sequences(), should probably be under "sequences"
- if (self.condition instanceof AST_Sequence) {
- var expressions = self.condition.expressions.slice();
- self.condition = expressions.pop();
- expressions.push(self);
- return make_sequence(self, expressions);
- }
- var cond = self.condition.evaluate(compressor);
- if (cond !== self.condition) {
- if (cond) {
- return maintain_this_binding(compressor.parent(), compressor.self(), self.consequent);
- } else {
- return maintain_this_binding(compressor.parent(), compressor.self(), self.alternative);
- }
- }
- var negated = cond.negate(compressor, first_in_statement(compressor));
- if (best_of(compressor, cond, negated) === negated) {
- self = make_node(AST_Conditional, self, {
- condition: negated,
- consequent: self.alternative,
- alternative: self.consequent
- });
- }
- var condition = self.condition;
- var consequent = self.consequent;
- var alternative = self.alternative;
- // x?x:y --> x||y
- if (condition instanceof AST_SymbolRef
- && consequent instanceof AST_SymbolRef
- && condition.definition() === consequent.definition()) {
- return make_node(AST_Binary, self, {
- operator: "||",
- left: condition,
- right: alternative
- });
- }
- // if (foo) exp = something; else exp = something_else;
- // |
- // v
- // exp = foo ? something : something_else;
- if (
- consequent instanceof AST_Assign
- && alternative instanceof AST_Assign
- && consequent.operator === alternative.operator
- && consequent.logical === alternative.logical
- && consequent.left.equivalent_to(alternative.left)
- && (!self.condition.has_side_effects(compressor)
- || consequent.operator == "="
- && !consequent.left.has_side_effects(compressor))
- ) {
- return make_node(AST_Assign, self, {
- operator: consequent.operator,
- left: consequent.left,
- logical: consequent.logical,
- right: make_node(AST_Conditional, self, {
- condition: self.condition,
- consequent: consequent.right,
- alternative: alternative.right
- })
- });
- }
- // x ? y(a) : y(b) --> y(x ? a : b)
- var arg_index;
- if (consequent instanceof AST_Call
- && alternative.TYPE === consequent.TYPE
- && consequent.args.length > 0
- && consequent.args.length == alternative.args.length
- && consequent.expression.equivalent_to(alternative.expression)
- && !self.condition.has_side_effects(compressor)
- && !consequent.expression.has_side_effects(compressor)
- && typeof (arg_index = single_arg_diff()) == "number") {
- var node = consequent.clone();
- node.args[arg_index] = make_node(AST_Conditional, self, {
- condition: self.condition,
- consequent: consequent.args[arg_index],
- alternative: alternative.args[arg_index]
- });
- return node;
- }
- // a ? b : c ? b : d --> (a || c) ? b : d
- if (alternative instanceof AST_Conditional
- && consequent.equivalent_to(alternative.consequent)) {
- return make_node(AST_Conditional, self, {
- condition: make_node(AST_Binary, self, {
- operator: "||",
- left: condition,
- right: alternative.condition
- }),
- consequent: consequent,
- alternative: alternative.alternative
- }).optimize(compressor);
- }
- // a == null ? b : a -> a ?? b
- if (
- compressor.option("ecma") >= 2020 &&
- is_nullish_check(condition, alternative, compressor)
- ) {
- return make_node(AST_Binary, self, {
- operator: "??",
- left: alternative,
- right: consequent
- }).optimize(compressor);
- }
- // a ? b : (c, b) --> (a || c), b
- if (alternative instanceof AST_Sequence
- && consequent.equivalent_to(alternative.expressions[alternative.expressions.length - 1])) {
- return make_sequence(self, [
- make_node(AST_Binary, self, {
- operator: "||",
- left: condition,
- right: make_sequence(self, alternative.expressions.slice(0, -1))
- }),
- consequent
- ]).optimize(compressor);
- }
- // a ? b : (c && b) --> (a || c) && b
- if (alternative instanceof AST_Binary
- && alternative.operator == "&&"
- && consequent.equivalent_to(alternative.right)) {
- return make_node(AST_Binary, self, {
- operator: "&&",
- left: make_node(AST_Binary, self, {
- operator: "||",
- left: condition,
- right: alternative.left
- }),
- right: consequent
- }).optimize(compressor);
- }
- // x?y?z:a:a --> x&&y?z:a
- if (consequent instanceof AST_Conditional
- && consequent.alternative.equivalent_to(alternative)) {
- return make_node(AST_Conditional, self, {
- condition: make_node(AST_Binary, self, {
- left: self.condition,
- operator: "&&",
- right: consequent.condition
- }),
- consequent: consequent.consequent,
- alternative: alternative
- });
- }
- // x ? y : y --> x, y
- if (consequent.equivalent_to(alternative)) {
- return make_sequence(self, [
- self.condition,
- consequent
- ]).optimize(compressor);
- }
- // x ? y || z : z --> x && y || z
- if (consequent instanceof AST_Binary
- && consequent.operator == "||"
- && consequent.right.equivalent_to(alternative)) {
- return make_node(AST_Binary, self, {
- operator: "||",
- left: make_node(AST_Binary, self, {
- operator: "&&",
- left: self.condition,
- right: consequent.left
- }),
- right: alternative
- }).optimize(compressor);
- }
- const in_bool = compressor.in_boolean_context();
- if (is_true(self.consequent)) {
- if (is_false(self.alternative)) {
- // c ? true : false ---> !!c
- return booleanize(self.condition);
- }
- // c ? true : x ---> !!c || x
- return make_node(AST_Binary, self, {
- operator: "||",
- left: booleanize(self.condition),
- right: self.alternative
- });
- }
- if (is_false(self.consequent)) {
- if (is_true(self.alternative)) {
- // c ? false : true ---> !c
- return booleanize(self.condition.negate(compressor));
- }
- // c ? false : x ---> !c && x
- return make_node(AST_Binary, self, {
- operator: "&&",
- left: booleanize(self.condition.negate(compressor)),
- right: self.alternative
- });
- }
- if (is_true(self.alternative)) {
- // c ? x : true ---> !c || x
- return make_node(AST_Binary, self, {
- operator: "||",
- left: booleanize(self.condition.negate(compressor)),
- right: self.consequent
- });
- }
- if (is_false(self.alternative)) {
- // c ? x : false ---> !!c && x
- return make_node(AST_Binary, self, {
- operator: "&&",
- left: booleanize(self.condition),
- right: self.consequent
- });
- }
- return self;
- function booleanize(node) {
- if (node.is_boolean()) return node;
- // !!expression
- return make_node(AST_UnaryPrefix, node, {
- operator: "!",
- expression: node.negate(compressor)
- });
- }
- // AST_True or !0
- function is_true(node) {
- return node instanceof AST_True
- || in_bool
- && node instanceof AST_Constant
- && node.getValue()
- || (node instanceof AST_UnaryPrefix
- && node.operator == "!"
- && node.expression instanceof AST_Constant
- && !node.expression.getValue());
- }
- // AST_False or !1
- function is_false(node) {
- return node instanceof AST_False
- || in_bool
- && node instanceof AST_Constant
- && !node.getValue()
- || (node instanceof AST_UnaryPrefix
- && node.operator == "!"
- && node.expression instanceof AST_Constant
- && node.expression.getValue());
- }
- function single_arg_diff() {
- var a = consequent.args;
- var b = alternative.args;
- for (var i = 0, len = a.length; i < len; i++) {
- if (a[i] instanceof AST_Expansion) return;
- if (!a[i].equivalent_to(b[i])) {
- if (b[i] instanceof AST_Expansion) return;
- for (var j = i + 1; j < len; j++) {
- if (a[j] instanceof AST_Expansion) return;
- if (!a[j].equivalent_to(b[j])) return;
- }
- return i;
- }
- }
- }
- });
- def_optimize(AST_Boolean, function(self, compressor) {
- if (compressor.in_boolean_context()) return make_node(AST_Number, self, {
- value: +self.value
- });
- var p = compressor.parent();
- if (compressor.option("booleans_as_integers")) {
- if (p instanceof AST_Binary && (p.operator == "===" || p.operator == "!==")) {
- p.operator = p.operator.replace(/=$/, "");
- }
- return make_node(AST_Number, self, {
- value: +self.value
- });
- }
- if (compressor.option("booleans")) {
- if (p instanceof AST_Binary && (p.operator == "=="
- || p.operator == "!=")) {
- return make_node(AST_Number, self, {
- value: +self.value
- });
- }
- return make_node(AST_UnaryPrefix, self, {
- operator: "!",
- expression: make_node(AST_Number, self, {
- value: 1 - self.value
- })
- });
- }
- return self;
- });
- function safe_to_flatten(value, compressor) {
- if (value instanceof AST_SymbolRef) {
- value = value.fixed_value();
- }
- if (!value) return false;
- if (!(value instanceof AST_Lambda || value instanceof AST_Class)) return true;
- if (!(value instanceof AST_Lambda && value.contains_this())) return true;
- return compressor.parent() instanceof AST_New;
- }
- AST_PropAccess.DEFMETHOD("flatten_object", function(key, compressor) {
- if (!compressor.option("properties")) return;
- if (key === "__proto__") return;
- if (this instanceof AST_DotHash) return;
- var arrows = compressor.option("unsafe_arrows") && compressor.option("ecma") >= 2015;
- var expr = this.expression;
- if (expr instanceof AST_Object) {
- var props = expr.properties;
- for (var i = props.length; --i >= 0;) {
- var prop = props[i];
- if ("" + (prop instanceof AST_ConciseMethod ? prop.key.name : prop.key) == key) {
- const all_props_flattenable = props.every((p) =>
- (p instanceof AST_ObjectKeyVal
- || arrows && p instanceof AST_ConciseMethod && !p.value.is_generator
- )
- && !p.computed_key()
- );
- if (!all_props_flattenable) return;
- if (!safe_to_flatten(prop.value, compressor)) return;
- return make_node(AST_Sub, this, {
- expression: make_node(AST_Array, expr, {
- elements: props.map(function(prop) {
- var v = prop.value;
- if (v instanceof AST_Accessor) {
- v = make_node(AST_Function, v, v);
- }
- var k = prop.key;
- if (k instanceof AST_Node && !(k instanceof AST_SymbolMethod)) {
- return make_sequence(prop, [ k, v ]);
- }
- return v;
- })
- }),
- property: make_node(AST_Number, this, {
- value: i
- })
- });
- }
- }
- }
- });
- def_optimize(AST_Sub, function(self, compressor) {
- var expr = self.expression;
- var prop = self.property;
- if (compressor.option("properties")) {
- var key = prop.evaluate(compressor);
- if (key !== prop) {
- if (typeof key == "string") {
- if (key == "undefined") {
- key = undefined;
- } else {
- var value = parseFloat(key);
- if (value.toString() == key) {
- key = value;
- }
- }
- }
- prop = self.property = best_of_expression(
- prop,
- make_node_from_constant(key, prop).transform(compressor)
- );
- var property = "" + key;
- if (is_basic_identifier_string(property)
- && property.length <= prop.size() + 1) {
- return make_node(AST_Dot, self, {
- expression: expr,
- optional: self.optional,
- property: property,
- quote: prop.quote,
- }).optimize(compressor);
- }
- }
- }
- var fn;
- OPT_ARGUMENTS: if (compressor.option("arguments")
- && expr instanceof AST_SymbolRef
- && expr.name == "arguments"
- && expr.definition().orig.length == 1
- && (fn = expr.scope) instanceof AST_Lambda
- && fn.uses_arguments
- && !(fn instanceof AST_Arrow)
- && prop instanceof AST_Number) {
- var index = prop.getValue();
- var params = new Set();
- var argnames = fn.argnames;
- for (var n = 0; n < argnames.length; n++) {
- if (!(argnames[n] instanceof AST_SymbolFunarg)) {
- break OPT_ARGUMENTS; // destructuring parameter - bail
- }
- var param = argnames[n].name;
- if (params.has(param)) {
- break OPT_ARGUMENTS; // duplicate parameter - bail
- }
- params.add(param);
- }
- var argname = fn.argnames[index];
- if (argname && compressor.has_directive("use strict")) {
- var def = argname.definition();
- if (!compressor.option("reduce_vars") || def.assignments || def.orig.length > 1) {
- argname = null;
- }
- } else if (!argname && !compressor.option("keep_fargs") && index < fn.argnames.length + 5) {
- while (index >= fn.argnames.length) {
- argname = fn.create_symbol(AST_SymbolFunarg, {
- source: fn,
- scope: fn,
- tentative_name: "argument_" + fn.argnames.length,
- });
- fn.argnames.push(argname);
- }
- }
- if (argname) {
- var sym = make_node(AST_SymbolRef, self, argname);
- sym.reference({});
- clear_flag(argname, UNUSED);
- return sym;
- }
- }
- if (compressor.is_lhs()) return self;
- if (key !== prop) {
- var sub = self.flatten_object(property, compressor);
- if (sub) {
- expr = self.expression = sub.expression;
- prop = self.property = sub.property;
- }
- }
- if (compressor.option("properties") && compressor.option("side_effects")
- && prop instanceof AST_Number && expr instanceof AST_Array) {
- var index = prop.getValue();
- var elements = expr.elements;
- var retValue = elements[index];
- FLATTEN: if (safe_to_flatten(retValue, compressor)) {
- var flatten = true;
- var values = [];
- for (var i = elements.length; --i > index;) {
- var value = elements[i].drop_side_effect_free(compressor);
- if (value) {
- values.unshift(value);
- if (flatten && value.has_side_effects(compressor)) flatten = false;
- }
- }
- if (retValue instanceof AST_Expansion) break FLATTEN;
- retValue = retValue instanceof AST_Hole ? make_void_0(retValue) : retValue;
- if (!flatten) values.unshift(retValue);
- while (--i >= 0) {
- var value = elements[i];
- if (value instanceof AST_Expansion) break FLATTEN;
- value = value.drop_side_effect_free(compressor);
- if (value) values.unshift(value);
- else index--;
- }
- if (flatten) {
- values.push(retValue);
- return make_sequence(self, values).optimize(compressor);
- } else return make_node(AST_Sub, self, {
- expression: make_node(AST_Array, expr, {
- elements: values
- }),
- property: make_node(AST_Number, prop, {
- value: index
- })
- });
- }
- }
- var ev = self.evaluate(compressor);
- if (ev !== self) {
- ev = make_node_from_constant(ev, self).optimize(compressor);
- return best_of(compressor, ev, self);
- }
- return self;
- });
- def_optimize(AST_Chain, function (self, compressor) {
- if (is_nullish(self.expression, compressor)) {
- let parent = compressor.parent();
- // It's valid to delete a nullish optional chain, but if we optimized
- // this to `delete undefined` then it would appear to be a syntax error
- // when we try to optimize the delete. Thankfully, `delete 0` is fine.
- if (parent instanceof AST_UnaryPrefix && parent.operator === "delete") {
- return make_node_from_constant(0, self);
- }
- return make_void_0(self).optimize(compressor);
- }
- if (
- self.expression instanceof AST_PropAccess
- || self.expression instanceof AST_Call
- ) {
- return self;
- } else {
- // Keep the AST valid, in case the child swapped itself
- return self.expression;
- }
- });
- def_optimize(AST_Dot, function(self, compressor) {
- const parent = compressor.parent();
- if (compressor.is_lhs()) return self;
- if (compressor.option("unsafe_proto")
- && self.expression instanceof AST_Dot
- && self.expression.property == "prototype") {
- var exp = self.expression.expression;
- if (is_undeclared_ref(exp)) switch (exp.name) {
- case "Array":
- self.expression = make_node(AST_Array, self.expression, {
- elements: []
- });
- break;
- case "Function":
- self.expression = make_empty_function(self.expression);
- break;
- case "Number":
- self.expression = make_node(AST_Number, self.expression, {
- value: 0
- });
- break;
- case "Object":
- self.expression = make_node(AST_Object, self.expression, {
- properties: []
- });
- break;
- case "RegExp":
- self.expression = make_node(AST_RegExp, self.expression, {
- value: { source: "t", flags: "" }
- });
- break;
- case "String":
- self.expression = make_node(AST_String, self.expression, {
- value: ""
- });
- break;
- }
- }
- if (!(parent instanceof AST_Call) || !has_annotation(parent, _NOINLINE)) {
- const sub = self.flatten_object(self.property, compressor);
- if (sub) return sub.optimize(compressor);
- }
- if (self.expression instanceof AST_PropAccess
- && parent instanceof AST_PropAccess) {
- return self;
- }
- let ev = self.evaluate(compressor);
- if (ev !== self) {
- ev = make_node_from_constant(ev, self).optimize(compressor);
- return best_of(compressor, ev, self);
- }
- return self;
- });
- function literals_in_boolean_context(self, compressor) {
- if (compressor.in_boolean_context()) {
- return best_of(compressor, self, make_sequence(self, [
- self,
- make_node(AST_True, self)
- ]).optimize(compressor));
- }
- return self;
- }
- function inline_array_like_spread(elements) {
- for (var i = 0; i < elements.length; i++) {
- var el = elements[i];
- if (el instanceof AST_Expansion) {
- var expr = el.expression;
- if (
- expr instanceof AST_Array
- && !expr.elements.some(elm => elm instanceof AST_Hole)
- ) {
- elements.splice(i, 1, ...expr.elements);
- // Step back one, as the element at i is now new.
- i--;
- }
- // In array-like spread, spreading a non-iterable value is TypeError.
- // We therefore can’t optimize anything else, unlike with object spread.
- }
- }
- }
- def_optimize(AST_Array, function(self, compressor) {
- var optimized = literals_in_boolean_context(self, compressor);
- if (optimized !== self) {
- return optimized;
- }
- inline_array_like_spread(self.elements);
- return self;
- });
- function inline_object_prop_spread(props) {
- for (var i = 0; i < props.length; i++) {
- var prop = props[i];
- if (prop instanceof AST_Expansion) {
- const expr = prop.expression;
- if (
- expr instanceof AST_Object
- && expr.properties.every(prop => prop instanceof AST_ObjectKeyVal)
- ) {
- props.splice(i, 1, ...expr.properties);
- // Step back one, as the property at i is now new.
- i--;
- } else if ((
- // `expr.is_constant()` returns `false` for `AST_RegExp`, so need both.
- expr instanceof AST_Constant
- || expr.is_constant()
- ) && !(expr instanceof AST_String)) {
- // Unlike array-like spread, in object spread, spreading a
- // non-iterable value silently does nothing; it is thus safe
- // to remove. AST_String is the only iterable constant.
- props.splice(i, 1);
- i--;
- }
- }
- }
- }
- def_optimize(AST_Object, function(self, compressor) {
- var optimized = literals_in_boolean_context(self, compressor);
- if (optimized !== self) {
- return optimized;
- }
- inline_object_prop_spread(self.properties);
- return self;
- });
- def_optimize(AST_RegExp, literals_in_boolean_context);
- def_optimize(AST_Return, function(self, compressor) {
- if (self.value && is_undefined(self.value, compressor)) {
- self.value = null;
- }
- return self;
- });
- def_optimize(AST_Arrow, opt_AST_Lambda);
- def_optimize(AST_Function, function(self, compressor) {
- self = opt_AST_Lambda(self, compressor);
- if (compressor.option("unsafe_arrows")
- && compressor.option("ecma") >= 2015
- && !self.name
- && !self.is_generator
- && !self.uses_arguments
- && !self.pinned()) {
- const uses_this = walk(self, node => {
- if (node instanceof AST_This) return walk_abort;
- });
- if (!uses_this) return make_node(AST_Arrow, self, self).optimize(compressor);
- }
- return self;
- });
- def_optimize(AST_Class, function(self) {
- for (let i = 0; i < self.properties.length; i++) {
- const prop = self.properties[i];
- if (prop instanceof AST_ClassStaticBlock && prop.body.length == 0) {
- self.properties.splice(i, 1);
- i--;
- }
- }
- return self;
- });
- def_optimize(AST_ClassStaticBlock, function(self, compressor) {
- tighten_body(self.body, compressor);
- return self;
- });
- def_optimize(AST_Yield, function(self, compressor) {
- if (self.expression && !self.is_star && is_undefined(self.expression, compressor)) {
- self.expression = null;
- }
- return self;
- });
- def_optimize(AST_TemplateString, function(self, compressor) {
- if (
- !compressor.option("evaluate")
- || compressor.parent() instanceof AST_PrefixedTemplateString
- ) {
- return self;
- }
- var segments = [];
- for (var i = 0; i < self.segments.length; i++) {
- var segment = self.segments[i];
- if (segment instanceof AST_Node) {
- var result = segment.evaluate(compressor);
- // Evaluate to constant value
- // Constant value shorter than ${segment}
- if (result !== segment && (result + "").length <= segment.size() + "${}".length) {
- // There should always be a previous and next segment if segment is a node
- segments[segments.length - 1].value = segments[segments.length - 1].value + result + self.segments[++i].value;
- continue;
- }
- // `before ${`innerBefore ${any} innerAfter`} after` => `before innerBefore ${any} innerAfter after`
- // TODO:
- // `before ${'test' + foo} after` => `before innerBefore ${any} innerAfter after`
- // `before ${foo + 'test} after` => `before innerBefore ${any} innerAfter after`
- if (segment instanceof AST_TemplateString) {
- var inners = segment.segments;
- segments[segments.length - 1].value += inners[0].value;
- for (var j = 1; j < inners.length; j++) {
- segment = inners[j];
- segments.push(segment);
- }
- continue;
- }
- }
- segments.push(segment);
- }
- self.segments = segments;
- // `foo` => "foo"
- if (segments.length == 1) {
- return make_node(AST_String, self, segments[0]);
- }
- if (
- segments.length === 3
- && segments[1] instanceof AST_Node
- && (
- segments[1].is_string(compressor)
- || segments[1].is_number_or_bigint(compressor)
- || is_nullish(segments[1], compressor)
- || compressor.option("unsafe")
- )
- ) {
- // `foo${bar}` => "foo" + bar
- if (segments[2].value === "") {
- return make_node(AST_Binary, self, {
- operator: "+",
- left: make_node(AST_String, self, {
- value: segments[0].value,
- }),
- right: segments[1],
- });
- }
- // `${bar}baz` => bar + "baz"
- if (segments[0].value === "") {
- return make_node(AST_Binary, self, {
- operator: "+",
- left: segments[1],
- right: make_node(AST_String, self, {
- value: segments[2].value,
- }),
- });
- }
- }
- return self;
- });
- def_optimize(AST_PrefixedTemplateString, function(self) {
- return self;
- });
- // ["p"]:1 ---> p:1
- // [42]:1 ---> 42:1
- function lift_key(self, compressor) {
- if (!compressor.option("computed_props")) return self;
- // save a comparison in the typical case
- if (!(self.key instanceof AST_Constant)) return self;
- // allow certain acceptable props as not all AST_Constants are true constants
- if (self.key instanceof AST_String || self.key instanceof AST_Number) {
- const key = self.key.value.toString();
- if (key === "__proto__") return self;
- if (key == "constructor"
- && compressor.parent() instanceof AST_Class) return self;
- if (self instanceof AST_ObjectKeyVal) {
- self.quote = self.key.quote;
- self.key = key;
- } else if (self instanceof AST_ClassProperty) {
- self.quote = self.key.quote;
- self.key = make_node(AST_SymbolClassProperty, self.key, {
- name: key,
- });
- } else {
- self.quote = self.key.quote;
- self.key = make_node(AST_SymbolMethod, self.key, {
- name: key,
- });
- }
- }
- return self;
- }
- def_optimize(AST_ObjectProperty, lift_key);
- def_optimize(AST_ConciseMethod, function(self, compressor) {
- lift_key(self, compressor);
- // p(){return x;} ---> p:()=>x
- if (compressor.option("arrows")
- && compressor.parent() instanceof AST_Object
- && !self.value.is_generator
- && !self.value.uses_arguments
- && !self.value.pinned()
- && self.value.body.length == 1
- && self.value.body[0] instanceof AST_Return
- && self.value.body[0].value
- && !self.value.contains_this()) {
- var arrow = make_node(AST_Arrow, self.value, self.value);
- arrow.async = self.value.async;
- arrow.is_generator = self.value.is_generator;
- return make_node(AST_ObjectKeyVal, self, {
- key: self.key instanceof AST_SymbolMethod ? self.key.name : self.key,
- value: arrow,
- quote: self.quote,
- });
- }
- return self;
- });
- def_optimize(AST_ObjectKeyVal, function(self, compressor) {
- lift_key(self, compressor);
- // p:function(){} ---> p(){}
- // p:function*(){} ---> *p(){}
- // p:async function(){} ---> async p(){}
- // p:()=>{} ---> p(){}
- // p:async()=>{} ---> async p(){}
- var unsafe_methods = compressor.option("unsafe_methods");
- if (unsafe_methods
- && compressor.option("ecma") >= 2015
- && (!(unsafe_methods instanceof RegExp) || unsafe_methods.test(self.key + ""))) {
- var key = self.key;
- var value = self.value;
- var is_arrow_with_block = value instanceof AST_Arrow
- && Array.isArray(value.body)
- && !value.contains_this();
- if ((is_arrow_with_block || value instanceof AST_Function) && !value.name) {
- return make_node(AST_ConciseMethod, self, {
- key: key instanceof AST_Node ? key : make_node(AST_SymbolMethod, self, {
- name: key,
- }),
- value: make_node(AST_Accessor, value, value),
- quote: self.quote,
- });
- }
- }
- return self;
- });
- def_optimize(AST_Destructuring, function(self, compressor) {
- if (compressor.option("pure_getters") == true
- && compressor.option("unused")
- && !self.is_array
- && Array.isArray(self.names)
- && !is_destructuring_export_decl(compressor)
- && !(self.names[self.names.length - 1] instanceof AST_Expansion)) {
- var keep = [];
- for (var i = 0; i < self.names.length; i++) {
- var elem = self.names[i];
- if (!(elem instanceof AST_ObjectKeyVal
- && typeof elem.key == "string"
- && elem.value instanceof AST_SymbolDeclaration
- && !should_retain(compressor, elem.value.definition()))) {
- keep.push(elem);
- }
- }
- if (keep.length != self.names.length) {
- self.names = keep;
- }
- }
- return self;
- function is_destructuring_export_decl(compressor) {
- var ancestors = [/^VarDef$/, /^(Const|Let|Var)$/, /^Export$/];
- for (var a = 0, p = 0, len = ancestors.length; a < len; p++) {
- var parent = compressor.parent(p);
- if (!parent) return false;
- if (a === 0 && parent.TYPE == "Destructuring") continue;
- if (!ancestors[a].test(parent.TYPE)) {
- return false;
- }
- a++;
- }
- return true;
- }
- function should_retain(compressor, def) {
- if (def.references.length) return true;
- if (!def.global) return false;
- if (compressor.toplevel.vars) {
- if (compressor.top_retain) {
- return compressor.top_retain(def);
- }
- return false;
- }
- return true;
- }
- });
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- // a small wrapper around source-map and @jridgewell/source-map
- function* SourceMap(options) {
- options = defaults(options, {
- file : null,
- root : null,
- orig : null,
- files: {},
- });
- var orig_map;
- var generator = new sourceMap.SourceMapGenerator({
- file : options.file,
- sourceRoot : options.root
- });
- let sourcesContent = {__proto__: null};
- let files = options.files;
- for (var name in files) if (HOP(files, name)) {
- sourcesContent[name] = files[name];
- }
- if (options.orig) {
- // We support both @jridgewell/source-map (which has a sync
- // SourceMapConsumer) and source-map (which has an async
- // SourceMapConsumer).
- orig_map = yield new sourceMap.SourceMapConsumer(options.orig);
- if (orig_map.sourcesContent) {
- orig_map.sources.forEach(function(source, i) {
- var content = orig_map.sourcesContent[i];
- if (content) {
- sourcesContent[source] = content;
- }
- });
- }
- }
- function add(source, gen_line, gen_col, orig_line, orig_col, name) {
- let generatedPos = { line: gen_line, column: gen_col };
- if (orig_map) {
- var info = orig_map.originalPositionFor({
- line: orig_line,
- column: orig_col
- });
- if (info.source === null) {
- generator.addMapping({
- generated: generatedPos,
- original: null,
- source: null,
- name: null
- });
- return;
- }
- source = info.source;
- orig_line = info.line;
- orig_col = info.column;
- name = info.name || name;
- }
- generator.addMapping({
- generated : generatedPos,
- original : { line: orig_line, column: orig_col },
- source : source,
- name : name
- });
- generator.setSourceContent(source, sourcesContent[source]);
- }
- function clean(map) {
- const allNull = map.sourcesContent && map.sourcesContent.every(c => c == null);
- if (allNull) delete map.sourcesContent;
- if (map.file === undefined) delete map.file;
- if (map.sourceRoot === undefined) delete map.sourceRoot;
- return map;
- }
- function getDecoded() {
- if (!generator.toDecodedMap) return null;
- return clean(generator.toDecodedMap());
- }
- function getEncoded() {
- return clean(generator.toJSON());
- }
- function destroy() {
- // @jridgewell/source-map's SourceMapConsumer does not need to be
- // manually freed.
- if (orig_map && orig_map.destroy) orig_map.destroy();
- }
- return {
- add,
- getDecoded,
- getEncoded,
- destroy,
- };
- }
- var domprops = [
- "$&",
- "$'",
- "$*",
- "$+",
- "$1",
- "$2",
- "$3",
- "$4",
- "$5",
- "$6",
- "$7",
- "$8",
- "$9",
- "$_",
- "$`",
- "$input",
- "-moz-animation",
- "-moz-animation-delay",
- "-moz-animation-direction",
- "-moz-animation-duration",
- "-moz-animation-fill-mode",
- "-moz-animation-iteration-count",
- "-moz-animation-name",
- "-moz-animation-play-state",
- "-moz-animation-timing-function",
- "-moz-appearance",
- "-moz-backface-visibility",
- "-moz-border-end",
- "-moz-border-end-color",
- "-moz-border-end-style",
- "-moz-border-end-width",
- "-moz-border-image",
- "-moz-border-start",
- "-moz-border-start-color",
- "-moz-border-start-style",
- "-moz-border-start-width",
- "-moz-box-align",
- "-moz-box-direction",
- "-moz-box-flex",
- "-moz-box-ordinal-group",
- "-moz-box-orient",
- "-moz-box-pack",
- "-moz-box-sizing",
- "-moz-float-edge",
- "-moz-font-feature-settings",
- "-moz-font-language-override",
- "-moz-force-broken-image-icon",
- "-moz-hyphens",
- "-moz-image-region",
- "-moz-margin-end",
- "-moz-margin-start",
- "-moz-orient",
- "-moz-osx-font-smoothing",
- "-moz-outline-radius",
- "-moz-outline-radius-bottomleft",
- "-moz-outline-radius-bottomright",
- "-moz-outline-radius-topleft",
- "-moz-outline-radius-topright",
- "-moz-padding-end",
- "-moz-padding-start",
- "-moz-perspective",
- "-moz-perspective-origin",
- "-moz-tab-size",
- "-moz-text-size-adjust",
- "-moz-transform",
- "-moz-transform-origin",
- "-moz-transform-style",
- "-moz-transition",
- "-moz-transition-delay",
- "-moz-transition-duration",
- "-moz-transition-property",
- "-moz-transition-timing-function",
- "-moz-user-focus",
- "-moz-user-input",
- "-moz-user-modify",
- "-moz-user-select",
- "-moz-window-dragging",
- "-webkit-align-content",
- "-webkit-align-items",
- "-webkit-align-self",
- "-webkit-animation",
- "-webkit-animation-delay",
- "-webkit-animation-direction",
- "-webkit-animation-duration",
- "-webkit-animation-fill-mode",
- "-webkit-animation-iteration-count",
- "-webkit-animation-name",
- "-webkit-animation-play-state",
- "-webkit-animation-timing-function",
- "-webkit-appearance",
- "-webkit-backface-visibility",
- "-webkit-background-clip",
- "-webkit-background-origin",
- "-webkit-background-size",
- "-webkit-border-bottom-left-radius",
- "-webkit-border-bottom-right-radius",
- "-webkit-border-image",
- "-webkit-border-radius",
- "-webkit-border-top-left-radius",
- "-webkit-border-top-right-radius",
- "-webkit-box-align",
- "-webkit-box-direction",
- "-webkit-box-flex",
- "-webkit-box-ordinal-group",
- "-webkit-box-orient",
- "-webkit-box-pack",
- "-webkit-box-shadow",
- "-webkit-box-sizing",
- "-webkit-clip-path",
- "-webkit-filter",
- "-webkit-flex",
- "-webkit-flex-basis",
- "-webkit-flex-direction",
- "-webkit-flex-flow",
- "-webkit-flex-grow",
- "-webkit-flex-shrink",
- "-webkit-flex-wrap",
- "-webkit-font-feature-settings",
- "-webkit-justify-content",
- "-webkit-line-clamp",
- "-webkit-mask",
- "-webkit-mask-clip",
- "-webkit-mask-composite",
- "-webkit-mask-image",
- "-webkit-mask-origin",
- "-webkit-mask-position",
- "-webkit-mask-position-x",
- "-webkit-mask-position-y",
- "-webkit-mask-repeat",
- "-webkit-mask-size",
- "-webkit-order",
- "-webkit-perspective",
- "-webkit-perspective-origin",
- "-webkit-text-fill-color",
- "-webkit-text-security",
- "-webkit-text-size-adjust",
- "-webkit-text-stroke",
- "-webkit-text-stroke-color",
- "-webkit-text-stroke-width",
- "-webkit-transform",
- "-webkit-transform-origin",
- "-webkit-transform-style",
- "-webkit-transition",
- "-webkit-transition-delay",
- "-webkit-transition-duration",
- "-webkit-transition-property",
- "-webkit-transition-timing-function",
- "-webkit-user-select",
- "@@iterator",
- "ABORT_ERR",
- "ACTIVE",
- "ACTIVE_ATTRIBUTES",
- "ACTIVE_TEXTURE",
- "ACTIVE_UNIFORMS",
- "ACTIVE_UNIFORM_BLOCKS",
- "ADDITION",
- "ALIASED_LINE_WIDTH_RANGE",
- "ALIASED_POINT_SIZE_RANGE",
- "ALL",
- "ALLOW_KEYBOARD_INPUT",
- "ALLPASS",
- "ALPHA",
- "ALPHA_BITS",
- "ALREADY_SIGNALED",
- "ALT_MASK",
- "ALWAYS",
- "ANY_SAMPLES_PASSED",
- "ANY_SAMPLES_PASSED_CONSERVATIVE",
- "ANY_TYPE",
- "ANY_UNORDERED_NODE_TYPE",
- "ARRAY_BUFFER",
- "ARRAY_BUFFER_BINDING",
- "ATTACHED_SHADERS",
- "ATTRIBUTE_NODE",
- "AT_TARGET",
- "AbortController",
- "AbortSignal",
- "AbsoluteOrientationSensor",
- "AbstractRange",
- "Accelerometer",
- "AddSearchProvider",
- "AggregateError",
- "AnalyserNode",
- "Animation",
- "AnimationEffect",
- "AnimationEvent",
- "AnimationPlaybackEvent",
- "AnimationTimeline",
- "AnonXMLHttpRequest",
- "Any",
- "AnyPermissions",
- "ApplicationCache",
- "ApplicationCacheErrorEvent",
- "Array",
- "ArrayBuffer",
- "ArrayType",
- "AsyncDisposableStack",
- "Atomics",
- "Attr",
- "Audio",
- "AudioBuffer",
- "AudioBufferSourceNode",
- "AudioContext",
- "AudioData",
- "AudioDecoder",
- "AudioDestinationNode",
- "AudioEncoder",
- "AudioListener",
- "AudioNode",
- "AudioParam",
- "AudioParamMap",
- "AudioProcessingEvent",
- "AudioScheduledSourceNode",
- "AudioSinkInfo",
- "AudioStreamTrack",
- "AudioWorklet",
- "AudioWorkletNode",
- "AuthenticatorAssertionResponse",
- "AuthenticatorAttestationResponse",
- "AuthenticatorResponse",
- "AutocompleteErrorEvent",
- "BACK",
- "BAD_BOUNDARYPOINTS_ERR",
- "BAD_REQUEST",
- "BANDPASS",
- "BLEND",
- "BLEND_COLOR",
- "BLEND_DST_ALPHA",
- "BLEND_DST_RGB",
- "BLEND_EQUATION",
- "BLEND_EQUATION_ALPHA",
- "BLEND_EQUATION_RGB",
- "BLEND_SRC_ALPHA",
- "BLEND_SRC_RGB",
- "BLUE",
- "BLUE_BITS",
- "BLUR",
- "BOOL",
- "BOOLEAN_TYPE",
- "BOOL_VEC2",
- "BOOL_VEC3",
- "BOOL_VEC4",
- "BOTH",
- "BROWSER_DEFAULT_WEBGL",
- "BUBBLING_PHASE",
- "BUFFER_SIZE",
- "BUFFER_USAGE",
- "BYTE",
- "BYTES_PER_ELEMENT",
- "BackgroundFetchManager",
- "BackgroundFetchRecord",
- "BackgroundFetchRegistration",
- "BarProp",
- "BarcodeDetector",
- "BaseAudioContext",
- "BaseHref",
- "BatteryManager",
- "BeforeInstallPromptEvent",
- "BeforeLoadEvent",
- "BeforeUnloadEvent",
- "BigInt",
- "BigInt64Array",
- "BigUint64Array",
- "BiquadFilterNode",
- "Blob",
- "BlobEvent",
- "Bluetooth",
- "BluetoothCharacteristicProperties",
- "BluetoothDevice",
- "BluetoothRemoteGATTCharacteristic",
- "BluetoothRemoteGATTDescriptor",
- "BluetoothRemoteGATTServer",
- "BluetoothRemoteGATTService",
- "BluetoothUUID",
- "Boolean",
- "BroadcastChannel",
- "BrowserCaptureMediaStreamTrack",
- "BrowserInfo",
- "ByteLengthQueuingStrategy",
- "CAPTURING_PHASE",
- "CCW",
- "CDATASection",
- "CDATA_SECTION_NODE",
- "CHANGE",
- "CHARSET_RULE",
- "CHECKING",
- "CLAMP_TO_EDGE",
- "CLICK",
- "CLOSED",
- "CLOSING",
- "COLOR",
- "COLOR_ATTACHMENT0",
- "COLOR_ATTACHMENT1",
- "COLOR_ATTACHMENT10",
- "COLOR_ATTACHMENT11",
- "COLOR_ATTACHMENT12",
- "COLOR_ATTACHMENT13",
- "COLOR_ATTACHMENT14",
- "COLOR_ATTACHMENT15",
- "COLOR_ATTACHMENT2",
- "COLOR_ATTACHMENT3",
- "COLOR_ATTACHMENT4",
- "COLOR_ATTACHMENT5",
- "COLOR_ATTACHMENT6",
- "COLOR_ATTACHMENT7",
- "COLOR_ATTACHMENT8",
- "COLOR_ATTACHMENT9",
- "COLOR_BUFFER_BIT",
- "COLOR_CLEAR_VALUE",
- "COLOR_WRITEMASK",
- "COMMENT_NODE",
- "COMPARE_REF_TO_TEXTURE",
- "COMPILE_STATUS",
- "COMPLETION_STATUS_KHR",
- "COMPRESSED_RGBA_S3TC_DXT1_EXT",
- "COMPRESSED_RGBA_S3TC_DXT3_EXT",
- "COMPRESSED_RGBA_S3TC_DXT5_EXT",
- "COMPRESSED_RGB_S3TC_DXT1_EXT",
- "COMPRESSED_TEXTURE_FORMATS",
- "COMPUTE",
- "CONDITION_SATISFIED",
- "CONFIGURATION_UNSUPPORTED",
- "CONNECTING",
- "CONSTANT_ALPHA",
- "CONSTANT_COLOR",
- "CONSTRAINT_ERR",
- "CONTEXT_LOST_WEBGL",
- "CONTROL_MASK",
- "COPY_DST",
- "COPY_READ_BUFFER",
- "COPY_READ_BUFFER_BINDING",
- "COPY_SRC",
- "COPY_WRITE_BUFFER",
- "COPY_WRITE_BUFFER_BINDING",
- "COUNTER_STYLE_RULE",
- "CSPViolationReportBody",
- "CSS",
- "CSS2Properties",
- "CSSAnimation",
- "CSSCharsetRule",
- "CSSConditionRule",
- "CSSContainerRule",
- "CSSCounterStyleRule",
- "CSSFontFaceRule",
- "CSSFontFeatureValuesRule",
- "CSSFontPaletteValuesRule",
- "CSSFunctionDeclarations",
- "CSSFunctionDescriptors",
- "CSSFunctionRule",
- "CSSGroupingRule",
- "CSSImageValue",
- "CSSImportRule",
- "CSSKeyframeRule",
- "CSSKeyframesRule",
- "CSSKeywordValue",
- "CSSLayerBlockRule",
- "CSSLayerStatementRule",
- "CSSMarginRule",
- "CSSMathClamp",
- "CSSMathInvert",
- "CSSMathMax",
- "CSSMathMin",
- "CSSMathNegate",
- "CSSMathProduct",
- "CSSMathSum",
- "CSSMathValue",
- "CSSMatrixComponent",
- "CSSMediaRule",
- "CSSMozDocumentRule",
- "CSSNameSpaceRule",
- "CSSNamespaceRule",
- "CSSNestedDeclarations",
- "CSSNumericArray",
- "CSSNumericValue",
- "CSSPageDescriptors",
- "CSSPageRule",
- "CSSPerspective",
- "CSSPositionTryDescriptors",
- "CSSPositionTryRule",
- "CSSPositionValue",
- "CSSPrimitiveValue",
- "CSSPropertyRule",
- "CSSRotate",
- "CSSRule",
- "CSSRuleList",
- "CSSScale",
- "CSSScopeRule",
- "CSSSkew",
- "CSSSkewX",
- "CSSSkewY",
- "CSSStartingStyleRule",
- "CSSStyleDeclaration",
- "CSSStyleProperties",
- "CSSStyleRule",
- "CSSStyleSheet",
- "CSSStyleValue",
- "CSSSupportsRule",
- "CSSTransformComponent",
- "CSSTransformValue",
- "CSSTransition",
- "CSSTranslate",
- "CSSUnitValue",
- "CSSUnknownRule",
- "CSSUnparsedValue",
- "CSSValue",
- "CSSValueList",
- "CSSVariableReferenceValue",
- "CSSVariablesDeclaration",
- "CSSVariablesRule",
- "CSSViewTransitionRule",
- "CSSViewportRule",
- "CSS_ATTR",
- "CSS_CM",
- "CSS_COUNTER",
- "CSS_CUSTOM",
- "CSS_DEG",
- "CSS_DIMENSION",
- "CSS_EMS",
- "CSS_EXS",
- "CSS_FILTER_BLUR",
- "CSS_FILTER_BRIGHTNESS",
- "CSS_FILTER_CONTRAST",
- "CSS_FILTER_CUSTOM",
- "CSS_FILTER_DROP_SHADOW",
- "CSS_FILTER_GRAYSCALE",
- "CSS_FILTER_HUE_ROTATE",
- "CSS_FILTER_INVERT",
- "CSS_FILTER_OPACITY",
- "CSS_FILTER_REFERENCE",
- "CSS_FILTER_SATURATE",
- "CSS_FILTER_SEPIA",
- "CSS_GRAD",
- "CSS_HZ",
- "CSS_IDENT",
- "CSS_IN",
- "CSS_INHERIT",
- "CSS_KHZ",
- "CSS_MATRIX",
- "CSS_MATRIX3D",
- "CSS_MM",
- "CSS_MS",
- "CSS_NUMBER",
- "CSS_PC",
- "CSS_PERCENTAGE",
- "CSS_PERSPECTIVE",
- "CSS_PRIMITIVE_VALUE",
- "CSS_PT",
- "CSS_PX",
- "CSS_RAD",
- "CSS_RECT",
- "CSS_RGBCOLOR",
- "CSS_ROTATE",
- "CSS_ROTATE3D",
- "CSS_ROTATEX",
- "CSS_ROTATEY",
- "CSS_ROTATEZ",
- "CSS_S",
- "CSS_SCALE",
- "CSS_SCALE3D",
- "CSS_SCALEX",
- "CSS_SCALEY",
- "CSS_SCALEZ",
- "CSS_SKEW",
- "CSS_SKEWX",
- "CSS_SKEWY",
- "CSS_STRING",
- "CSS_TRANSLATE",
- "CSS_TRANSLATE3D",
- "CSS_TRANSLATEX",
- "CSS_TRANSLATEY",
- "CSS_TRANSLATEZ",
- "CSS_UNKNOWN",
- "CSS_URI",
- "CSS_VALUE_LIST",
- "CSS_VH",
- "CSS_VMAX",
- "CSS_VMIN",
- "CSS_VW",
- "CULL_FACE",
- "CULL_FACE_MODE",
- "CURRENT_PROGRAM",
- "CURRENT_QUERY",
- "CURRENT_VERTEX_ATTRIB",
- "CUSTOM",
- "CW",
- "Cache",
- "CacheStorage",
- "CanvasCaptureMediaStream",
- "CanvasCaptureMediaStreamTrack",
- "CanvasGradient",
- "CanvasPattern",
- "CanvasRenderingContext2D",
- "CaptureController",
- "CaretPosition",
- "ChannelMergerNode",
- "ChannelSplitterNode",
- "ChapterInformation",
- "CharacterBoundsUpdateEvent",
- "CharacterData",
- "ClientRect",
- "ClientRectList",
- "Clipboard",
- "ClipboardEvent",
- "ClipboardItem",
- "CloseEvent",
- "CloseWatcher",
- "Collator",
- "ColorArray",
- "ColorValue",
- "CommandEvent",
- "Comment",
- "CompileError",
- "CompositionEvent",
- "CompressionStream",
- "Console",
- "ConstantSourceNode",
- "ContentVisibilityAutoStateChangeEvent",
- "ContextFilter",
- "ContextType",
- "Controllers",
- "ConvolverNode",
- "CookieChangeEvent",
- "CookieStore",
- "CookieStoreManager",
- "CountQueuingStrategy",
- "Counter",
- "CreateMonitor",
- "CreateType",
- "Credential",
- "CredentialsContainer",
- "CropTarget",
- "Crypto",
- "CryptoKey",
- "CustomElementRegistry",
- "CustomEvent",
- "CustomStateSet",
- "DATABASE_ERR",
- "DATA_CLONE_ERR",
- "DATA_ERR",
- "DBLCLICK",
- "DECR",
- "DECR_WRAP",
- "DELETE_STATUS",
- "DEPTH",
- "DEPTH24_STENCIL8",
- "DEPTH32F_STENCIL8",
- "DEPTH_ATTACHMENT",
- "DEPTH_BITS",
- "DEPTH_BUFFER_BIT",
- "DEPTH_CLEAR_VALUE",
- "DEPTH_COMPONENT",
- "DEPTH_COMPONENT16",
- "DEPTH_COMPONENT24",
- "DEPTH_COMPONENT32F",
- "DEPTH_FUNC",
- "DEPTH_RANGE",
- "DEPTH_STENCIL",
- "DEPTH_STENCIL_ATTACHMENT",
- "DEPTH_TEST",
- "DEPTH_WRITEMASK",
- "DEVICE_INELIGIBLE",
- "DIRECTION_DOWN",
- "DIRECTION_LEFT",
- "DIRECTION_RIGHT",
- "DIRECTION_UP",
- "DISABLED",
- "DISPATCH_REQUEST_ERR",
- "DITHER",
- "DOCUMENT_FRAGMENT_NODE",
- "DOCUMENT_NODE",
- "DOCUMENT_POSITION_CONTAINED_BY",
- "DOCUMENT_POSITION_CONTAINS",
- "DOCUMENT_POSITION_DISCONNECTED",
- "DOCUMENT_POSITION_FOLLOWING",
- "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC",
- "DOCUMENT_POSITION_PRECEDING",
- "DOCUMENT_TYPE_NODE",
- "DOMCursor",
- "DOMError",
- "DOMException",
- "DOMImplementation",
- "DOMImplementationLS",
- "DOMMatrix",
- "DOMMatrixReadOnly",
- "DOMParser",
- "DOMPoint",
- "DOMPointReadOnly",
- "DOMQuad",
- "DOMRect",
- "DOMRectList",
- "DOMRectReadOnly",
- "DOMRequest",
- "DOMSTRING_SIZE_ERR",
- "DOMSettableTokenList",
- "DOMStringList",
- "DOMStringMap",
- "DOMTokenList",
- "DOMTransactionEvent",
- "DOM_DELTA_LINE",
- "DOM_DELTA_PAGE",
- "DOM_DELTA_PIXEL",
- "DOM_INPUT_METHOD_DROP",
- "DOM_INPUT_METHOD_HANDWRITING",
- "DOM_INPUT_METHOD_IME",
- "DOM_INPUT_METHOD_KEYBOARD",
- "DOM_INPUT_METHOD_MULTIMODAL",
- "DOM_INPUT_METHOD_OPTION",
- "DOM_INPUT_METHOD_PASTE",
- "DOM_INPUT_METHOD_SCRIPT",
- "DOM_INPUT_METHOD_UNKNOWN",
- "DOM_INPUT_METHOD_VOICE",
- "DOM_KEY_LOCATION_JOYSTICK",
- "DOM_KEY_LOCATION_LEFT",
- "DOM_KEY_LOCATION_MOBILE",
- "DOM_KEY_LOCATION_NUMPAD",
- "DOM_KEY_LOCATION_RIGHT",
- "DOM_KEY_LOCATION_STANDARD",
- "DOM_VK_0",
- "DOM_VK_1",
- "DOM_VK_2",
- "DOM_VK_3",
- "DOM_VK_4",
- "DOM_VK_5",
- "DOM_VK_6",
- "DOM_VK_7",
- "DOM_VK_8",
- "DOM_VK_9",
- "DOM_VK_A",
- "DOM_VK_ACCEPT",
- "DOM_VK_ADD",
- "DOM_VK_ALT",
- "DOM_VK_ALTGR",
- "DOM_VK_AMPERSAND",
- "DOM_VK_ASTERISK",
- "DOM_VK_AT",
- "DOM_VK_ATTN",
- "DOM_VK_B",
- "DOM_VK_BACKSPACE",
- "DOM_VK_BACK_QUOTE",
- "DOM_VK_BACK_SLASH",
- "DOM_VK_BACK_SPACE",
- "DOM_VK_C",
- "DOM_VK_CANCEL",
- "DOM_VK_CAPS_LOCK",
- "DOM_VK_CIRCUMFLEX",
- "DOM_VK_CLEAR",
- "DOM_VK_CLOSE_BRACKET",
- "DOM_VK_CLOSE_CURLY_BRACKET",
- "DOM_VK_CLOSE_PAREN",
- "DOM_VK_COLON",
- "DOM_VK_COMMA",
- "DOM_VK_CONTEXT_MENU",
- "DOM_VK_CONTROL",
- "DOM_VK_CONVERT",
- "DOM_VK_CRSEL",
- "DOM_VK_CTRL",
- "DOM_VK_D",
- "DOM_VK_DECIMAL",
- "DOM_VK_DELETE",
- "DOM_VK_DIVIDE",
- "DOM_VK_DOLLAR",
- "DOM_VK_DOUBLE_QUOTE",
- "DOM_VK_DOWN",
- "DOM_VK_E",
- "DOM_VK_EISU",
- "DOM_VK_END",
- "DOM_VK_ENTER",
- "DOM_VK_EQUALS",
- "DOM_VK_EREOF",
- "DOM_VK_ESCAPE",
- "DOM_VK_EXCLAMATION",
- "DOM_VK_EXECUTE",
- "DOM_VK_EXSEL",
- "DOM_VK_F",
- "DOM_VK_F1",
- "DOM_VK_F10",
- "DOM_VK_F11",
- "DOM_VK_F12",
- "DOM_VK_F13",
- "DOM_VK_F14",
- "DOM_VK_F15",
- "DOM_VK_F16",
- "DOM_VK_F17",
- "DOM_VK_F18",
- "DOM_VK_F19",
- "DOM_VK_F2",
- "DOM_VK_F20",
- "DOM_VK_F21",
- "DOM_VK_F22",
- "DOM_VK_F23",
- "DOM_VK_F24",
- "DOM_VK_F25",
- "DOM_VK_F26",
- "DOM_VK_F27",
- "DOM_VK_F28",
- "DOM_VK_F29",
- "DOM_VK_F3",
- "DOM_VK_F30",
- "DOM_VK_F31",
- "DOM_VK_F32",
- "DOM_VK_F33",
- "DOM_VK_F34",
- "DOM_VK_F35",
- "DOM_VK_F36",
- "DOM_VK_F4",
- "DOM_VK_F5",
- "DOM_VK_F6",
- "DOM_VK_F7",
- "DOM_VK_F8",
- "DOM_VK_F9",
- "DOM_VK_FINAL",
- "DOM_VK_FRONT",
- "DOM_VK_G",
- "DOM_VK_GREATER_THAN",
- "DOM_VK_H",
- "DOM_VK_HANGUL",
- "DOM_VK_HANJA",
- "DOM_VK_HASH",
- "DOM_VK_HELP",
- "DOM_VK_HK_TOGGLE",
- "DOM_VK_HOME",
- "DOM_VK_HYPHEN_MINUS",
- "DOM_VK_I",
- "DOM_VK_INSERT",
- "DOM_VK_J",
- "DOM_VK_JUNJA",
- "DOM_VK_K",
- "DOM_VK_KANA",
- "DOM_VK_KANJI",
- "DOM_VK_L",
- "DOM_VK_LEFT",
- "DOM_VK_LEFT_TAB",
- "DOM_VK_LESS_THAN",
- "DOM_VK_M",
- "DOM_VK_META",
- "DOM_VK_MODECHANGE",
- "DOM_VK_MULTIPLY",
- "DOM_VK_N",
- "DOM_VK_NONCONVERT",
- "DOM_VK_NUMPAD0",
- "DOM_VK_NUMPAD1",
- "DOM_VK_NUMPAD2",
- "DOM_VK_NUMPAD3",
- "DOM_VK_NUMPAD4",
- "DOM_VK_NUMPAD5",
- "DOM_VK_NUMPAD6",
- "DOM_VK_NUMPAD7",
- "DOM_VK_NUMPAD8",
- "DOM_VK_NUMPAD9",
- "DOM_VK_NUM_LOCK",
- "DOM_VK_O",
- "DOM_VK_OEM_1",
- "DOM_VK_OEM_102",
- "DOM_VK_OEM_2",
- "DOM_VK_OEM_3",
- "DOM_VK_OEM_4",
- "DOM_VK_OEM_5",
- "DOM_VK_OEM_6",
- "DOM_VK_OEM_7",
- "DOM_VK_OEM_8",
- "DOM_VK_OEM_COMMA",
- "DOM_VK_OEM_MINUS",
- "DOM_VK_OEM_PERIOD",
- "DOM_VK_OEM_PLUS",
- "DOM_VK_OPEN_BRACKET",
- "DOM_VK_OPEN_CURLY_BRACKET",
- "DOM_VK_OPEN_PAREN",
- "DOM_VK_P",
- "DOM_VK_PA1",
- "DOM_VK_PAGEDOWN",
- "DOM_VK_PAGEUP",
- "DOM_VK_PAGE_DOWN",
- "DOM_VK_PAGE_UP",
- "DOM_VK_PAUSE",
- "DOM_VK_PERCENT",
- "DOM_VK_PERIOD",
- "DOM_VK_PIPE",
- "DOM_VK_PLAY",
- "DOM_VK_PLUS",
- "DOM_VK_PRINT",
- "DOM_VK_PRINTSCREEN",
- "DOM_VK_PROCESSKEY",
- "DOM_VK_PROPERITES",
- "DOM_VK_Q",
- "DOM_VK_QUESTION_MARK",
- "DOM_VK_QUOTE",
- "DOM_VK_R",
- "DOM_VK_REDO",
- "DOM_VK_RETURN",
- "DOM_VK_RIGHT",
- "DOM_VK_S",
- "DOM_VK_SCROLL_LOCK",
- "DOM_VK_SELECT",
- "DOM_VK_SEMICOLON",
- "DOM_VK_SEPARATOR",
- "DOM_VK_SHIFT",
- "DOM_VK_SLASH",
- "DOM_VK_SLEEP",
- "DOM_VK_SPACE",
- "DOM_VK_SUBTRACT",
- "DOM_VK_T",
- "DOM_VK_TAB",
- "DOM_VK_TILDE",
- "DOM_VK_U",
- "DOM_VK_UNDERSCORE",
- "DOM_VK_UNDO",
- "DOM_VK_UNICODE",
- "DOM_VK_UP",
- "DOM_VK_V",
- "DOM_VK_VOLUME_DOWN",
- "DOM_VK_VOLUME_MUTE",
- "DOM_VK_VOLUME_UP",
- "DOM_VK_W",
- "DOM_VK_WIN",
- "DOM_VK_WINDOW",
- "DOM_VK_WIN_ICO_00",
- "DOM_VK_WIN_ICO_CLEAR",
- "DOM_VK_WIN_ICO_HELP",
- "DOM_VK_WIN_OEM_ATTN",
- "DOM_VK_WIN_OEM_AUTO",
- "DOM_VK_WIN_OEM_BACKTAB",
- "DOM_VK_WIN_OEM_CLEAR",
- "DOM_VK_WIN_OEM_COPY",
- "DOM_VK_WIN_OEM_CUSEL",
- "DOM_VK_WIN_OEM_ENLW",
- "DOM_VK_WIN_OEM_FINISH",
- "DOM_VK_WIN_OEM_FJ_JISHO",
- "DOM_VK_WIN_OEM_FJ_LOYA",
- "DOM_VK_WIN_OEM_FJ_MASSHOU",
- "DOM_VK_WIN_OEM_FJ_ROYA",
- "DOM_VK_WIN_OEM_FJ_TOUROKU",
- "DOM_VK_WIN_OEM_JUMP",
- "DOM_VK_WIN_OEM_PA1",
- "DOM_VK_WIN_OEM_PA2",
- "DOM_VK_WIN_OEM_PA3",
- "DOM_VK_WIN_OEM_RESET",
- "DOM_VK_WIN_OEM_WSCTRL",
- "DOM_VK_X",
- "DOM_VK_XF86XK_ADD_FAVORITE",
- "DOM_VK_XF86XK_APPLICATION_LEFT",
- "DOM_VK_XF86XK_APPLICATION_RIGHT",
- "DOM_VK_XF86XK_AUDIO_CYCLE_TRACK",
- "DOM_VK_XF86XK_AUDIO_FORWARD",
- "DOM_VK_XF86XK_AUDIO_LOWER_VOLUME",
- "DOM_VK_XF86XK_AUDIO_MEDIA",
- "DOM_VK_XF86XK_AUDIO_MUTE",
- "DOM_VK_XF86XK_AUDIO_NEXT",
- "DOM_VK_XF86XK_AUDIO_PAUSE",
- "DOM_VK_XF86XK_AUDIO_PLAY",
- "DOM_VK_XF86XK_AUDIO_PREV",
- "DOM_VK_XF86XK_AUDIO_RAISE_VOLUME",
- "DOM_VK_XF86XK_AUDIO_RANDOM_PLAY",
- "DOM_VK_XF86XK_AUDIO_RECORD",
- "DOM_VK_XF86XK_AUDIO_REPEAT",
- "DOM_VK_XF86XK_AUDIO_REWIND",
- "DOM_VK_XF86XK_AUDIO_STOP",
- "DOM_VK_XF86XK_AWAY",
- "DOM_VK_XF86XK_BACK",
- "DOM_VK_XF86XK_BACK_FORWARD",
- "DOM_VK_XF86XK_BATTERY",
- "DOM_VK_XF86XK_BLUE",
- "DOM_VK_XF86XK_BLUETOOTH",
- "DOM_VK_XF86XK_BOOK",
- "DOM_VK_XF86XK_BRIGHTNESS_ADJUST",
- "DOM_VK_XF86XK_CALCULATOR",
- "DOM_VK_XF86XK_CALENDAR",
- "DOM_VK_XF86XK_CD",
- "DOM_VK_XF86XK_CLOSE",
- "DOM_VK_XF86XK_COMMUNITY",
- "DOM_VK_XF86XK_CONTRAST_ADJUST",
- "DOM_VK_XF86XK_COPY",
- "DOM_VK_XF86XK_CUT",
- "DOM_VK_XF86XK_CYCLE_ANGLE",
- "DOM_VK_XF86XK_DISPLAY",
- "DOM_VK_XF86XK_DOCUMENTS",
- "DOM_VK_XF86XK_DOS",
- "DOM_VK_XF86XK_EJECT",
- "DOM_VK_XF86XK_EXCEL",
- "DOM_VK_XF86XK_EXPLORER",
- "DOM_VK_XF86XK_FAVORITES",
- "DOM_VK_XF86XK_FINANCE",
- "DOM_VK_XF86XK_FORWARD",
- "DOM_VK_XF86XK_FRAME_BACK",
- "DOM_VK_XF86XK_FRAME_FORWARD",
- "DOM_VK_XF86XK_GAME",
- "DOM_VK_XF86XK_GO",
- "DOM_VK_XF86XK_GREEN",
- "DOM_VK_XF86XK_HIBERNATE",
- "DOM_VK_XF86XK_HISTORY",
- "DOM_VK_XF86XK_HOME_PAGE",
- "DOM_VK_XF86XK_HOT_LINKS",
- "DOM_VK_XF86XK_I_TOUCH",
- "DOM_VK_XF86XK_KBD_BRIGHTNESS_DOWN",
- "DOM_VK_XF86XK_KBD_BRIGHTNESS_UP",
- "DOM_VK_XF86XK_KBD_LIGHT_ON_OFF",
- "DOM_VK_XF86XK_LAUNCH0",
- "DOM_VK_XF86XK_LAUNCH1",
- "DOM_VK_XF86XK_LAUNCH2",
- "DOM_VK_XF86XK_LAUNCH3",
- "DOM_VK_XF86XK_LAUNCH4",
- "DOM_VK_XF86XK_LAUNCH5",
- "DOM_VK_XF86XK_LAUNCH6",
- "DOM_VK_XF86XK_LAUNCH7",
- "DOM_VK_XF86XK_LAUNCH8",
- "DOM_VK_XF86XK_LAUNCH9",
- "DOM_VK_XF86XK_LAUNCH_A",
- "DOM_VK_XF86XK_LAUNCH_B",
- "DOM_VK_XF86XK_LAUNCH_C",
- "DOM_VK_XF86XK_LAUNCH_D",
- "DOM_VK_XF86XK_LAUNCH_E",
- "DOM_VK_XF86XK_LAUNCH_F",
- "DOM_VK_XF86XK_LIGHT_BULB",
- "DOM_VK_XF86XK_LOG_OFF",
- "DOM_VK_XF86XK_MAIL",
- "DOM_VK_XF86XK_MAIL_FORWARD",
- "DOM_VK_XF86XK_MARKET",
- "DOM_VK_XF86XK_MEETING",
- "DOM_VK_XF86XK_MEMO",
- "DOM_VK_XF86XK_MENU_KB",
- "DOM_VK_XF86XK_MENU_PB",
- "DOM_VK_XF86XK_MESSENGER",
- "DOM_VK_XF86XK_MON_BRIGHTNESS_DOWN",
- "DOM_VK_XF86XK_MON_BRIGHTNESS_UP",
- "DOM_VK_XF86XK_MUSIC",
- "DOM_VK_XF86XK_MY_COMPUTER",
- "DOM_VK_XF86XK_MY_SITES",
- "DOM_VK_XF86XK_NEW",
- "DOM_VK_XF86XK_NEWS",
- "DOM_VK_XF86XK_OFFICE_HOME",
- "DOM_VK_XF86XK_OPEN",
- "DOM_VK_XF86XK_OPEN_URL",
- "DOM_VK_XF86XK_OPTION",
- "DOM_VK_XF86XK_PASTE",
- "DOM_VK_XF86XK_PHONE",
- "DOM_VK_XF86XK_PICTURES",
- "DOM_VK_XF86XK_POWER_DOWN",
- "DOM_VK_XF86XK_POWER_OFF",
- "DOM_VK_XF86XK_RED",
- "DOM_VK_XF86XK_REFRESH",
- "DOM_VK_XF86XK_RELOAD",
- "DOM_VK_XF86XK_REPLY",
- "DOM_VK_XF86XK_ROCKER_DOWN",
- "DOM_VK_XF86XK_ROCKER_ENTER",
- "DOM_VK_XF86XK_ROCKER_UP",
- "DOM_VK_XF86XK_ROTATE_WINDOWS",
- "DOM_VK_XF86XK_ROTATION_KB",
- "DOM_VK_XF86XK_ROTATION_PB",
- "DOM_VK_XF86XK_SAVE",
- "DOM_VK_XF86XK_SCREEN_SAVER",
- "DOM_VK_XF86XK_SCROLL_CLICK",
- "DOM_VK_XF86XK_SCROLL_DOWN",
- "DOM_VK_XF86XK_SCROLL_UP",
- "DOM_VK_XF86XK_SEARCH",
- "DOM_VK_XF86XK_SEND",
- "DOM_VK_XF86XK_SHOP",
- "DOM_VK_XF86XK_SPELL",
- "DOM_VK_XF86XK_SPLIT_SCREEN",
- "DOM_VK_XF86XK_STANDBY",
- "DOM_VK_XF86XK_START",
- "DOM_VK_XF86XK_STOP",
- "DOM_VK_XF86XK_SUBTITLE",
- "DOM_VK_XF86XK_SUPPORT",
- "DOM_VK_XF86XK_SUSPEND",
- "DOM_VK_XF86XK_TASK_PANE",
- "DOM_VK_XF86XK_TERMINAL",
- "DOM_VK_XF86XK_TIME",
- "DOM_VK_XF86XK_TOOLS",
- "DOM_VK_XF86XK_TOP_MENU",
- "DOM_VK_XF86XK_TO_DO_LIST",
- "DOM_VK_XF86XK_TRAVEL",
- "DOM_VK_XF86XK_USER1KB",
- "DOM_VK_XF86XK_USER2KB",
- "DOM_VK_XF86XK_USER_PB",
- "DOM_VK_XF86XK_UWB",
- "DOM_VK_XF86XK_VENDOR_HOME",
- "DOM_VK_XF86XK_VIDEO",
- "DOM_VK_XF86XK_VIEW",
- "DOM_VK_XF86XK_WAKE_UP",
- "DOM_VK_XF86XK_WEB_CAM",
- "DOM_VK_XF86XK_WHEEL_BUTTON",
- "DOM_VK_XF86XK_WLAN",
- "DOM_VK_XF86XK_WORD",
- "DOM_VK_XF86XK_WWW",
- "DOM_VK_XF86XK_XFER",
- "DOM_VK_XF86XK_YELLOW",
- "DOM_VK_XF86XK_ZOOM_IN",
- "DOM_VK_XF86XK_ZOOM_OUT",
- "DOM_VK_Y",
- "DOM_VK_Z",
- "DOM_VK_ZOOM",
- "DONE",
- "DONT_CARE",
- "DOWNLOADING",
- "DRAGDROP",
- "DRAW_BUFFER0",
- "DRAW_BUFFER1",
- "DRAW_BUFFER10",
- "DRAW_BUFFER11",
- "DRAW_BUFFER12",
- "DRAW_BUFFER13",
- "DRAW_BUFFER14",
- "DRAW_BUFFER15",
- "DRAW_BUFFER2",
- "DRAW_BUFFER3",
- "DRAW_BUFFER4",
- "DRAW_BUFFER5",
- "DRAW_BUFFER6",
- "DRAW_BUFFER7",
- "DRAW_BUFFER8",
- "DRAW_BUFFER9",
- "DRAW_FRAMEBUFFER",
- "DRAW_FRAMEBUFFER_BINDING",
- "DST_ALPHA",
- "DST_COLOR",
- "DYNAMIC_COPY",
- "DYNAMIC_DRAW",
- "DYNAMIC_READ",
- "DataChannel",
- "DataTransfer",
- "DataTransferItem",
- "DataTransferItemList",
- "DataView",
- "Date",
- "DateTimeFormat",
- "DecompressionStream",
- "DelayNode",
- "DelegatedInkTrailPresenter",
- "DeprecationReportBody",
- "DesktopNotification",
- "DesktopNotificationCenter",
- "Details",
- "DeviceLightEvent",
- "DeviceMotionEvent",
- "DeviceMotionEventAcceleration",
- "DeviceMotionEventRotationRate",
- "DeviceOrientationEvent",
- "DevicePosture",
- "DeviceProximityEvent",
- "DeviceStorage",
- "DeviceStorageChangeEvent",
- "DigitalCredential",
- "Directory",
- "DisplayNames",
- "DisposableStack",
- "Document",
- "DocumentFragment",
- "DocumentPictureInPicture",
- "DocumentPictureInPictureEvent",
- "DocumentTimeline",
- "DocumentType",
- "DragEvent",
- "Duration",
- "DurationFormat",
- "DynamicsCompressorNode",
- "E",
- "ELEMENT_ARRAY_BUFFER",
- "ELEMENT_ARRAY_BUFFER_BINDING",
- "ELEMENT_NODE",
- "EMPTY",
- "ENCODING_ERR",
- "ENDED",
- "END_TO_END",
- "END_TO_START",
- "ENTITY_NODE",
- "ENTITY_REFERENCE_NODE",
- "EPSILON",
- "EQUAL",
- "EQUALPOWER",
- "ERROR",
- "EXPONENTIAL_DISTANCE",
- "EditContext",
- "Element",
- "ElementInternals",
- "ElementQuery",
- "EncodedAudioChunk",
- "EncodedVideoChunk",
- "EnterPictureInPictureEvent",
- "Entity",
- "EntityReference",
- "Error",
- "ErrorEvent",
- "EvalError",
- "Event",
- "EventCounts",
- "EventException",
- "EventSource",
- "EventTarget",
- "Exception",
- "ExtensionContext",
- "ExtensionDisabledReason",
- "ExtensionInfo",
- "ExtensionInstallType",
- "ExtensionType",
- "External",
- "EyeDropper",
- "FASTEST",
- "FIDOSDK",
- "FILTER_ACCEPT",
- "FILTER_INTERRUPT",
- "FILTER_REJECT",
- "FILTER_SKIP",
- "FINISHED_STATE",
- "FIRST_ORDERED_NODE_TYPE",
- "FLOAT",
- "FLOAT_32_UNSIGNED_INT_24_8_REV",
- "FLOAT_MAT2",
- "FLOAT_MAT2x3",
- "FLOAT_MAT2x4",
- "FLOAT_MAT3",
- "FLOAT_MAT3x2",
- "FLOAT_MAT3x4",
- "FLOAT_MAT4",
- "FLOAT_MAT4x2",
- "FLOAT_MAT4x3",
- "FLOAT_VEC2",
- "FLOAT_VEC3",
- "FLOAT_VEC4",
- "FOCUS",
- "FONT_FACE_RULE",
- "FONT_FEATURE_VALUES_RULE",
- "FRAGMENT",
- "FRAGMENT_SHADER",
- "FRAGMENT_SHADER_DERIVATIVE_HINT",
- "FRAGMENT_SHADER_DERIVATIVE_HINT_OES",
- "FRAMEBUFFER",
- "FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",
- "FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",
- "FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING",
- "FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE",
- "FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",
- "FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",
- "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",
- "FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE",
- "FRAMEBUFFER_ATTACHMENT_RED_SIZE",
- "FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",
- "FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE",
- "FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER",
- "FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL",
- "FRAMEBUFFER_BINDING",
- "FRAMEBUFFER_COMPLETE",
- "FRAMEBUFFER_DEFAULT",
- "FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
- "FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
- "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
- "FRAMEBUFFER_INCOMPLETE_MULTISAMPLE",
- "FRAMEBUFFER_UNSUPPORTED",
- "FRONT",
- "FRONT_AND_BACK",
- "FRONT_FACE",
- "FUNC_ADD",
- "FUNC_REVERSE_SUBTRACT",
- "FUNC_SUBTRACT",
- "FeaturePolicy",
- "FeaturePolicyViolationReportBody",
- "FederatedCredential",
- "Feed",
- "FeedEntry",
- "Fence",
- "FencedFrameConfig",
- "FetchLaterResult",
- "File",
- "FileError",
- "FileList",
- "FileReader",
- "FileSystem",
- "FileSystemDirectoryEntry",
- "FileSystemDirectoryHandle",
- "FileSystemDirectoryReader",
- "FileSystemEntry",
- "FileSystemFileEntry",
- "FileSystemFileHandle",
- "FileSystemHandle",
- "FileSystemObserver",
- "FileSystemWritableFileStream",
- "FinalizationRegistry",
- "FindInPage",
- "Float16Array",
- "Float32Array",
- "Float64Array",
- "FocusEvent",
- "FontData",
- "FontFace",
- "FontFaceSet",
- "FontFaceSetLoadEvent",
- "FormData",
- "FormDataEvent",
- "FragmentDirective",
- "Function",
- "GENERATE_MIPMAP_HINT",
- "GEQUAL",
- "GPU",
- "GPUAdapter",
- "GPUAdapterInfo",
- "GPUBindGroup",
- "GPUBindGroupLayout",
- "GPUBuffer",
- "GPUBufferUsage",
- "GPUCanvasContext",
- "GPUColorWrite",
- "GPUCommandBuffer",
- "GPUCommandEncoder",
- "GPUCompilationInfo",
- "GPUCompilationMessage",
- "GPUComputePassEncoder",
- "GPUComputePipeline",
- "GPUDevice",
- "GPUDeviceLostInfo",
- "GPUError",
- "GPUExternalTexture",
- "GPUInternalError",
- "GPUMapMode",
- "GPUOutOfMemoryError",
- "GPUPipelineError",
- "GPUPipelineLayout",
- "GPUQuerySet",
- "GPUQueue",
- "GPURenderBundle",
- "GPURenderBundleEncoder",
- "GPURenderPassEncoder",
- "GPURenderPipeline",
- "GPUSampler",
- "GPUShaderModule",
- "GPUShaderStage",
- "GPUSupportedFeatures",
- "GPUSupportedLimits",
- "GPUTexture",
- "GPUTextureUsage",
- "GPUTextureView",
- "GPUUncapturedErrorEvent",
- "GPUValidationError",
- "GREATER",
- "GREEN",
- "GREEN_BITS",
- "GainNode",
- "Gamepad",
- "GamepadAxisMoveEvent",
- "GamepadButton",
- "GamepadButtonEvent",
- "GamepadEvent",
- "GamepadHapticActuator",
- "GamepadPose",
- "Geolocation",
- "GeolocationCoordinates",
- "GeolocationPosition",
- "GeolocationPositionError",
- "GestureEvent",
- "GetInfo",
- "Global",
- "GravitySensor",
- "Gyroscope",
- "HALF_FLOAT",
- "HAVE_CURRENT_DATA",
- "HAVE_ENOUGH_DATA",
- "HAVE_FUTURE_DATA",
- "HAVE_METADATA",
- "HAVE_NOTHING",
- "HEADERS_RECEIVED",
- "HID",
- "HIDConnectionEvent",
- "HIDDEN",
- "HIDDevice",
- "HIDInputReportEvent",
- "HIERARCHY_REQUEST_ERR",
- "HIGHPASS",
- "HIGHSHELF",
- "HIGH_FLOAT",
- "HIGH_INT",
- "HORIZONTAL",
- "HORIZONTAL_AXIS",
- "HRTF",
- "HTMLAllCollection",
- "HTMLAnchorElement",
- "HTMLAppletElement",
- "HTMLAreaElement",
- "HTMLAudioElement",
- "HTMLBRElement",
- "HTMLBaseElement",
- "HTMLBaseFontElement",
- "HTMLBlockquoteElement",
- "HTMLBodyElement",
- "HTMLButtonElement",
- "HTMLCanvasElement",
- "HTMLCollection",
- "HTMLCommandElement",
- "HTMLContentElement",
- "HTMLDListElement",
- "HTMLDataElement",
- "HTMLDataListElement",
- "HTMLDetailsElement",
- "HTMLDialogElement",
- "HTMLDirectoryElement",
- "HTMLDivElement",
- "HTMLDocument",
- "HTMLElement",
- "HTMLEmbedElement",
- "HTMLFencedFrameElement",
- "HTMLFieldSetElement",
- "HTMLFontElement",
- "HTMLFormControlsCollection",
- "HTMLFormElement",
- "HTMLFrameElement",
- "HTMLFrameSetElement",
- "HTMLHRElement",
- "HTMLHeadElement",
- "HTMLHeadingElement",
- "HTMLHtmlElement",
- "HTMLIFrameElement",
- "HTMLImageElement",
- "HTMLInputElement",
- "HTMLIsIndexElement",
- "HTMLKeygenElement",
- "HTMLLIElement",
- "HTMLLabelElement",
- "HTMLLegendElement",
- "HTMLLinkElement",
- "HTMLMapElement",
- "HTMLMarqueeElement",
- "HTMLMediaElement",
- "HTMLMenuElement",
- "HTMLMenuItemElement",
- "HTMLMetaElement",
- "HTMLMeterElement",
- "HTMLModElement",
- "HTMLOListElement",
- "HTMLObjectElement",
- "HTMLOptGroupElement",
- "HTMLOptionElement",
- "HTMLOptionsCollection",
- "HTMLOutputElement",
- "HTMLParagraphElement",
- "HTMLParamElement",
- "HTMLPictureElement",
- "HTMLPreElement",
- "HTMLProgressElement",
- "HTMLPropertiesCollection",
- "HTMLQuoteElement",
- "HTMLScriptElement",
- "HTMLSelectElement",
- "HTMLSelectedContentElement",
- "HTMLShadowElement",
- "HTMLSlotElement",
- "HTMLSourceElement",
- "HTMLSpanElement",
- "HTMLStyleElement",
- "HTMLTableCaptionElement",
- "HTMLTableCellElement",
- "HTMLTableColElement",
- "HTMLTableElement",
- "HTMLTableRowElement",
- "HTMLTableSectionElement",
- "HTMLTemplateElement",
- "HTMLTextAreaElement",
- "HTMLTimeElement",
- "HTMLTitleElement",
- "HTMLTrackElement",
- "HTMLUListElement",
- "HTMLUnknownElement",
- "HTMLVideoElement",
- "HashChangeEvent",
- "Headers",
- "Highlight",
- "HighlightRegistry",
- "History",
- "Hz",
- "ICE_CHECKING",
- "ICE_CLOSED",
- "ICE_COMPLETED",
- "ICE_CONNECTED",
- "ICE_FAILED",
- "ICE_GATHERING",
- "ICE_WAITING",
- "IDBCursor",
- "IDBCursorWithValue",
- "IDBDatabase",
- "IDBDatabaseException",
- "IDBFactory",
- "IDBFileHandle",
- "IDBFileRequest",
- "IDBIndex",
- "IDBKeyRange",
- "IDBMutableFile",
- "IDBObjectStore",
- "IDBOpenDBRequest",
- "IDBRecord",
- "IDBRequest",
- "IDBTransaction",
- "IDBVersionChangeEvent",
- "IDLE",
- "IIRFilterNode",
- "IMPLEMENTATION_COLOR_READ_FORMAT",
- "IMPLEMENTATION_COLOR_READ_TYPE",
- "IMPORT_RULE",
- "INCR",
- "INCR_WRAP",
- "INDEX",
- "INDEX_SIZE_ERR",
- "INDIRECT",
- "INT",
- "INTERLEAVED_ATTRIBS",
- "INT_2_10_10_10_REV",
- "INT_SAMPLER_2D",
- "INT_SAMPLER_2D_ARRAY",
- "INT_SAMPLER_3D",
- "INT_SAMPLER_CUBE",
- "INT_VEC2",
- "INT_VEC3",
- "INT_VEC4",
- "INUSE_ATTRIBUTE_ERR",
- "INVALID_ACCESS_ERR",
- "INVALID_CHARACTER_ERR",
- "INVALID_ENUM",
- "INVALID_EXPRESSION_ERR",
- "INVALID_FRAMEBUFFER_OPERATION",
- "INVALID_INDEX",
- "INVALID_MODIFICATION_ERR",
- "INVALID_NODE_TYPE_ERR",
- "INVALID_OPERATION",
- "INVALID_STATE_ERR",
- "INVALID_VALUE",
- "INVERSE_DISTANCE",
- "INVERT",
- "IceCandidate",
- "IconInfo",
- "IdentityCredential",
- "IdentityCredentialError",
- "IdentityProvider",
- "IdleDeadline",
- "IdleDetector",
- "Image",
- "ImageBitmap",
- "ImageBitmapRenderingContext",
- "ImageCapture",
- "ImageData",
- "ImageDataType",
- "ImageDecoder",
- "ImageTrack",
- "ImageTrackList",
- "Infinity",
- "Ink",
- "InputDeviceCapabilities",
- "InputDeviceInfo",
- "InputEvent",
- "InputMethodContext",
- "InstallTrigger",
- "InstallTriggerImpl",
- "Instance",
- "Instant",
- "Int16Array",
- "Int32Array",
- "Int8Array",
- "IntegrityViolationReportBody",
- "Intent",
- "InterestEvent",
- "InternalError",
- "IntersectionObserver",
- "IntersectionObserverEntry",
- "Intl",
- "IsSearchProviderInstalled",
- "Iterator",
- "JSON",
- "JSTag",
- "KEEP",
- "KEYDOWN",
- "KEYFRAMES_RULE",
- "KEYFRAME_RULE",
- "KEYPRESS",
- "KEYUP",
- "KeyEvent",
- "Keyboard",
- "KeyboardEvent",
- "KeyboardLayoutMap",
- "KeyframeEffect",
- "LENGTHADJUST_SPACING",
- "LENGTHADJUST_SPACINGANDGLYPHS",
- "LENGTHADJUST_UNKNOWN",
- "LEQUAL",
- "LESS",
- "LINEAR",
- "LINEAR_DISTANCE",
- "LINEAR_MIPMAP_LINEAR",
- "LINEAR_MIPMAP_NEAREST",
- "LINES",
- "LINE_LOOP",
- "LINE_STRIP",
- "LINE_WIDTH",
- "LINK_STATUS",
- "LIVE",
- "LN10",
- "LN2",
- "LOADED",
- "LOADING",
- "LOG10E",
- "LOG2E",
- "LOWPASS",
- "LOWSHELF",
- "LOW_FLOAT",
- "LOW_INT",
- "LSException",
- "LSParserFilter",
- "LUMINANCE",
- "LUMINANCE_ALPHA",
- "LanguageCode",
- "LanguageDetector",
- "LargestContentfulPaint",
- "LaunchParams",
- "LaunchQueue",
- "LaunchType",
- "LayoutShift",
- "LayoutShiftAttribution",
- "LinearAccelerationSensor",
- "LinkError",
- "ListFormat",
- "LocalMediaStream",
- "Locale",
- "Location",
- "Lock",
- "LockManager",
- "MAP_READ",
- "MAP_WRITE",
- "MARGIN_RULE",
- "MAX",
- "MAX_3D_TEXTURE_SIZE",
- "MAX_ARRAY_TEXTURE_LAYERS",
- "MAX_CAPTURE_VISIBLE_TAB_CALLS_PER_SECOND",
- "MAX_CLIENT_WAIT_TIMEOUT_WEBGL",
- "MAX_COLOR_ATTACHMENTS",
- "MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS",
- "MAX_COMBINED_TEXTURE_IMAGE_UNITS",
- "MAX_COMBINED_UNIFORM_BLOCKS",
- "MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS",
- "MAX_CUBE_MAP_TEXTURE_SIZE",
- "MAX_DRAW_BUFFERS",
- "MAX_ELEMENTS_INDICES",
- "MAX_ELEMENTS_VERTICES",
- "MAX_ELEMENT_INDEX",
- "MAX_FRAGMENT_INPUT_COMPONENTS",
- "MAX_FRAGMENT_UNIFORM_BLOCKS",
- "MAX_FRAGMENT_UNIFORM_COMPONENTS",
- "MAX_FRAGMENT_UNIFORM_VECTORS",
- "MAX_PROGRAM_TEXEL_OFFSET",
- "MAX_RENDERBUFFER_SIZE",
- "MAX_SAFE_INTEGER",
- "MAX_SAMPLES",
- "MAX_SERVER_WAIT_TIMEOUT",
- "MAX_TEXTURE_IMAGE_UNITS",
- "MAX_TEXTURE_LOD_BIAS",
- "MAX_TEXTURE_MAX_ANISOTROPY_EXT",
- "MAX_TEXTURE_SIZE",
- "MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS",
- "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS",
- "MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS",
- "MAX_UNIFORM_BLOCK_SIZE",
- "MAX_UNIFORM_BUFFER_BINDINGS",
- "MAX_VALUE",
- "MAX_VARYING_COMPONENTS",
- "MAX_VARYING_VECTORS",
- "MAX_VERTEX_ATTRIBS",
- "MAX_VERTEX_OUTPUT_COMPONENTS",
- "MAX_VERTEX_TEXTURE_IMAGE_UNITS",
- "MAX_VERTEX_UNIFORM_BLOCKS",
- "MAX_VERTEX_UNIFORM_COMPONENTS",
- "MAX_VERTEX_UNIFORM_VECTORS",
- "MAX_VIEWPORT_DIMS",
- "MEDIA_ERR_ABORTED",
- "MEDIA_ERR_DECODE",
- "MEDIA_ERR_ENCRYPTED",
- "MEDIA_ERR_NETWORK",
- "MEDIA_ERR_SRC_NOT_SUPPORTED",
- "MEDIA_KEYERR_CLIENT",
- "MEDIA_KEYERR_DOMAIN",
- "MEDIA_KEYERR_HARDWARECHANGE",
- "MEDIA_KEYERR_OUTPUT",
- "MEDIA_KEYERR_SERVICE",
- "MEDIA_KEYERR_UNKNOWN",
- "MEDIA_RULE",
- "MEDIUM_FLOAT",
- "MEDIUM_INT",
- "META_MASK",
- "MIDIAccess",
- "MIDIConnectionEvent",
- "MIDIInput",
- "MIDIInputMap",
- "MIDIMessageEvent",
- "MIDIOutput",
- "MIDIOutputMap",
- "MIDIPort",
- "MIN",
- "MIN_PROGRAM_TEXEL_OFFSET",
- "MIN_SAFE_INTEGER",
- "MIN_VALUE",
- "MIRRORED_REPEAT",
- "MODE_ASYNCHRONOUS",
- "MODE_SYNCHRONOUS",
- "MODIFICATION",
- "MOUSEDOWN",
- "MOUSEDRAG",
- "MOUSEMOVE",
- "MOUSEOUT",
- "MOUSEOVER",
- "MOUSEUP",
- "MOZ_KEYFRAMES_RULE",
- "MOZ_KEYFRAME_RULE",
- "MOZ_SOURCE_CURSOR",
- "MOZ_SOURCE_ERASER",
- "MOZ_SOURCE_KEYBOARD",
- "MOZ_SOURCE_MOUSE",
- "MOZ_SOURCE_PEN",
- "MOZ_SOURCE_TOUCH",
- "MOZ_SOURCE_UNKNOWN",
- "MSGESTURE_FLAG_BEGIN",
- "MSGESTURE_FLAG_CANCEL",
- "MSGESTURE_FLAG_END",
- "MSGESTURE_FLAG_INERTIA",
- "MSGESTURE_FLAG_NONE",
- "MSPOINTER_TYPE_MOUSE",
- "MSPOINTER_TYPE_PEN",
- "MSPOINTER_TYPE_TOUCH",
- "MS_ASYNC_CALLBACK_STATUS_ASSIGN_DELEGATE",
- "MS_ASYNC_CALLBACK_STATUS_CANCEL",
- "MS_ASYNC_CALLBACK_STATUS_CHOOSEANY",
- "MS_ASYNC_CALLBACK_STATUS_ERROR",
- "MS_ASYNC_CALLBACK_STATUS_JOIN",
- "MS_ASYNC_OP_STATUS_CANCELED",
- "MS_ASYNC_OP_STATUS_ERROR",
- "MS_ASYNC_OP_STATUS_SUCCESS",
- "MS_MANIPULATION_STATE_ACTIVE",
- "MS_MANIPULATION_STATE_CANCELLED",
- "MS_MANIPULATION_STATE_COMMITTED",
- "MS_MANIPULATION_STATE_DRAGGING",
- "MS_MANIPULATION_STATE_INERTIA",
- "MS_MANIPULATION_STATE_PRESELECT",
- "MS_MANIPULATION_STATE_SELECTING",
- "MS_MANIPULATION_STATE_STOPPED",
- "MS_MEDIA_ERR_ENCRYPTED",
- "MS_MEDIA_KEYERR_CLIENT",
- "MS_MEDIA_KEYERR_DOMAIN",
- "MS_MEDIA_KEYERR_HARDWARECHANGE",
- "MS_MEDIA_KEYERR_OUTPUT",
- "MS_MEDIA_KEYERR_SERVICE",
- "MS_MEDIA_KEYERR_UNKNOWN",
- "Map",
- "Math",
- "MathMLElement",
- "MediaCapabilities",
- "MediaCapabilitiesInfo",
- "MediaController",
- "MediaDeviceInfo",
- "MediaDevices",
- "MediaElementAudioSourceNode",
- "MediaEncryptedEvent",
- "MediaError",
- "MediaKeyError",
- "MediaKeyEvent",
- "MediaKeyMessageEvent",
- "MediaKeyNeededEvent",
- "MediaKeySession",
- "MediaKeyStatusMap",
- "MediaKeySystemAccess",
- "MediaKeys",
- "MediaList",
- "MediaMetadata",
- "MediaQueryList",
- "MediaQueryListEvent",
- "MediaRecorder",
- "MediaRecorderErrorEvent",
- "MediaSession",
- "MediaSettingsRange",
- "MediaSource",
- "MediaSourceHandle",
- "MediaStream",
- "MediaStreamAudioDestinationNode",
- "MediaStreamAudioSourceNode",
- "MediaStreamEvent",
- "MediaStreamTrack",
- "MediaStreamTrackAudioSourceNode",
- "MediaStreamTrackAudioStats",
- "MediaStreamTrackEvent",
- "MediaStreamTrackGenerator",
- "MediaStreamTrackProcessor",
- "MediaStreamTrackVideoStats",
- "Memory",
- "MessageChannel",
- "MessageEvent",
- "MessagePort",
- "MessageSender",
- "Methods",
- "MimeType",
- "MimeTypeArray",
- "Module",
- "MouseEvent",
- "MouseScrollEvent",
- "MozAnimation",
- "MozAnimationDelay",
- "MozAnimationDirection",
- "MozAnimationDuration",
- "MozAnimationFillMode",
- "MozAnimationIterationCount",
- "MozAnimationName",
- "MozAnimationPlayState",
- "MozAnimationTimingFunction",
- "MozAppearance",
- "MozBackfaceVisibility",
- "MozBinding",
- "MozBorderBottomColors",
- "MozBorderEnd",
- "MozBorderEndColor",
- "MozBorderEndStyle",
- "MozBorderEndWidth",
- "MozBorderImage",
- "MozBorderLeftColors",
- "MozBorderRightColors",
- "MozBorderStart",
- "MozBorderStartColor",
- "MozBorderStartStyle",
- "MozBorderStartWidth",
- "MozBorderTopColors",
- "MozBoxAlign",
- "MozBoxDirection",
- "MozBoxFlex",
- "MozBoxOrdinalGroup",
- "MozBoxOrient",
- "MozBoxPack",
- "MozBoxSizing",
- "MozCSSKeyframeRule",
- "MozCSSKeyframesRule",
- "MozColumnCount",
- "MozColumnFill",
- "MozColumnGap",
- "MozColumnRule",
- "MozColumnRuleColor",
- "MozColumnRuleStyle",
- "MozColumnRuleWidth",
- "MozColumnWidth",
- "MozColumns",
- "MozContactChangeEvent",
- "MozFloatEdge",
- "MozFontFeatureSettings",
- "MozFontLanguageOverride",
- "MozForceBrokenImageIcon",
- "MozHyphens",
- "MozImageRegion",
- "MozMarginEnd",
- "MozMarginStart",
- "MozMmsEvent",
- "MozMmsMessage",
- "MozMobileMessageThread",
- "MozOSXFontSmoothing",
- "MozOrient",
- "MozOsxFontSmoothing",
- "MozOutlineRadius",
- "MozOutlineRadiusBottomleft",
- "MozOutlineRadiusBottomright",
- "MozOutlineRadiusTopleft",
- "MozOutlineRadiusTopright",
- "MozPaddingEnd",
- "MozPaddingStart",
- "MozPerspective",
- "MozPerspectiveOrigin",
- "MozPowerManager",
- "MozSettingsEvent",
- "MozSmsEvent",
- "MozSmsMessage",
- "MozStackSizing",
- "MozTabSize",
- "MozTextAlignLast",
- "MozTextDecorationColor",
- "MozTextDecorationLine",
- "MozTextDecorationStyle",
- "MozTextSizeAdjust",
- "MozTransform",
- "MozTransformOrigin",
- "MozTransformStyle",
- "MozTransition",
- "MozTransitionDelay",
- "MozTransitionDuration",
- "MozTransitionProperty",
- "MozTransitionTimingFunction",
- "MozUserFocus",
- "MozUserInput",
- "MozUserModify",
- "MozUserSelect",
- "MozWindowDragging",
- "MozWindowShadow",
- "MutationEvent",
- "MutationObserver",
- "MutationRecord",
- "MutedInfo",
- "MutedInfoReason",
- "NAMESPACE_ERR",
- "NAMESPACE_RULE",
- "NEAREST",
- "NEAREST_MIPMAP_LINEAR",
- "NEAREST_MIPMAP_NEAREST",
- "NEGATIVE_INFINITY",
- "NETWORK_EMPTY",
- "NETWORK_ERR",
- "NETWORK_IDLE",
- "NETWORK_LOADED",
- "NETWORK_LOADING",
- "NETWORK_NO_SOURCE",
- "NEVER",
- "NEW",
- "NEXT",
- "NEXT_NO_DUPLICATE",
- "NICEST",
- "NODE_AFTER",
- "NODE_BEFORE",
- "NODE_BEFORE_AND_AFTER",
- "NODE_INSIDE",
- "NONE",
- "NON_TRANSIENT_ERR",
- "NOTATION_NODE",
- "NOTCH",
- "NOTEQUAL",
- "NOT_ALLOWED_ERR",
- "NOT_FOUND_ERR",
- "NOT_READABLE_ERR",
- "NOT_SUPPORTED_ERR",
- "NO_DATA_ALLOWED_ERR",
- "NO_ERR",
- "NO_ERROR",
- "NO_MODIFICATION_ALLOWED_ERR",
- "NUMBER_TYPE",
- "NUM_COMPRESSED_TEXTURE_FORMATS",
- "NaN",
- "NamedNodeMap",
- "NavigateEvent",
- "Navigation",
- "NavigationActivation",
- "NavigationCurrentEntryChangeEvent",
- "NavigationDestination",
- "NavigationHistoryEntry",
- "NavigationPrecommitController",
- "NavigationPreloadManager",
- "NavigationTransition",
- "Navigator",
- "NavigatorLogin",
- "NavigatorManagedData",
- "NavigatorUAData",
- "NearbyLinks",
- "NetworkInformation",
- "Node",
- "NodeFilter",
- "NodeIterator",
- "NodeList",
- "NotRestoredReasonDetails",
- "NotRestoredReasons",
- "Notation",
- "Notification",
- "NotifyPaintEvent",
- "Now",
- "Number",
- "NumberFormat",
- "OBJECT_TYPE",
- "OBSOLETE",
- "OK",
- "ONE",
- "ONE_MINUS_CONSTANT_ALPHA",
- "ONE_MINUS_CONSTANT_COLOR",
- "ONE_MINUS_DST_ALPHA",
- "ONE_MINUS_DST_COLOR",
- "ONE_MINUS_SRC_ALPHA",
- "ONE_MINUS_SRC_COLOR",
- "OPEN",
- "OPENED",
- "OPENING",
- "ORDERED_NODE_ITERATOR_TYPE",
- "ORDERED_NODE_SNAPSHOT_TYPE",
- "OTHER_ERROR",
- "OTPCredential",
- "OUT_OF_MEMORY",
- "Object",
- "Observable",
- "OfflineAudioCompletionEvent",
- "OfflineAudioContext",
- "OfflineResourceList",
- "OffscreenCanvas",
- "OffscreenCanvasRenderingContext2D",
- "OnClickData",
- "OnInstalledReason",
- "OnPerformanceWarningCategory",
- "OnPerformanceWarningSeverity",
- "OnRestartRequiredReason",
- "Option",
- "OrientationSensor",
- "OscillatorNode",
- "OverconstrainedError",
- "OverflowEvent",
- "PACK_ALIGNMENT",
- "PACK_ROW_LENGTH",
- "PACK_SKIP_PIXELS",
- "PACK_SKIP_ROWS",
- "PAGE_RULE",
- "PARSE_ERR",
- "PATHSEG_ARC_ABS",
- "PATHSEG_ARC_REL",
- "PATHSEG_CLOSEPATH",
- "PATHSEG_CURVETO_CUBIC_ABS",
- "PATHSEG_CURVETO_CUBIC_REL",
- "PATHSEG_CURVETO_CUBIC_SMOOTH_ABS",
- "PATHSEG_CURVETO_CUBIC_SMOOTH_REL",
- "PATHSEG_CURVETO_QUADRATIC_ABS",
- "PATHSEG_CURVETO_QUADRATIC_REL",
- "PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS",
- "PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL",
- "PATHSEG_LINETO_ABS",
- "PATHSEG_LINETO_HORIZONTAL_ABS",
- "PATHSEG_LINETO_HORIZONTAL_REL",
- "PATHSEG_LINETO_REL",
- "PATHSEG_LINETO_VERTICAL_ABS",
- "PATHSEG_LINETO_VERTICAL_REL",
- "PATHSEG_MOVETO_ABS",
- "PATHSEG_MOVETO_REL",
- "PATHSEG_UNKNOWN",
- "PATH_EXISTS_ERR",
- "PEAKING",
- "PERMISSION_DENIED",
- "PERSISTENT",
- "PI",
- "PIXEL_PACK_BUFFER",
- "PIXEL_PACK_BUFFER_BINDING",
- "PIXEL_UNPACK_BUFFER",
- "PIXEL_UNPACK_BUFFER_BINDING",
- "PLAYING_STATE",
- "POINTS",
- "POLYGON_OFFSET_FACTOR",
- "POLYGON_OFFSET_FILL",
- "POLYGON_OFFSET_UNITS",
- "POSITION_UNAVAILABLE",
- "POSITIVE_INFINITY",
- "PREV",
- "PREV_NO_DUPLICATE",
- "PROCESSING_INSTRUCTION_NODE",
- "PageChangeEvent",
- "PageRevealEvent",
- "PageSettings",
- "PageSwapEvent",
- "PageTransitionEvent",
- "PaintRequest",
- "PaintRequestList",
- "PannerNode",
- "PasswordCredential",
- "Path2D",
- "PaymentAddress",
- "PaymentInstruments",
- "PaymentManager",
- "PaymentMethodChangeEvent",
- "PaymentRequest",
- "PaymentRequestUpdateEvent",
- "PaymentResponse",
- "Performance",
- "PerformanceElementTiming",
- "PerformanceEntry",
- "PerformanceEventTiming",
- "PerformanceLongAnimationFrameTiming",
- "PerformanceLongTaskTiming",
- "PerformanceMark",
- "PerformanceMeasure",
- "PerformanceNavigation",
- "PerformanceNavigationTiming",
- "PerformanceObserver",
- "PerformanceObserverEntryList",
- "PerformancePaintTiming",
- "PerformanceResourceTiming",
- "PerformanceScriptTiming",
- "PerformanceServerTiming",
- "PerformanceTiming",
- "PeriodicSyncManager",
- "PeriodicWave",
- "PermissionStatus",
- "Permissions",
- "PhotoCapabilities",
- "PictureInPictureEvent",
- "PictureInPictureWindow",
- "PlainDate",
- "PlainDateTime",
- "PlainMonthDay",
- "PlainTime",
- "PlainYearMonth",
- "PlatformArch",
- "PlatformInfo",
- "PlatformNaclArch",
- "PlatformOs",
- "Plugin",
- "PluginArray",
- "PluralRules",
- "PointerEvent",
- "PopStateEvent",
- "PopupBlockedEvent",
- "Port",
- "Presentation",
- "PresentationAvailability",
- "PresentationConnection",
- "PresentationConnectionAvailableEvent",
- "PresentationConnectionCloseEvent",
- "PresentationConnectionList",
- "PresentationReceiver",
- "PresentationRequest",
- "PressureObserver",
- "PressureRecord",
- "ProcessingInstruction",
- "Profiler",
- "ProgressEvent",
- "Promise",
- "PromiseRejectionEvent",
- "PropertyNodeList",
- "ProtectedAudience",
- "Proxy",
- "PublicKeyCredential",
- "PushManager",
- "PushSubscription",
- "PushSubscriptionOptions",
- "Q",
- "QUERY_RESOLVE",
- "QUERY_RESULT",
- "QUERY_RESULT_AVAILABLE",
- "QUOTA_ERR",
- "QUOTA_EXCEEDED_ERR",
- "QueryInterface",
- "QuotaExceededError",
- "R11F_G11F_B10F",
- "R16F",
- "R16I",
- "R16UI",
- "R32F",
- "R32I",
- "R32UI",
- "R8",
- "R8I",
- "R8UI",
- "R8_SNORM",
- "RASTERIZER_DISCARD",
- "READ",
- "READ_BUFFER",
- "READ_FRAMEBUFFER",
- "READ_FRAMEBUFFER_BINDING",
- "READ_ONLY",
- "READ_ONLY_ERR",
- "READ_WRITE",
- "RED",
- "RED_BITS",
- "RED_INTEGER",
- "REMOVAL",
- "RENDERBUFFER",
- "RENDERBUFFER_ALPHA_SIZE",
- "RENDERBUFFER_BINDING",
- "RENDERBUFFER_BLUE_SIZE",
- "RENDERBUFFER_DEPTH_SIZE",
- "RENDERBUFFER_GREEN_SIZE",
- "RENDERBUFFER_HEIGHT",
- "RENDERBUFFER_INTERNAL_FORMAT",
- "RENDERBUFFER_RED_SIZE",
- "RENDERBUFFER_SAMPLES",
- "RENDERBUFFER_STENCIL_SIZE",
- "RENDERBUFFER_WIDTH",
- "RENDERER",
- "RENDERING_INTENT_ABSOLUTE_COLORIMETRIC",
- "RENDERING_INTENT_AUTO",
- "RENDERING_INTENT_PERCEPTUAL",
- "RENDERING_INTENT_RELATIVE_COLORIMETRIC",
- "RENDERING_INTENT_SATURATION",
- "RENDERING_INTENT_UNKNOWN",
- "RENDER_ATTACHMENT",
- "REPEAT",
- "REPLACE",
- "RG",
- "RG16F",
- "RG16I",
- "RG16UI",
- "RG32F",
- "RG32I",
- "RG32UI",
- "RG8",
- "RG8I",
- "RG8UI",
- "RG8_SNORM",
- "RGB",
- "RGB10_A2",
- "RGB10_A2UI",
- "RGB16F",
- "RGB16I",
- "RGB16UI",
- "RGB32F",
- "RGB32I",
- "RGB32UI",
- "RGB565",
- "RGB5_A1",
- "RGB8",
- "RGB8I",
- "RGB8UI",
- "RGB8_SNORM",
- "RGB9_E5",
- "RGBA",
- "RGBA16F",
- "RGBA16I",
- "RGBA16UI",
- "RGBA32F",
- "RGBA32I",
- "RGBA32UI",
- "RGBA4",
- "RGBA8",
- "RGBA8I",
- "RGBA8UI",
- "RGBA8_SNORM",
- "RGBA_INTEGER",
- "RGBColor",
- "RGB_INTEGER",
- "RG_INTEGER",
- "ROTATION_CLOCKWISE",
- "ROTATION_COUNTERCLOCKWISE",
- "RTCCertificate",
- "RTCDTMFSender",
- "RTCDTMFToneChangeEvent",
- "RTCDataChannel",
- "RTCDataChannelEvent",
- "RTCDtlsTransport",
- "RTCEncodedAudioFrame",
- "RTCEncodedVideoFrame",
- "RTCError",
- "RTCErrorEvent",
- "RTCIceCandidate",
- "RTCIceTransport",
- "RTCPeerConnection",
- "RTCPeerConnectionIceErrorEvent",
- "RTCPeerConnectionIceEvent",
- "RTCRtpReceiver",
- "RTCRtpScriptTransform",
- "RTCRtpSender",
- "RTCRtpTransceiver",
- "RTCSctpTransport",
- "RTCSessionDescription",
- "RTCStatsReport",
- "RTCTrackEvent",
- "RadioNodeList",
- "Range",
- "RangeError",
- "RangeException",
- "ReadableByteStreamController",
- "ReadableStream",
- "ReadableStreamBYOBReader",
- "ReadableStreamBYOBRequest",
- "ReadableStreamDefaultController",
- "ReadableStreamDefaultReader",
- "RecordErrorEvent",
- "Rect",
- "ReferenceError",
- "Reflect",
- "RegExp",
- "RelativeOrientationSensor",
- "RelativeTimeFormat",
- "RemotePlayback",
- "Report",
- "ReportBody",
- "ReportingObserver",
- "Request",
- "RequestUpdateCheckStatus",
- "ResizeObserver",
- "ResizeObserverEntry",
- "ResizeObserverSize",
- "Response",
- "RestrictionTarget",
- "RuntimeError",
- "SAMPLER_2D",
- "SAMPLER_2D_ARRAY",
- "SAMPLER_2D_ARRAY_SHADOW",
- "SAMPLER_2D_SHADOW",
- "SAMPLER_3D",
- "SAMPLER_BINDING",
- "SAMPLER_CUBE",
- "SAMPLER_CUBE_SHADOW",
- "SAMPLES",
- "SAMPLE_ALPHA_TO_COVERAGE",
- "SAMPLE_BUFFERS",
- "SAMPLE_COVERAGE",
- "SAMPLE_COVERAGE_INVERT",
- "SAMPLE_COVERAGE_VALUE",
- "SAWTOOTH",
- "SCHEDULED_STATE",
- "SCISSOR_BOX",
- "SCISSOR_TEST",
- "SCROLL_PAGE_DOWN",
- "SCROLL_PAGE_UP",
- "SDP_ANSWER",
- "SDP_OFFER",
- "SDP_PRANSWER",
- "SECURITY_ERR",
- "SELECT",
- "SEPARATE_ATTRIBS",
- "SERIALIZE_ERR",
- "SEVERITY_ERROR",
- "SEVERITY_FATAL_ERROR",
- "SEVERITY_WARNING",
- "SHADER_COMPILER",
- "SHADER_TYPE",
- "SHADING_LANGUAGE_VERSION",
- "SHIFT_MASK",
- "SHORT",
- "SHOWING",
- "SHOW_ALL",
- "SHOW_ATTRIBUTE",
- "SHOW_CDATA_SECTION",
- "SHOW_COMMENT",
- "SHOW_DOCUMENT",
- "SHOW_DOCUMENT_FRAGMENT",
- "SHOW_DOCUMENT_TYPE",
- "SHOW_ELEMENT",
- "SHOW_ENTITY",
- "SHOW_ENTITY_REFERENCE",
- "SHOW_NOTATION",
- "SHOW_PROCESSING_INSTRUCTION",
- "SHOW_TEXT",
- "SIGNALED",
- "SIGNED_NORMALIZED",
- "SINE",
- "SOUNDFIELD",
- "SQLException",
- "SQRT1_2",
- "SQRT2",
- "SQUARE",
- "SRC_ALPHA",
- "SRC_ALPHA_SATURATE",
- "SRC_COLOR",
- "SRGB",
- "SRGB8",
- "SRGB8_ALPHA8",
- "START_TO_END",
- "START_TO_START",
- "STATIC_COPY",
- "STATIC_DRAW",
- "STATIC_READ",
- "STENCIL",
- "STENCIL_ATTACHMENT",
- "STENCIL_BACK_FAIL",
- "STENCIL_BACK_FUNC",
- "STENCIL_BACK_PASS_DEPTH_FAIL",
- "STENCIL_BACK_PASS_DEPTH_PASS",
- "STENCIL_BACK_REF",
- "STENCIL_BACK_VALUE_MASK",
- "STENCIL_BACK_WRITEMASK",
- "STENCIL_BITS",
- "STENCIL_BUFFER_BIT",
- "STENCIL_CLEAR_VALUE",
- "STENCIL_FAIL",
- "STENCIL_FUNC",
- "STENCIL_INDEX",
- "STENCIL_INDEX8",
- "STENCIL_PASS_DEPTH_FAIL",
- "STENCIL_PASS_DEPTH_PASS",
- "STENCIL_REF",
- "STENCIL_TEST",
- "STENCIL_VALUE_MASK",
- "STENCIL_WRITEMASK",
- "STORAGE",
- "STORAGE_BINDING",
- "STREAM_COPY",
- "STREAM_DRAW",
- "STREAM_READ",
- "STRING_TYPE",
- "STYLE_RULE",
- "SUBPIXEL_BITS",
- "SUPPORTS_RULE",
- "SVGAElement",
- "SVGAltGlyphDefElement",
- "SVGAltGlyphElement",
- "SVGAltGlyphItemElement",
- "SVGAngle",
- "SVGAnimateColorElement",
- "SVGAnimateElement",
- "SVGAnimateMotionElement",
- "SVGAnimateTransformElement",
- "SVGAnimatedAngle",
- "SVGAnimatedBoolean",
- "SVGAnimatedEnumeration",
- "SVGAnimatedInteger",
- "SVGAnimatedLength",
- "SVGAnimatedLengthList",
- "SVGAnimatedNumber",
- "SVGAnimatedNumberList",
- "SVGAnimatedPreserveAspectRatio",
- "SVGAnimatedRect",
- "SVGAnimatedString",
- "SVGAnimatedTransformList",
- "SVGAnimationElement",
- "SVGCircleElement",
- "SVGClipPathElement",
- "SVGColor",
- "SVGComponentTransferFunctionElement",
- "SVGCursorElement",
- "SVGDefsElement",
- "SVGDescElement",
- "SVGDiscardElement",
- "SVGDocument",
- "SVGElement",
- "SVGElementInstance",
- "SVGElementInstanceList",
- "SVGEllipseElement",
- "SVGException",
- "SVGFEBlendElement",
- "SVGFEColorMatrixElement",
- "SVGFEComponentTransferElement",
- "SVGFECompositeElement",
- "SVGFEConvolveMatrixElement",
- "SVGFEDiffuseLightingElement",
- "SVGFEDisplacementMapElement",
- "SVGFEDistantLightElement",
- "SVGFEDropShadowElement",
- "SVGFEFloodElement",
- "SVGFEFuncAElement",
- "SVGFEFuncBElement",
- "SVGFEFuncGElement",
- "SVGFEFuncRElement",
- "SVGFEGaussianBlurElement",
- "SVGFEImageElement",
- "SVGFEMergeElement",
- "SVGFEMergeNodeElement",
- "SVGFEMorphologyElement",
- "SVGFEOffsetElement",
- "SVGFEPointLightElement",
- "SVGFESpecularLightingElement",
- "SVGFESpotLightElement",
- "SVGFETileElement",
- "SVGFETurbulenceElement",
- "SVGFilterElement",
- "SVGFontElement",
- "SVGFontFaceElement",
- "SVGFontFaceFormatElement",
- "SVGFontFaceNameElement",
- "SVGFontFaceSrcElement",
- "SVGFontFaceUriElement",
- "SVGForeignObjectElement",
- "SVGGElement",
- "SVGGeometryElement",
- "SVGGlyphElement",
- "SVGGlyphRefElement",
- "SVGGradientElement",
- "SVGGraphicsElement",
- "SVGHKernElement",
- "SVGImageElement",
- "SVGLength",
- "SVGLengthList",
- "SVGLineElement",
- "SVGLinearGradientElement",
- "SVGMPathElement",
- "SVGMarkerElement",
- "SVGMaskElement",
- "SVGMatrix",
- "SVGMetadataElement",
- "SVGMissingGlyphElement",
- "SVGNumber",
- "SVGNumberList",
- "SVGPaint",
- "SVGPathElement",
- "SVGPathSeg",
- "SVGPathSegArcAbs",
- "SVGPathSegArcRel",
- "SVGPathSegClosePath",
- "SVGPathSegCurvetoCubicAbs",
- "SVGPathSegCurvetoCubicRel",
- "SVGPathSegCurvetoCubicSmoothAbs",
- "SVGPathSegCurvetoCubicSmoothRel",
- "SVGPathSegCurvetoQuadraticAbs",
- "SVGPathSegCurvetoQuadraticRel",
- "SVGPathSegCurvetoQuadraticSmoothAbs",
- "SVGPathSegCurvetoQuadraticSmoothRel",
- "SVGPathSegLinetoAbs",
- "SVGPathSegLinetoHorizontalAbs",
- "SVGPathSegLinetoHorizontalRel",
- "SVGPathSegLinetoRel",
- "SVGPathSegLinetoVerticalAbs",
- "SVGPathSegLinetoVerticalRel",
- "SVGPathSegList",
- "SVGPathSegMovetoAbs",
- "SVGPathSegMovetoRel",
- "SVGPatternElement",
- "SVGPoint",
- "SVGPointList",
- "SVGPolygonElement",
- "SVGPolylineElement",
- "SVGPreserveAspectRatio",
- "SVGRadialGradientElement",
- "SVGRect",
- "SVGRectElement",
- "SVGRenderingIntent",
- "SVGSVGElement",
- "SVGScriptElement",
- "SVGSetElement",
- "SVGStopElement",
- "SVGStringList",
- "SVGStyleElement",
- "SVGSwitchElement",
- "SVGSymbolElement",
- "SVGTRefElement",
- "SVGTSpanElement",
- "SVGTextContentElement",
- "SVGTextElement",
- "SVGTextPathElement",
- "SVGTextPositioningElement",
- "SVGTitleElement",
- "SVGTransform",
- "SVGTransformList",
- "SVGUnitTypes",
- "SVGUseElement",
- "SVGVKernElement",
- "SVGViewElement",
- "SVGViewSpec",
- "SVGZoomAndPan",
- "SVGZoomEvent",
- "SVG_ANGLETYPE_DEG",
- "SVG_ANGLETYPE_GRAD",
- "SVG_ANGLETYPE_RAD",
- "SVG_ANGLETYPE_UNKNOWN",
- "SVG_ANGLETYPE_UNSPECIFIED",
- "SVG_CHANNEL_A",
- "SVG_CHANNEL_B",
- "SVG_CHANNEL_G",
- "SVG_CHANNEL_R",
- "SVG_CHANNEL_UNKNOWN",
- "SVG_COLORTYPE_CURRENTCOLOR",
- "SVG_COLORTYPE_RGBCOLOR",
- "SVG_COLORTYPE_RGBCOLOR_ICCCOLOR",
- "SVG_COLORTYPE_UNKNOWN",
- "SVG_EDGEMODE_DUPLICATE",
- "SVG_EDGEMODE_NONE",
- "SVG_EDGEMODE_UNKNOWN",
- "SVG_EDGEMODE_WRAP",
- "SVG_FEBLEND_MODE_COLOR",
- "SVG_FEBLEND_MODE_COLOR_BURN",
- "SVG_FEBLEND_MODE_COLOR_DODGE",
- "SVG_FEBLEND_MODE_DARKEN",
- "SVG_FEBLEND_MODE_DIFFERENCE",
- "SVG_FEBLEND_MODE_EXCLUSION",
- "SVG_FEBLEND_MODE_HARD_LIGHT",
- "SVG_FEBLEND_MODE_HUE",
- "SVG_FEBLEND_MODE_LIGHTEN",
- "SVG_FEBLEND_MODE_LUMINOSITY",
- "SVG_FEBLEND_MODE_MULTIPLY",
- "SVG_FEBLEND_MODE_NORMAL",
- "SVG_FEBLEND_MODE_OVERLAY",
- "SVG_FEBLEND_MODE_SATURATION",
- "SVG_FEBLEND_MODE_SCREEN",
- "SVG_FEBLEND_MODE_SOFT_LIGHT",
- "SVG_FEBLEND_MODE_UNKNOWN",
- "SVG_FECOLORMATRIX_TYPE_HUEROTATE",
- "SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA",
- "SVG_FECOLORMATRIX_TYPE_MATRIX",
- "SVG_FECOLORMATRIX_TYPE_SATURATE",
- "SVG_FECOLORMATRIX_TYPE_UNKNOWN",
- "SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE",
- "SVG_FECOMPONENTTRANSFER_TYPE_GAMMA",
- "SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY",
- "SVG_FECOMPONENTTRANSFER_TYPE_LINEAR",
- "SVG_FECOMPONENTTRANSFER_TYPE_TABLE",
- "SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN",
- "SVG_FECOMPOSITE_OPERATOR_ARITHMETIC",
- "SVG_FECOMPOSITE_OPERATOR_ATOP",
- "SVG_FECOMPOSITE_OPERATOR_IN",
- "SVG_FECOMPOSITE_OPERATOR_LIGHTER",
- "SVG_FECOMPOSITE_OPERATOR_OUT",
- "SVG_FECOMPOSITE_OPERATOR_OVER",
- "SVG_FECOMPOSITE_OPERATOR_UNKNOWN",
- "SVG_FECOMPOSITE_OPERATOR_XOR",
- "SVG_INVALID_VALUE_ERR",
- "SVG_LENGTHTYPE_CM",
- "SVG_LENGTHTYPE_EMS",
- "SVG_LENGTHTYPE_EXS",
- "SVG_LENGTHTYPE_IN",
- "SVG_LENGTHTYPE_MM",
- "SVG_LENGTHTYPE_NUMBER",
- "SVG_LENGTHTYPE_PC",
- "SVG_LENGTHTYPE_PERCENTAGE",
- "SVG_LENGTHTYPE_PT",
- "SVG_LENGTHTYPE_PX",
- "SVG_LENGTHTYPE_UNKNOWN",
- "SVG_MARKERUNITS_STROKEWIDTH",
- "SVG_MARKERUNITS_UNKNOWN",
- "SVG_MARKERUNITS_USERSPACEONUSE",
- "SVG_MARKER_ORIENT_ANGLE",
- "SVG_MARKER_ORIENT_AUTO",
- "SVG_MARKER_ORIENT_AUTO_START_REVERSE",
- "SVG_MARKER_ORIENT_UNKNOWN",
- "SVG_MASKTYPE_ALPHA",
- "SVG_MASKTYPE_LUMINANCE",
- "SVG_MATRIX_NOT_INVERTABLE",
- "SVG_MEETORSLICE_MEET",
- "SVG_MEETORSLICE_SLICE",
- "SVG_MEETORSLICE_UNKNOWN",
- "SVG_MORPHOLOGY_OPERATOR_DILATE",
- "SVG_MORPHOLOGY_OPERATOR_ERODE",
- "SVG_MORPHOLOGY_OPERATOR_UNKNOWN",
- "SVG_PAINTTYPE_CURRENTCOLOR",
- "SVG_PAINTTYPE_NONE",
- "SVG_PAINTTYPE_RGBCOLOR",
- "SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR",
- "SVG_PAINTTYPE_UNKNOWN",
- "SVG_PAINTTYPE_URI",
- "SVG_PAINTTYPE_URI_CURRENTCOLOR",
- "SVG_PAINTTYPE_URI_NONE",
- "SVG_PAINTTYPE_URI_RGBCOLOR",
- "SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR",
- "SVG_PRESERVEASPECTRATIO_NONE",
- "SVG_PRESERVEASPECTRATIO_UNKNOWN",
- "SVG_PRESERVEASPECTRATIO_XMAXYMAX",
- "SVG_PRESERVEASPECTRATIO_XMAXYMID",
- "SVG_PRESERVEASPECTRATIO_XMAXYMIN",
- "SVG_PRESERVEASPECTRATIO_XMIDYMAX",
- "SVG_PRESERVEASPECTRATIO_XMIDYMID",
- "SVG_PRESERVEASPECTRATIO_XMIDYMIN",
- "SVG_PRESERVEASPECTRATIO_XMINYMAX",
- "SVG_PRESERVEASPECTRATIO_XMINYMID",
- "SVG_PRESERVEASPECTRATIO_XMINYMIN",
- "SVG_SPREADMETHOD_PAD",
- "SVG_SPREADMETHOD_REFLECT",
- "SVG_SPREADMETHOD_REPEAT",
- "SVG_SPREADMETHOD_UNKNOWN",
- "SVG_STITCHTYPE_NOSTITCH",
- "SVG_STITCHTYPE_STITCH",
- "SVG_STITCHTYPE_UNKNOWN",
- "SVG_TRANSFORM_MATRIX",
- "SVG_TRANSFORM_ROTATE",
- "SVG_TRANSFORM_SCALE",
- "SVG_TRANSFORM_SKEWX",
- "SVG_TRANSFORM_SKEWY",
- "SVG_TRANSFORM_TRANSLATE",
- "SVG_TRANSFORM_UNKNOWN",
- "SVG_TURBULENCE_TYPE_FRACTALNOISE",
- "SVG_TURBULENCE_TYPE_TURBULENCE",
- "SVG_TURBULENCE_TYPE_UNKNOWN",
- "SVG_UNIT_TYPE_OBJECTBOUNDINGBOX",
- "SVG_UNIT_TYPE_UNKNOWN",
- "SVG_UNIT_TYPE_USERSPACEONUSE",
- "SVG_WRONG_TYPE_ERR",
- "SVG_ZOOMANDPAN_DISABLE",
- "SVG_ZOOMANDPAN_MAGNIFY",
- "SVG_ZOOMANDPAN_UNKNOWN",
- "SYNC_CONDITION",
- "SYNC_FENCE",
- "SYNC_FLAGS",
- "SYNC_FLUSH_COMMANDS_BIT",
- "SYNC_GPU_COMMANDS_COMPLETE",
- "SYNC_STATUS",
- "SYNTAX_ERR",
- "SavedPages",
- "Scheduler",
- "Scheduling",
- "Screen",
- "ScreenDetailed",
- "ScreenDetails",
- "ScreenOrientation",
- "Script",
- "ScriptProcessorNode",
- "ScrollAreaEvent",
- "ScrollTimeline",
- "SecurityPolicyViolationEvent",
- "Segmenter",
- "Selection",
- "Sensor",
- "SensorErrorEvent",
- "Serial",
- "SerialPort",
- "ServiceWorker",
- "ServiceWorkerContainer",
- "ServiceWorkerRegistration",
- "SessionDescription",
- "Set",
- "ShadowRoot",
- "SharedArrayBuffer",
- "SharedStorage",
- "SharedStorageAppendMethod",
- "SharedStorageClearMethod",
- "SharedStorageDeleteMethod",
- "SharedStorageModifierMethod",
- "SharedStorageSetMethod",
- "SharedStorageWorklet",
- "SharedWorker",
- "SharingState",
- "SimpleGestureEvent",
- "SnapEvent",
- "SourceBuffer",
- "SourceBufferList",
- "SpeechGrammar",
- "SpeechGrammarList",
- "SpeechRecognition",
- "SpeechRecognitionErrorEvent",
- "SpeechRecognitionEvent",
- "SpeechRecognitionPhrase",
- "SpeechSynthesis",
- "SpeechSynthesisErrorEvent",
- "SpeechSynthesisEvent",
- "SpeechSynthesisUtterance",
- "SpeechSynthesisVoice",
- "StaticRange",
- "StereoPannerNode",
- "StopIteration",
- "Storage",
- "StorageBucket",
- "StorageBucketManager",
- "StorageEvent",
- "StorageManager",
- "String",
- "StructType",
- "StylePropertyMap",
- "StylePropertyMapReadOnly",
- "StyleSheet",
- "StyleSheetList",
- "SubmitEvent",
- "Subscriber",
- "SubtleCrypto",
- "Summarizer",
- "SuppressedError",
- "SuspendError",
- "Suspending",
- "Symbol",
- "SyncManager",
- "SyntaxError",
- "TAB_ID_NONE",
- "TAB_INDEX_NONE",
- "TEMPORARY",
- "TEXTPATH_METHODTYPE_ALIGN",
- "TEXTPATH_METHODTYPE_STRETCH",
- "TEXTPATH_METHODTYPE_UNKNOWN",
- "TEXTPATH_SPACINGTYPE_AUTO",
- "TEXTPATH_SPACINGTYPE_EXACT",
- "TEXTPATH_SPACINGTYPE_UNKNOWN",
- "TEXTURE",
- "TEXTURE0",
- "TEXTURE1",
- "TEXTURE10",
- "TEXTURE11",
- "TEXTURE12",
- "TEXTURE13",
- "TEXTURE14",
- "TEXTURE15",
- "TEXTURE16",
- "TEXTURE17",
- "TEXTURE18",
- "TEXTURE19",
- "TEXTURE2",
- "TEXTURE20",
- "TEXTURE21",
- "TEXTURE22",
- "TEXTURE23",
- "TEXTURE24",
- "TEXTURE25",
- "TEXTURE26",
- "TEXTURE27",
- "TEXTURE28",
- "TEXTURE29",
- "TEXTURE3",
- "TEXTURE30",
- "TEXTURE31",
- "TEXTURE4",
- "TEXTURE5",
- "TEXTURE6",
- "TEXTURE7",
- "TEXTURE8",
- "TEXTURE9",
- "TEXTURE_2D",
- "TEXTURE_2D_ARRAY",
- "TEXTURE_3D",
- "TEXTURE_BASE_LEVEL",
- "TEXTURE_BINDING",
- "TEXTURE_BINDING_2D",
- "TEXTURE_BINDING_2D_ARRAY",
- "TEXTURE_BINDING_3D",
- "TEXTURE_BINDING_CUBE_MAP",
- "TEXTURE_COMPARE_FUNC",
- "TEXTURE_COMPARE_MODE",
- "TEXTURE_CUBE_MAP",
- "TEXTURE_CUBE_MAP_NEGATIVE_X",
- "TEXTURE_CUBE_MAP_NEGATIVE_Y",
- "TEXTURE_CUBE_MAP_NEGATIVE_Z",
- "TEXTURE_CUBE_MAP_POSITIVE_X",
- "TEXTURE_CUBE_MAP_POSITIVE_Y",
- "TEXTURE_CUBE_MAP_POSITIVE_Z",
- "TEXTURE_IMMUTABLE_FORMAT",
- "TEXTURE_IMMUTABLE_LEVELS",
- "TEXTURE_MAG_FILTER",
- "TEXTURE_MAX_ANISOTROPY_EXT",
- "TEXTURE_MAX_LEVEL",
- "TEXTURE_MAX_LOD",
- "TEXTURE_MIN_FILTER",
- "TEXTURE_MIN_LOD",
- "TEXTURE_WRAP_R",
- "TEXTURE_WRAP_S",
- "TEXTURE_WRAP_T",
- "TEXT_NODE",
- "TIMEOUT",
- "TIMEOUT_ERR",
- "TIMEOUT_EXPIRED",
- "TIMEOUT_IGNORED",
- "TOO_LARGE_ERR",
- "TRANSACTION_INACTIVE_ERR",
- "TRANSFORM_FEEDBACK",
- "TRANSFORM_FEEDBACK_ACTIVE",
- "TRANSFORM_FEEDBACK_BINDING",
- "TRANSFORM_FEEDBACK_BUFFER",
- "TRANSFORM_FEEDBACK_BUFFER_BINDING",
- "TRANSFORM_FEEDBACK_BUFFER_MODE",
- "TRANSFORM_FEEDBACK_BUFFER_SIZE",
- "TRANSFORM_FEEDBACK_BUFFER_START",
- "TRANSFORM_FEEDBACK_PAUSED",
- "TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN",
- "TRANSFORM_FEEDBACK_VARYINGS",
- "TRIANGLE",
- "TRIANGLES",
- "TRIANGLE_FAN",
- "TRIANGLE_STRIP",
- "TYPE_BACK_FORWARD",
- "TYPE_ERR",
- "TYPE_MISMATCH_ERR",
- "TYPE_NAVIGATE",
- "TYPE_RELOAD",
- "TYPE_RESERVED",
- "Tab",
- "TabStatus",
- "Table",
- "Tag",
- "TaskAttributionTiming",
- "TaskController",
- "TaskPriorityChangeEvent",
- "TaskSignal",
- "Temporal",
- "Text",
- "TextDecoder",
- "TextDecoderStream",
- "TextEncoder",
- "TextEncoderStream",
- "TextEvent",
- "TextFormat",
- "TextFormatUpdateEvent",
- "TextMetrics",
- "TextTrack",
- "TextTrackCue",
- "TextTrackCueList",
- "TextTrackList",
- "TextUpdateEvent",
- "TimeEvent",
- "TimeRanges",
- "ToggleEvent",
- "Touch",
- "TouchEvent",
- "TouchList",
- "TrackEvent",
- "TransformStream",
- "TransformStreamDefaultController",
- "TransitionEvent",
- "Translator",
- "TreeWalker",
- "TrustedHTML",
- "TrustedScript",
- "TrustedScriptURL",
- "TrustedTypePolicy",
- "TrustedTypePolicyFactory",
- "TypeError",
- "TypedObject",
- "U2F",
- "UIEvent",
- "UNCACHED",
- "UNIFORM",
- "UNIFORM_ARRAY_STRIDE",
- "UNIFORM_BLOCK_ACTIVE_UNIFORMS",
- "UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES",
- "UNIFORM_BLOCK_BINDING",
- "UNIFORM_BLOCK_DATA_SIZE",
- "UNIFORM_BLOCK_INDEX",
- "UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER",
- "UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER",
- "UNIFORM_BUFFER",
- "UNIFORM_BUFFER_BINDING",
- "UNIFORM_BUFFER_OFFSET_ALIGNMENT",
- "UNIFORM_BUFFER_SIZE",
- "UNIFORM_BUFFER_START",
- "UNIFORM_IS_ROW_MAJOR",
- "UNIFORM_MATRIX_STRIDE",
- "UNIFORM_OFFSET",
- "UNIFORM_SIZE",
- "UNIFORM_TYPE",
- "UNKNOWN_ERR",
- "UNKNOWN_RULE",
- "UNMASKED_RENDERER_WEBGL",
- "UNMASKED_VENDOR_WEBGL",
- "UNORDERED_NODE_ITERATOR_TYPE",
- "UNORDERED_NODE_SNAPSHOT_TYPE",
- "UNPACK_ALIGNMENT",
- "UNPACK_COLORSPACE_CONVERSION_WEBGL",
- "UNPACK_FLIP_Y_WEBGL",
- "UNPACK_IMAGE_HEIGHT",
- "UNPACK_PREMULTIPLY_ALPHA_WEBGL",
- "UNPACK_ROW_LENGTH",
- "UNPACK_SKIP_IMAGES",
- "UNPACK_SKIP_PIXELS",
- "UNPACK_SKIP_ROWS",
- "UNSCHEDULED_STATE",
- "UNSENT",
- "UNSIGNALED",
- "UNSIGNED_BYTE",
- "UNSIGNED_INT",
- "UNSIGNED_INT_10F_11F_11F_REV",
- "UNSIGNED_INT_24_8",
- "UNSIGNED_INT_2_10_10_10_REV",
- "UNSIGNED_INT_5_9_9_9_REV",
- "UNSIGNED_INT_SAMPLER_2D",
- "UNSIGNED_INT_SAMPLER_2D_ARRAY",
- "UNSIGNED_INT_SAMPLER_3D",
- "UNSIGNED_INT_SAMPLER_CUBE",
- "UNSIGNED_INT_VEC2",
- "UNSIGNED_INT_VEC3",
- "UNSIGNED_INT_VEC4",
- "UNSIGNED_NORMALIZED",
- "UNSIGNED_SHORT",
- "UNSIGNED_SHORT_4_4_4_4",
- "UNSIGNED_SHORT_5_5_5_1",
- "UNSIGNED_SHORT_5_6_5",
- "UNSPECIFIED_EVENT_TYPE_ERR",
- "UPDATEREADY",
- "URIError",
- "URL",
- "URLPattern",
- "URLSearchParams",
- "URLUnencoded",
- "URL_MISMATCH_ERR",
- "USB",
- "USBAlternateInterface",
- "USBConfiguration",
- "USBConnectionEvent",
- "USBDevice",
- "USBEndpoint",
- "USBInTransferResult",
- "USBInterface",
- "USBIsochronousInTransferPacket",
- "USBIsochronousInTransferResult",
- "USBIsochronousOutTransferPacket",
- "USBIsochronousOutTransferResult",
- "USBOutTransferResult",
- "UTC",
- "Uint16Array",
- "Uint32Array",
- "Uint8Array",
- "Uint8ClampedArray",
- "UpdateFilter",
- "UpdatePropertyName",
- "UserActivation",
- "UserMessageHandler",
- "UserMessageHandlersNamespace",
- "UserProximityEvent",
- "VALIDATE_STATUS",
- "VALIDATION_ERR",
- "VARIABLES_RULE",
- "VENDOR",
- "VERSION",
- "VERSION_CHANGE",
- "VERSION_ERR",
- "VERTEX",
- "VERTEX_ARRAY_BINDING",
- "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING",
- "VERTEX_ATTRIB_ARRAY_DIVISOR",
- "VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE",
- "VERTEX_ATTRIB_ARRAY_ENABLED",
- "VERTEX_ATTRIB_ARRAY_INTEGER",
- "VERTEX_ATTRIB_ARRAY_NORMALIZED",
- "VERTEX_ATTRIB_ARRAY_POINTER",
- "VERTEX_ATTRIB_ARRAY_SIZE",
- "VERTEX_ATTRIB_ARRAY_STRIDE",
- "VERTEX_ATTRIB_ARRAY_TYPE",
- "VERTEX_SHADER",
- "VERTICAL",
- "VERTICAL_AXIS",
- "VER_ERR",
- "VIEWPORT",
- "VIEWPORT_RULE",
- "VRDisplay",
- "VRDisplayCapabilities",
- "VRDisplayEvent",
- "VREyeParameters",
- "VRFieldOfView",
- "VRFrameData",
- "VRPose",
- "VRStageParameters",
- "VTTCue",
- "VTTRegion",
- "ValidityState",
- "VideoColorSpace",
- "VideoDecoder",
- "VideoEncoder",
- "VideoFrame",
- "VideoPlaybackQuality",
- "VideoStreamTrack",
- "ViewTimeline",
- "ViewTransition",
- "ViewTransitionTypeSet",
- "ViewType",
- "Viewport",
- "VirtualKeyboard",
- "VirtualKeyboardGeometryChangeEvent",
- "VisibilityStateEntry",
- "VisualViewport",
- "WAIT_FAILED",
- "WEBKIT_FILTER_RULE",
- "WEBKIT_KEYFRAMES_RULE",
- "WEBKIT_KEYFRAME_RULE",
- "WEBKIT_REGION_RULE",
- "WGSLLanguageFeatures",
- "WINDOW_ID_CURRENT",
- "WINDOW_ID_NONE",
- "WRITE",
- "WRONG_DOCUMENT_ERR",
- "WakeLock",
- "WakeLockSentinel",
- "WasmAnyRef",
- "WaveShaperNode",
- "WeakMap",
- "WeakRef",
- "WeakSet",
- "WebAssembly",
- "WebGL2RenderingContext",
- "WebGLActiveInfo",
- "WebGLBuffer",
- "WebGLContextEvent",
- "WebGLFramebuffer",
- "WebGLObject",
- "WebGLProgram",
- "WebGLQuery",
- "WebGLRenderbuffer",
- "WebGLRenderingContext",
- "WebGLSampler",
- "WebGLShader",
- "WebGLShaderPrecisionFormat",
- "WebGLSync",
- "WebGLTexture",
- "WebGLTransformFeedback",
- "WebGLUniformLocation",
- "WebGLVertexArray",
- "WebGLVertexArrayObject",
- "WebKitAnimationEvent",
- "WebKitBlobBuilder",
- "WebKitCSSFilterRule",
- "WebKitCSSFilterValue",
- "WebKitCSSKeyframeRule",
- "WebKitCSSKeyframesRule",
- "WebKitCSSMatrix",
- "WebKitCSSRegionRule",
- "WebKitCSSTransformValue",
- "WebKitDataCue",
- "WebKitGamepad",
- "WebKitMediaKeyError",
- "WebKitMediaKeyMessageEvent",
- "WebKitMediaKeySession",
- "WebKitMediaKeys",
- "WebKitMediaSource",
- "WebKitMutationObserver",
- "WebKitNamespace",
- "WebKitPlaybackTargetAvailabilityEvent",
- "WebKitPoint",
- "WebKitShadowRoot",
- "WebKitSourceBuffer",
- "WebKitSourceBufferList",
- "WebKitTransitionEvent",
- "WebSocket",
- "WebSocketError",
- "WebSocketStream",
- "WebTransport",
- "WebTransportBidirectionalStream",
- "WebTransportDatagramDuplexStream",
- "WebTransportError",
- "WebTransportReceiveStream",
- "WebTransportSendStream",
- "WebkitAlignContent",
- "WebkitAlignItems",
- "WebkitAlignSelf",
- "WebkitAnimation",
- "WebkitAnimationDelay",
- "WebkitAnimationDirection",
- "WebkitAnimationDuration",
- "WebkitAnimationFillMode",
- "WebkitAnimationIterationCount",
- "WebkitAnimationName",
- "WebkitAnimationPlayState",
- "WebkitAnimationTimingFunction",
- "WebkitAppearance",
- "WebkitBackfaceVisibility",
- "WebkitBackgroundClip",
- "WebkitBackgroundOrigin",
- "WebkitBackgroundSize",
- "WebkitBorderBottomLeftRadius",
- "WebkitBorderBottomRightRadius",
- "WebkitBorderImage",
- "WebkitBorderRadius",
- "WebkitBorderTopLeftRadius",
- "WebkitBorderTopRightRadius",
- "WebkitBoxAlign",
- "WebkitBoxDirection",
- "WebkitBoxFlex",
- "WebkitBoxOrdinalGroup",
- "WebkitBoxOrient",
- "WebkitBoxPack",
- "WebkitBoxShadow",
- "WebkitBoxSizing",
- "WebkitClipPath",
- "WebkitFilter",
- "WebkitFlex",
- "WebkitFlexBasis",
- "WebkitFlexDirection",
- "WebkitFlexFlow",
- "WebkitFlexGrow",
- "WebkitFlexShrink",
- "WebkitFlexWrap",
- "WebkitFontFeatureSettings",
- "WebkitJustifyContent",
- "WebkitLineClamp",
- "WebkitMask",
- "WebkitMaskClip",
- "WebkitMaskComposite",
- "WebkitMaskImage",
- "WebkitMaskOrigin",
- "WebkitMaskPosition",
- "WebkitMaskPositionX",
- "WebkitMaskPositionY",
- "WebkitMaskRepeat",
- "WebkitMaskSize",
- "WebkitOrder",
- "WebkitPerspective",
- "WebkitPerspectiveOrigin",
- "WebkitTextFillColor",
- "WebkitTextSecurity",
- "WebkitTextSizeAdjust",
- "WebkitTextStroke",
- "WebkitTextStrokeColor",
- "WebkitTextStrokeWidth",
- "WebkitTransform",
- "WebkitTransformOrigin",
- "WebkitTransformStyle",
- "WebkitTransition",
- "WebkitTransitionDelay",
- "WebkitTransitionDuration",
- "WebkitTransitionProperty",
- "WebkitTransitionTimingFunction",
- "WebkitUserSelect",
- "WheelEvent",
- "Window",
- "WindowControlsOverlay",
- "WindowControlsOverlayGeometryChangeEvent",
- "WindowState",
- "WindowType",
- "Worker",
- "Worklet",
- "WritableStream",
- "WritableStreamDefaultController",
- "WritableStreamDefaultWriter",
- "XMLDocument",
- "XMLHttpRequest",
- "XMLHttpRequestEventTarget",
- "XMLHttpRequestException",
- "XMLHttpRequestProgressEvent",
- "XMLHttpRequestUpload",
- "XMLSerializer",
- "XMLStylesheetProcessingInstruction",
- "XPathEvaluator",
- "XPathException",
- "XPathExpression",
- "XPathNSResolver",
- "XPathResult",
- "XRAnchor",
- "XRAnchorSet",
- "XRBoundedReferenceSpace",
- "XRCPUDepthInformation",
- "XRCamera",
- "XRDOMOverlayState",
- "XRDepthInformation",
- "XRFrame",
- "XRHand",
- "XRHitTestResult",
- "XRHitTestSource",
- "XRInputSource",
- "XRInputSourceArray",
- "XRInputSourceEvent",
- "XRInputSourcesChangeEvent",
- "XRJointPose",
- "XRJointSpace",
- "XRLayer",
- "XRLightEstimate",
- "XRLightProbe",
- "XRPose",
- "XRRay",
- "XRReferenceSpace",
- "XRReferenceSpaceEvent",
- "XRRenderState",
- "XRRigidTransform",
- "XRSession",
- "XRSessionEvent",
- "XRSpace",
- "XRSystem",
- "XRTransientInputHitTestResult",
- "XRTransientInputHitTestSource",
- "XRView",
- "XRViewerPose",
- "XRViewport",
- "XRWebGLBinding",
- "XRWebGLDepthInformation",
- "XRWebGLLayer",
- "XSLTProcessor",
- "ZERO",
- "ZonedDateTime",
- "ZoomSettings",
- "ZoomSettingsMode",
- "ZoomSettingsScope",
- "_XD0M_",
- "_YD0M_",
- "__REACT_DEVTOOLS_GLOBAL_HOOK__",
- "__brand",
- "__defineGetter__",
- "__defineSetter__",
- "__lookupGetter__",
- "__lookupSetter__",
- "__opera",
- "__proto__",
- "_browserjsran",
- "a",
- "aLink",
- "abbr",
- "abort",
- "aborted",
- "aboutConfigPrefs",
- "abs",
- "absolute",
- "acceleration",
- "accelerationIncludingGravity",
- "accelerator",
- "accent-color",
- "accentColor",
- "accept",
- "acceptCharset",
- "acceptNode",
- "access",
- "accessKey",
- "accessKeyLabel",
- "accuracy",
- "acos",
- "acosh",
- "action",
- "actionURL",
- "actions",
- "activated",
- "activation",
- "activationStart",
- "active",
- "activeCues",
- "activeElement",
- "activeSourceBuffers",
- "activeSourceCount",
- "activeTexture",
- "activeVRDisplays",
- "activeViewTransition",
- "activityLog",
- "actualBoundingBoxAscent",
- "actualBoundingBoxDescent",
- "actualBoundingBoxLeft",
- "actualBoundingBoxRight",
- "adAuctionComponents",
- "adAuctionHeaders",
- "adapterInfo",
- "add",
- "addAll",
- "addBehavior",
- "addCandidate",
- "addColorStop",
- "addCue",
- "addElement",
- "addEventListener",
- "addFilter",
- "addFromString",
- "addFromUri",
- "addIceCandidate",
- "addImport",
- "addListener",
- "addModule",
- "addNamed",
- "addPageRule",
- "addPath",
- "addPointer",
- "addRange",
- "addRegion",
- "addRule",
- "addSearchEngine",
- "addSourceBuffer",
- "addStream",
- "addTeardown",
- "addTextTrack",
- "addTrack",
- "addTransceiver",
- "addWakeLockListener",
- "added",
- "addedNodes",
- "additionalName",
- "additiveSymbols",
- "addons",
- "address",
- "addressLine",
- "addressModeU",
- "addressModeV",
- "addressModeW",
- "adopt",
- "adoptNode",
- "adoptedCallback",
- "adoptedStyleSheets",
- "adr",
- "advance",
- "after",
- "alarms",
- "album",
- "alert",
- "algorithm",
- "align",
- "align-content",
- "align-items",
- "align-self",
- "alignContent",
- "alignItems",
- "alignSelf",
- "alignmentBaseline",
- "alinkColor",
- "all",
- "allSettled",
- "allocationSize",
- "allow",
- "allowFullscreen",
- "allowPaymentRequest",
- "allowedDirections",
- "allowedFeatures",
- "allowedToPlay",
- "allowsFeature",
- "alpha",
- "alphaMode",
- "alphaToCoverageEnabled",
- "alphabeticBaseline",
- "alt",
- "altGraphKey",
- "altHtml",
- "altKey",
- "altLeft",
- "alternate",
- "alternateSetting",
- "alternates",
- "altitude",
- "altitudeAccuracy",
- "altitudeAngle",
- "amplitude",
- "ancestorOrigins",
- "anchor",
- "anchorName",
- "anchorNode",
- "anchorOffset",
- "anchorScope",
- "anchorSpace",
- "anchors",
- "and",
- "angle",
- "angularAcceleration",
- "angularVelocity",
- "animVal",
- "animate",
- "animated",
- "animatedInstanceRoot",
- "animatedNormalizedPathSegList",
- "animatedPathSegList",
- "animatedPoints",
- "animation",
- "animation-composition",
- "animation-delay",
- "animation-direction",
- "animation-duration",
- "animation-fill-mode",
- "animation-iteration-count",
- "animation-name",
- "animation-play-state",
- "animation-timing-function",
- "animationComposition",
- "animationDelay",
- "animationDirection",
- "animationDuration",
- "animationFillMode",
- "animationIterationCount",
- "animationName",
- "animationPlayState",
- "animationStartTime",
- "animationTimingFunction",
- "animationsPaused",
- "anniversary",
- "annotation",
- "antialias",
- "anticipatedRemoval",
- "any",
- "app",
- "appCodeName",
- "appMinorVersion",
- "appName",
- "appNotifications",
- "appVersion",
- "appearance",
- "append",
- "appendBuffer",
- "appendChild",
- "appendData",
- "appendItem",
- "appendMedium",
- "appendNamed",
- "appendRule",
- "appendStream",
- "appendWindowEnd",
- "appendWindowStart",
- "applets",
- "applicationCache",
- "applicationServerKey",
- "apply",
- "applyConstraints",
- "applyElement",
- "arc",
- "arcTo",
- "arch",
- "architecture",
- "archive",
- "areas",
- "arguments",
- "ariaActiveDescendantElement",
- "ariaAtomic",
- "ariaAutoComplete",
- "ariaBrailleLabel",
- "ariaBrailleRoleDescription",
- "ariaBusy",
- "ariaChecked",
- "ariaColCount",
- "ariaColIndex",
- "ariaColIndexText",
- "ariaColSpan",
- "ariaControlsElements",
- "ariaCurrent",
- "ariaDescribedByElements",
- "ariaDescription",
- "ariaDetailsElements",
- "ariaDisabled",
- "ariaErrorMessageElements",
- "ariaExpanded",
- "ariaFlowToElements",
- "ariaHasPopup",
- "ariaHidden",
- "ariaInvalid",
- "ariaKeyShortcuts",
- "ariaLabel",
- "ariaLabelledByElements",
- "ariaLevel",
- "ariaLive",
- "ariaModal",
- "ariaMultiLine",
- "ariaMultiSelectable",
- "ariaNotify",
- "ariaOrientation",
- "ariaOwnsElements",
- "ariaPlaceholder",
- "ariaPosInSet",
- "ariaPressed",
- "ariaReadOnly",
- "ariaRelevant",
- "ariaRequired",
- "ariaRoleDescription",
- "ariaRowCount",
- "ariaRowIndex",
- "ariaRowIndexText",
- "ariaRowSpan",
- "ariaSelected",
- "ariaSetSize",
- "ariaSort",
- "ariaValueMax",
- "ariaValueMin",
- "ariaValueNow",
- "ariaValueText",
- "arrayBuffer",
- "arrayLayerCount",
- "arrayStride",
- "artist",
- "artwork",
- "as",
- "asIntN",
- "asUintN",
- "ascentOverride",
- "asin",
- "asinh",
- "aspect",
- "aspect-ratio",
- "aspectRatio",
- "assert",
- "assign",
- "assignedElements",
- "assignedNodes",
- "assignedSlot",
- "async",
- "asyncDispose",
- "asyncIterator",
- "at",
- "atEnd",
- "atan",
- "atan2",
- "atanh",
- "atob",
- "attachEvent",
- "attachInternals",
- "attachShader",
- "attachShadow",
- "attachedElements",
- "attachments",
- "attack",
- "attestationObject",
- "attrChange",
- "attrName",
- "attributeChangedCallback",
- "attributeFilter",
- "attributeName",
- "attributeNamespace",
- "attributeOldValue",
- "attributeStyleMap",
- "attributes",
- "attribution",
- "attributionSrc",
- "audioBitrateMode",
- "audioBitsPerSecond",
- "audioTracks",
- "audioWorklet",
- "authenticatedSignedWrites",
- "authenticatorAttachment",
- "authenticatorData",
- "autoIncrement",
- "autobuffer",
- "autocapitalize",
- "autocomplete",
- "autocorrect",
- "autofocus",
- "automationRate",
- "autoplay",
- "availHeight",
- "availLeft",
- "availTop",
- "availWidth",
- "availability",
- "available",
- "averageLatency",
- "aversion",
- "ax",
- "axes",
- "axis",
- "ay",
- "azimuth",
- "azimuthAngle",
- "b",
- "back",
- "backdrop-filter",
- "backdropFilter",
- "backends",
- "backface-visibility",
- "backfaceVisibility",
- "background",
- "background-attachment",
- "background-blend-mode",
- "background-clip",
- "background-color",
- "background-image",
- "background-origin",
- "background-position",
- "background-position-x",
- "background-position-y",
- "background-repeat",
- "background-size",
- "backgroundAttachment",
- "backgroundBlendMode",
- "backgroundClip",
- "backgroundColor",
- "backgroundFetch",
- "backgroundImage",
- "backgroundOrigin",
- "backgroundPosition",
- "backgroundPositionX",
- "backgroundPositionY",
- "backgroundRepeat",
- "backgroundSize",
- "badInput",
- "badge",
- "balance",
- "baseArrayLayer",
- "baseFrequencyX",
- "baseFrequencyY",
- "baseLatency",
- "baseLayer",
- "baseMipLevel",
- "baseNode",
- "baseOffset",
- "basePalette",
- "baseURI",
- "baseVal",
- "baseline-source",
- "baselineShift",
- "baselineSource",
- "batchUpdate",
- "battery",
- "bday",
- "before",
- "beginComputePass",
- "beginElement",
- "beginElementAt",
- "beginOcclusionQuery",
- "beginPath",
- "beginQuery",
- "beginRenderPass",
- "beginTransformFeedback",
- "beginningOfPassWriteIndex",
- "behavior",
- "behaviorCookie",
- "behaviorPart",
- "behaviorUrns",
- "beta",
- "bezierCurveTo",
- "bgColor",
- "bgProperties",
- "bias",
- "big",
- "bigint64",
- "biguint64",
- "binaryType",
- "bind",
- "bindAttribLocation",
- "bindBuffer",
- "bindBufferBase",
- "bindBufferRange",
- "bindFramebuffer",
- "bindGroupLayouts",
- "bindRenderbuffer",
- "bindSampler",
- "bindTexture",
- "bindTransformFeedback",
- "bindVertexArray",
- "binding",
- "bitness",
- "blend",
- "blendColor",
- "blendEquation",
- "blendEquationSeparate",
- "blendFunc",
- "blendFuncSeparate",
- "blink",
- "blitFramebuffer",
- "blob",
- "block-size",
- "blockDirection",
- "blockSize",
- "blockedURI",
- "blockedURL",
- "blocking",
- "blockingDuration",
- "blue",
- "bluetooth",
- "blur",
- "body",
- "bodyUsed",
- "bold",
- "bookmarks",
- "booleanValue",
- "boost",
- "border",
- "border-block",
- "border-block-color",
- "border-block-end",
- "border-block-end-color",
- "border-block-end-style",
- "border-block-end-width",
- "border-block-start",
- "border-block-start-color",
- "border-block-start-style",
- "border-block-start-width",
- "border-block-style",
- "border-block-width",
- "border-bottom",
- "border-bottom-color",
- "border-bottom-left-radius",
- "border-bottom-right-radius",
- "border-bottom-style",
- "border-bottom-width",
- "border-collapse",
- "border-color",
- "border-end-end-radius",
- "border-end-start-radius",
- "border-image",
- "border-image-outset",
- "border-image-repeat",
- "border-image-slice",
- "border-image-source",
- "border-image-width",
- "border-inline",
- "border-inline-color",
- "border-inline-end",
- "border-inline-end-color",
- "border-inline-end-style",
- "border-inline-end-width",
- "border-inline-start",
- "border-inline-start-color",
- "border-inline-start-style",
- "border-inline-start-width",
- "border-inline-style",
- "border-inline-width",
- "border-left",
- "border-left-color",
- "border-left-style",
- "border-left-width",
- "border-radius",
- "border-right",
- "border-right-color",
- "border-right-style",
- "border-right-width",
- "border-spacing",
- "border-start-end-radius",
- "border-start-start-radius",
- "border-style",
- "border-top",
- "border-top-color",
- "border-top-left-radius",
- "border-top-right-radius",
- "border-top-style",
- "border-top-width",
- "border-width",
- "borderBlock",
- "borderBlockColor",
- "borderBlockEnd",
- "borderBlockEndColor",
- "borderBlockEndStyle",
- "borderBlockEndWidth",
- "borderBlockStart",
- "borderBlockStartColor",
- "borderBlockStartStyle",
- "borderBlockStartWidth",
- "borderBlockStyle",
- "borderBlockWidth",
- "borderBottom",
- "borderBottomColor",
- "borderBottomLeftRadius",
- "borderBottomRightRadius",
- "borderBottomStyle",
- "borderBottomWidth",
- "borderBoxSize",
- "borderCollapse",
- "borderColor",
- "borderColorDark",
- "borderColorLight",
- "borderEndEndRadius",
- "borderEndStartRadius",
- "borderImage",
- "borderImageOutset",
- "borderImageRepeat",
- "borderImageSlice",
- "borderImageSource",
- "borderImageWidth",
- "borderInline",
- "borderInlineColor",
- "borderInlineEnd",
- "borderInlineEndColor",
- "borderInlineEndStyle",
- "borderInlineEndWidth",
- "borderInlineStart",
- "borderInlineStartColor",
- "borderInlineStartStyle",
- "borderInlineStartWidth",
- "borderInlineStyle",
- "borderInlineWidth",
- "borderLeft",
- "borderLeftColor",
- "borderLeftStyle",
- "borderLeftWidth",
- "borderRadius",
- "borderRight",
- "borderRightColor",
- "borderRightStyle",
- "borderRightWidth",
- "borderSpacing",
- "borderStartEndRadius",
- "borderStartStartRadius",
- "borderStyle",
- "borderTop",
- "borderTopColor",
- "borderTopLeftRadius",
- "borderTopRightRadius",
- "borderTopStyle",
- "borderTopWidth",
- "borderWidth",
- "bottom",
- "bottomMargin",
- "bound",
- "boundElements",
- "boundingClientRect",
- "boundingHeight",
- "boundingLeft",
- "boundingRect",
- "boundingTop",
- "boundingWidth",
- "bounds",
- "boundsGeometry",
- "box",
- "box-decoration-break",
- "box-shadow",
- "box-sizing",
- "boxDecorationBreak",
- "boxShadow",
- "boxSizing",
- "brand",
- "brands",
- "break-after",
- "break-before",
- "break-inside",
- "breakAfter",
- "breakBefore",
- "breakInside",
- "broadcast",
- "browser",
- "browserLanguage",
- "browserSettings",
- "browsingData",
- "browsingTopics",
- "btoa",
- "bubbles",
- "buffer",
- "bufferData",
- "bufferDepth",
- "bufferSize",
- "bufferSubData",
- "buffered",
- "bufferedAmount",
- "bufferedAmountLowThreshold",
- "buffers",
- "buildID",
- "buildNumber",
- "button",
- "buttonID",
- "buttons",
- "byobRequest",
- "byteLength",
- "byteOffset",
- "bytes",
- "bytesPerRow",
- "bytesWritten",
- "c",
- "cache",
- "caches",
- "calendar",
- "call",
- "caller",
- "camera",
- "canBeFormatted",
- "canBeMounted",
- "canBeShared",
- "canConstructInDedicatedWorker",
- "canGoBack",
- "canGoForward",
- "canHaveChildren",
- "canHaveHTML",
- "canInsertDTMF",
- "canIntercept",
- "canLoadAdAuctionFencedFrame",
- "canLoadOpaqueURL",
- "canMakePayment",
- "canParse",
- "canPlayType",
- "canPresent",
- "canShare",
- "canTransition",
- "canTrickleIceCandidates",
- "cancel",
- "cancelAndHoldAtTime",
- "cancelAnimationFrame",
- "cancelBubble",
- "cancelIdleCallback",
- "cancelScheduledValues",
- "cancelVideoFrameCallback",
- "cancelWatchAvailability",
- "cancelable",
- "candidate",
- "canonicalUUID",
- "canvas",
- "cap",
- "capabilities",
- "caption",
- "caption-side",
- "captionSide",
- "captivePortal",
- "capture",
- "captureEvents",
- "captureStackTrace",
- "captureStream",
- "captureTab",
- "captureVisibleTab",
- "caret-color",
- "caretBidiLevel",
- "caretColor",
- "caretPositionFromPoint",
- "caretRangeFromPoint",
- "cast",
- "catch",
- "category",
- "cause",
- "cbrt",
- "cd",
- "ceil",
- "cellIndex",
- "cellPadding",
- "cellSpacing",
- "cells",
- "ch",
- "chOff",
- "chain",
- "challenge",
- "changeType",
- "changed",
- "changedTouches",
- "channel",
- "channelCount",
- "channelCountMode",
- "channelInterpretation",
- "chapterInfo",
- "char",
- "charAt",
- "charCode",
- "charCodeAt",
- "charIndex",
- "charLength",
- "characterBounds",
- "characterBoundsRangeStart",
- "characterData",
- "characterDataOldValue",
- "characterSet",
- "characterVariant",
- "characteristic",
- "charging",
- "chargingTime",
- "charset",
- "check",
- "checkDCE",
- "checkEnclosure",
- "checkFramebufferStatus",
- "checkIntersection",
- "checkValidity",
- "checkVisibility",
- "checked",
- "childElementCount",
- "childList",
- "childNodes",
- "children",
- "chrome",
- "ciphertext",
- "cite",
- "city",
- "claimInterface",
- "claimed",
- "classList",
- "className",
- "classid",
- "clear",
- "clearAppBadge",
- "clearAttributes",
- "clearBuffer",
- "clearBufferfi",
- "clearBufferfv",
- "clearBufferiv",
- "clearBufferuiv",
- "clearColor",
- "clearData",
- "clearDepth",
- "clearHalt",
- "clearImmediate",
- "clearInterval",
- "clearLiveSeekableRange",
- "clearMarks",
- "clearMaxGCPauseAccumulator",
- "clearMeasures",
- "clearOriginJoinedAdInterestGroups",
- "clearParameters",
- "clearRect",
- "clearResourceTimings",
- "clearShadow",
- "clearStencil",
- "clearTimeout",
- "clearValue",
- "clearWatch",
- "click",
- "clickCount",
- "clientDataJSON",
- "clientHeight",
- "clientInformation",
- "clientLeft",
- "clientRect",
- "clientRects",
- "clientTop",
- "clientWaitSync",
- "clientWidth",
- "clientX",
- "clientY",
- "clip",
- "clip-path",
- "clip-rule",
- "clipBottom",
- "clipLeft",
- "clipPath",
- "clipPathUnits",
- "clipRight",
- "clipRule",
- "clipTop",
- "clipboard",
- "clipboardData",
- "clonable",
- "clone",
- "cloneContents",
- "cloneNode",
- "cloneRange",
- "close",
- "closeCode",
- "closePath",
- "closed",
- "closedBy",
- "closest",
- "clz",
- "clz32",
- "cm",
- "cmp",
- "code",
- "codeBase",
- "codePointAt",
- "codeType",
- "codedHeight",
- "codedRect",
- "codedWidth",
- "colSpan",
- "collapse",
- "collapseToEnd",
- "collapseToStart",
- "collapsed",
- "collect",
- "collections",
- "colno",
- "color",
- "color-adjust",
- "color-interpolation",
- "color-interpolation-filters",
- "color-scheme",
- "colorAdjust",
- "colorAttachments",
- "colorDepth",
- "colorFormats",
- "colorInterpolation",
- "colorInterpolationFilters",
- "colorMask",
- "colorScheme",
- "colorSpace",
- "colorType",
- "cols",
- "column-count",
- "column-fill",
- "column-gap",
- "column-rule",
- "column-rule-color",
- "column-rule-style",
- "column-rule-width",
- "column-span",
- "column-width",
- "columnCount",
- "columnFill",
- "columnGap",
- "columnNumber",
- "columnRule",
- "columnRuleColor",
- "columnRuleStyle",
- "columnRuleWidth",
- "columnSpan",
- "columnWidth",
- "columns",
- "command",
- "commandForElement",
- "commands",
- "commit",
- "commitLoadTime",
- "commitPreferences",
- "commitStyles",
- "committed",
- "commonAncestorContainer",
- "compact",
- "compare",
- "compareBoundaryPoints",
- "compareDocumentPosition",
- "compareEndPoints",
- "compareExchange",
- "compareNode",
- "comparePoint",
- "compatMode",
- "compatible",
- "compile",
- "compileShader",
- "compileStreaming",
- "complete",
- "completed",
- "component",
- "componentFromPoint",
- "composed",
- "composedPath",
- "composite",
- "compositionEndOffset",
- "compositionStartOffset",
- "compressedTexImage2D",
- "compressedTexImage3D",
- "compressedTexSubImage2D",
- "compressedTexSubImage3D",
- "compute",
- "computedStyleMap",
- "concat",
- "conditionText",
- "coneInnerAngle",
- "coneOuterAngle",
- "coneOuterGain",
- "config",
- "configURL",
- "configurable",
- "configuration",
- "configurationName",
- "configurationValue",
- "configurations",
- "configure",
- "confirm",
- "confirmComposition",
- "confirmSiteSpecificTrackingException",
- "confirmWebWideTrackingException",
- "congestionControl",
- "connect",
- "connectEnd",
- "connectNative",
- "connectShark",
- "connectStart",
- "connected",
- "connectedCallback",
- "connectedMoveCallback",
- "connection",
- "connectionInfo",
- "connectionList",
- "connectionSpeed",
- "connectionState",
- "connections",
- "console",
- "consolidate",
- "constants",
- "constraint",
- "constrictionActive",
- "construct",
- "constructor",
- "contactID",
- "contain",
- "contain-intrinsic-block-size",
- "contain-intrinsic-height",
- "contain-intrinsic-inline-size",
- "contain-intrinsic-size",
- "contain-intrinsic-width",
- "containIntrinsicBlockSize",
- "containIntrinsicHeight",
- "containIntrinsicInlineSize",
- "containIntrinsicSize",
- "containIntrinsicWidth",
- "container",
- "container-name",
- "container-type",
- "containerId",
- "containerName",
- "containerQuery",
- "containerSrc",
- "containerType",
- "contains",
- "containsNode",
- "content",
- "content-visibility",
- "contentBoxSize",
- "contentDocument",
- "contentEditable",
- "contentEncoding",
- "contentHint",
- "contentOverflow",
- "contentRect",
- "contentScriptType",
- "contentStyleType",
- "contentType",
- "contentVisibility",
- "contentWindow",
- "context",
- "contextId",
- "contextIds",
- "contextMenu",
- "contextMenus",
- "contextType",
- "contextTypes",
- "contextmenu",
- "contextualIdentities",
- "continue",
- "continuePrimaryKey",
- "continuous",
- "control",
- "controlTransferIn",
- "controlTransferOut",
- "controller",
- "controls",
- "controlsList",
- "convertPointFromNode",
- "convertQuadFromNode",
- "convertRectFromNode",
- "convertToBlob",
- "convertToSpecifiedUnits",
- "cookie",
- "cookieEnabled",
- "cookieStore",
- "cookies",
- "coords",
- "copyBufferSubData",
- "copyBufferToBuffer",
- "copyBufferToTexture",
- "copyExternalImageToTexture",
- "copyFromChannel",
- "copyTexImage2D",
- "copyTexSubImage2D",
- "copyTexSubImage3D",
- "copyTextureToBuffer",
- "copyTextureToTexture",
- "copyTo",
- "copyToChannel",
- "copyWithin",
- "correspondingElement",
- "correspondingUseElement",
- "corruptedVideoFrames",
- "cos",
- "cosh",
- "count",
- "countReset",
- "counter-increment",
- "counter-reset",
- "counter-set",
- "counterIncrement",
- "counterReset",
- "counterSet",
- "country",
- "cpuClass",
- "cpuSleepAllowed",
- "cqb",
- "cqh",
- "cqi",
- "cqmax",
- "cqmin",
- "cqw",
- "create",
- "createAnalyser",
- "createAnchor",
- "createAnswer",
- "createAttribute",
- "createAttributeNS",
- "createAuctionNonce",
- "createBidirectionalStream",
- "createBindGroup",
- "createBindGroupLayout",
- "createBiquadFilter",
- "createBuffer",
- "createBufferSource",
- "createCDATASection",
- "createCSSStyleSheet",
- "createCaption",
- "createChannelMerger",
- "createChannelSplitter",
- "createCommandEncoder",
- "createComment",
- "createComputePipeline",
- "createComputePipelineAsync",
- "createConicGradient",
- "createConstantSource",
- "createContextualFragment",
- "createControlRange",
- "createConvolver",
- "createDTMFSender",
- "createDataChannel",
- "createDelay",
- "createDelayNode",
- "createDocument",
- "createDocumentFragment",
- "createDocumentType",
- "createDynamicsCompressor",
- "createElement",
- "createElementNS",
- "createEncodedStreams",
- "createEntityReference",
- "createEvent",
- "createEventObject",
- "createExpression",
- "createFramebuffer",
- "createFunction",
- "createGain",
- "createGainNode",
- "createHTML",
- "createHTMLDocument",
- "createIIRFilter",
- "createImageBitmap",
- "createImageData",
- "createIndex",
- "createJavaScriptNode",
- "createLinearGradient",
- "createMediaElementSource",
- "createMediaKeys",
- "createMediaStreamDestination",
- "createMediaStreamSource",
- "createMediaStreamTrackSource",
- "createMutableFile",
- "createNSResolver",
- "createNodeIterator",
- "createNotification",
- "createObjectStore",
- "createObjectURL",
- "createOffer",
- "createOscillator",
- "createPanner",
- "createPattern",
- "createPeriodicWave",
- "createPipelineLayout",
- "createPolicy",
- "createPopup",
- "createProcessingInstruction",
- "createProgram",
- "createQuery",
- "createQuerySet",
- "createRadialGradient",
- "createRange",
- "createRangeCollection",
- "createReader",
- "createRenderBundleEncoder",
- "createRenderPipeline",
- "createRenderPipelineAsync",
- "createRenderbuffer",
- "createSVGAngle",
- "createSVGLength",
- "createSVGMatrix",
- "createSVGNumber",
- "createSVGPathSegArcAbs",
- "createSVGPathSegArcRel",
- "createSVGPathSegClosePath",
- "createSVGPathSegCurvetoCubicAbs",
- "createSVGPathSegCurvetoCubicRel",
- "createSVGPathSegCurvetoCubicSmoothAbs",
- "createSVGPathSegCurvetoCubicSmoothRel",
- "createSVGPathSegCurvetoQuadraticAbs",
- "createSVGPathSegCurvetoQuadraticRel",
- "createSVGPathSegCurvetoQuadraticSmoothAbs",
- "createSVGPathSegCurvetoQuadraticSmoothRel",
- "createSVGPathSegLinetoAbs",
- "createSVGPathSegLinetoHorizontalAbs",
- "createSVGPathSegLinetoHorizontalRel",
- "createSVGPathSegLinetoRel",
- "createSVGPathSegLinetoVerticalAbs",
- "createSVGPathSegLinetoVerticalRel",
- "createSVGPathSegMovetoAbs",
- "createSVGPathSegMovetoRel",
- "createSVGPoint",
- "createSVGRect",
- "createSVGTransform",
- "createSVGTransformFromMatrix",
- "createSampler",
- "createScript",
- "createScriptProcessor",
- "createScriptURL",
- "createSession",
- "createShader",
- "createShaderModule",
- "createShadowRoot",
- "createStereoPanner",
- "createStyleSheet",
- "createTBody",
- "createTFoot",
- "createTHead",
- "createTask",
- "createTextNode",
- "createTextRange",
- "createTexture",
- "createTouch",
- "createTouchList",
- "createTransformFeedback",
- "createTreeWalker",
- "createUnidirectionalStream",
- "createVertexArray",
- "createView",
- "createWaveShaper",
- "createWorklet",
- "createWritable",
- "creationTime",
- "credentialless",
- "credentials",
- "criticalCHRestart",
- "cropTo",
- "crossOrigin",
- "crossOriginIsolated",
- "crypto",
- "csi",
- "csp",
- "cssFloat",
- "cssRules",
- "cssText",
- "cssValueType",
- "ctrlKey",
- "ctrlLeft",
- "cues",
- "cullFace",
- "cullMode",
- "currentCSSZoom",
- "currentDirection",
- "currentEntry",
- "currentLocalDescription",
- "currentNode",
- "currentPage",
- "currentRect",
- "currentRemoteDescription",
- "currentScale",
- "currentScreen",
- "currentScript",
- "currentSrc",
- "currentState",
- "currentStyle",
- "currentTarget",
- "currentTime",
- "currentTranslate",
- "currentView",
- "cursor",
- "curve",
- "customElements",
- "customError",
- "cx",
- "cy",
- "d",
- "data",
- "dataFld",
- "dataFormatAs",
- "dataLoss",
- "dataLossMessage",
- "dataPageSize",
- "dataSrc",
- "dataTransfer",
- "database",
- "databases",
- "datagrams",
- "dataset",
- "dateStyle",
- "dateTime",
- "day",
- "dayPeriod",
- "days",
- "db",
- "debug",
- "debuggerEnabled",
- "declarativeNetRequest",
- "declare",
- "decode",
- "decodeAudioData",
- "decodeQueueSize",
- "decodeURI",
- "decodeURIComponent",
- "decodedBodySize",
- "decoding",
- "decodingInfo",
- "decreaseZoomLevel",
- "decrypt",
- "default",
- "defaultCharset",
- "defaultChecked",
- "defaultMuted",
- "defaultPlaybackRate",
- "defaultPolicy",
- "defaultPrevented",
- "defaultQueue",
- "defaultRequest",
- "defaultSelected",
- "defaultStatus",
- "defaultURL",
- "defaultValue",
- "defaultView",
- "defaultstatus",
- "defer",
- "define",
- "defineMagicFunction",
- "defineMagicVariable",
- "defineProperties",
- "defineProperty",
- "deg",
- "delay",
- "delayTime",
- "delegatesFocus",
- "delete",
- "deleteBuffer",
- "deleteCaption",
- "deleteCell",
- "deleteContents",
- "deleteData",
- "deleteDatabase",
- "deleteFramebuffer",
- "deleteFromDocument",
- "deleteIndex",
- "deleteMedium",
- "deleteObjectStore",
- "deleteProgram",
- "deleteProperty",
- "deleteQuery",
- "deleteRenderbuffer",
- "deleteRow",
- "deleteRule",
- "deleteSampler",
- "deleteShader",
- "deleteSync",
- "deleteTFoot",
- "deleteTHead",
- "deleteTexture",
- "deleteTransformFeedback",
- "deleteVertexArray",
- "deleted",
- "deliverChangeRecords",
- "deliveredFrames",
- "deliveredFramesDuration",
- "delivery",
- "deliveryInfo",
- "deliveryStatus",
- "deliveryTimestamp",
- "deliveryType",
- "delta",
- "deltaMode",
- "deltaX",
- "deltaY",
- "deltaZ",
- "dependentLocality",
- "deprecatedReplaceInURN",
- "deprecatedRunAdAuctionEnforcesKAnonymity",
- "deprecatedURNToURL",
- "depthActive",
- "depthBias",
- "depthBiasClamp",
- "depthBiasSlopeScale",
- "depthClearValue",
- "depthCompare",
- "depthDataFormat",
- "depthFailOp",
- "depthFar",
- "depthFunc",
- "depthLoadOp",
- "depthMask",
- "depthNear",
- "depthOrArrayLayers",
- "depthRange",
- "depthReadOnly",
- "depthStencil",
- "depthStencilAttachment",
- "depthStencilFormat",
- "depthStoreOp",
- "depthType",
- "depthUsage",
- "depthWriteEnabled",
- "deref",
- "deriveBits",
- "deriveKey",
- "descentOverride",
- "description",
- "deselectAll",
- "designMode",
- "desiredSize",
- "destination",
- "destinationURL",
- "destroy",
- "detach",
- "detachEvent",
- "detachShader",
- "detached",
- "detail",
- "details",
- "detect",
- "detectLanguage",
- "detune",
- "device",
- "deviceClass",
- "deviceId",
- "deviceMemory",
- "devicePixelContentBoxSize",
- "devicePixelRatio",
- "devicePosture",
- "deviceProtocol",
- "deviceSubclass",
- "deviceVersionMajor",
- "deviceVersionMinor",
- "deviceVersionSubminor",
- "deviceXDPI",
- "deviceYDPI",
- "devtools",
- "devtools_panels",
- "didTimeout",
- "difference",
- "diffuseConstant",
- "digest",
- "dimension",
- "dimensions",
- "dir",
- "dirName",
- "direction",
- "dirxml",
- "disable",
- "disablePictureInPicture",
- "disableRemotePlayback",
- "disableVertexAttribArray",
- "disabled",
- "discard",
- "discardedFrames",
- "dischargingTime",
- "disconnect",
- "disconnectShark",
- "disconnectedCallback",
- "dispatchEvent",
- "dispatchWorkgroups",
- "dispatchWorkgroupsIndirect",
- "display",
- "displayHeight",
- "displayId",
- "displayName",
- "displayWidth",
- "dispose",
- "disposeAsync",
- "disposed",
- "disposition",
- "distanceModel",
- "div",
- "divisor",
- "djsapi",
- "djsproxy",
- "dns",
- "doImport",
- "doNotTrack",
- "doScroll",
- "doctype",
- "document",
- "documentElement",
- "documentId",
- "documentIds",
- "documentLifecycle",
- "documentMode",
- "documentOrigin",
- "documentOrigins",
- "documentPictureInPicture",
- "documentURI",
- "documentURL",
- "documentUrl",
- "documentUrls",
- "dolphin",
- "dolphinGameCenter",
- "dolphininfo",
- "dolphinmeta",
- "dom",
- "domComplete",
- "domContentLoadedEventEnd",
- "domContentLoadedEventStart",
- "domInteractive",
- "domLoading",
- "domOverlayState",
- "domain",
- "domainLookupEnd",
- "domainLookupStart",
- "dominant-baseline",
- "dominantBaseline",
- "done",
- "dopplerFactor",
- "dotAll",
- "downDegrees",
- "downlink",
- "download",
- "downloadRequest",
- "downloadTotal",
- "downloaded",
- "downloads",
- "dpcm",
- "dpi",
- "dppx",
- "dragDrop",
- "draggable",
- "draw",
- "drawArrays",
- "drawArraysInstanced",
- "drawArraysInstancedANGLE",
- "drawBuffers",
- "drawCustomFocusRing",
- "drawElements",
- "drawElementsInstanced",
- "drawElementsInstancedANGLE",
- "drawFocusIfNeeded",
- "drawImage",
- "drawImageFromRect",
- "drawIndexed",
- "drawIndexedIndirect",
- "drawIndirect",
- "drawRangeElements",
- "drawSystemFocusRing",
- "drawingBufferColorSpace",
- "drawingBufferFormat",
- "drawingBufferHeight",
- "drawingBufferStorage",
- "drawingBufferWidth",
- "drop",
- "dropEffect",
- "droppedVideoFrames",
- "dropzone",
- "dstFactor",
- "dtmf",
- "dump",
- "dumpProfile",
- "duplex",
- "duplicate",
- "durability",
- "duration",
- "dvb",
- "dvh",
- "dvi",
- "dvmax",
- "dvmin",
- "dvname",
- "dvnum",
- "dvw",
- "dx",
- "dy",
- "dynamicId",
- "dynsrc",
- "e",
- "edgeMode",
- "editContext",
- "effect",
- "effectAllowed",
- "effectiveDirective",
- "effectiveType",
- "effects",
- "elapsedTime",
- "element",
- "elementFromPoint",
- "elementTiming",
- "elements",
- "elementsFromPoint",
- "elevation",
- "ellipse",
- "em",
- "emHeightAscent",
- "emHeightDescent",
- "email",
- "embeds",
- "emit",
- "emma",
- "empty",
- "empty-cells",
- "emptyCells",
- "emptyHTML",
- "emptyScript",
- "emulatedPosition",
- "enable",
- "enableBackground",
- "enableDelegations",
- "enableStyleSheetsForSet",
- "enableVertexAttribArray",
- "enabled",
- "enabledFeatures",
- "enabledPlugin",
- "encode",
- "encodeInto",
- "encodeQueueSize",
- "encodeURI",
- "encodeURIComponent",
- "encodedBodySize",
- "encoding",
- "encodingInfo",
- "encrypt",
- "enctype",
- "end",
- "endContainer",
- "endElement",
- "endElementAt",
- "endOcclusionQuery",
- "endOfPassWriteIndex",
- "endOfStream",
- "endOffset",
- "endQuery",
- "endTime",
- "endTransformFeedback",
- "ended",
- "endpoint",
- "endpointNumber",
- "endpoints",
- "endsWith",
- "enqueue",
- "enterKeyHint",
- "entities",
- "entries",
- "entry",
- "entryPoint",
- "entryType",
- "enumerable",
- "enumerate",
- "enumerateDevices",
- "enumerateEditable",
- "environmentBlendMode",
- "equals",
- "era",
- "error",
- "errorCode",
- "errorDetail",
- "errorText",
- "escape",
- "estimate",
- "eval",
- "evaluate",
- "event",
- "eventCounts",
- "eventPhase",
- "events",
- "every",
- "ex",
- "exception",
- "exchange",
- "exec",
- "execCommand",
- "execCommandShowHelp",
- "execScript",
- "executeBundles",
- "executionStart",
- "exitFullscreen",
- "exitPictureInPicture",
- "exitPointerLock",
- "exitPresent",
- "exp",
- "expand",
- "expandEntityReferences",
- "expando",
- "expansion",
- "expectedContextLanguages",
- "expectedImprovement",
- "expectedInputLanguages",
- "experiments",
- "expiration",
- "expirationTime",
- "expires",
- "expiryDate",
- "explicitOriginalTarget",
- "expm1",
- "exponent",
- "exponentialRampToValueAtTime",
- "exportKey",
- "exports",
- "extend",
- "extension",
- "extensionTypes",
- "extensions",
- "extentNode",
- "extentOffset",
- "external",
- "externalResourcesRequired",
- "externalTexture",
- "extractContents",
- "extractable",
- "eye",
- "f",
- "f16round",
- "face",
- "factoryReset",
- "failOp",
- "failureReason",
- "fallback",
- "family",
- "familyName",
- "farthestViewportElement",
- "fastSeek",
- "fatal",
- "featureId",
- "featurePolicy",
- "featureSettings",
- "features",
- "fence",
- "fenceSync",
- "fetch",
- "fetchLater",
- "fetchPriority",
- "fetchStart",
- "fftSize",
- "fgColor",
- "fieldOfView",
- "file",
- "fileCreatedDate",
- "fileHandle",
- "fileModifiedDate",
- "fileName",
- "fileSize",
- "fileUpdatedDate",
- "filename",
- "files",
- "filesystem",
- "fill",
- "fill-opacity",
- "fill-rule",
- "fillJointRadii",
- "fillLightMode",
- "fillOpacity",
- "fillPoses",
- "fillRect",
- "fillRule",
- "fillStyle",
- "fillText",
- "filter",
- "filterResX",
- "filterResY",
- "filterUnits",
- "filters",
- "finalResponseHeadersStart",
- "finally",
- "find",
- "findIndex",
- "findLast",
- "findLastIndex",
- "findRule",
- "findText",
- "finish",
- "finishDocumentLoadTime",
- "finishLoadTime",
- "finished",
- "fireEvent",
- "firesTouchEvents",
- "first",
- "firstChild",
- "firstElementChild",
- "firstInterimResponseStart",
- "firstPage",
- "firstPaintAfterLoadTime",
- "firstPaintTime",
- "firstUIEventTimestamp",
- "fixed",
- "flags",
- "flat",
- "flatMap",
- "flex",
- "flex-basis",
- "flex-direction",
- "flex-flow",
- "flex-grow",
- "flex-shrink",
- "flex-wrap",
- "flexBasis",
- "flexDirection",
- "flexFlow",
- "flexGrow",
- "flexShrink",
- "flexWrap",
- "flip",
- "flipX",
- "flipY",
- "float",
- "float32",
- "float64",
- "flood-color",
- "flood-opacity",
- "floodColor",
- "floodOpacity",
- "floor",
- "flush",
- "focus",
- "focusNode",
- "focusOffset",
- "font",
- "font-family",
- "font-feature-settings",
- "font-kerning",
- "font-language-override",
- "font-optical-sizing",
- "font-palette",
- "font-size",
- "font-size-adjust",
- "font-stretch",
- "font-style",
- "font-synthesis",
- "font-synthesis-position",
- "font-synthesis-small-caps",
- "font-synthesis-style",
- "font-synthesis-weight",
- "font-variant",
- "font-variant-alternates",
- "font-variant-caps",
- "font-variant-east-asian",
- "font-variant-ligatures",
- "font-variant-numeric",
- "font-variant-position",
- "font-variation-settings",
- "font-weight",
- "fontBoundingBoxAscent",
- "fontBoundingBoxDescent",
- "fontFamily",
- "fontFeatureSettings",
- "fontKerning",
- "fontLanguageOverride",
- "fontOpticalSizing",
- "fontPalette",
- "fontSize",
- "fontSizeAdjust",
- "fontSmoothingEnabled",
- "fontStretch",
- "fontStyle",
- "fontSynthesis",
- "fontSynthesisPosition",
- "fontSynthesisSmallCaps",
- "fontSynthesisStyle",
- "fontSynthesisWeight",
- "fontVariant",
- "fontVariantAlternates",
- "fontVariantCaps",
- "fontVariantEastAsian",
- "fontVariantEmoji",
- "fontVariantLigatures",
- "fontVariantNumeric",
- "fontVariantPosition",
- "fontVariationSettings",
- "fontWeight",
- "fontcolor",
- "fontfaces",
- "fonts",
- "fontsize",
- "for",
- "forEach",
- "force",
- "forceFallbackAdapter",
- "forceRedraw",
- "forced-color-adjust",
- "forcedColorAdjust",
- "forcedStyleAndLayoutDuration",
- "forget",
- "form",
- "formAction",
- "formData",
- "formEnctype",
- "formMethod",
- "formNoValidate",
- "formTarget",
- "format",
- "formatToParts",
- "forms",
- "forward",
- "forwardWheel",
- "forwardX",
- "forwardY",
- "forwardZ",
- "foundation",
- "fr",
- "fractionalSecondDigits",
- "fragment",
- "fragmentDirective",
- "frame",
- "frameBorder",
- "frameCount",
- "frameElement",
- "frameId",
- "frameIds",
- "frameSpacing",
- "framebuffer",
- "framebufferHeight",
- "framebufferRenderbuffer",
- "framebufferTexture2D",
- "framebufferTextureLayer",
- "framebufferWidth",
- "frames",
- "freeSpace",
- "freeze",
- "frequency",
- "frequencyBinCount",
- "from",
- "fromAsync",
- "fromBase64",
- "fromCharCode",
- "fromCodePoint",
- "fromElement",
- "fromEntries",
- "fromFloat32Array",
- "fromFloat64Array",
- "fromHex",
- "fromMatrix",
- "fromPoint",
- "fromQuad",
- "fromRect",
- "frontFace",
- "fround",
- "fullName",
- "fullPath",
- "fullRange",
- "fullScreen",
- "fullVersionList",
- "fullscreen",
- "fullscreenElement",
- "fullscreenEnabled",
- "fx",
- "fy",
- "g",
- "gain",
- "gamepad",
- "gamma",
- "gap",
- "gatheringState",
- "gatt",
- "geckoProfiler",
- "genderIdentity",
- "generateCertificate",
- "generateKey",
- "generateMipmap",
- "generateRequest",
- "geolocation",
- "gestureObject",
- "get",
- "getAcceptLanguages",
- "getActiveAttrib",
- "getActiveUniform",
- "getActiveUniformBlockName",
- "getActiveUniformBlockParameter",
- "getActiveUniforms",
- "getAdjacentText",
- "getAll",
- "getAllKeys",
- "getAllRecords",
- "getAllResponseHeaders",
- "getAllowlistForFeature",
- "getAnimations",
- "getAsFile",
- "getAsFileSystemHandle",
- "getAsString",
- "getAttachedShaders",
- "getAttribLocation",
- "getAttribute",
- "getAttributeNS",
- "getAttributeNames",
- "getAttributeNode",
- "getAttributeNodeNS",
- "getAttributeType",
- "getAudioTracks",
- "getAuthenticatorData",
- "getAutoplayPolicy",
- "getAvailability",
- "getBBox",
- "getBackgroundPage",
- "getBadgeBackgroundColor",
- "getBadgeText",
- "getBadgeTextColor",
- "getBattery",
- "getBigInt64",
- "getBigUint64",
- "getBindGroupLayout",
- "getBlob",
- "getBookmark",
- "getBoundingClientRect",
- "getBounds",
- "getBoxQuads",
- "getBrowserInfo",
- "getBufferParameter",
- "getBufferSubData",
- "getByteFrequencyData",
- "getByteTimeDomainData",
- "getCSSCanvasContext",
- "getCTM",
- "getCameraImage",
- "getCandidateWindowClientRect",
- "getCanonicalLocales",
- "getCapabilities",
- "getCaptureHandle",
- "getChannelData",
- "getCharNumAtPosition",
- "getCharacteristic",
- "getCharacteristics",
- "getClientCapabilities",
- "getClientExtensionResults",
- "getClientRect",
- "getClientRects",
- "getCoalescedEvents",
- "getCompilationInfo",
- "getComposedRanges",
- "getCompositionAlternatives",
- "getComputedStyle",
- "getComputedTextLength",
- "getComputedTiming",
- "getConfiguration",
- "getConstraints",
- "getContext",
- "getContextAttributes",
- "getContexts",
- "getContributingSources",
- "getCounterValue",
- "getCueAsHTML",
- "getCueById",
- "getCurrent",
- "getCurrentPosition",
- "getCurrentTexture",
- "getCurrentTime",
- "getData",
- "getDatabaseNames",
- "getDate",
- "getDay",
- "getDefaultComputedStyle",
- "getDepthInMeters",
- "getDepthInformation",
- "getDescriptor",
- "getDescriptors",
- "getDestinationInsertionPoints",
- "getDevices",
- "getDirectory",
- "getDirectoryHandle",
- "getDisplayMedia",
- "getDistributedNodes",
- "getEditable",
- "getElementById",
- "getElementsByClassName",
- "getElementsByName",
- "getElementsByTagName",
- "getElementsByTagNameNS",
- "getEnclosureList",
- "getEndPositionOfChar",
- "getEntries",
- "getEntriesByName",
- "getEntriesByType",
- "getError",
- "getExtension",
- "getExtentOfChar",
- "getEyeParameters",
- "getFeature",
- "getFiberRoots",
- "getFile",
- "getFileHandle",
- "getFiles",
- "getFilesAndDirectories",
- "getFingerprints",
- "getFloat16",
- "getFloat32",
- "getFloat64",
- "getFloatFrequencyData",
- "getFloatTimeDomainData",
- "getFloatValue",
- "getFragDataLocation",
- "getFrameData",
- "getFrameId",
- "getFramebufferAttachmentParameter",
- "getFrequencyResponse",
- "getFullYear",
- "getGamepads",
- "getHTML",
- "getHeaderExtensionsToNegotiate",
- "getHighEntropyValues",
- "getHitTestResults",
- "getHitTestResultsForTransientInput",
- "getHours",
- "getIdentityAssertion",
- "getIds",
- "getImageData",
- "getIndexedParameter",
- "getInfo",
- "getInnerHTML",
- "getInstalledRelatedApps",
- "getInt16",
- "getInt32",
- "getInt8",
- "getInterestGroupAdAuctionData",
- "getInternalModuleRanges",
- "getInternalformatParameter",
- "getIntersectionList",
- "getItem",
- "getItems",
- "getJointPose",
- "getKey",
- "getKeyframes",
- "getLastFocused",
- "getLayers",
- "getLayoutMap",
- "getLightEstimate",
- "getLineDash",
- "getLocalCandidates",
- "getLocalParameters",
- "getLocalStreams",
- "getManagedConfiguration",
- "getManifest",
- "getMappedRange",
- "getMarks",
- "getMatchedCSSRules",
- "getMaxGCPauseSinceClear",
- "getMeasures",
- "getMessage",
- "getMetadata",
- "getMilliseconds",
- "getMinutes",
- "getModifierState",
- "getMonth",
- "getName",
- "getNamedItem",
- "getNamedItemNS",
- "getNativeFramebufferScaleFactor",
- "getNegotiatedHeaderExtensions",
- "getNestedConfigs",
- "getNotifications",
- "getNotifier",
- "getNumberOfChars",
- "getOffsetReferenceSpace",
- "getOrInsert",
- "getOrInsertComputed",
- "getOutputTimestamp",
- "getOverrideHistoryNavigationMode",
- "getOverrideStyle",
- "getOwnPropertyDescriptor",
- "getOwnPropertyDescriptors",
- "getOwnPropertyNames",
- "getOwnPropertySymbols",
- "getPackageDirectoryEntry",
- "getParameter",
- "getParameters",
- "getParent",
- "getPathData",
- "getPathSegAtLength",
- "getPathSegmentAtLength",
- "getPermissionWarningsByManifest",
- "getPhotoCapabilities",
- "getPhotoSettings",
- "getPlatformInfo",
- "getPointAtLength",
- "getPopup",
- "getPorts",
- "getPose",
- "getPredictedEvents",
- "getPreference",
- "getPreferenceDefault",
- "getPreferredCanvasFormat",
- "getPresentationAttribute",
- "getPreventDefault",
- "getPrimaryService",
- "getPrimaryServices",
- "getProgramInfoLog",
- "getProgramParameter",
- "getPropertyCSSValue",
- "getPropertyPriority",
- "getPropertyShorthand",
- "getPropertyType",
- "getPropertyValue",
- "getPrototypeOf",
- "getPublicKey",
- "getPublicKeyAlgorithm",
- "getQuery",
- "getQueryParameter",
- "getRGBColorValue",
- "getRandomValues",
- "getRangeAt",
- "getReader",
- "getReceivers",
- "getRectValue",
- "getReflectionCubeMap",
- "getRegistration",
- "getRegistrations",
- "getRemoteCandidates",
- "getRemoteCertificates",
- "getRemoteParameters",
- "getRemoteStreams",
- "getRenderbufferParameter",
- "getResponseHeader",
- "getRoot",
- "getRootNode",
- "getRotationOfChar",
- "getSVGDocument",
- "getSamplerParameter",
- "getScreenCTM",
- "getScreenDetails",
- "getSeconds",
- "getSelectedCandidatePair",
- "getSelection",
- "getSelf",
- "getSenders",
- "getService",
- "getSetCookie",
- "getSettings",
- "getShaderInfoLog",
- "getShaderParameter",
- "getShaderPrecisionFormat",
- "getShaderSource",
- "getSignals",
- "getSimpleDuration",
- "getSiteIcons",
- "getSources",
- "getSpeculativeParserUrls",
- "getStartPositionOfChar",
- "getStartTime",
- "getState",
- "getStats",
- "getStatusForPolicy",
- "getStorageUpdates",
- "getStreamById",
- "getStringValue",
- "getSubStringLength",
- "getSubscription",
- "getSubscriptions",
- "getSupportedConstraints",
- "getSupportedExtensions",
- "getSupportedFormats",
- "getSupportedZoomLevels",
- "getSyncParameter",
- "getSynchronizationSources",
- "getTags",
- "getTargetRanges",
- "getTexParameter",
- "getTextFormats",
- "getTime",
- "getTimezoneOffset",
- "getTiming",
- "getTitle",
- "getTitlebarAreaRect",
- "getTotalLength",
- "getTrackById",
- "getTracks",
- "getTransceivers",
- "getTransform",
- "getTransformFeedbackVarying",
- "getTransformToElement",
- "getTransports",
- "getType",
- "getTypeMapping",
- "getUILanguage",
- "getURL",
- "getUTCDate",
- "getUTCDay",
- "getUTCFullYear",
- "getUTCHours",
- "getUTCMilliseconds",
- "getUTCMinutes",
- "getUTCMonth",
- "getUTCSeconds",
- "getUint16",
- "getUint32",
- "getUint8",
- "getUniform",
- "getUniformBlockIndex",
- "getUniformIndices",
- "getUniformLocation",
- "getUserInfo",
- "getUserMedia",
- "getUserSettings",
- "getVRDisplays",
- "getValues",
- "getVarDate",
- "getVariableValue",
- "getVertexAttrib",
- "getVertexAttribOffset",
- "getVideoPlaybackQuality",
- "getVideoTracks",
- "getViewerPose",
- "getViewport",
- "getViews",
- "getVoices",
- "getWakeLockState",
- "getWriter",
- "getYear",
- "getZoom",
- "getZoomSettings",
- "givenName",
- "global",
- "globalAlpha",
- "globalCompositeOperation",
- "globalPrivacyControl",
- "globalThis",
- "glyphOrientationHorizontal",
- "glyphOrientationVertical",
- "glyphRef",
- "go",
- "goBack",
- "goForward",
- "gpu",
- "grabFrame",
- "grad",
- "gradientTransform",
- "gradientUnits",
- "grammars",
- "green",
- "grid",
- "grid-area",
- "grid-auto-columns",
- "grid-auto-flow",
- "grid-auto-rows",
- "grid-column",
- "grid-column-end",
- "grid-column-gap",
- "grid-column-start",
- "grid-gap",
- "grid-row",
- "grid-row-end",
- "grid-row-gap",
- "grid-row-start",
- "grid-template",
- "grid-template-areas",
- "grid-template-columns",
- "grid-template-rows",
- "gridArea",
- "gridAutoColumns",
- "gridAutoFlow",
- "gridAutoRows",
- "gridColumn",
- "gridColumnEnd",
- "gridColumnGap",
- "gridColumnStart",
- "gridGap",
- "gridRow",
- "gridRowEnd",
- "gridRowGap",
- "gridRowStart",
- "gridTemplate",
- "gridTemplateAreas",
- "gridTemplateColumns",
- "gridTemplateRows",
- "gripSpace",
- "group",
- "groupBy",
- "groupCollapsed",
- "groupEnd",
- "groupId",
- "groups",
- "grow",
- "growable",
- "guestProcessId",
- "guestRenderFrameRoutingId",
- "hadRecentInput",
- "hand",
- "handedness",
- "hangingBaseline",
- "hapticActuators",
- "hardwareConcurrency",
- "has",
- "hasAttribute",
- "hasAttributeNS",
- "hasAttributes",
- "hasBeenActive",
- "hasChildNodes",
- "hasComposition",
- "hasDynamicOffset",
- "hasEnrolledInstrument",
- "hasExtension",
- "hasExternalDisplay",
- "hasFeature",
- "hasFocus",
- "hasIndices",
- "hasInstance",
- "hasLayout",
- "hasOrientation",
- "hasOwn",
- "hasOwnProperty",
- "hasPointerCapture",
- "hasPosition",
- "hasPrivateToken",
- "hasReading",
- "hasRedemptionRecord",
- "hasRegExpGroups",
- "hasStorageAccess",
- "hasUAVisualTransition",
- "hasUnpartitionedCookieAccess",
- "hash",
- "hashChange",
- "head",
- "headers",
- "heading",
- "height",
- "hid",
- "hidden",
- "hide",
- "hideFocus",
- "hidePopover",
- "high",
- "highWaterMark",
- "highlight",
- "highlights",
- "highlightsFromPoint",
- "hint",
- "hints",
- "history",
- "honorificPrefix",
- "honorificSuffix",
- "horizontalOverflow",
- "host",
- "hostCandidate",
- "hostname",
- "hour",
- "hour12",
- "hourCycle",
- "hours",
- "href",
- "hrefTranslate",
- "hreflang",
- "hspace",
- "html5TagCheckInerface",
- "htmlFor",
- "htmlText",
- "httpEquiv",
- "httpRequestStatusCode",
- "hwTimestamp",
- "hyphenate-character",
- "hyphenateCharacter",
- "hyphenateLimitChars",
- "hyphens",
- "hypot",
- "i18n",
- "ic",
- "iccId",
- "iceConnectionState",
- "iceGatheringState",
- "iceTransport",
- "icon",
- "iconURL",
- "id",
- "identifier",
- "identity",
- "ideographicBaseline",
- "idle",
- "idpLoginUrl",
- "ignoreBOM",
- "ignoreCase",
- "ignoreDepthValues",
- "image",
- "image-orientation",
- "image-rendering",
- "imageHeight",
- "imageOrientation",
- "imageRendering",
- "imageSizes",
- "imageSmoothingEnabled",
- "imageSmoothingQuality",
- "imageSrcset",
- "imageWidth",
- "images",
- "ime-mode",
- "imeMode",
- "implementation",
- "importExternalTexture",
- "importKey",
- "importNode",
- "importStylesheet",
- "imports",
- "impp",
- "imul",
- "in",
- "in1",
- "in2",
- "inBandMetadataTrackDispatchType",
- "inIncognitoContext",
- "inRange",
- "includes",
- "incognito",
- "incomingBidirectionalStreams",
- "incomingHighWaterMark",
- "incomingMaxAge",
- "incomingUnidirectionalStreams",
- "increaseZoomLevel",
- "incremental",
- "indeterminate",
- "index",
- "indexNames",
- "indexOf",
- "indexedDB",
- "indicate",
- "indices",
- "inert",
- "inertiaDestinationX",
- "inertiaDestinationY",
- "info",
- "inherits",
- "init",
- "initAnimationEvent",
- "initBeforeLoadEvent",
- "initClipboardEvent",
- "initCloseEvent",
- "initCommandEvent",
- "initCompositionEvent",
- "initCustomEvent",
- "initData",
- "initDataType",
- "initDeviceMotionEvent",
- "initDeviceOrientationEvent",
- "initDragEvent",
- "initErrorEvent",
- "initEvent",
- "initFocusEvent",
- "initGestureEvent",
- "initHashChangeEvent",
- "initKeyEvent",
- "initKeyboardEvent",
- "initMSManipulationEvent",
- "initMessageEvent",
- "initMouseEvent",
- "initMouseScrollEvent",
- "initMouseWheelEvent",
- "initMutationEvent",
- "initNSMouseEvent",
- "initOverflowEvent",
- "initPageEvent",
- "initPageTransitionEvent",
- "initPointerEvent",
- "initPopStateEvent",
- "initProgressEvent",
- "initScrollAreaEvent",
- "initSimpleGestureEvent",
- "initStorageEvent",
- "initTextEvent",
- "initTimeEvent",
- "initTouchEvent",
- "initTransitionEvent",
- "initUIEvent",
- "initWebKitAnimationEvent",
- "initWebKitTransitionEvent",
- "initWebKitWheelEvent",
- "initWheelEvent",
- "initialTime",
- "initialValue",
- "initialize",
- "initiatorType",
- "inject",
- "ink",
- "inline-size",
- "inlineSize",
- "inlineVerticalFieldOfView",
- "inner",
- "innerHTML",
- "innerHeight",
- "innerText",
- "innerWidth",
- "input",
- "inputBuffer",
- "inputEncoding",
- "inputMethod",
- "inputMode",
- "inputQuota",
- "inputSource",
- "inputSources",
- "inputType",
- "inputs",
- "insertAdjacentElement",
- "insertAdjacentHTML",
- "insertAdjacentText",
- "insertBefore",
- "insertCell",
- "insertDTMF",
- "insertData",
- "insertDebugMarker",
- "insertItemBefore",
- "insertNode",
- "insertRow",
- "insertRule",
- "inset",
- "inset-block",
- "inset-block-end",
- "inset-block-start",
- "inset-inline",
- "inset-inline-end",
- "inset-inline-start",
- "insetBlock",
- "insetBlockEnd",
- "insetBlockStart",
- "insetInline",
- "insetInlineEnd",
- "insetInlineStart",
- "inspect",
- "install",
- "installing",
- "instanceRoot",
- "instantiate",
- "instantiateStreaming",
- "instruments",
- "int16",
- "int32",
- "int8",
- "integrity",
- "interactionCount",
- "interactionId",
- "interactionMode",
- "intercept",
- "interestForElement",
- "interfaceClass",
- "interfaceName",
- "interfaceNumber",
- "interfaceProtocol",
- "interfaceSubclass",
- "interfaces",
- "interimResults",
- "internalSubset",
- "interpretation",
- "intersection",
- "intersectionRatio",
- "intersectionRect",
- "intersectsNode",
- "interval",
- "invalidIteratorState",
- "invalidateFramebuffer",
- "invalidateSubFramebuffer",
- "inverse",
- "invertSelf",
- "invoker",
- "invokerType",
- "is",
- "is2D",
- "isActive",
- "isAllowedFileSchemeAccess",
- "isAllowedIncognitoAccess",
- "isAlternate",
- "isArray",
- "isAutoSelected",
- "isBingCurrentSearchDefault",
- "isBuffer",
- "isCandidateWindowVisible",
- "isChar",
- "isCollapsed",
- "isComposing",
- "isConcatSpreadable",
- "isConditionalMediationAvailable",
- "isConfigSupported",
- "isConnected",
- "isContentEditable",
- "isContentHandlerRegistered",
- "isContextLost",
- "isDefaultNamespace",
- "isDirectory",
- "isDisabled",
- "isDisjointFrom",
- "isEnabled",
- "isEqual",
- "isEqualNode",
- "isError",
- "isExtended",
- "isExtensible",
- "isExternalCTAP2SecurityKeySupported",
- "isFallbackAdapter",
- "isFile",
- "isFinite",
- "isFirstPersonObserver",
- "isFramebuffer",
- "isFrozen",
- "isGenerator",
- "isHTML",
- "isHistoryNavigation",
- "isId",
- "isIdentity",
- "isInjected",
- "isInputPending",
- "isInteger",
- "isInternal",
- "isIntersecting",
- "isLockFree",
- "isMap",
- "isMultiLine",
- "isNaN",
- "isOpen",
- "isPointInFill",
- "isPointInPath",
- "isPointInRange",
- "isPointInStroke",
- "isPrefAlternate",
- "isPresenting",
- "isPrimary",
- "isProgram",
- "isPropertyImplicit",
- "isProtocolHandlerRegistered",
- "isPrototypeOf",
- "isQuery",
- "isRawJSON",
- "isRenderbuffer",
- "isSafeInteger",
- "isSameEntry",
- "isSameNode",
- "isSampler",
- "isScript",
- "isScriptURL",
- "isSealed",
- "isSecureContext",
- "isSessionSupported",
- "isShader",
- "isSubsetOf",
- "isSupersetOf",
- "isSupported",
- "isSync",
- "isTextEdit",
- "isTexture",
- "isTransformFeedback",
- "isTrusted",
- "isTypeSupported",
- "isUserVerifyingPlatformAuthenticatorAvailable",
- "isVertexArray",
- "isView",
- "isVisible",
- "isWellFormed",
- "isochronousTransferIn",
- "isochronousTransferOut",
- "isolation",
- "italics",
- "item",
- "itemId",
- "itemProp",
- "itemRef",
- "itemScope",
- "itemType",
- "itemValue",
- "items",
- "iterateNext",
- "iterationComposite",
- "iterator",
- "javaEnabled",
- "jitterBufferTarget",
- "jobTitle",
- "join",
- "joinAdInterestGroup",
- "jointName",
- "json",
- "justify-content",
- "justify-items",
- "justify-self",
- "justifyContent",
- "justifyItems",
- "justifySelf",
- "k1",
- "k2",
- "k3",
- "k4",
- "kHz",
- "keepalive",
- "kernelMatrix",
- "kernelUnitLengthX",
- "kernelUnitLengthY",
- "kerning",
- "key",
- "keyCode",
- "keyFor",
- "keyIdentifier",
- "keyLightEnabled",
- "keyLocation",
- "keyPath",
- "keyStatuses",
- "keySystem",
- "keyText",
- "keyUsage",
- "keyboard",
- "keys",
- "keytype",
- "kind",
- "knee",
- "knownSources",
- "label",
- "labels",
- "lang",
- "language",
- "languages",
- "largeArcFlag",
- "last",
- "lastChild",
- "lastElementChild",
- "lastError",
- "lastEventId",
- "lastIndex",
- "lastIndexOf",
- "lastInputTime",
- "lastMatch",
- "lastMessageSubject",
- "lastMessageType",
- "lastModified",
- "lastModifiedDate",
- "lastPage",
- "lastParen",
- "lastState",
- "lastStyleSheetSet",
- "latency",
- "latitude",
- "launchQueue",
- "layerName",
- "layerX",
- "layerY",
- "layout",
- "layoutFlow",
- "layoutGrid",
- "layoutGridChar",
- "layoutGridLine",
- "layoutGridMode",
- "layoutGridType",
- "lbound",
- "leaveAdInterestGroup",
- "left",
- "leftContext",
- "leftDegrees",
- "leftMargin",
- "leftProjectionMatrix",
- "leftViewMatrix",
- "length",
- "lengthAdjust",
- "lengthComputable",
- "letter-spacing",
- "letterSpacing",
- "level",
- "lh",
- "lighting-color",
- "lightingColor",
- "limitingConeAngle",
- "limits",
- "line",
- "line-break",
- "line-height",
- "lineAlign",
- "lineBreak",
- "lineCap",
- "lineDashOffset",
- "lineGapOverride",
- "lineHeight",
- "lineJoin",
- "lineNum",
- "lineNumber",
- "linePos",
- "lineTo",
- "lineWidth",
- "linearAcceleration",
- "linearRampToValueAtTime",
- "linearVelocity",
- "lineno",
- "lines",
- "link",
- "linkColor",
- "linkProgram",
- "links",
- "list",
- "list-style",
- "list-style-image",
- "list-style-position",
- "list-style-type",
- "listStyle",
- "listStyleImage",
- "listStylePosition",
- "listStyleType",
- "listener",
- "listeners",
- "load",
- "loadEventEnd",
- "loadEventStart",
- "loadOp",
- "loadTime",
- "loadTimes",
- "loaded",
- "loading",
- "localDescription",
- "localName",
- "localService",
- "localStorage",
- "locale",
- "localeCompare",
- "location",
- "locationbar",
- "lock",
- "locked",
- "lockedFile",
- "locks",
- "lodMaxClamp",
- "lodMinClamp",
- "log",
- "log10",
- "log1p",
- "log2",
- "logicalXDPI",
- "logicalYDPI",
- "login",
- "loglevel",
- "longDesc",
- "longitude",
- "lookupNamespaceURI",
- "lookupPrefix",
- "loop",
- "loopEnd",
- "loopStart",
- "looping",
- "lost",
- "low",
- "lower",
- "lowerBound",
- "lowerOpen",
- "lowsrc",
- "lvb",
- "lvh",
- "lvi",
- "lvmax",
- "lvmin",
- "lvw",
- "m11",
- "m12",
- "m13",
- "m14",
- "m21",
- "m22",
- "m23",
- "m24",
- "m31",
- "m32",
- "m33",
- "m34",
- "m41",
- "m42",
- "m43",
- "m44",
- "magFilter",
- "makeXRCompatible",
- "managed",
- "management",
- "manifest",
- "manufacturer",
- "manufacturerName",
- "map",
- "mapAsync",
- "mapState",
- "mappedAtCreation",
- "mapping",
- "margin",
- "margin-block",
- "margin-block-end",
- "margin-block-start",
- "margin-bottom",
- "margin-inline",
- "margin-inline-end",
- "margin-inline-start",
- "margin-left",
- "margin-right",
- "margin-top",
- "marginBlock",
- "marginBlockEnd",
- "marginBlockStart",
- "marginBottom",
- "marginHeight",
- "marginInline",
- "marginInlineEnd",
- "marginInlineStart",
- "marginLeft",
- "marginRight",
- "marginTop",
- "marginWidth",
- "mark",
- "marker",
- "marker-end",
- "marker-mid",
- "marker-offset",
- "marker-start",
- "markerEnd",
- "markerHeight",
- "markerMid",
- "markerOffset",
- "markerStart",
- "markerUnits",
- "markerWidth",
- "marks",
- "mask",
- "mask-clip",
- "mask-composite",
- "mask-image",
- "mask-mode",
- "mask-origin",
- "mask-position",
- "mask-position-x",
- "mask-position-y",
- "mask-repeat",
- "mask-size",
- "mask-type",
- "maskClip",
- "maskComposite",
- "maskContentUnits",
- "maskImage",
- "maskMode",
- "maskOrigin",
- "maskPosition",
- "maskPositionX",
- "maskPositionY",
- "maskRepeat",
- "maskSize",
- "maskType",
- "maskUnits",
- "match",
- "matchAll",
- "matchMedia",
- "matchMedium",
- "matchPatterns",
- "matches",
- "math-depth",
- "math-style",
- "mathDepth",
- "mathShift",
- "mathStyle",
- "matrix",
- "matrixTransform",
- "max",
- "max-block-size",
- "max-height",
- "max-inline-size",
- "max-width",
- "maxActions",
- "maxAlternatives",
- "maxAnisotropy",
- "maxBindGroups",
- "maxBindGroupsPlusVertexBuffers",
- "maxBindingsPerBindGroup",
- "maxBlockSize",
- "maxBufferSize",
- "maxByteLength",
- "maxChannelCount",
- "maxChannels",
- "maxColorAttachmentBytesPerSample",
- "maxColorAttachments",
- "maxComputeInvocationsPerWorkgroup",
- "maxComputeWorkgroupSizeX",
- "maxComputeWorkgroupSizeY",
- "maxComputeWorkgroupSizeZ",
- "maxComputeWorkgroupStorageSize",
- "maxComputeWorkgroupsPerDimension",
- "maxConnectionsPerServer",
- "maxDatagramSize",
- "maxDecibels",
- "maxDistance",
- "maxDrawCount",
- "maxDynamicStorageBuffersPerPipelineLayout",
- "maxDynamicUniformBuffersPerPipelineLayout",
- "maxHeight",
- "maxInlineSize",
- "maxInterStageShaderComponents",
- "maxInterStageShaderVariables",
- "maxLayers",
- "maxLength",
- "maxMessageSize",
- "maxPacketLifeTime",
- "maxRetransmits",
- "maxSampledTexturesPerShaderStage",
- "maxSamplersPerShaderStage",
- "maxStorageBufferBindingSize",
- "maxStorageBuffersPerShaderStage",
- "maxStorageTexturesPerShaderStage",
- "maxTextureArrayLayers",
- "maxTextureDimension1D",
- "maxTextureDimension2D",
- "maxTextureDimension3D",
- "maxTouchPoints",
- "maxUniformBufferBindingSize",
- "maxUniformBuffersPerShaderStage",
- "maxValue",
- "maxVertexAttributes",
- "maxVertexBufferArrayStride",
- "maxVertexBuffers",
- "maxWidth",
- "maximumLatency",
- "measure",
- "measureInputUsage",
- "measureText",
- "media",
- "mediaCapabilities",
- "mediaDevices",
- "mediaElement",
- "mediaGroup",
- "mediaKeys",
- "mediaSession",
- "mediaStream",
- "mediaText",
- "meetOrSlice",
- "memory",
- "menubar",
- "menus",
- "menusChild",
- "menusInternal",
- "mergeAttributes",
- "message",
- "messageClass",
- "messageHandlers",
- "messageType",
- "messages",
- "metaKey",
- "metadata",
- "method",
- "methodDetails",
- "methodName",
- "microseconds",
- "mid",
- "milliseconds",
- "mimeType",
- "mimeTypes",
- "min",
- "min-block-size",
- "min-height",
- "min-inline-size",
- "min-width",
- "minBindingSize",
- "minBlockSize",
- "minDecibels",
- "minFilter",
- "minHeight",
- "minInlineSize",
- "minLength",
- "minStorageBufferOffsetAlignment",
- "minUniformBufferOffsetAlignment",
- "minValue",
- "minWidth",
- "minimumLatency",
- "minute",
- "minutes",
- "mipLevel",
- "mipLevelCount",
- "mipmapFilter",
- "miterLimit",
- "mix-blend-mode",
- "mixBlendMode",
- "mm",
- "mobile",
- "mode",
- "model",
- "modify",
- "module",
- "month",
- "months",
- "mount",
- "move",
- "moveBefore",
- "moveBy",
- "moveEnd",
- "moveFirst",
- "moveFocusDown",
- "moveFocusLeft",
- "moveFocusRight",
- "moveFocusUp",
- "moveInSuccession",
- "moveNext",
- "moveRow",
- "moveStart",
- "moveTo",
- "moveToBookmark",
- "moveToElementText",
- "moveToPoint",
- "movementX",
- "movementY",
- "mozAdd",
- "mozAnimationStartTime",
- "mozAnon",
- "mozApps",
- "mozAudioCaptured",
- "mozAudioChannelType",
- "mozAutoplayEnabled",
- "mozCancelAnimationFrame",
- "mozCancelFullScreen",
- "mozCancelRequestAnimationFrame",
- "mozCaptureStream",
- "mozCaptureStreamUntilEnded",
- "mozClearDataAt",
- "mozContact",
- "mozContacts",
- "mozCreateFileHandle",
- "mozCurrentTransform",
- "mozCurrentTransformInverse",
- "mozCursor",
- "mozDash",
- "mozDashOffset",
- "mozDecodedFrames",
- "mozExitPointerLock",
- "mozFillRule",
- "mozFragmentEnd",
- "mozFrameDelay",
- "mozFullScreen",
- "mozFullScreenElement",
- "mozFullScreenEnabled",
- "mozGetAll",
- "mozGetAllKeys",
- "mozGetAsFile",
- "mozGetDataAt",
- "mozGetMetadata",
- "mozGetUserMedia",
- "mozHasAudio",
- "mozHasItem",
- "mozHidden",
- "mozImageSmoothingEnabled",
- "mozIndexedDB",
- "mozInnerScreenX",
- "mozInnerScreenY",
- "mozInputSource",
- "mozIsTextField",
- "mozItem",
- "mozItemCount",
- "mozItems",
- "mozLength",
- "mozLockOrientation",
- "mozMatchesSelector",
- "mozMovementX",
- "mozMovementY",
- "mozOpaque",
- "mozOrientation",
- "mozPaintCount",
- "mozPaintedFrames",
- "mozParsedFrames",
- "mozPay",
- "mozPointerLockElement",
- "mozPresentedFrames",
- "mozPreservesPitch",
- "mozPressure",
- "mozPrintCallback",
- "mozRTCIceCandidate",
- "mozRTCPeerConnection",
- "mozRTCSessionDescription",
- "mozRemove",
- "mozRequestAnimationFrame",
- "mozRequestFullScreen",
- "mozRequestPointerLock",
- "mozSetDataAt",
- "mozSetImageElement",
- "mozSourceNode",
- "mozSrcObject",
- "mozSystem",
- "mozTCPSocket",
- "mozTextStyle",
- "mozTypesAt",
- "mozUnlockOrientation",
- "mozUserCancelled",
- "mozVisibilityState",
- "ms",
- "msAnimation",
- "msAnimationDelay",
- "msAnimationDirection",
- "msAnimationDuration",
- "msAnimationFillMode",
- "msAnimationIterationCount",
- "msAnimationName",
- "msAnimationPlayState",
- "msAnimationStartTime",
- "msAnimationTimingFunction",
- "msBackfaceVisibility",
- "msBlockProgression",
- "msCSSOMElementFloatMetrics",
- "msCaching",
- "msCachingEnabled",
- "msCancelRequestAnimationFrame",
- "msCapsLockWarningOff",
- "msClearImmediate",
- "msClose",
- "msContentZoomChaining",
- "msContentZoomFactor",
- "msContentZoomLimit",
- "msContentZoomLimitMax",
- "msContentZoomLimitMin",
- "msContentZoomSnap",
- "msContentZoomSnapPoints",
- "msContentZoomSnapType",
- "msContentZooming",
- "msConvertURL",
- "msCrypto",
- "msDoNotTrack",
- "msElementsFromPoint",
- "msElementsFromRect",
- "msExitFullscreen",
- "msExtendedCode",
- "msFillRule",
- "msFirstPaint",
- "msFlex",
- "msFlexAlign",
- "msFlexDirection",
- "msFlexFlow",
- "msFlexItemAlign",
- "msFlexLinePack",
- "msFlexNegative",
- "msFlexOrder",
- "msFlexPack",
- "msFlexPositive",
- "msFlexPreferredSize",
- "msFlexWrap",
- "msFlowFrom",
- "msFlowInto",
- "msFontFeatureSettings",
- "msFullscreenElement",
- "msFullscreenEnabled",
- "msGetInputContext",
- "msGetRegionContent",
- "msGetUntransformedBounds",
- "msGraphicsTrustStatus",
- "msGridColumn",
- "msGridColumnAlign",
- "msGridColumnSpan",
- "msGridColumns",
- "msGridRow",
- "msGridRowAlign",
- "msGridRowSpan",
- "msGridRows",
- "msHidden",
- "msHighContrastAdjust",
- "msHyphenateLimitChars",
- "msHyphenateLimitLines",
- "msHyphenateLimitZone",
- "msHyphens",
- "msImageSmoothingEnabled",
- "msImeAlign",
- "msIndexedDB",
- "msInterpolationMode",
- "msIsStaticHTML",
- "msKeySystem",
- "msKeys",
- "msLaunchUri",
- "msLockOrientation",
- "msManipulationViewsEnabled",
- "msMatchMedia",
- "msMatchesSelector",
- "msMaxTouchPoints",
- "msOrientation",
- "msOverflowStyle",
- "msPerspective",
- "msPerspectiveOrigin",
- "msPlayToDisabled",
- "msPlayToPreferredSourceUri",
- "msPlayToPrimary",
- "msPointerEnabled",
- "msRegionOverflow",
- "msReleasePointerCapture",
- "msRequestAnimationFrame",
- "msRequestFullscreen",
- "msSaveBlob",
- "msSaveOrOpenBlob",
- "msScrollChaining",
- "msScrollLimit",
- "msScrollLimitXMax",
- "msScrollLimitXMin",
- "msScrollLimitYMax",
- "msScrollLimitYMin",
- "msScrollRails",
- "msScrollSnapPointsX",
- "msScrollSnapPointsY",
- "msScrollSnapType",
- "msScrollSnapX",
- "msScrollSnapY",
- "msScrollTranslation",
- "msSetImmediate",
- "msSetMediaKeys",
- "msSetPointerCapture",
- "msTextCombineHorizontal",
- "msTextSizeAdjust",
- "msToBlob",
- "msTouchAction",
- "msTouchSelect",
- "msTraceAsyncCallbackCompleted",
- "msTraceAsyncCallbackStarting",
- "msTraceAsyncOperationCompleted",
- "msTraceAsyncOperationStarting",
- "msTransform",
- "msTransformOrigin",
- "msTransformStyle",
- "msTransition",
- "msTransitionDelay",
- "msTransitionDuration",
- "msTransitionProperty",
- "msTransitionTimingFunction",
- "msUnlockOrientation",
- "msUpdateAsyncCallbackRelation",
- "msUserSelect",
- "msVisibilityState",
- "msWrapFlow",
- "msWrapMargin",
- "msWrapThrough",
- "msWriteProfilerMark",
- "msZoom",
- "msZoomTo",
- "mt",
- "mul",
- "multiEntry",
- "multiSelectionObj",
- "multiline",
- "multiple",
- "multiply",
- "multiplySelf",
- "multisample",
- "multisampled",
- "mutableFile",
- "muted",
- "n",
- "nacl_arch",
- "name",
- "nameList",
- "nameProp",
- "namedItem",
- "namedRecordset",
- "names",
- "namespaceURI",
- "namespaces",
- "nanoseconds",
- "nativeApplication",
- "nativeMap",
- "nativeObjectCreate",
- "nativeSet",
- "nativeWeakMap",
- "naturalHeight",
- "naturalWidth",
- "navigate",
- "navigation",
- "navigationMode",
- "navigationPreload",
- "navigationStart",
- "navigationType",
- "navigator",
- "near",
- "nearestViewportElement",
- "negative",
- "negotiated",
- "netscape",
- "networkState",
- "networkStatus",
- "newScale",
- "newState",
- "newTranslate",
- "newURL",
- "newValue",
- "newValueSpecifiedUnits",
- "newVersion",
- "newhome",
- "next",
- "nextElementSibling",
- "nextHopProtocol",
- "nextNode",
- "nextPage",
- "nextSibling",
- "nickname",
- "noHref",
- "noModule",
- "noResize",
- "noShade",
- "noValidate",
- "noWrap",
- "node",
- "nodeName",
- "nodeType",
- "nodeValue",
- "nonce",
- "normDepthBufferFromNormView",
- "normalize",
- "normalizedPathSegList",
- "normandyAddonStudy",
- "notRestoredReasons",
- "notationName",
- "notations",
- "note",
- "noteGrainOn",
- "noteOff",
- "noteOn",
- "notifications",
- "notify",
- "now",
- "npnNegotiatedProtocol",
- "numOctaves",
- "number",
- "numberOfChannels",
- "numberOfFrames",
- "numberOfInputs",
- "numberOfItems",
- "numberOfOutputs",
- "numberValue",
- "numberingSystem",
- "numeric",
- "oMatchesSelector",
- "object",
- "object-fit",
- "object-position",
- "objectFit",
- "objectPosition",
- "objectStore",
- "objectStoreNames",
- "objectType",
- "observe",
- "observedAttributes",
- "occlusionQuerySet",
- "of",
- "off",
- "offscreenBuffering",
- "offset",
- "offset-anchor",
- "offset-distance",
- "offset-path",
- "offset-position",
- "offset-rotate",
- "offsetAnchor",
- "offsetDistance",
- "offsetHeight",
- "offsetLeft",
- "offsetNode",
- "offsetParent",
- "offsetPath",
- "offsetPosition",
- "offsetRotate",
- "offsetTop",
- "offsetWidth",
- "offsetX",
- "offsetY",
- "ok",
- "oldState",
- "oldURL",
- "oldValue",
- "oldVersion",
- "olderShadowRoot",
- "omnibox",
- "on",
- "onActivated",
- "onAdded",
- "onAttached",
- "onBoundsChanged",
- "onBrowserUpdateAvailable",
- "onClicked",
- "onCommitFiberRoot",
- "onCommitFiberUnmount",
- "onConnect",
- "onConnectExternal",
- "onConnectNative",
- "onCreated",
- "onDetached",
- "onDisabled",
- "onEnabled",
- "onFocusChanged",
- "onHighlighted",
- "onInstalled",
- "onLine",
- "onMessage",
- "onMessageExternal",
- "onMoved",
- "onPerformanceWarning",
- "onPostCommitFiberRoot",
- "onRemoved",
- "onReplaced",
- "onRestartRequired",
- "onStartup",
- "onSubmittedWorkDone",
- "onSuspend",
- "onSuspendCanceled",
- "onUninstalled",
- "onUpdateAvailable",
- "onUpdated",
- "onUserScriptConnect",
- "onUserScriptMessage",
- "onUserSettingsChanged",
- "onZoomChange",
- "onabort",
- "onabsolutedeviceorientation",
- "onactivate",
- "onactive",
- "onaddsourcebuffer",
- "onaddstream",
- "onaddtrack",
- "onafterprint",
- "onafterscriptexecute",
- "onafterupdate",
- "onanimationcancel",
- "onanimationend",
- "onanimationiteration",
- "onanimationstart",
- "onappinstalled",
- "onaudioend",
- "onaudioprocess",
- "onaudiostart",
- "onautocomplete",
- "onautocompleteerror",
- "onauxclick",
- "onbeforeactivate",
- "onbeforecopy",
- "onbeforecut",
- "onbeforedeactivate",
- "onbeforeeditfocus",
- "onbeforeinput",
- "onbeforeinstallprompt",
- "onbeforematch",
- "onbeforepaste",
- "onbeforeprint",
- "onbeforescriptexecute",
- "onbeforetoggle",
- "onbeforeunload",
- "onbeforeupdate",
- "onbeforexrselect",
- "onbegin",
- "onblocked",
- "onblur",
- "onbounce",
- "onboundary",
- "onbufferedamountlow",
- "oncached",
- "oncancel",
- "oncandidatewindowhide",
- "oncandidatewindowshow",
- "oncandidatewindowupdate",
- "oncanplay",
- "oncanplaythrough",
- "oncapturehandlechange",
- "once",
- "oncellchange",
- "onchange",
- "oncharacterboundsupdate",
- "oncharacteristicvaluechanged",
- "onchargingchange",
- "onchargingtimechange",
- "onchecking",
- "onclick",
- "onclose",
- "onclosing",
- "oncommand",
- "oncompassneedscalibration",
- "oncomplete",
- "oncompositionend",
- "oncompositionstart",
- "onconnect",
- "onconnecting",
- "onconnectionavailable",
- "onconnectionstatechange",
- "oncontentvisibilityautostatechange",
- "oncontextlost",
- "oncontextmenu",
- "oncontextrestored",
- "oncontrollerchange",
- "oncontrolselect",
- "oncopy",
- "oncuechange",
- "oncurrententrychange",
- "oncurrentscreenchange",
- "oncut",
- "ondataavailable",
- "ondatachannel",
- "ondatasetchanged",
- "ondatasetcomplete",
- "ondblclick",
- "ondeactivate",
- "ondequeue",
- "ondevicechange",
- "ondevicelight",
- "ondevicemotion",
- "ondeviceorientation",
- "ondeviceorientationabsolute",
- "ondeviceproximity",
- "ondischargingtimechange",
- "ondisconnect",
- "ondisplay",
- "ondispose",
- "ondownloading",
- "ondownloadprogress",
- "ondrag",
- "ondragend",
- "ondragenter",
- "ondragexit",
- "ondragleave",
- "ondragover",
- "ondragstart",
- "ondrop",
- "ondurationchange",
- "onemptied",
- "onencrypted",
- "onend",
- "onended",
- "onenter",
- "onenterpictureinpicture",
- "onerror",
- "onerrorupdate",
- "onexit",
- "onfencedtreeclick",
- "onfilterchange",
- "onfinish",
- "onfocus",
- "onfocusin",
- "onfocusout",
- "onformdata",
- "onfreeze",
- "onfullscreenchange",
- "onfullscreenerror",
- "ongamepadconnected",
- "ongamepaddisconnected",
- "ongatheringstatechange",
- "ongattserverdisconnected",
- "ongeometrychange",
- "ongesturechange",
- "ongestureend",
- "ongesturestart",
- "ongotpointercapture",
- "onhashchange",
- "onhelp",
- "onicecandidate",
- "onicecandidateerror",
- "oniceconnectionstatechange",
- "onicegatheringstatechange",
- "oninactive",
- "oninput",
- "oninputreport",
- "oninputsourceschange",
- "oninvalid",
- "onkeydown",
- "onkeypress",
- "onkeystatuseschange",
- "onkeyup",
- "onlanguagechange",
- "onlayoutcomplete",
- "onleavepictureinpicture",
- "onlevelchange",
- "onload",
- "onloadT",
- "onloadeddata",
- "onloadedmetadata",
- "onloadend",
- "onloading",
- "onloadingdone",
- "onloadingerror",
- "onloadstart",
- "onlosecapture",
- "onlostpointercapture",
- "only",
- "onmanagedconfigurationchange",
- "onmark",
- "onmessage",
- "onmessageerror",
- "onmidimessage",
- "onmousedown",
- "onmouseenter",
- "onmouseleave",
- "onmousemove",
- "onmouseout",
- "onmouseover",
- "onmouseup",
- "onmousewheel",
- "onmove",
- "onmoveend",
- "onmovestart",
- "onmozfullscreenchange",
- "onmozfullscreenerror",
- "onmozorientationchange",
- "onmozpointerlockchange",
- "onmozpointerlockerror",
- "onmscontentzoom",
- "onmsfullscreenchange",
- "onmsfullscreenerror",
- "onmsgesturechange",
- "onmsgesturedoubletap",
- "onmsgestureend",
- "onmsgesturehold",
- "onmsgesturestart",
- "onmsgesturetap",
- "onmsgotpointercapture",
- "onmsinertiastart",
- "onmslostpointercapture",
- "onmsmanipulationstatechanged",
- "onmsneedkey",
- "onmsorientationchange",
- "onmspointercancel",
- "onmspointerdown",
- "onmspointerenter",
- "onmspointerhover",
- "onmspointerleave",
- "onmspointermove",
- "onmspointerout",
- "onmspointerover",
- "onmspointerup",
- "onmssitemodejumplistitemremoved",
- "onmsthumbnailclick",
- "onmute",
- "onnavigate",
- "onnavigateerror",
- "onnavigatesuccess",
- "onnegotiationneeded",
- "onnomatch",
- "onnoupdate",
- "onobsolete",
- "onoffline",
- "ononline",
- "onopen",
- "onorientationchange",
- "onpagechange",
- "onpagehide",
- "onpagereveal",
- "onpageshow",
- "onpageswap",
- "onpaste",
- "onpause",
- "onpayerdetailchange",
- "onpaymentmethodchange",
- "onplay",
- "onplaying",
- "onpluginstreamstart",
- "onpointercancel",
- "onpointerdown",
- "onpointerenter",
- "onpointerleave",
- "onpointerlockchange",
- "onpointerlockerror",
- "onpointermove",
- "onpointerout",
- "onpointerover",
- "onpointerrawupdate",
- "onpointerup",
- "onpopstate",
- "onprerenderingchange",
- "onprioritychange",
- "onprocessorerror",
- "onprogress",
- "onpropertychange",
- "onratechange",
- "onreading",
- "onreadystatechange",
- "onreflectionchange",
- "onrejectionhandled",
- "onrelease",
- "onremove",
- "onremovesourcebuffer",
- "onremovestream",
- "onremovetrack",
- "onrepeat",
- "onreset",
- "onresize",
- "onresizeend",
- "onresizestart",
- "onresourcetimingbufferfull",
- "onresult",
- "onresume",
- "onrowenter",
- "onrowexit",
- "onrowsdelete",
- "onrowsinserted",
- "onscreenschange",
- "onscroll",
- "onscrollend",
- "onscrollsnapchange",
- "onscrollsnapchanging",
- "onsearch",
- "onsecuritypolicyviolation",
- "onseeked",
- "onseeking",
- "onselect",
- "onselectedcandidatepairchange",
- "onselectend",
- "onselectionchange",
- "onselectstart",
- "onshippingaddresschange",
- "onshippingoptionchange",
- "onshow",
- "onsignalingstatechange",
- "onsinkchange",
- "onslotchange",
- "onsoundend",
- "onsoundstart",
- "onsourceclose",
- "onsourceclosed",
- "onsourceended",
- "onsourceopen",
- "onspeechend",
- "onspeechstart",
- "onsqueeze",
- "onsqueezeend",
- "onsqueezestart",
- "onstalled",
- "onstart",
- "onstatechange",
- "onstop",
- "onstorage",
- "onstoragecommit",
- "onsubmit",
- "onsuccess",
- "onsuspend",
- "onterminate",
- "ontextformatupdate",
- "ontextinput",
- "ontextupdate",
- "ontimeout",
- "ontimeupdate",
- "ontoggle",
- "ontonechange",
- "ontouchcancel",
- "ontouchend",
- "ontouchmove",
- "ontouchstart",
- "ontrack",
- "ontransitioncancel",
- "ontransitionend",
- "ontransitionrun",
- "ontransitionstart",
- "onuncapturederror",
- "onunhandledrejection",
- "onunload",
- "onunmute",
- "onupdate",
- "onupdateend",
- "onupdatefound",
- "onupdateready",
- "onupdatestart",
- "onupgradeneeded",
- "onuserproximity",
- "onversionchange",
- "onvisibilitychange",
- "onvoiceschanged",
- "onvolumechange",
- "onvrdisplayactivate",
- "onvrdisplayconnect",
- "onvrdisplaydeactivate",
- "onvrdisplaydisconnect",
- "onvrdisplaypresentchange",
- "onwaiting",
- "onwaitingforkey",
- "onwarning",
- "onwebkitanimationend",
- "onwebkitanimationiteration",
- "onwebkitanimationstart",
- "onwebkitcurrentplaybacktargetiswirelesschanged",
- "onwebkitfullscreenchange",
- "onwebkitfullscreenerror",
- "onwebkitkeyadded",
- "onwebkitkeyerror",
- "onwebkitkeymessage",
- "onwebkitneedkey",
- "onwebkitorientationchange",
- "onwebkitplaybacktargetavailabilitychanged",
- "onwebkitpointerlockchange",
- "onwebkitpointerlockerror",
- "onwebkitresourcetimingbufferfull",
- "onwebkittransitionend",
- "onwheel",
- "onzoom",
- "onzoomlevelchange",
- "opacity",
- "open",
- "openCursor",
- "openDatabase",
- "openKeyCursor",
- "openOptionsPage",
- "openOrClosedShadowRoot",
- "openPopup",
- "opened",
- "opener",
- "opera",
- "operation",
- "operationType",
- "operator",
- "opr",
- "optimum",
- "options",
- "or",
- "order",
- "orderX",
- "orderY",
- "ordered",
- "org",
- "organization",
- "orient",
- "orientAngle",
- "orientType",
- "orientation",
- "orientationX",
- "orientationY",
- "orientationZ",
- "origin",
- "originAgentCluster",
- "originalPolicy",
- "originalTarget",
- "ornaments",
- "orphans",
- "os",
- "oscpu",
- "outerHTML",
- "outerHeight",
- "outerText",
- "outerWidth",
- "outgoingHighWaterMark",
- "outgoingMaxAge",
- "outline",
- "outline-color",
- "outline-offset",
- "outline-style",
- "outline-width",
- "outlineColor",
- "outlineOffset",
- "outlineStyle",
- "outlineWidth",
- "outputBuffer",
- "outputChannelCount",
- "outputLanguage",
- "outputLatency",
- "outputs",
- "overallProgress",
- "overflow",
- "overflow-anchor",
- "overflow-block",
- "overflow-clip-margin",
- "overflow-inline",
- "overflow-wrap",
- "overflow-x",
- "overflow-y",
- "overflowAnchor",
- "overflowBlock",
- "overflowClipMargin",
- "overflowInline",
- "overflowWrap",
- "overflowX",
- "overflowY",
- "overlaysContent",
- "overrideColors",
- "overrideMimeType",
- "oversample",
- "overscroll-behavior",
- "overscroll-behavior-block",
- "overscroll-behavior-inline",
- "overscroll-behavior-x",
- "overscroll-behavior-y",
- "overscrollBehavior",
- "overscrollBehaviorBlock",
- "overscrollBehaviorInline",
- "overscrollBehaviorX",
- "overscrollBehaviorY",
- "ownKeys",
- "ownerDocument",
- "ownerElement",
- "ownerNode",
- "ownerRule",
- "ownerSVGElement",
- "owningElement",
- "p1",
- "p2",
- "p3",
- "p4",
- "packetSize",
- "packets",
- "pad",
- "padEnd",
- "padStart",
- "padding",
- "padding-block",
- "padding-block-end",
- "padding-block-start",
- "padding-bottom",
- "padding-inline",
- "padding-inline-end",
- "padding-inline-start",
- "padding-left",
- "padding-right",
- "padding-top",
- "paddingBlock",
- "paddingBlockEnd",
- "paddingBlockStart",
- "paddingBottom",
- "paddingInline",
- "paddingInlineEnd",
- "paddingInlineStart",
- "paddingLeft",
- "paddingRight",
- "paddingTop",
- "page",
- "page-break-after",
- "page-break-before",
- "page-break-inside",
- "page-orientation",
- "pageAction",
- "pageBreakAfter",
- "pageBreakBefore",
- "pageBreakInside",
- "pageCount",
- "pageLeft",
- "pageOrientation",
- "pageT",
- "pageTop",
- "pageX",
- "pageXOffset",
- "pageY",
- "pageYOffset",
- "pages",
- "paint-order",
- "paintOrder",
- "paintRequests",
- "paintTime",
- "paintType",
- "paintWorklet",
- "palette",
- "pan",
- "panningModel",
- "parameterData",
- "parameters",
- "parent",
- "parentElement",
- "parentNode",
- "parentRule",
- "parentStyleSheet",
- "parentTextEdit",
- "parentWindow",
- "parse",
- "parseAll",
- "parseCreationOptionsFromJSON",
- "parseFloat",
- "parseFromString",
- "parseHTMLUnsafe",
- "parseInt",
- "parseRequestOptionsFromJSON",
- "part",
- "participants",
- "passOp",
- "passive",
- "password",
- "pasteHTML",
- "path",
- "pathLength",
- "pathSegList",
- "pathSegType",
- "pathSegTypeAsLetter",
- "pathname",
- "pattern",
- "patternContentUnits",
- "patternMismatch",
- "patternTransform",
- "patternUnits",
- "pause",
- "pauseAnimations",
- "pauseDepthSensing",
- "pauseDuration",
- "pauseOnExit",
- "pauseProfilers",
- "pauseTransformFeedback",
- "paused",
- "payerEmail",
- "payerName",
- "payerPhone",
- "paymentManager",
- "pc",
- "pdfViewerEnabled",
- "peerIdentity",
- "pending",
- "pendingLocalDescription",
- "pendingRemoteDescription",
- "percent",
- "performance",
- "periodicSync",
- "permission",
- "permissionState",
- "permissions",
- "persist",
- "persisted",
- "persistentDeviceId",
- "personalbar",
- "perspective",
- "perspective-origin",
- "perspectiveOrigin",
- "phone",
- "phoneticFamilyName",
- "phoneticGivenName",
- "photo",
- "phrase",
- "phrases",
- "pictureInPictureChild",
- "pictureInPictureElement",
- "pictureInPictureEnabled",
- "pictureInPictureWindow",
- "ping",
- "pipeThrough",
- "pipeTo",
- "pitch",
- "pixelBottom",
- "pixelDepth",
- "pixelFormat",
- "pixelHeight",
- "pixelLeft",
- "pixelRight",
- "pixelStorei",
- "pixelTop",
- "pixelUnitToMillimeterX",
- "pixelUnitToMillimeterY",
- "pixelWidth",
- "pkcs11",
- "place-content",
- "place-items",
- "place-self",
- "placeContent",
- "placeItems",
- "placeSelf",
- "placeholder",
- "platform",
- "platformVersion",
- "platforms",
- "play",
- "playEffect",
- "playState",
- "playbackRate",
- "playbackState",
- "playbackTime",
- "played",
- "playoutDelayHint",
- "playsInline",
- "plugins",
- "pluginspage",
- "pname",
- "pointer-events",
- "pointerBeforeReferenceNode",
- "pointerEnabled",
- "pointerEvents",
- "pointerId",
- "pointerLockElement",
- "pointerType",
- "points",
- "pointsAtX",
- "pointsAtY",
- "pointsAtZ",
- "polygonOffset",
- "pop",
- "popDebugGroup",
- "popErrorScope",
- "popover",
- "popoverTargetAction",
- "popoverTargetElement",
- "populateMatrix",
- "popupWindowFeatures",
- "popupWindowName",
- "popupWindowURI",
- "port",
- "port1",
- "port2",
- "ports",
- "posBottom",
- "posHeight",
- "posLeft",
- "posRight",
- "posTop",
- "posWidth",
- "pose",
- "position",
- "position-anchor",
- "position-area",
- "positionAlign",
- "positionAnchor",
- "positionArea",
- "positionTry",
- "positionTryFallbacks",
- "positionVisibility",
- "positionX",
- "positionY",
- "positionZ",
- "postError",
- "postMessage",
- "postTask",
- "postalCode",
- "poster",
- "postscriptName",
- "pow",
- "powerEfficient",
- "powerOff",
- "powerPreference",
- "preMultiplySelf",
- "precision",
- "preferredReflectionFormat",
- "preferredStyleSheetSet",
- "preferredStylesheetSet",
- "prefix",
- "preload",
- "premultipliedAlpha",
- "prepend",
- "prerendering",
- "presentation",
- "presentationArea",
- "presentationStyle",
- "presentationTime",
- "preserveAlpha",
- "preserveAspectRatio",
- "preserveAspectRatioString",
- "preservesPitch",
- "pressed",
- "pressure",
- "prevValue",
- "preventDefault",
- "preventExtensions",
- "preventSilentAccess",
- "previousElementSibling",
- "previousNode",
- "previousPage",
- "previousPriority",
- "previousRect",
- "previousScale",
- "previousSibling",
- "previousTranslate",
- "primaries",
- "primaryKey",
- "primaryLightDirection",
- "primaryLightIntensity",
- "primitive",
- "primitiveType",
- "primitiveUnits",
- "principals",
- "print",
- "print-color-adjust",
- "printColorAdjust",
- "printPreview",
- "priority",
- "privacy",
- "privateKey",
- "privateToken",
- "probablySupportsContext",
- "probeSpace",
- "process",
- "processIceMessage",
- "processLocally",
- "processingEnd",
- "processingStart",
- "processorOptions",
- "product",
- "productId",
- "productName",
- "productSub",
- "profile",
- "profileEnd",
- "profiles",
- "projectionMatrix",
- "promise",
- "promising",
- "prompt",
- "properties",
- "propertyIsEnumerable",
- "propertyName",
- "protectedAudience",
- "protocol",
- "protocolLong",
- "prototype",
- "provider",
- "proxy",
- "pseudoClass",
- "pseudoElement",
- "pt",
- "publicId",
- "publicKey",
- "published",
- "pulse",
- "push",
- "pushDebugGroup",
- "pushErrorScope",
- "pushManager",
- "pushNotification",
- "pushState",
- "put",
- "putImageData",
- "px",
- "quadraticCurveTo",
- "qualifier",
- "quaternion",
- "query",
- "queryCommandEnabled",
- "queryCommandIndeterm",
- "queryCommandState",
- "queryCommandSupported",
- "queryCommandText",
- "queryCommandValue",
- "queryFeatureSupport",
- "queryLocalFonts",
- "queryPermission",
- "querySelector",
- "querySelectorAll",
- "querySet",
- "queue",
- "queueMicrotask",
- "quota",
- "quote",
- "quotes",
- "r",
- "r1",
- "r2",
- "race",
- "rad",
- "radiogroup",
- "radius",
- "radiusX",
- "radiusY",
- "random",
- "randomUUID",
- "range",
- "rangeCount",
- "rangeEnd",
- "rangeMax",
- "rangeMin",
- "rangeOffset",
- "rangeOverflow",
- "rangeParent",
- "rangeStart",
- "rangeUnderflow",
- "rate",
- "ratio",
- "raw",
- "rawId",
- "rawJSON",
- "rawValueToMeters",
- "rcap",
- "rch",
- "read",
- "readAsArrayBuffer",
- "readAsBinaryString",
- "readAsBlob",
- "readAsDataURL",
- "readAsText",
- "readBuffer",
- "readEntries",
- "readOnly",
- "readPixels",
- "readReportRequested",
- "readText",
- "readValue",
- "readable",
- "ready",
- "readyState",
- "reason",
- "reasons",
- "reboot",
- "receiveFeatureReport",
- "receivedAlert",
- "receiver",
- "receivers",
- "recipient",
- "recommendedViewportScale",
- "reconnect",
- "recordNumber",
- "recordsAvailable",
- "recordset",
- "rect",
- "red",
- "redEyeReduction",
- "redirect",
- "redirectCount",
- "redirectEnd",
- "redirectStart",
- "redirected",
- "reduce",
- "reduceRight",
- "reduction",
- "refDistance",
- "refX",
- "refY",
- "referenceNode",
- "referenceSpace",
- "referrer",
- "referrerPolicy",
- "refresh",
- "region",
- "regionAnchorX",
- "regionAnchorY",
- "regionId",
- "regions",
- "register",
- "registerContentHandler",
- "registerElement",
- "registerInternalModuleStart",
- "registerInternalModuleStop",
- "registerProperty",
- "registerProtocolHandler",
- "reject",
- "rel",
- "relList",
- "relatedAddress",
- "relatedNode",
- "relatedPort",
- "relatedTarget",
- "relayProtocol",
- "release",
- "releaseCapture",
- "releaseEvents",
- "releaseInterface",
- "releaseLock",
- "releasePointerCapture",
- "releaseShaderCompiler",
- "released",
- "reliability",
- "reliable",
- "reliableWrite",
- "reload",
- "rem",
- "remainingSpace",
- "remote",
- "remoteDescription",
- "remove",
- "removeAllRanges",
- "removeAttribute",
- "removeAttributeNS",
- "removeAttributeNode",
- "removeBehavior",
- "removeChild",
- "removeCue",
- "removeEntry",
- "removeEventListener",
- "removeFilter",
- "removeImport",
- "removeItem",
- "removeListener",
- "removeNamedItem",
- "removeNamedItemNS",
- "removeNode",
- "removeParameter",
- "removeProperty",
- "removeRange",
- "removeRegion",
- "removeRule",
- "removeSiteSpecificTrackingException",
- "removeSourceBuffer",
- "removeStream",
- "removeTrack",
- "removeVariable",
- "removeWakeLockListener",
- "removeWebWideTrackingException",
- "removed",
- "removedNodes",
- "renderBlockingStatus",
- "renderHeight",
- "renderStart",
- "renderState",
- "renderTime",
- "renderWidth",
- "renderbufferStorage",
- "renderbufferStorageMultisample",
- "renderedBuffer",
- "rendererInterfaces",
- "renderers",
- "renderingMode",
- "renotify",
- "repeat",
- "repetitionCount",
- "replace",
- "replaceAdjacentText",
- "replaceAll",
- "replaceChild",
- "replaceChildren",
- "replaceData",
- "replaceId",
- "replaceItem",
- "replaceNode",
- "replaceState",
- "replaceSync",
- "replaceTrack",
- "replaceWholeText",
- "replaceWith",
- "reportError",
- "reportEvent",
- "reportId",
- "reportOnly",
- "reportValidity",
- "request",
- "requestAdapter",
- "requestAdapterInfo",
- "requestAnimationFrame",
- "requestAutocomplete",
- "requestClose",
- "requestData",
- "requestDevice",
- "requestFrame",
- "requestFullscreen",
- "requestHitTestSource",
- "requestHitTestSourceForTransientInput",
- "requestId",
- "requestIdleCallback",
- "requestLightProbe",
- "requestMIDIAccess",
- "requestMediaKeySystemAccess",
- "requestPermission",
- "requestPictureInPicture",
- "requestPointerLock",
- "requestPort",
- "requestPresent",
- "requestPresenter",
- "requestReferenceSpace",
- "requestSession",
- "requestStart",
- "requestStorageAccess",
- "requestStorageAccessFor",
- "requestSubmit",
- "requestTime",
- "requestUpdateCheck",
- "requestVideoFrameCallback",
- "requestViewportScale",
- "requestWindow",
- "requested",
- "requestingWindow",
- "requireInteraction",
- "required",
- "requiredExtensions",
- "requiredFeatures",
- "requiredLimits",
- "reset",
- "resetLatency",
- "resetPose",
- "resetTransform",
- "resetZoomLevel",
- "resizable",
- "resize",
- "resizeBy",
- "resizeTo",
- "resolve",
- "resolveQuerySet",
- "resolveTarget",
- "resource",
- "respond",
- "respondWithNewView",
- "response",
- "responseBody",
- "responseEnd",
- "responseReady",
- "responseStart",
- "responseStatus",
- "responseText",
- "responseType",
- "responseURL",
- "responseXML",
- "restart",
- "restartAfterDelay",
- "restartIce",
- "restore",
- "restrictTo",
- "result",
- "resultIndex",
- "resultType",
- "results",
- "resume",
- "resumeDepthSensing",
- "resumeProfilers",
- "resumeTransformFeedback",
- "retry",
- "returnType",
- "returnValue",
- "rev",
- "reverse",
- "reversed",
- "revocable",
- "revokeObjectURL",
- "rex",
- "rgbColor",
- "ric",
- "right",
- "rightContext",
- "rightDegrees",
- "rightMargin",
- "rightProjectionMatrix",
- "rightViewMatrix",
- "rlh",
- "role",
- "rolloffFactor",
- "root",
- "rootBounds",
- "rootElement",
- "rootMargin",
- "rotate",
- "rotateAxisAngle",
- "rotateAxisAngleSelf",
- "rotateFromVector",
- "rotateFromVectorSelf",
- "rotateSelf",
- "rotation",
- "rotationAngle",
- "rotationRate",
- "round",
- "roundRect",
- "row-gap",
- "rowGap",
- "rowIndex",
- "rowSpan",
- "rows",
- "rowsPerImage",
- "rtcpTransport",
- "rtt",
- "ruby-align",
- "ruby-position",
- "rubyAlign",
- "rubyOverhang",
- "rubyPosition",
- "rules",
- "run",
- "runAdAuction",
- "runtime",
- "runtimeStyle",
- "rx",
- "ry",
- "s",
- "safari",
- "sameDocument",
- "sample",
- "sampleCount",
- "sampleCoverage",
- "sampleInterval",
- "sampleRate",
- "sampleType",
- "sampler",
- "samplerParameterf",
- "samplerParameteri",
- "sandbox",
- "save",
- "saveAsPDF",
- "saveData",
- "scale",
- "scale3d",
- "scale3dSelf",
- "scaleNonUniform",
- "scaleNonUniformSelf",
- "scaleSelf",
- "scheduler",
- "scheduling",
- "scheme",
- "scissor",
- "scope",
- "scopeName",
- "scoped",
- "screen",
- "screenBrightness",
- "screenEnabled",
- "screenLeft",
- "screenPixelToMillimeterX",
- "screenPixelToMillimeterY",
- "screenState",
- "screenTop",
- "screenX",
- "screenY",
- "screens",
- "scriptURL",
- "scripting",
- "scripts",
- "scroll",
- "scroll-behavior",
- "scroll-margin",
- "scroll-margin-block",
- "scroll-margin-block-end",
- "scroll-margin-block-start",
- "scroll-margin-bottom",
- "scroll-margin-inline",
- "scroll-margin-inline-end",
- "scroll-margin-inline-start",
- "scroll-margin-left",
- "scroll-margin-right",
- "scroll-margin-top",
- "scroll-padding",
- "scroll-padding-block",
- "scroll-padding-block-end",
- "scroll-padding-block-start",
- "scroll-padding-bottom",
- "scroll-padding-inline",
- "scroll-padding-inline-end",
- "scroll-padding-inline-start",
- "scroll-padding-left",
- "scroll-padding-right",
- "scroll-padding-top",
- "scroll-snap-align",
- "scroll-snap-stop",
- "scroll-snap-type",
- "scrollAmount",
- "scrollBehavior",
- "scrollBy",
- "scrollByLines",
- "scrollByPages",
- "scrollDelay",
- "scrollHeight",
- "scrollIntoView",
- "scrollIntoViewIfNeeded",
- "scrollLeft",
- "scrollLeftMax",
- "scrollMargin",
- "scrollMarginBlock",
- "scrollMarginBlockEnd",
- "scrollMarginBlockStart",
- "scrollMarginBottom",
- "scrollMarginInline",
- "scrollMarginInlineEnd",
- "scrollMarginInlineStart",
- "scrollMarginLeft",
- "scrollMarginRight",
- "scrollMarginTop",
- "scrollMaxX",
- "scrollMaxY",
- "scrollPadding",
- "scrollPaddingBlock",
- "scrollPaddingBlockEnd",
- "scrollPaddingBlockStart",
- "scrollPaddingBottom",
- "scrollPaddingInline",
- "scrollPaddingInlineEnd",
- "scrollPaddingInlineStart",
- "scrollPaddingLeft",
- "scrollPaddingRight",
- "scrollPaddingTop",
- "scrollRestoration",
- "scrollSnapAlign",
- "scrollSnapStop",
- "scrollSnapType",
- "scrollTo",
- "scrollTop",
- "scrollTopMax",
- "scrollWidth",
- "scrollX",
- "scrollY",
- "scrollbar-color",
- "scrollbar-gutter",
- "scrollbar-width",
- "scrollbar3dLightColor",
- "scrollbarArrowColor",
- "scrollbarBaseColor",
- "scrollbarColor",
- "scrollbarDarkShadowColor",
- "scrollbarFaceColor",
- "scrollbarGutter",
- "scrollbarHighlightColor",
- "scrollbarShadowColor",
- "scrollbarTrackColor",
- "scrollbarWidth",
- "scrollbars",
- "scrolling",
- "scrollingElement",
- "sctp",
- "sctpCauseCode",
- "sdp",
- "sdpLineNumber",
- "sdpMLineIndex",
- "sdpMid",
- "seal",
- "search",
- "searchBox",
- "searchBoxJavaBridge_",
- "searchParams",
- "second",
- "seconds",
- "sectionRowIndex",
- "secureConnectionStart",
- "securePaymentConfirmationAvailability",
- "security",
- "seed",
- "seek",
- "seekToNextFrame",
- "seekable",
- "seeking",
- "segments",
- "select",
- "selectAllChildren",
- "selectAlternateInterface",
- "selectAudioOutput",
- "selectConfiguration",
- "selectNode",
- "selectNodeContents",
- "selectNodes",
- "selectSingleNode",
- "selectSubString",
- "selectURL",
- "selected",
- "selectedIndex",
- "selectedOptions",
- "selectedStyleSheetSet",
- "selectedStylesheetSet",
- "selectedTrack",
- "selection",
- "selectionDirection",
- "selectionEnd",
- "selectionStart",
- "selector",
- "selectorText",
- "self",
- "send",
- "sendAsBinary",
- "sendBeacon",
- "sendFeatureReport",
- "sendMessage",
- "sendNativeMessage",
- "sendOrder",
- "sendReport",
- "sender",
- "sentAlert",
- "sentTimestamp",
- "separator",
- "serial",
- "serialNumber",
- "serializable",
- "serializeToString",
- "serverTiming",
- "service",
- "serviceWorker",
- "session",
- "sessionId",
- "sessionStorage",
- "sessions",
- "set",
- "setActionHandler",
- "setActive",
- "setAlpha",
- "setAppBadge",
- "setAttribute",
- "setAttributeNS",
- "setAttributeNode",
- "setAttributeNodeNS",
- "setAttributionReporting",
- "setBadgeBackgroundColor",
- "setBadgeText",
- "setBadgeTextColor",
- "setBaseAndExtent",
- "setBigInt64",
- "setBigUint64",
- "setBindGroup",
- "setBingCurrentSearchDefault",
- "setBlendConstant",
- "setCameraActive",
- "setCapture",
- "setCaptureHandleConfig",
- "setCodecPreferences",
- "setColor",
- "setCompositeOperation",
- "setConfiguration",
- "setConsumer",
- "setCurrentTime",
- "setCustomValidity",
- "setData",
- "setDate",
- "setDragImage",
- "setEnabled",
- "setEnd",
- "setEndAfter",
- "setEndBefore",
- "setEndPoint",
- "setExpires",
- "setFillColor",
- "setFilterRes",
- "setFloat16",
- "setFloat32",
- "setFloat64",
- "setFloatValue",
- "setFocusBehavior",
- "setFormValue",
- "setFromBase64",
- "setFromHex",
- "setFullYear",
- "setHTMLUnsafe",
- "setHeaderExtensionsToNegotiate",
- "setHeaderValue",
- "setHours",
- "setIcon",
- "setIdentityProvider",
- "setImmediate",
- "setIndexBuffer",
- "setInt16",
- "setInt32",
- "setInt8",
- "setInterval",
- "setItem",
- "setKeyframes",
- "setLineCap",
- "setLineDash",
- "setLineJoin",
- "setLineWidth",
- "setLiveSeekableRange",
- "setLocalDescription",
- "setMatrix",
- "setMatrixValue",
- "setMediaKeys",
- "setMicrophoneActive",
- "setMilliseconds",
- "setMinutes",
- "setMiterLimit",
- "setMonth",
- "setNamedItem",
- "setNamedItemNS",
- "setNonUserCodeExceptions",
- "setOrientToAngle",
- "setOrientToAuto",
- "setOrientation",
- "setOverrideHistoryNavigationMode",
- "setPaint",
- "setParameter",
- "setParameters",
- "setPathData",
- "setPeriodicWave",
- "setPipeline",
- "setPointerCapture",
- "setPopup",
- "setPosition",
- "setPositionState",
- "setPreference",
- "setPriority",
- "setPrivateToken",
- "setProperty",
- "setPrototypeOf",
- "setRGBColor",
- "setRGBColorICCColor",
- "setRadius",
- "setRangeText",
- "setRemoteDescription",
- "setReportEventDataForAutomaticBeacons",
- "setRequestHeader",
- "setResizable",
- "setResourceTimingBufferSize",
- "setRotate",
- "setScale",
- "setScissorRect",
- "setSeconds",
- "setSelectionRange",
- "setServerCertificate",
- "setShadow",
- "setSharedStorageContext",
- "setSignals",
- "setSinkId",
- "setSkewX",
- "setSkewY",
- "setStart",
- "setStartAfter",
- "setStartBefore",
- "setStatus",
- "setStdDeviation",
- "setStencilReference",
- "setStreams",
- "setStrictMode",
- "setStringValue",
- "setStrokeColor",
- "setSuggestResult",
- "setTargetAtTime",
- "setTargetValueAtTime",
- "setTime",
- "setTimeout",
- "setTitle",
- "setTransform",
- "setTranslate",
- "setUTCDate",
- "setUTCFullYear",
- "setUTCHours",
- "setUTCMilliseconds",
- "setUTCMinutes",
- "setUTCMonth",
- "setUTCSeconds",
- "setUint16",
- "setUint32",
- "setUint8",
- "setUninstallURL",
- "setUpdateUrlData",
- "setUri",
- "setValidity",
- "setValueAtTime",
- "setValueCurveAtTime",
- "setVariable",
- "setVelocity",
- "setVersion",
- "setVertexBuffer",
- "setViewport",
- "setYear",
- "setZoom",
- "setZoomSettings",
- "settingName",
- "settingValue",
- "sex",
- "shaderLocation",
- "shaderSource",
- "shadowBlur",
- "shadowColor",
- "shadowOffsetX",
- "shadowOffsetY",
- "shadowRoot",
- "shadowRootClonable",
- "shadowRootDelegatesFocus",
- "shadowRootMode",
- "shadowRootSerializable",
- "shape",
- "shape-image-threshold",
- "shape-margin",
- "shape-outside",
- "shape-rendering",
- "shapeImageThreshold",
- "shapeMargin",
- "shapeOutside",
- "shapeRendering",
- "share",
- "sharedContext",
- "sharedStorage",
- "sharedStorageWritable",
- "sheet",
- "shift",
- "shiftKey",
- "shiftLeft",
- "shippingAddress",
- "shippingOption",
- "shippingType",
- "show",
- "showDirectoryPicker",
- "showHelp",
- "showModal",
- "showModalDialog",
- "showModelessDialog",
- "showNotification",
- "showOpenFilePicker",
- "showPicker",
- "showPopover",
- "showSaveFilePicker",
- "sidebar",
- "sidebarAction",
- "sign",
- "signal",
- "signalAllAcceptedCredentials",
- "signalCurrentUserDetails",
- "signalUnknownCredential",
- "signalingState",
- "signature",
- "silent",
- "sin",
- "singleNodeValue",
- "sinh",
- "sinkId",
- "sittingToStandingTransform",
- "size",
- "sizeAdjust",
- "sizeToContent",
- "sizeX",
- "sizeZ",
- "sizes",
- "skewX",
- "skewXSelf",
- "skewY",
- "skewYSelf",
- "skipTransition",
- "skipped",
- "slice",
- "slope",
- "slot",
- "slotAssignment",
- "small",
- "smil",
- "smooth",
- "smoothingTimeConstant",
- "snapTargetBlock",
- "snapTargetInline",
- "snapToLines",
- "snapshotItem",
- "snapshotLength",
- "some",
- "sort",
- "sortingCode",
- "source",
- "sourceBuffer",
- "sourceBuffers",
- "sourceCapabilities",
- "sourceCharPosition",
- "sourceElement",
- "sourceFile",
- "sourceFunctionName",
- "sourceIndex",
- "sourceLanguage",
- "sourceMap",
- "sourceURL",
- "sources",
- "spacing",
- "span",
- "speak",
- "speakAs",
- "speaking",
- "species",
- "specified",
- "specularConstant",
- "specularExponent",
- "speechSynthesis",
- "speed",
- "speedOfSound",
- "spellcheck",
- "sphericalHarmonicsCoefficients",
- "splice",
- "split",
- "splitText",
- "spreadMethod",
- "sqrt",
- "src",
- "srcElement",
- "srcFactor",
- "srcFilter",
- "srcObject",
- "srcUrn",
- "srcdoc",
- "srclang",
- "srcset",
- "stack",
- "stackTraceLimit",
- "stacktrace",
- "stageParameters",
- "standalone",
- "standby",
- "start",
- "startContainer",
- "startE",
- "startIce",
- "startLoadTime",
- "startMessages",
- "startNotifications",
- "startOffset",
- "startProfiling",
- "startRendering",
- "startShark",
- "startTime",
- "startViewTransition",
- "startsWith",
- "state",
- "states",
- "stats",
- "status",
- "statusCode",
- "statusMessage",
- "statusText",
- "statusbar",
- "stdDeviationX",
- "stdDeviationY",
- "stencilBack",
- "stencilClearValue",
- "stencilFront",
- "stencilFunc",
- "stencilFuncSeparate",
- "stencilLoadOp",
- "stencilMask",
- "stencilMaskSeparate",
- "stencilOp",
- "stencilOpSeparate",
- "stencilReadMask",
- "stencilReadOnly",
- "stencilStoreOp",
- "stencilWriteMask",
- "step",
- "stepDown",
- "stepMismatch",
- "stepMode",
- "stepUp",
- "sticky",
- "stitchTiles",
- "stop",
- "stop-color",
- "stop-opacity",
- "stopColor",
- "stopImmediatePropagation",
- "stopNotifications",
- "stopOpacity",
- "stopProfiling",
- "stopPropagation",
- "stopShark",
- "stopped",
- "storage",
- "storageArea",
- "storageBuckets",
- "storageName",
- "storageStatus",
- "storageTexture",
- "store",
- "storeOp",
- "storeSiteSpecificTrackingException",
- "storeWebWideTrackingException",
- "stpVersion",
- "stream",
- "streamErrorCode",
- "streams",
- "stretch",
- "strike",
- "string",
- "stringValue",
- "stringify",
- "stripIndexFormat",
- "stroke",
- "stroke-dasharray",
- "stroke-dashoffset",
- "stroke-linecap",
- "stroke-linejoin",
- "stroke-miterlimit",
- "stroke-opacity",
- "stroke-width",
- "strokeDasharray",
- "strokeDashoffset",
- "strokeLinecap",
- "strokeLinejoin",
- "strokeMiterlimit",
- "strokeOpacity",
- "strokeRect",
- "strokeStyle",
- "strokeText",
- "strokeWidth",
- "structuredClone",
- "style",
- "styleAndLayoutStart",
- "styleFloat",
- "styleMap",
- "styleMedia",
- "styleSheet",
- "styleSheetSets",
- "styleSheets",
- "styleset",
- "stylistic",
- "sub",
- "subarray",
- "subgroupMaxSize",
- "subgroupMinSize",
- "subject",
- "submit",
- "submitFrame",
- "submitter",
- "subscribe",
- "substr",
- "substring",
- "substringData",
- "subtle",
- "subtree",
- "suffix",
- "suffixes",
- "sumPrecise",
- "summarize",
- "summarizeStreaming",
- "summary",
- "sup",
- "supported",
- "supportedContentEncodings",
- "supportedEntryTypes",
- "supportedValuesOf",
- "supports",
- "supportsFiber",
- "supportsSession",
- "supportsText",
- "suppressed",
- "surfaceScale",
- "surroundContents",
- "suspend",
- "suspendRedraw",
- "svb",
- "svh",
- "svi",
- "svmax",
- "svmin",
- "svw",
- "swapCache",
- "swapNode",
- "swash",
- "sweepFlag",
- "switchMap",
- "symbols",
- "symmetricDifference",
- "sync",
- "syntax",
- "sysexEnabled",
- "system",
- "systemCode",
- "systemId",
- "systemLanguage",
- "systemXDPI",
- "systemYDPI",
- "tBodies",
- "tFoot",
- "tHead",
- "tab",
- "tab-size",
- "tabId",
- "tabIds",
- "tabIndex",
- "tabSize",
- "table",
- "table-layout",
- "tableLayout",
- "tableValues",
- "tabs",
- "tag",
- "tagName",
- "tagUrn",
- "tags",
- "taintEnabled",
- "take",
- "takePhoto",
- "takeRecords",
- "takeUntil",
- "tan",
- "tangentialPressure",
- "tanh",
- "target",
- "targetAddressSpace",
- "targetElement",
- "targetLanguage",
- "targetRayMode",
- "targetRaySpace",
- "targetTouches",
- "targetURL",
- "targetX",
- "targetY",
- "targets",
- "tcpType",
- "tee",
- "tel",
- "telemetry",
- "terminate",
- "test",
- "texImage2D",
- "texImage3D",
- "texParameterf",
- "texParameteri",
- "texStorage2D",
- "texStorage3D",
- "texSubImage2D",
- "texSubImage3D",
- "text",
- "text-align",
- "text-align-last",
- "text-anchor",
- "text-combine-upright",
- "text-decoration",
- "text-decoration-color",
- "text-decoration-line",
- "text-decoration-skip-ink",
- "text-decoration-style",
- "text-decoration-thickness",
- "text-emphasis",
- "text-emphasis-color",
- "text-emphasis-position",
- "text-emphasis-style",
- "text-indent",
- "text-justify",
- "text-orientation",
- "text-overflow",
- "text-rendering",
- "text-shadow",
- "text-transform",
- "text-underline-offset",
- "text-underline-position",
- "text-wrap",
- "text-wrap-mode",
- "text-wrap-style",
- "textAlign",
- "textAlignLast",
- "textAnchor",
- "textAutospace",
- "textBaseline",
- "textCombineUpright",
- "textContent",
- "textDecoration",
- "textDecorationBlink",
- "textDecorationColor",
- "textDecorationInset",
- "textDecorationLine",
- "textDecorationLineThrough",
- "textDecorationNone",
- "textDecorationOverline",
- "textDecorationSkipInk",
- "textDecorationStyle",
- "textDecorationThickness",
- "textDecorationUnderline",
- "textEmphasis",
- "textEmphasisColor",
- "textEmphasisPosition",
- "textEmphasisStyle",
- "textIndent",
- "textJustify",
- "textJustifyTrim",
- "textKashida",
- "textKashidaSpace",
- "textLength",
- "textOrientation",
- "textOverflow",
- "textRendering",
- "textShadow",
- "textTracks",
- "textTransform",
- "textUnderlineOffset",
- "textUnderlinePosition",
- "textWrap",
- "textWrapMode",
- "textWrapStyle",
- "texture",
- "theme",
- "then",
- "threadId",
- "threshold",
- "thresholds",
- "throwIfAborted",
- "tiltX",
- "tiltY",
- "time",
- "timeEnd",
- "timeLog",
- "timeOrigin",
- "timeRemaining",
- "timeStamp",
- "timeStyle",
- "timeZone",
- "timeZoneName",
- "timecode",
- "timeline",
- "timelineTime",
- "timeout",
- "timestamp",
- "timestampOffset",
- "timestampWrites",
- "timing",
- "title",
- "titlebarAreaRect",
- "tlsChannelId",
- "to",
- "toArray",
- "toBase64",
- "toBlob",
- "toDataURL",
- "toDateString",
- "toElement",
- "toExponential",
- "toFixed",
- "toFloat32Array",
- "toFloat64Array",
- "toGMTString",
- "toHex",
- "toISOString",
- "toJSON",
- "toLocaleDateString",
- "toLocaleFormat",
- "toLocaleLowerCase",
- "toLocaleString",
- "toLocaleTimeString",
- "toLocaleUpperCase",
- "toLowerCase",
- "toMatrix",
- "toMethod",
- "toPrecision",
- "toPrimitive",
- "toReversed",
- "toSdp",
- "toSorted",
- "toSource",
- "toSpliced",
- "toStaticHTML",
- "toString",
- "toStringTag",
- "toSum",
- "toTemporalInstant",
- "toTimeString",
- "toUTCString",
- "toUpperCase",
- "toWellFormed",
- "toggle",
- "toggleAttribute",
- "toggleLongPressEnabled",
- "togglePopover",
- "toggleReaderMode",
- "token",
- "tone",
- "toneBuffer",
- "tooLong",
- "tooShort",
- "toolbar",
- "top",
- "topMargin",
- "topSites",
- "topology",
- "total",
- "totalFrameDelay",
- "totalFrames",
- "totalFramesDuration",
- "totalVideoFrames",
- "touch-action",
- "touchAction",
- "touched",
- "touches",
- "trace",
- "track",
- "trackVisibility",
- "trackedAnchors",
- "tracks",
- "tran",
- "transaction",
- "transactions",
- "transceiver",
- "transfer",
- "transferControlToOffscreen",
- "transferFromImageBitmap",
- "transferImageBitmap",
- "transferIn",
- "transferOut",
- "transferSize",
- "transferToFixedLength",
- "transferToImageBitmap",
- "transform",
- "transform-box",
- "transform-origin",
- "transform-style",
- "transformBox",
- "transformFeedbackVaryings",
- "transformOrigin",
- "transformPoint",
- "transformString",
- "transformStyle",
- "transformToDocument",
- "transformToFragment",
- "transition",
- "transition-behavior",
- "transition-delay",
- "transition-duration",
- "transition-property",
- "transition-timing-function",
- "transitionBehavior",
- "transitionDelay",
- "transitionDuration",
- "transitionProperty",
- "transitionTimingFunction",
- "translate",
- "translateSelf",
- "translateStreaming",
- "translationX",
- "translationY",
- "transport",
- "traverseTo",
- "trim",
- "trimEnd",
- "trimLeft",
- "trimRight",
- "trimStart",
- "trueSpeed",
- "trunc",
- "truncate",
- "trustedTypes",
- "try",
- "turn",
- "twist",
- "type",
- "typeDetail",
- "typeMismatch",
- "typeMustMatch",
- "types",
- "u2f",
- "ubound",
- "uint16",
- "uint32",
- "uint8",
- "uint8Clamped",
- "unadjustedMovement",
- "unclippedDepth",
- "unconfigure",
- "undefined",
- "underlineStyle",
- "underlineThickness",
- "unescape",
- "uneval",
- "ungroup",
- "unicode",
- "unicode-bidi",
- "unicodeBidi",
- "unicodeRange",
- "unicodeSets",
- "uniform1f",
- "uniform1fv",
- "uniform1i",
- "uniform1iv",
- "uniform1ui",
- "uniform1uiv",
- "uniform2f",
- "uniform2fv",
- "uniform2i",
- "uniform2iv",
- "uniform2ui",
- "uniform2uiv",
- "uniform3f",
- "uniform3fv",
- "uniform3i",
- "uniform3iv",
- "uniform3ui",
- "uniform3uiv",
- "uniform4f",
- "uniform4fv",
- "uniform4i",
- "uniform4iv",
- "uniform4ui",
- "uniform4uiv",
- "uniformBlockBinding",
- "uniformMatrix2fv",
- "uniformMatrix2x3fv",
- "uniformMatrix2x4fv",
- "uniformMatrix3fv",
- "uniformMatrix3x2fv",
- "uniformMatrix3x4fv",
- "uniformMatrix4fv",
- "uniformMatrix4x2fv",
- "uniformMatrix4x3fv",
- "uninstallSelf",
- "union",
- "unique",
- "uniqueID",
- "uniqueNumber",
- "unit",
- "unitType",
- "units",
- "unloadEventEnd",
- "unloadEventStart",
- "unlock",
- "unmap",
- "unmount",
- "unobserve",
- "unpackColorSpace",
- "unpause",
- "unpauseAnimations",
- "unreadCount",
- "unregister",
- "unregisterContentHandler",
- "unregisterProtocolHandler",
- "unscopables",
- "unselectable",
- "unshift",
- "unsubscribe",
- "unsuspendRedraw",
- "unsuspendRedrawAll",
- "unwatch",
- "unwrapKey",
- "upDegrees",
- "upX",
- "upY",
- "upZ",
- "update",
- "updateAdInterestGroups",
- "updateCallbackDone",
- "updateCharacterBounds",
- "updateCommands",
- "updateControlBounds",
- "updateCurrentEntry",
- "updateIce",
- "updateInkTrailStartPoint",
- "updateInterval",
- "updatePlaybackRate",
- "updateRangeEnd",
- "updateRangeStart",
- "updateRenderState",
- "updateSelection",
- "updateSelectionBounds",
- "updateSettings",
- "updateText",
- "updateTiming",
- "updateViaCache",
- "updateWith",
- "updated",
- "updating",
- "upgrade",
- "upload",
- "uploadTotal",
- "uploaded",
- "upper",
- "upperBound",
- "upperOpen",
- "uri",
- "url",
- "urn",
- "urns",
- "usage",
- "usages",
- "usb",
- "usbVersionMajor",
- "usbVersionMinor",
- "usbVersionSubminor",
- "use",
- "useCurrentView",
- "useMap",
- "useProgram",
- "usedSpace",
- "user-select",
- "userActivation",
- "userAgent",
- "userAgentAllowsProtocol",
- "userAgentData",
- "userChoice",
- "userHandle",
- "userHint",
- "userInitiated",
- "userLanguage",
- "userSelect",
- "userState",
- "userVisibleOnly",
- "username",
- "usernameFragment",
- "utterance",
- "uuid",
- "v8BreakIterator",
- "vAlign",
- "vLink",
- "valid",
- "validate",
- "validateProgram",
- "validationMessage",
- "validity",
- "value",
- "valueAsDate",
- "valueAsNumber",
- "valueAsString",
- "valueInSpecifiedUnits",
- "valueMissing",
- "valueOf",
- "valueText",
- "valueType",
- "values",
- "variable",
- "variant",
- "variationSettings",
- "vb",
- "vector-effect",
- "vectorEffect",
- "velocityAngular",
- "velocityExpansion",
- "velocityX",
- "velocityY",
- "vendor",
- "vendorId",
- "vendorSub",
- "verify",
- "version",
- "vertex",
- "vertexAttrib1f",
- "vertexAttrib1fv",
- "vertexAttrib2f",
- "vertexAttrib2fv",
- "vertexAttrib3f",
- "vertexAttrib3fv",
- "vertexAttrib4f",
- "vertexAttrib4fv",
- "vertexAttribDivisor",
- "vertexAttribDivisorANGLE",
- "vertexAttribI4i",
- "vertexAttribI4iv",
- "vertexAttribI4ui",
- "vertexAttribI4uiv",
- "vertexAttribIPointer",
- "vertexAttribPointer",
- "vertical",
- "vertical-align",
- "verticalAlign",
- "verticalOverflow",
- "vh",
- "vi",
- "vibrate",
- "vibrationActuator",
- "videoBitsPerSecond",
- "videoHeight",
- "videoTracks",
- "videoWidth",
- "view",
- "viewBox",
- "viewBoxString",
- "viewDimension",
- "viewFormats",
- "viewTarget",
- "viewTargetString",
- "viewTransition",
- "viewTransitionClass",
- "viewTransitionName",
- "viewport",
- "viewportAnchorX",
- "viewportAnchorY",
- "viewportElement",
- "views",
- "violatedDirective",
- "virtualKeyboard",
- "virtualKeyboardPolicy",
- "visibility",
- "visibilityState",
- "visible",
- "visibleRect",
- "visualViewport",
- "vlinkColor",
- "vmax",
- "vmin",
- "voice",
- "voiceURI",
- "volume",
- "vrml",
- "vspace",
- "vw",
- "w",
- "wait",
- "waitAsync",
- "waitSync",
- "waiting",
- "wake",
- "wakeLock",
- "wand",
- "warmup",
- "warn",
- "wasAlternateProtocolAvailable",
- "wasClean",
- "wasDiscarded",
- "wasFetchedViaSpdy",
- "wasNpnNegotiated",
- "watch",
- "watchAvailability",
- "watchPosition",
- "webNavigation",
- "webRequest",
- "webdriver",
- "webkitAddKey",
- "webkitAlignContent",
- "webkitAlignItems",
- "webkitAlignSelf",
- "webkitAnimation",
- "webkitAnimationDelay",
- "webkitAnimationDirection",
- "webkitAnimationDuration",
- "webkitAnimationFillMode",
- "webkitAnimationIterationCount",
- "webkitAnimationName",
- "webkitAnimationPlayState",
- "webkitAnimationTimingFunction",
- "webkitAppearance",
- "webkitAudioContext",
- "webkitAudioDecodedByteCount",
- "webkitAudioPannerNode",
- "webkitBackfaceVisibility",
- "webkitBackground",
- "webkitBackgroundAttachment",
- "webkitBackgroundClip",
- "webkitBackgroundColor",
- "webkitBackgroundImage",
- "webkitBackgroundOrigin",
- "webkitBackgroundPosition",
- "webkitBackgroundPositionX",
- "webkitBackgroundPositionY",
- "webkitBackgroundRepeat",
- "webkitBackgroundSize",
- "webkitBackingStorePixelRatio",
- "webkitBorderBottomLeftRadius",
- "webkitBorderBottomRightRadius",
- "webkitBorderImage",
- "webkitBorderImageOutset",
- "webkitBorderImageRepeat",
- "webkitBorderImageSlice",
- "webkitBorderImageSource",
- "webkitBorderImageWidth",
- "webkitBorderRadius",
- "webkitBorderTopLeftRadius",
- "webkitBorderTopRightRadius",
- "webkitBoxAlign",
- "webkitBoxDirection",
- "webkitBoxFlex",
- "webkitBoxOrdinalGroup",
- "webkitBoxOrient",
- "webkitBoxPack",
- "webkitBoxShadow",
- "webkitBoxSizing",
- "webkitCancelAnimationFrame",
- "webkitCancelFullScreen",
- "webkitCancelKeyRequest",
- "webkitCancelRequestAnimationFrame",
- "webkitClearResourceTimings",
- "webkitClipPath",
- "webkitClosedCaptionsVisible",
- "webkitConvertPointFromNodeToPage",
- "webkitConvertPointFromPageToNode",
- "webkitCreateShadowRoot",
- "webkitCurrentFullScreenElement",
- "webkitCurrentPlaybackTargetIsWireless",
- "webkitDecodedFrameCount",
- "webkitDirectionInvertedFromDevice",
- "webkitDisplayingFullscreen",
- "webkitDroppedFrameCount",
- "webkitEnterFullScreen",
- "webkitEnterFullscreen",
- "webkitEntries",
- "webkitExitFullScreen",
- "webkitExitFullscreen",
- "webkitExitPointerLock",
- "webkitFilter",
- "webkitFlex",
- "webkitFlexBasis",
- "webkitFlexDirection",
- "webkitFlexFlow",
- "webkitFlexGrow",
- "webkitFlexShrink",
- "webkitFlexWrap",
- "webkitFontFeatureSettings",
- "webkitFullScreenKeyboardInputAllowed",
- "webkitFullscreenElement",
- "webkitFullscreenEnabled",
- "webkitGenerateKeyRequest",
- "webkitGetAsEntry",
- "webkitGetDatabaseNames",
- "webkitGetEntries",
- "webkitGetEntriesByName",
- "webkitGetEntriesByType",
- "webkitGetFlowByName",
- "webkitGetGamepads",
- "webkitGetImageDataHD",
- "webkitGetNamedFlows",
- "webkitGetRegionFlowRanges",
- "webkitGetUserMedia",
- "webkitHasClosedCaptions",
- "webkitHidden",
- "webkitIDBCursor",
- "webkitIDBDatabase",
- "webkitIDBDatabaseError",
- "webkitIDBDatabaseException",
- "webkitIDBFactory",
- "webkitIDBIndex",
- "webkitIDBKeyRange",
- "webkitIDBObjectStore",
- "webkitIDBRequest",
- "webkitIDBTransaction",
- "webkitImageSmoothingEnabled",
- "webkitIndexedDB",
- "webkitInitMessageEvent",
- "webkitIsFullScreen",
- "webkitJustifyContent",
- "webkitKeys",
- "webkitLineClamp",
- "webkitLineDashOffset",
- "webkitLockOrientation",
- "webkitMask",
- "webkitMaskClip",
- "webkitMaskComposite",
- "webkitMaskImage",
- "webkitMaskOrigin",
- "webkitMaskPosition",
- "webkitMaskPositionX",
- "webkitMaskPositionY",
- "webkitMaskRepeat",
- "webkitMaskSize",
- "webkitMatchesSelector",
- "webkitMediaStream",
- "webkitNotifications",
- "webkitOfflineAudioContext",
- "webkitOrder",
- "webkitOrientation",
- "webkitPeerConnection00",
- "webkitPersistentStorage",
- "webkitPerspective",
- "webkitPerspectiveOrigin",
- "webkitPointerLockElement",
- "webkitPostMessage",
- "webkitPreservesPitch",
- "webkitPutImageDataHD",
- "webkitRTCPeerConnection",
- "webkitRegionOverset",
- "webkitRelativePath",
- "webkitRequestAnimationFrame",
- "webkitRequestFileSystem",
- "webkitRequestFullScreen",
- "webkitRequestFullscreen",
- "webkitRequestPointerLock",
- "webkitResolveLocalFileSystemURL",
- "webkitSetMediaKeys",
- "webkitSetResourceTimingBufferSize",
- "webkitShadowRoot",
- "webkitShowPlaybackTargetPicker",
- "webkitSlice",
- "webkitSpeechGrammar",
- "webkitSpeechGrammarList",
- "webkitSpeechRecognition",
- "webkitSpeechRecognitionError",
- "webkitSpeechRecognitionEvent",
- "webkitStorageInfo",
- "webkitSupportsFullscreen",
- "webkitTemporaryStorage",
- "webkitTextFillColor",
- "webkitTextSecurity",
- "webkitTextSizeAdjust",
- "webkitTextStroke",
- "webkitTextStrokeColor",
- "webkitTextStrokeWidth",
- "webkitTransform",
- "webkitTransformOrigin",
- "webkitTransformStyle",
- "webkitTransition",
- "webkitTransitionDelay",
- "webkitTransitionDuration",
- "webkitTransitionProperty",
- "webkitTransitionTimingFunction",
- "webkitURL",
- "webkitUnlockOrientation",
- "webkitUserSelect",
- "webkitVideoDecodedByteCount",
- "webkitVisibilityState",
- "webkitWirelessVideoPlaybackDisabled",
- "webkitdirectory",
- "webkitdropzone",
- "webstore",
- "weekday",
- "weeks",
- "weight",
- "wgslLanguageFeatures",
- "whatToShow",
- "wheelDelta",
- "wheelDeltaX",
- "wheelDeltaY",
- "when",
- "whenDefined",
- "which",
- "white-space",
- "white-space-collapse",
- "whiteSpace",
- "whiteSpaceCollapse",
- "wholeText",
- "widows",
- "width",
- "will-change",
- "willChange",
- "willValidate",
- "window",
- "windowAttribution",
- "windowControlsOverlay",
- "windowId",
- "windowIds",
- "windows",
- "with",
- "withCredentials",
- "withResolvers",
- "word-break",
- "word-spacing",
- "word-wrap",
- "wordBreak",
- "wordSpacing",
- "wordWrap",
- "workerCacheLookupStart",
- "workerFinalSourceType",
- "workerMatchedSourceType",
- "workerRouterEvaluationStart",
- "workerStart",
- "worklet",
- "wow64",
- "wrap",
- "wrapKey",
- "writable",
- "writableAuxiliaries",
- "write",
- "writeBuffer",
- "writeMask",
- "writeText",
- "writeTexture",
- "writeTimestamp",
- "writeValue",
- "writeValueWithResponse",
- "writeValueWithoutResponse",
- "writeWithoutResponse",
- "writeln",
- "writing-mode",
- "writingMode",
- "writingSuggestions",
- "x",
- "x1",
- "x2",
- "xChannelSelector",
- "xmlEncoding",
- "xmlStandalone",
- "xmlVersion",
- "xmlbase",
- "xmllang",
- "xmlspace",
- "xor",
- "xr",
- "y",
- "y1",
- "y2",
- "yChannelSelector",
- "yandex",
- "year",
- "years",
- "yield",
- "z",
- "z-index",
- "zIndex",
- "zoom",
- "zoomAndPan",
- "zoomLevel",
- "zoomRectScreen",
- ];
- /***********************************************************************
- A JavaScript tokenizer / parser / beautifier / compressor.
- https://github.com/mishoo/UglifyJS2
- -------------------------------- (C) ---------------------------------
- Author: Mihai Bazon
- <mihai.bazon@gmail.com>
- http://mihai.bazon.net/blog
- Distributed under the BSD license:
- Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ***********************************************************************/
- function find_builtins(reserved) {
- domprops.forEach(add);
- // Compatibility fix for some standard defined globals not defined on every js environment
- var new_globals = ["Symbol", "Map", "Promise", "Proxy", "Reflect", "Set", "WeakMap", "WeakSet"];
- var objects = {};
- var global_ref = typeof global === "object" ? global : self;
- new_globals.forEach(function (new_global) {
- objects[new_global] = global_ref[new_global] || function() {};
- });
- [
- "null",
- "true",
- "false",
- "NaN",
- "Infinity",
- "-Infinity",
- "undefined",
- ].forEach(add);
- [ Object, Array, Function, Number,
- String, Boolean, Error, Math,
- Date, RegExp, objects.Symbol, ArrayBuffer,
- DataView, decodeURI, decodeURIComponent,
- encodeURI, encodeURIComponent, eval, EvalError,
- Float32Array, Float64Array, Int8Array, Int16Array,
- Int32Array, isFinite, isNaN, JSON, objects.Map, parseFloat,
- parseInt, objects.Promise, objects.Proxy, RangeError, ReferenceError,
- objects.Reflect, objects.Set, SyntaxError, TypeError, Uint8Array,
- Uint8ClampedArray, Uint16Array, Uint32Array, URIError,
- objects.WeakMap, objects.WeakSet
- ].forEach(function(ctor) {
- Object.getOwnPropertyNames(ctor).map(add);
- if (ctor.prototype) {
- Object.getOwnPropertyNames(ctor.prototype).map(add);
- }
- });
- function add(name) {
- reserved.add(name);
- }
- }
- function reserve_quoted_keys(ast, reserved) {
- function add(name) {
- push_uniq(reserved, name);
- }
- ast.walk(new TreeWalker(function(node) {
- if (node instanceof AST_ObjectKeyVal && node.quote) {
- add(node.key);
- } else if (node instanceof AST_ObjectProperty && node.quote) {
- add(node.key.name);
- } else if (node instanceof AST_Sub) {
- addStrings(node.property, add);
- }
- }));
- }
- function addStrings(node, add) {
- node.walk(new TreeWalker(function(node) {
- if (node instanceof AST_Sequence) {
- addStrings(node.tail_node(), add);
- } else if (node instanceof AST_String) {
- add(node.value);
- } else if (node instanceof AST_Conditional) {
- addStrings(node.consequent, add);
- addStrings(node.alternative, add);
- }
- return true;
- }));
- }
- function mangle_private_properties(ast, options) {
- var cprivate = -1;
- var private_cache = new Map();
- var nth_identifier = options.nth_identifier || base54;
- ast = ast.transform(new TreeTransformer(function(node) {
- if (
- node instanceof AST_ClassPrivateProperty
- || node instanceof AST_PrivateMethod
- || node instanceof AST_PrivateGetter
- || node instanceof AST_PrivateSetter
- || node instanceof AST_PrivateIn
- ) {
- node.key.name = mangle_private(node.key.name);
- } else if (node instanceof AST_DotHash) {
- node.property = mangle_private(node.property);
- }
- }));
- return ast;
- function mangle_private(name) {
- let mangled = private_cache.get(name);
- if (!mangled) {
- mangled = nth_identifier.get(++cprivate);
- private_cache.set(name, mangled);
- }
- return mangled;
- }
- }
- function find_annotated_props(ast) {
- var annotated_props = new Set();
- walk(ast, node => {
- if (
- node instanceof AST_ClassPrivateProperty
- || node instanceof AST_PrivateMethod
- || node instanceof AST_PrivateGetter
- || node instanceof AST_PrivateSetter
- || node instanceof AST_DotHash
- ) ; else if (node instanceof AST_ObjectKeyVal) {
- if (typeof node.key == "string" && has_annotation(node, _MANGLEPROP)) {
- annotated_props.add(node.key);
- }
- } else if (node instanceof AST_ObjectProperty) {
- // setter or getter, since KeyVal is handled above
- if (has_annotation(node, _MANGLEPROP)) {
- annotated_props.add(node.key.name);
- }
- } else if (node instanceof AST_Dot) {
- if (has_annotation(node, _MANGLEPROP)) {
- annotated_props.add(node.property);
- }
- } else if (node instanceof AST_Sub) {
- if (node.property instanceof AST_String && has_annotation(node, _MANGLEPROP)) {
- annotated_props.add(node.property.value);
- }
- }
- });
- return annotated_props;
- }
- function mangle_properties(ast, options, annotated_props = find_annotated_props(ast)) {
- options = defaults(options, {
- builtins: false,
- cache: null,
- debug: false,
- keep_quoted: false,
- nth_identifier: base54,
- only_cache: false,
- regex: null,
- reserved: null,
- undeclared: false,
- only_annotated: false,
- }, true);
- var nth_identifier = options.nth_identifier;
- var reserved_option = options.reserved;
- if (!Array.isArray(reserved_option)) reserved_option = [reserved_option];
- var reserved = new Set(reserved_option);
- if (!options.builtins) find_builtins(reserved);
- var cname = -1;
- var cache;
- if (options.cache) {
- cache = options.cache.props;
- } else {
- cache = new Map();
- }
- var only_annotated = options.only_annotated;
- var regex = options.regex && new RegExp(options.regex);
- // note debug is either false (disabled), or a string of the debug suffix to use (enabled).
- // note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
- // the same as passing an empty string.
- var debug = options.debug !== false;
- var debug_name_suffix;
- if (debug) {
- debug_name_suffix = (options.debug === true ? "" : options.debug);
- }
- var names_to_mangle = new Set();
- var unmangleable = new Set();
- // Track each already-mangled name to prevent nth_identifier from generating
- // the same name.
- cache.forEach((mangled_name) => unmangleable.add(mangled_name));
- var keep_quoted = !!options.keep_quoted;
- // step 1: find candidates to mangle
- ast.walk(new TreeWalker(function(node) {
- if (
- node instanceof AST_ClassPrivateProperty
- || node instanceof AST_PrivateMethod
- || node instanceof AST_PrivateGetter
- || node instanceof AST_PrivateSetter
- || node instanceof AST_DotHash
- ) ; else if (node instanceof AST_ObjectKeyVal) {
- if (typeof node.key == "string" && (!keep_quoted || !node.quote)) {
- add(node.key);
- }
- } else if (node instanceof AST_ObjectProperty) {
- // setter or getter, since KeyVal is handled above
- if (!keep_quoted || !node.quote) {
- add(node.key.name);
- }
- } else if (node instanceof AST_Dot) {
- var declared = !!options.undeclared;
- if (!declared) {
- var root = node;
- while (root.expression) {
- root = root.expression;
- }
- declared = !(root.thedef && root.thedef.undeclared);
- }
- if (declared &&
- (!keep_quoted || !node.quote)) {
- add(node.property);
- }
- } else if (node instanceof AST_Sub) {
- if (!keep_quoted) {
- addStrings(node.property, add);
- }
- } else if (node instanceof AST_Call
- && node.expression.print_to_string() == "Object.defineProperty") {
- addStrings(node.args[1], add);
- } else if (node instanceof AST_Binary && node.operator === "in") {
- addStrings(node.left, add);
- } else if (node instanceof AST_String && has_annotation(node, _KEY)) {
- add(node.value);
- }
- }));
- // step 2: transform the tree, renaming properties
- return ast.transform(new TreeTransformer(function(node) {
- if (
- node instanceof AST_ClassPrivateProperty
- || node instanceof AST_PrivateMethod
- || node instanceof AST_PrivateGetter
- || node instanceof AST_PrivateSetter
- || node instanceof AST_DotHash
- ) ; else if (node instanceof AST_ObjectKeyVal) {
- if (typeof node.key == "string" && (!keep_quoted || !node.quote)) {
- node.key = mangle(node.key);
- }
- } else if (node instanceof AST_ObjectProperty) {
- // setter, getter, method or class field
- if (!keep_quoted || !node.quote) {
- if (!node.computed_key()) {
- node.key.name = mangle(node.key.name);
- }
- }
- } else if (node instanceof AST_Dot) {
- if (!keep_quoted || !node.quote) {
- node.property = mangle(node.property);
- }
- } else if (!keep_quoted && node instanceof AST_Sub) {
- node.property = mangleStrings(node.property);
- } else if (node instanceof AST_Call
- && node.expression.print_to_string() == "Object.defineProperty") {
- node.args[1] = mangleStrings(node.args[1]);
- } else if (node instanceof AST_Binary && node.operator === "in") {
- node.left = mangleStrings(node.left);
- } else if (node instanceof AST_String && has_annotation(node, _KEY)) {
- // Clear _KEY annotation to prevent double mangling
- clear_annotation(node, _KEY);
- node.value = mangle(node.value);
- }
- }));
- // only function declarations after this line
- function can_mangle(name) {
- if (unmangleable.has(name)) return false;
- if (reserved.has(name)) return false;
- if (options.only_cache) {
- return cache.has(name);
- }
- if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
- return true;
- }
- function should_mangle(name) {
- if (only_annotated && !annotated_props.has(name)) return false;
- if (regex && !regex.test(name)) {
- return annotated_props.has(name);
- }
- if (reserved.has(name)) return false;
- return cache.has(name)
- || names_to_mangle.has(name);
- }
- function add(name) {
- if (can_mangle(name)) {
- names_to_mangle.add(name);
- }
- if (!should_mangle(name)) {
- unmangleable.add(name);
- }
- }
- function mangle(name) {
- if (!should_mangle(name)) {
- return name;
- }
- var mangled = cache.get(name);
- if (!mangled) {
- if (debug) {
- // debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
- var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
- if (can_mangle(debug_mangled)) {
- mangled = debug_mangled;
- }
- }
- // either debug mode is off, or it is on and we could not use the mangled name
- if (!mangled) {
- do {
- mangled = nth_identifier.get(++cname);
- } while (!can_mangle(mangled));
- }
- cache.set(name, mangled);
- }
- return mangled;
- }
- function mangleStrings(node) {
- return node.transform(new TreeTransformer(function(node) {
- if (node instanceof AST_Sequence) {
- var last = node.expressions.length - 1;
- node.expressions[last] = mangleStrings(node.expressions[last]);
- } else if (node instanceof AST_String) {
- // Clear _KEY annotation to prevent double mangling
- clear_annotation(node, _KEY);
- node.value = mangle(node.value);
- } else if (node instanceof AST_Conditional) {
- node.consequent = mangleStrings(node.consequent);
- node.alternative = mangleStrings(node.alternative);
- }
- return node;
- }));
- }
- }
- // to/from base64 functions
- // Prefer built-in Buffer, if available, then use hack
- // https://developer.mozilla.org/en-US/docs/Glossary/Base64#The_Unicode_Problem
- var to_ascii = typeof Buffer !== "undefined"
- ? (b64) => Buffer.from(b64, "base64").toString()
- : (b64) => decodeURIComponent(escape(atob(b64)));
- var to_base64 = typeof Buffer !== "undefined"
- ? (str) => Buffer.from(str).toString("base64")
- : (str) => btoa(unescape(encodeURIComponent(str)));
- function read_source_map(code) {
- var match = /(?:^|[^.])\/\/# sourceMappingURL=data:application\/json(;[\w=-]*)?;base64,([+/0-9A-Za-z]*=*)\s*$/.exec(code);
- if (!match) {
- console.warn("inline source map not found");
- return null;
- }
- return to_ascii(match[2]);
- }
- function set_shorthand(name, options, keys) {
- if (options[name]) {
- keys.forEach(function(key) {
- if (options[key]) {
- if (typeof options[key] != "object") options[key] = {};
- if (!(name in options[key])) options[key][name] = options[name];
- }
- });
- }
- }
- function init_cache(cache) {
- if (!cache) return;
- if (!("props" in cache)) {
- cache.props = new Map();
- } else if (!(cache.props instanceof Map)) {
- cache.props = map_from_object(cache.props);
- }
- }
- function cache_to_json(cache) {
- return {
- props: map_to_object(cache.props)
- };
- }
- function log_input(files, options, fs, debug_folder) {
- if (!(fs && fs.writeFileSync && fs.mkdirSync)) {
- return;
- }
- try {
- fs.mkdirSync(debug_folder);
- } catch (e) {
- if (e.code !== "EEXIST") throw e;
- }
- const log_path = `${debug_folder}/terser-debug-${(Math.random() * 9999999) | 0}.log`;
- options = options || {};
- const options_str = JSON.stringify(options, (_key, thing) => {
- if (typeof thing === "function") return "[Function " + thing.toString() + "]";
- if (thing instanceof RegExp) return "[RegExp " + thing.toString() + "]";
- return thing;
- }, 4);
- const files_str = (file) => {
- if (typeof file === "object" && options.parse && options.parse.spidermonkey) {
- return JSON.stringify(file, null, 2);
- } else if (typeof file === "object") {
- return Object.keys(file)
- .map((key) => key + ": " + files_str(file[key]))
- .join("\n\n");
- } else if (typeof file === "string") {
- return "```\n" + file + "\n```";
- } else {
- return file; // What do?
- }
- };
- fs.writeFileSync(log_path, "Options: \n" + options_str + "\n\nInput files:\n\n" + files_str(files) + "\n");
- }
- function* minify_sync_or_async(files, options, _fs_module) {
- if (
- _fs_module
- && typeof process === "object"
- && process.env
- && typeof process.env.TERSER_DEBUG_DIR === "string"
- ) {
- log_input(files, options, _fs_module, process.env.TERSER_DEBUG_DIR);
- }
- options = defaults(options, {
- compress: {},
- ecma: undefined,
- enclose: false,
- ie8: false,
- keep_classnames: undefined,
- keep_fnames: false,
- mangle: {},
- module: false,
- nameCache: null,
- output: null,
- format: null,
- parse: {},
- rename: undefined,
- safari10: false,
- sourceMap: false,
- spidermonkey: false,
- timings: false,
- toplevel: false,
- warnings: false,
- wrap: false,
- }, true);
- var timings = options.timings && {
- start: Date.now()
- };
- if (options.keep_classnames === undefined) {
- options.keep_classnames = options.keep_fnames;
- }
- if (options.rename === undefined) {
- options.rename = options.compress && options.mangle;
- }
- if (options.output && options.format) {
- throw new Error("Please only specify either output or format option, preferrably format.");
- }
- options.format = options.format || options.output || {};
- set_shorthand("ecma", options, [ "parse", "compress", "format" ]);
- set_shorthand("ie8", options, [ "compress", "mangle", "format" ]);
- set_shorthand("keep_classnames", options, [ "compress", "mangle" ]);
- set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
- set_shorthand("module", options, [ "parse", "compress", "mangle" ]);
- set_shorthand("safari10", options, [ "mangle", "format" ]);
- set_shorthand("toplevel", options, [ "compress", "mangle" ]);
- set_shorthand("warnings", options, [ "compress" ]); // legacy
- var quoted_props;
- if (options.mangle) {
- options.mangle = defaults(options.mangle, {
- cache: options.nameCache && (options.nameCache.vars || {}),
- eval: false,
- ie8: false,
- keep_classnames: false,
- keep_fnames: false,
- module: false,
- nth_identifier: base54,
- properties: false,
- reserved: [],
- safari10: false,
- toplevel: false,
- }, true);
- if (options.mangle.properties) {
- if (typeof options.mangle.properties != "object") {
- options.mangle.properties = {};
- }
- if (options.mangle.properties.keep_quoted) {
- quoted_props = options.mangle.properties.reserved;
- if (!Array.isArray(quoted_props)) quoted_props = [];
- options.mangle.properties.reserved = quoted_props;
- }
- if (options.nameCache && !("cache" in options.mangle.properties)) {
- options.mangle.properties.cache = options.nameCache.props || {};
- }
- }
- init_cache(options.mangle.cache);
- init_cache(options.mangle.properties.cache);
- }
- if (options.sourceMap) {
- options.sourceMap = defaults(options.sourceMap, {
- asObject: false,
- content: null,
- filename: null,
- includeSources: false,
- root: null,
- url: null,
- }, true);
- }
- // -- Parse phase --
- if (timings) timings.parse = Date.now();
- var toplevel;
- if (files instanceof AST_Toplevel) {
- toplevel = files;
- } else {
- if (typeof files == "string" || (options.parse.spidermonkey && !Array.isArray(files))) {
- files = [ files ];
- }
- options.parse = options.parse || {};
- options.parse.toplevel = null;
- if (options.parse.spidermonkey) {
- options.parse.toplevel = AST_Node.from_mozilla_ast(Object.keys(files).reduce(function(toplevel, name) {
- if (!toplevel) return files[name];
- toplevel.body = toplevel.body.concat(files[name].body);
- return toplevel;
- }, null));
- } else {
- delete options.parse.spidermonkey;
- for (var name in files) if (HOP(files, name)) {
- options.parse.filename = name;
- options.parse.toplevel = parse(files[name], options.parse);
- if (options.sourceMap && options.sourceMap.content == "inline") {
- if (Object.keys(files).length > 1)
- throw new Error("inline source map only works with singular input");
- options.sourceMap.content = read_source_map(files[name]);
- }
- }
- }
- if (options.parse.toplevel === null) {
- throw new Error("no source file given");
- }
- toplevel = options.parse.toplevel;
- }
- if (quoted_props && options.mangle.properties.keep_quoted !== "strict") {
- reserve_quoted_keys(toplevel, quoted_props);
- }
- var annotated_props;
- if (options.mangle && options.mangle.properties) {
- annotated_props = find_annotated_props(toplevel);
- }
- if (options.wrap) {
- toplevel = toplevel.wrap_commonjs(options.wrap);
- }
- if (options.enclose) {
- toplevel = toplevel.wrap_enclose(options.enclose);
- }
- if (timings) timings.rename = Date.now();
- // -- Compress phase --
- if (timings) timings.compress = Date.now();
- if (options.compress) {
- toplevel = new Compressor(options.compress, {
- mangle_options: options.mangle
- }).compress(toplevel);
- }
- // -- Mangle phase --
- if (timings) timings.scope = Date.now();
- if (options.mangle) toplevel.figure_out_scope(options.mangle);
- if (timings) timings.mangle = Date.now();
- if (options.mangle) {
- toplevel.compute_char_frequency(options.mangle);
- toplevel.mangle_names(options.mangle);
- toplevel = mangle_private_properties(toplevel, options.mangle);
- }
- if (timings) timings.properties = Date.now();
- if (options.mangle && options.mangle.properties) {
- toplevel = mangle_properties(toplevel, options.mangle.properties, annotated_props);
- }
- // Format phase
- if (timings) timings.format = Date.now();
- var result = {};
- if (options.format.ast) {
- result.ast = toplevel;
- }
- if (options.format.spidermonkey) {
- result.ast = toplevel.to_mozilla_ast();
- }
- let format_options;
- if (!HOP(options.format, "code") || options.format.code) {
- // Make a shallow copy so that we can modify without mutating the user's input.
- format_options = {...options.format};
- if (!format_options.ast) {
- // Destroy stuff to save RAM. (unless the deprecated `ast` option is on)
- format_options._destroy_ast = true;
- walk(toplevel, node => {
- if (node instanceof AST_Scope) {
- node.variables = undefined;
- node.enclosed = undefined;
- node.parent_scope = undefined;
- }
- if (node.block_scope) {
- node.block_scope.variables = undefined;
- node.block_scope.enclosed = undefined;
- node.block_scope.parent_scope = undefined;
- }
- });
- }
- if (options.sourceMap) {
- if (options.sourceMap.includeSources && files instanceof AST_Toplevel) {
- throw new Error("original source content unavailable");
- }
- format_options.source_map = yield* SourceMap({
- file: options.sourceMap.filename,
- orig: options.sourceMap.content,
- root: options.sourceMap.root,
- files: options.sourceMap.includeSources ? files : null,
- });
- }
- delete format_options.ast;
- delete format_options.code;
- delete format_options.spidermonkey;
- var stream = OutputStream(format_options);
- toplevel.print(stream);
- result.code = stream.get();
- if (options.sourceMap) {
- Object.defineProperty(result, "map", {
- configurable: true,
- enumerable: true,
- get() {
- const map = format_options.source_map.getEncoded();
- return (result.map = options.sourceMap.asObject ? map : JSON.stringify(map));
- },
- set(value) {
- Object.defineProperty(result, "map", {
- value,
- writable: true,
- });
- }
- });
- result.decoded_map = format_options.source_map.getDecoded();
- if (options.sourceMap.url == "inline") {
- var sourceMap = typeof result.map === "object" ? JSON.stringify(result.map) : result.map;
- result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(sourceMap);
- } else if (options.sourceMap.url) {
- result.code += "\n//# sourceMappingURL=" + options.sourceMap.url;
- }
- }
- }
- if (options.nameCache && options.mangle) {
- if (options.mangle.cache) options.nameCache.vars = cache_to_json(options.mangle.cache);
- if (options.mangle.properties && options.mangle.properties.cache) {
- options.nameCache.props = cache_to_json(options.mangle.properties.cache);
- }
- }
- if (format_options && format_options.source_map) {
- format_options.source_map.destroy();
- }
- if (timings) {
- timings.end = Date.now();
- result.timings = {
- parse: 1e-3 * (timings.rename - timings.parse),
- rename: 1e-3 * (timings.compress - timings.rename),
- compress: 1e-3 * (timings.scope - timings.compress),
- scope: 1e-3 * (timings.mangle - timings.scope),
- mangle: 1e-3 * (timings.properties - timings.mangle),
- properties: 1e-3 * (timings.format - timings.properties),
- format: 1e-3 * (timings.end - timings.format),
- total: 1e-3 * (timings.end - timings.start)
- };
- }
- return result;
- }
- async function minify(files, options, _fs_module) {
- const gen = minify_sync_or_async(files, options, _fs_module);
- let yielded;
- let val;
- do {
- val = gen.next(await yielded);
- yielded = val.value;
- } while (!val.done);
- return val.value;
- }
- function minify_sync(files, options, _fs_module) {
- const gen = minify_sync_or_async(files, options, _fs_module);
- let yielded;
- let val;
- do {
- if (yielded && typeof yielded.then === "function") {
- throw new Error("minify_sync cannot be used with the legacy source-map module");
- }
- val = gen.next(yielded);
- yielded = val.value;
- } while (!val.done);
- return val.value;
- }
- async function run_cli({ program, packageJson, fs, path }) {
- const skip_keys = new Set([ "cname", "parent_scope", "scope", "uses_eval", "uses_with" ]);
- var files = {};
- var options = {
- compress: false,
- mangle: false
- };
- const default_options = await _default_options();
- program.version(packageJson.name + " " + packageJson.version);
- program.parseArgv = program.parse;
- program.parse = undefined;
- if (process.argv.includes("ast")) program.helpInformation = describe_ast;
- else if (process.argv.includes("options")) program.helpInformation = function() {
- var text = [];
- for (var option in default_options) {
- text.push("--" + (option === "sourceMap" ? "source-map" : option) + " options:");
- text.push(format_object(default_options[option]));
- text.push("");
- }
- return text.join("\n");
- };
- program.option("-p, --parse <options>", "Specify parser options.", parse_js());
- program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js());
- program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js());
- program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js());
- program.option("-f, --format [options]", "Format options.", parse_js());
- program.option("-b, --beautify [options]", "Alias for --format.", parse_js());
- program.option("-o, --output <file>", "Output file (default STDOUT).");
- program.option("--comments [filter]", "Preserve copyright comments in the output.");
- program.option("--config-file <file>", "Read minify() options from JSON file.");
- program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
- program.option("--ecma <version>", "Specify ECMAScript release: 5, 2015, 2016 or 2017...");
- program.option("-e, --enclose [arg[,...][:value[,...]]]", "Embed output in a big function with configurable arguments and values.");
- program.option("--ie8", "Support non-standard Internet Explorer 8.");
- program.option("--keep-classnames", "Do not mangle/drop class names.");
- program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
- program.option("--module", "Input is an ES6 module");
- program.option("--name-cache <file>", "File to hold mangled name mappings.");
- program.option("--rename", "Force symbol expansion.");
- program.option("--no-rename", "Disable symbol expansion.");
- program.option("--safari10", "Support non-standard Safari 10.");
- program.option("--source-map [options]", "Enable source map/specify source map options.", parse_js());
- program.option("--timings", "Display operations run time on STDERR.");
- program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
- program.option("--wrap <name>", "Embed everything as a function with “exports” corresponding to “name” globally.");
- program.arguments("[files...]").parseArgv(process.argv);
- if (program.configFile) {
- options = JSON.parse(read_file(program.configFile));
- }
- if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
- fatal("ERROR: cannot write source map to STDOUT");
- }
- [
- "compress",
- "enclose",
- "ie8",
- "mangle",
- "module",
- "safari10",
- "sourceMap",
- "toplevel",
- "wrap"
- ].forEach(function(name) {
- if (name in program) {
- options[name] = program[name];
- }
- });
- if ("ecma" in program) {
- if (program.ecma != (program.ecma | 0)) fatal("ERROR: ecma must be an integer");
- const ecma = program.ecma | 0;
- if (ecma > 5 && ecma < 2015)
- options.ecma = ecma + 2009;
- else
- options.ecma = ecma;
- }
- if (program.format || program.beautify) {
- const chosenOption = program.format || program.beautify;
- options.format = typeof chosenOption === "object" ? chosenOption : {};
- }
- if (program.comments) {
- if (typeof options.format != "object") options.format = {};
- options.format.comments = typeof program.comments == "string" ? (program.comments == "false" ? false : program.comments) : "some";
- }
- if (program.define) {
- if (typeof options.compress != "object") options.compress = {};
- if (typeof options.compress.global_defs != "object") options.compress.global_defs = {};
- for (var expr in program.define) {
- options.compress.global_defs[expr] = program.define[expr];
- }
- }
- if (program.keepClassnames) {
- options.keep_classnames = true;
- }
- if (program.keepFnames) {
- options.keep_fnames = true;
- }
- if (program.mangleProps) {
- if (program.mangleProps.domprops) {
- delete program.mangleProps.domprops;
- } else {
- if (typeof program.mangleProps != "object") program.mangleProps = {};
- if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = [];
- }
- if (typeof options.mangle != "object") options.mangle = {};
- options.mangle.properties = program.mangleProps;
- }
- if (program.nameCache) {
- options.nameCache = JSON.parse(read_file(program.nameCache, "{}"));
- }
- if (program.output == "ast") {
- options.format = {
- ast: true,
- code: false
- };
- }
- if (program.parse) {
- if (!program.parse.acorn && !program.parse.spidermonkey) {
- options.parse = program.parse;
- } else if (program.sourceMap && program.sourceMap.content == "inline") {
- fatal("ERROR: inline source map only works with built-in parser");
- }
- }
- if (~program.rawArgs.indexOf("--rename")) {
- options.rename = true;
- } else if (!program.rename) {
- options.rename = false;
- }
- let convert_path = name => name;
- if (typeof program.sourceMap == "object" && "base" in program.sourceMap) {
- convert_path = function() {
- var base = program.sourceMap.base;
- delete options.sourceMap.base;
- return function(name) {
- return path.relative(base, name);
- };
- }();
- }
- let filesList;
- if (options.files && options.files.length) {
- filesList = options.files;
- delete options.files;
- } else if (program.args.length) {
- filesList = program.args;
- }
- if (filesList) {
- simple_glob(filesList).forEach(function(name) {
- files[convert_path(name)] = read_file(name);
- });
- } else {
- await new Promise((resolve) => {
- var chunks = [];
- process.stdin.setEncoding("utf8");
- process.stdin.on("data", function(chunk) {
- chunks.push(chunk);
- }).on("end", function() {
- files = [ chunks.join("") ];
- resolve();
- });
- process.stdin.resume();
- });
- }
- await run_cli();
- function convert_ast(fn) {
- return AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null));
- }
- async function run_cli() {
- var content = program.sourceMap && program.sourceMap.content;
- if (content && content !== "inline") {
- options.sourceMap.content = read_file(content, content);
- }
- if (program.timings) options.timings = true;
- try {
- if (program.parse) {
- if (program.parse.acorn) {
- files = convert_ast(function(toplevel, name) {
- return require("acorn").parse(files[name], {
- ecmaVersion: 2024,
- locations: true,
- program: toplevel,
- sourceFile: name,
- sourceType: options.module || program.parse.module ? "module" : "script"
- });
- });
- } else if (program.parse.spidermonkey) {
- files = convert_ast(function(toplevel, name) {
- var obj = JSON.parse(files[name]);
- if (!toplevel) return obj;
- toplevel.body = toplevel.body.concat(obj.body);
- return toplevel;
- });
- }
- }
- } catch (ex) {
- fatal(ex);
- }
- let result;
- try {
- result = await minify(files, options, fs);
- } catch (ex) {
- if (ex.name == "SyntaxError") {
- print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
- var col = ex.col;
- var lines = files[ex.filename].split(/\r?\n/);
- var line = lines[ex.line - 1];
- if (!line && !col) {
- line = lines[ex.line - 2];
- col = line.length;
- }
- if (line) {
- var limit = 70;
- if (col > limit) {
- line = line.slice(col - limit);
- col = limit;
- }
- print_error(line.slice(0, 80));
- print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
- }
- }
- if (ex.defs) {
- print_error("Supported options:");
- print_error(format_object(ex.defs));
- }
- fatal(ex);
- return;
- }
- if (program.output == "ast") {
- if (!options.compress && !options.mangle) {
- result.ast.figure_out_scope({});
- }
- console.log(JSON.stringify(result.ast, function(key, value) {
- if (value) switch (key) {
- case "thedef":
- return symdef(value);
- case "enclosed":
- return value.length ? value.map(symdef) : undefined;
- case "variables":
- case "globals":
- return value.size ? collect_from_map(value, symdef) : undefined;
- }
- if (skip_keys.has(key)) return;
- if (value instanceof AST_Token) return;
- if (value instanceof Map) return;
- if (value instanceof AST_Node) {
- var result = {
- _class: "AST_" + value.TYPE
- };
- if (value.block_scope) {
- result.variables = value.block_scope.variables;
- result.enclosed = value.block_scope.enclosed;
- }
- value.CTOR.PROPS.forEach(function(prop) {
- if (prop !== "block_scope") {
- result[prop] = value[prop];
- }
- });
- return result;
- }
- return value;
- }, 2));
- } else if (program.output == "spidermonkey") {
- try {
- const minified = await minify(
- result.code,
- {
- compress: false,
- mangle: false,
- format: {
- ast: true,
- code: false
- }
- },
- fs
- );
- console.log(JSON.stringify(minified.ast.to_mozilla_ast(), null, 2));
- } catch (ex) {
- fatal(ex);
- return;
- }
- } else if (program.output) {
- fs.mkdirSync(path.dirname(program.output), { recursive: true });
- fs.writeFileSync(program.output, result.code);
- if (options.sourceMap && options.sourceMap.url !== "inline" && result.map) {
- fs.writeFileSync(program.output + ".map", result.map);
- }
- } else {
- console.log(result.code);
- }
- if (program.nameCache) {
- fs.writeFileSync(program.nameCache, JSON.stringify(options.nameCache));
- }
- if (result.timings) for (var phase in result.timings) {
- print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
- }
- }
- function fatal(message) {
- if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:");
- print_error(message);
- process.exit(1);
- }
- // A file glob function that only supports "*" and "?" wildcards in the basename.
- // Example: "foo/bar/*baz??.*.js"
- // Argument `glob` may be a string or an array of strings.
- // Returns an array of strings. Garbage in, garbage out.
- function simple_glob(glob) {
- if (Array.isArray(glob)) {
- return [].concat.apply([], glob.map(simple_glob));
- }
- if (glob && glob.match(/[*?]/)) {
- var dir = path.dirname(glob);
- try {
- var entries = fs.readdirSync(dir);
- } catch (ex) {}
- if (entries) {
- var pattern = "^" + path.basename(glob)
- .replace(/[.+^$[\]\\(){}]/g, "\\$&")
- .replace(/\*/g, "[^/\\\\]*")
- .replace(/\?/g, "[^/\\\\]") + "$";
- var mod = process.platform === "win32" ? "i" : "";
- var rx = new RegExp(pattern, mod);
- var results = entries.filter(function(name) {
- return rx.test(name);
- }).map(function(name) {
- return path.join(dir, name);
- });
- if (results.length) return results;
- }
- }
- return [ glob ];
- }
- function read_file(path, default_value) {
- try {
- return fs.readFileSync(path, "utf8");
- } catch (ex) {
- if ((ex.code == "ENOENT" || ex.code == "ENAMETOOLONG") && default_value != null) return default_value;
- fatal(ex);
- }
- }
- function parse_js(flag) {
- return function(value, options) {
- options = options || {};
- try {
- walk(parse(value, { expression: true }), node => {
- if (node instanceof AST_Assign) {
- var name = node.left.print_to_string();
- var value = node.right;
- if (flag) {
- options[name] = value;
- } else if (value instanceof AST_Array) {
- options[name] = value.elements.map(to_string);
- } else if (value instanceof AST_RegExp) {
- value = value.value;
- options[name] = new RegExp(value.source, value.flags);
- } else {
- options[name] = to_string(value);
- }
- return true;
- }
- if (node instanceof AST_Symbol || node instanceof AST_PropAccess) {
- var name = node.print_to_string();
- options[name] = true;
- return true;
- }
- if (!(node instanceof AST_Sequence)) throw node;
- function to_string(value) {
- return value instanceof AST_Constant ? value.getValue() : value.print_to_string({
- quote_keys: true
- });
- }
- });
- } catch(ex) {
- if (flag) {
- fatal("Error parsing arguments for '" + flag + "': " + value);
- } else {
- options[value] = null;
- }
- }
- return options;
- };
- }
- function symdef(def) {
- var ret = (1e6 + def.id) + " " + def.name;
- if (def.mangled_name) ret += " " + def.mangled_name;
- return ret;
- }
- function collect_from_map(map, callback) {
- var result = [];
- map.forEach(function (def) {
- result.push(callback(def));
- });
- return result;
- }
- function format_object(obj) {
- var lines = [];
- var padding = "";
- Object.keys(obj).map(function(name) {
- if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
- return [ name, JSON.stringify(obj[name]) ];
- }).forEach(function(tokens) {
- lines.push(" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
- });
- return lines.join("\n");
- }
- function print_error(msg) {
- process.stderr.write(msg);
- process.stderr.write("\n");
- }
- function describe_ast() {
- var out = OutputStream({ beautify: true });
- function doitem(ctor) {
- out.print("AST_" + ctor.TYPE);
- const props = ctor.SELF_PROPS.filter(prop => !/^\$/.test(prop));
- if (props.length > 0) {
- out.space();
- out.with_parens(function() {
- props.forEach(function(prop, i) {
- if (i) out.space();
- out.print(prop);
- });
- });
- }
- if (ctor.documentation) {
- out.space();
- out.print_string(ctor.documentation);
- }
- if (ctor.SUBCLASSES.length > 0) {
- out.space();
- out.with_block(function() {
- ctor.SUBCLASSES.forEach(function(ctor) {
- out.indent();
- doitem(ctor);
- out.newline();
- });
- });
- }
- }
- doitem(AST_Node);
- return out + "\n";
- }
- }
- async function _default_options() {
- const defs = {};
- Object.keys(infer_options({ 0: 0 })).forEach((component) => {
- const options = infer_options({
- [component]: {0: 0}
- });
- if (options) defs[component] = options;
- });
- return defs;
- }
- async function infer_options(options) {
- try {
- await minify("", options);
- } catch (error) {
- return error.defs;
- }
- }
- exports._default_options = _default_options;
- exports._run_cli = run_cli;
- exports.minify = minify;
- exports.minify_sync = minify_sync;
- }));
|