| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532335333353433535335363353733538335393354033541335423354333544335453354633547335483354933550335513355233553335543355533556335573355833559335603356133562335633356433565335663356733568335693357033571335723357333574335753357633577335783357933580335813358233583335843358533586335873358833589335903359133592335933359433595335963359733598335993360033601336023360333604336053360633607336083360933610336113361233613336143361533616336173361833619336203362133622336233362433625336263362733628336293363033631336323363333634336353363633637336383363933640336413364233643336443364533646336473364833649336503365133652336533365433655336563365733658336593366033661336623366333664336653366633667336683366933670336713367233673336743367533676336773367833679336803368133682336833368433685336863368733688336893369033691336923369333694336953369633697336983369933700337013370233703337043370533706337073370833709337103371133712337133371433715337163371733718337193372033721337223372333724337253372633727337283372933730337313373233733337343373533736337373373833739337403374133742337433374433745337463374733748337493375033751337523375333754337553375633757337583375933760337613376233763337643376533766337673376833769337703377133772337733377433775337763377733778337793378033781337823378333784337853378633787337883378933790337913379233793337943379533796337973379833799338003380133802338033380433805338063380733808338093381033811338123381333814338153381633817338183381933820338213382233823338243382533826338273382833829338303383133832338333383433835338363383733838338393384033841338423384333844338453384633847338483384933850338513385233853338543385533856338573385833859338603386133862338633386433865338663386733868338693387033871338723387333874338753387633877338783387933880338813388233883338843388533886338873388833889338903389133892338933389433895338963389733898338993390033901339023390333904339053390633907339083390933910339113391233913339143391533916339173391833919339203392133922339233392433925339263392733928339293393033931339323393333934339353393633937339383393933940339413394233943339443394533946339473394833949339503395133952339533395433955339563395733958339593396033961339623396333964339653396633967339683396933970339713397233973339743397533976339773397833979339803398133982339833398433985339863398733988339893399033991339923399333994339953399633997339983399934000340013400234003340043400534006340073400834009340103401134012340133401434015340163401734018340193402034021340223402334024340253402634027340283402934030340313403234033340343403534036340373403834039340403404134042340433404434045340463404734048340493405034051340523405334054340553405634057340583405934060340613406234063340643406534066340673406834069340703407134072340733407434075340763407734078340793408034081340823408334084340853408634087340883408934090340913409234093340943409534096340973409834099341003410134102341033410434105341063410734108341093411034111341123411334114341153411634117341183411934120341213412234123341243412534126341273412834129341303413134132341333413434135341363413734138341393414034141341423414334144341453414634147341483414934150341513415234153341543415534156 |
- (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;
- }
- /***********************************************************************
- 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 ]----- */
- // surrogate safe regexps adapted from https://github.com/mathiasbynens/unicode-8.0.0/tree/89b412d8a71ecca9ed593d9e9fa073ab64acfebe/Binary_Property
- var UNICODE = {
- 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])+/,
- };
- 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
- if (is_surrogate_pair_head(str.charCodeAt(pos))) {
- return 0x10000 + (str.charCodeAt(pos) - 0xd800 << 10) + str.charCodeAt(pos + 1) - 0xdc00;
- }
- return str.charCodeAt(pos);
- }
- 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_digit(code) {
- return code >= 48 && code <= 57;
- }
- function is_identifier_start(ch) {
- return UNICODE.ID_Start.test(ch);
- }
- function is_identifier_char(ch) {
- return UNICODE.ID_Continue.test(ch);
- }
- const BASIC_IDENT = /^[a-z_$][a-z0-9_$]*$/i;
- function is_basic_identifier_string(str) {
- return BASIC_IDENT.test(str);
- }
- 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.ID_Start.exec(str);
- if (!match || match.index !== 0) {
- return false;
- }
- str = str.slice(match[0].length);
- if (!str) {
- return true;
- }
- match = UNICODE.ID_Continue.exec(str);
- return !!match && match[0].length === str.length;
- }
- 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(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(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(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(ch)) {
- parse_error("First identifier char is an invalid identifier char");
- }
- } else if (is_identifier_start(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(ch)) {
- parse_error("Invalid escaped identifier char");
- }
- } else {
- if (!is_identifier_char(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(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;
- 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,
- }, 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");
- }
- return function_(AST_Defun, false, true, is_export_default);
- }
- 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;
- }
- }
- 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");
- }
- return function_(AST_Defun, false, false, is_export_default);
- 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);
- 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());
- var args = [];
- var body = _function_body(true, is_generator, is_async, name, args);
- return new ctor({
- start : args.start,
- end : body.end,
- is_generator: is_generator,
- async : is_async,
- name : name,
- argnames: args,
- body : body
- });
- };
- 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", ")")) {
- 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("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", ")")) {
- expect(",");
- if (is("punc", ")")) {
- trailing_comma = prev();
- if (maybe_sequence) invalid_sequence = trailing_comma;
- }
- }
- }
- expect(")");
- 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 (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 = [];
- var def;
- 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 { a } = b
- if (is("punc", "{") || is("punc", "[")) {
- def = new def_type({
- start: S.token,
- name: binding_element(undefined, sym_type),
- value: is("operator", "=") ? (expect_token("operator", "="), expression(false, no_in)) : null,
- end: prev()
- });
- } else {
- def = new def_type({
- start : S.token,
- name : as_symbol(sym_type),
- value : is("operator", "=")
- ? (next(), expression(false, no_in))
- : !no_in && (kind === "const" || kind === "using" || kind === "await using")
- ? croak("Missing initializer in " + kind + " declaration") : null,
- end : prev()
- });
- if (def.name.name == "import") croak("Unexpected token: import");
- }
- 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", "new")) {
- return new_(allow_calls);
- }
- if (is("name", "import") && is_token(peek(), "punc", ".")) {
- return import_meta(allow_calls);
- }
- var start = S.token;
- var peeked;
- var async = is("name", "async")
- && (peeked = peek()).value != "["
- && peeked.type != "arrow"
- && as_atom_node();
- 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("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);
- 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 = embed_tokens((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) {
- 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 (S.token.value == "extends") {
- next();
- extends_ = expression(true);
- }
- 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(), start, true);
- if (!method) { unexpected(); }
- 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 (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();
- }
- 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 (accessor_type != null) {
- if (!is_private) {
- const AccessorClass = accessor_type === "get"
- ? AST_ObjectGetter
- : AST_ObjectSetter;
- name = get_symbol_ast(name, AST_SymbolMethod);
- return annotate(new AccessorClass({
- start,
- static: is_static,
- key: name,
- quote: name instanceof AST_SymbolMethod ? property_token.quote : undefined,
- value: create_accessor(),
- end: prev()
- }));
- } else {
- const AccessorClass = accessor_type === "get"
- ? AST_PrivateGetter
- : AST_PrivateSetter;
- return annotate(new AccessorClass({
- start,
- static: is_static,
- key: get_symbol_ast(name, AST_SymbolMethod),
- value: create_accessor(),
- end: prev(),
- }));
- }
- }
- if (is("punc", "(")) {
- name = get_symbol_ast(name, AST_SymbolMethod);
- const AST_MethodVariant = is_private
- ? AST_PrivateMethod
- : AST_ConciseMethod;
- var node = new AST_MethodVariant({
- start : start,
- static : is_static,
- key : name,
- quote : name instanceof AST_SymbolMethod ?
- property_token.quote : undefined,
- value : create_accessor(is_generator, is_async),
- 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();
- 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;
- 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,
- end: S.token,
- });
- }
- function import_meta(allow_calls) {
- var start = S.token;
- expect_token("name", "import");
- expect_token("punc", ".");
- 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", "}")) {
- names.push(map_name(is_import));
- if (is("punc", ",")) {
- next();
- }
- }
- 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("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() {
- var tmp = S.token;
- switch (tmp.type) {
- case "punc":
- if (tmp.value === "[") {
- next();
- var ex = expression(false);
- 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("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("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();
- }
- 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();
- 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;
- }
- 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 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.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",
- is_generator: "[boolean] is this a generator method",
- async: "[boolean] is this method async",
- },
- args_as_names: function () {
- 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 {
- 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",
- "imported_name imported_names module_name attributes",
- function AST_Import(props) {
- if (props) {
- 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: {
- 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_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`"
- }, 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)",
- }, 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_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)
- });
- },
- 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_Call({
- start: my_start_token(M),
- end: my_end_token(M),
- expression: from_moz({
- type: "Identifier",
- name: "import"
- }),
- optional: false,
- 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) {
- if (M.expression instanceof AST_SymbolRef && M.expression.name === "import") {
- const [source, options] = M.args.map(to_moz);
- return {
- type: "ImportExpression",
- source,
- options: options || null
- };
- }
- return {
- type: "CallExpression",
- callee: to_moz(M.expression),
- optional: M.optional,
- arguments: M.args.map(to_moz)
- };
- });
- 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_imported_foreign_name = M.imported_names[0].foreign_name;
- if (first_imported_foreign_name.name === "*" && !first_imported_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)
- });
- });
- }
- }
- return {
- type: "ImportDeclaration",
- specifiers: specifiers,
- source: to_moz(M.module_name),
- attributes: import_attributes_to_moz(M.attributes)
- };
- });
- 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;
- });
- };
- 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 = 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(prev)
- && (is_identifier_char(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_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.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_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_name === other.imported_name) && (this.imported_names == null ? other.imported_names == null : this.imported_names === other.imported_names) && (this.attributes == null ? other.attributes == null : this.attributes === other.attributes);
- };
- AST_ImportMeta.prototype.shallow_cmp = pass_through;
- 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;
- 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);
- });
- }
- }
- });
- 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.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_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_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`
- if (
- (typeof left === "bigint") !== (typeof right === "bigint")
- || typeof left === "bigint"
- && (this.operator === ">>>"
- || this.operator === "/" && Number(right) === 0)
- ) {
- 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_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.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-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;
- }));
|