nimcity.js 417 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187
  1. // include: shell.js
  2. // include: minimum_runtime_check.js
  3. (function() {
  4. // "30.0.0" -> 300000
  5. function humanReadableVersionToPacked(str) {
  6. str = str.split("-")[0];
  7. // Remove any trailing part from e.g. "12.53.3-alpha"
  8. var vers = str.split(".").slice(0, 3);
  9. while (vers.length < 3) vers.push("00");
  10. vers = vers.map((n, i, arr) => n.padStart(2, "0"));
  11. return vers.join("");
  12. }
  13. // 300000 -> "30.0.0"
  14. var packedVersionToHumanReadable = n => [ n / 1e4 | 0, (n / 100 | 0) % 100, n % 100 ].join(".");
  15. var TARGET_NOT_SUPPORTED = 2147483647;
  16. // Note: We use a typeof check here instead of optional chaining using
  17. // globalThis because older browsers might not have globalThis defined.
  18. var currentNodeVersion = typeof process !== "undefined" && process.versions?.node ? humanReadableVersionToPacked(process.versions.node) : TARGET_NOT_SUPPORTED;
  19. if (currentNodeVersion < 180300) {
  20. throw new Error(`This emscripten-generated code requires node v${packedVersionToHumanReadable(180300)} (detected v${packedVersionToHumanReadable(currentNodeVersion)})`);
  21. }
  22. var userAgent = typeof navigator !== "undefined" && navigator.userAgent;
  23. if (!userAgent) {
  24. return;
  25. }
  26. var currentSafariVersion = userAgent.includes("Safari/") && !userAgent.includes("Chrome/") && userAgent.match(/Version\/(\d+\.?\d*\.?\d*)/) ? humanReadableVersionToPacked(userAgent.match(/Version\/(\d+\.?\d*\.?\d*)/)[1]) : TARGET_NOT_SUPPORTED;
  27. if (currentSafariVersion < 15e4) {
  28. throw new Error(`This emscripten-generated code requires Safari v${packedVersionToHumanReadable(15e4)} (detected v${currentSafariVersion})`);
  29. }
  30. var currentFirefoxVersion = userAgent.match(/Firefox\/(\d+(?:\.\d+)?)/) ? parseFloat(userAgent.match(/Firefox\/(\d+(?:\.\d+)?)/)[1]) : TARGET_NOT_SUPPORTED;
  31. if (currentFirefoxVersion < 79) {
  32. throw new Error(`This emscripten-generated code requires Firefox v79 (detected v${currentFirefoxVersion})`);
  33. }
  34. var currentChromeVersion = userAgent.match(/Chrome\/(\d+(?:\.\d+)?)/) ? parseFloat(userAgent.match(/Chrome\/(\d+(?:\.\d+)?)/)[1]) : TARGET_NOT_SUPPORTED;
  35. if (currentChromeVersion < 85) {
  36. throw new Error(`This emscripten-generated code requires Chrome v85 (detected v${currentChromeVersion})`);
  37. }
  38. })();
  39. // end include: minimum_runtime_check.js
  40. // The Module object: Our interface to the outside world. We import
  41. // and export values on it. There are various ways Module can be used:
  42. // 1. Not defined. We create it here
  43. // 2. A function parameter, function(moduleArg) => Promise<Module>
  44. // 3. pre-run appended it, var Module = {}; ..generated code..
  45. // 4. External script tag defines var Module.
  46. // We need to check if Module already exists (e.g. case 3 above).
  47. // Substitution will be replaced with actual code on later stage of the build,
  48. // this way Closure Compiler will not mangle it (e.g. case 4. above).
  49. // Note that if you want to run closure, and also to use Module
  50. // after the generated code, you will need to define var Module = {};
  51. // before the code. Then that object will be used in the code, and you
  52. // can continue to use Module afterwards as well.
  53. var Module = typeof Module != "undefined" ? Module : {};
  54. // Determine the runtime environment we are in. You can customize this by
  55. // setting the ENVIRONMENT setting at compile time (see settings.js).
  56. // Attempt to auto-detect the environment
  57. var ENVIRONMENT_IS_WEB = !!globalThis.window;
  58. var ENVIRONMENT_IS_WORKER = !!globalThis.WorkerGlobalScope;
  59. // N.b. Electron.js environment is simultaneously a NODE-environment, but
  60. // also a web environment.
  61. var ENVIRONMENT_IS_NODE = globalThis.process?.versions?.node && globalThis.process?.type != "renderer";
  62. var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
  63. // Three configurations we can be running in:
  64. // 1) We could be the application main() thread running in the main JS UI thread. (ENVIRONMENT_IS_WORKER == false and ENVIRONMENT_IS_PTHREAD == false)
  65. // 2) We could be the application main() running directly in a worker. (ENVIRONMENT_IS_WORKER == true, ENVIRONMENT_IS_PTHREAD == false)
  66. // 3) We could be an application pthread running in a worker. (ENVIRONMENT_IS_WORKER == true and ENVIRONMENT_IS_PTHREAD == true)
  67. // The way we signal to a worker that it is hosting a pthread is to construct
  68. // it with a specific name.
  69. var ENVIRONMENT_IS_PTHREAD = ENVIRONMENT_IS_WORKER && globalThis.name?.startsWith("em-pthread");
  70. if (ENVIRONMENT_IS_NODE) {
  71. var worker_threads = require("node:worker_threads");
  72. globalThis.Worker = worker_threads.Worker;
  73. ENVIRONMENT_IS_WORKER = !worker_threads.isMainThread;
  74. // Under node we set `workerData` to `em-pthread` to signal that the worker
  75. // is hosting a pthread.
  76. ENVIRONMENT_IS_PTHREAD = ENVIRONMENT_IS_WORKER && worker_threads.workerData == "em-pthread";
  77. }
  78. // --pre-jses are emitted after the Module integration code, so that they can
  79. // refer to Module (if they choose; they can also define Module)
  80. // include: /tmp/tmpzje_h4f0.js
  81. if (!Module["expectedDataFileDownloads"]) Module["expectedDataFileDownloads"] = 0;
  82. Module["expectedDataFileDownloads"]++;
  83. (() => {
  84. // Do not attempt to redownload the virtual filesystem data when in a pthread or a Wasm Worker context.
  85. var isPthread = typeof ENVIRONMENT_IS_PTHREAD != "undefined" && ENVIRONMENT_IS_PTHREAD;
  86. var isWasmWorker = typeof ENVIRONMENT_IS_WASM_WORKER != "undefined" && ENVIRONMENT_IS_WASM_WORKER;
  87. if (isPthread || isWasmWorker) return;
  88. var isNode = globalThis.process && globalThis.process.versions && globalThis.process.versions.node && globalThis.process.type != "renderer";
  89. async function loadPackage(metadata) {
  90. var PACKAGE_PATH = "";
  91. if (typeof window === "object") {
  92. PACKAGE_PATH = window["encodeURIComponent"](window.location.pathname.substring(0, window.location.pathname.lastIndexOf("/")) + "/");
  93. } else if (typeof process === "undefined" && typeof location !== "undefined") {
  94. // web worker
  95. PACKAGE_PATH = encodeURIComponent(location.pathname.substring(0, location.pathname.lastIndexOf("/")) + "/");
  96. }
  97. var PACKAGE_NAME = "nimсity.data";
  98. var REMOTE_PACKAGE_BASE = "nimсity.data";
  99. var REMOTE_PACKAGE_NAME = Module["locateFile"] ? Module["locateFile"](REMOTE_PACKAGE_BASE, "") : REMOTE_PACKAGE_BASE;
  100. var REMOTE_PACKAGE_SIZE = metadata["remote_package_size"];
  101. async function fetchRemotePackage(packageName, packageSize) {
  102. if (isNode) {
  103. var contents = require("fs").readFileSync(packageName);
  104. return new Uint8Array(contents).buffer;
  105. }
  106. if (!Module["dataFileDownloads"]) Module["dataFileDownloads"] = {};
  107. try {
  108. var response = await fetch(packageName);
  109. } catch (e) {
  110. throw new Error(`Network Error: ${packageName}`, {
  111. e
  112. });
  113. }
  114. if (!response.ok) {
  115. throw new Error(`${response.status}: ${response.url}`);
  116. }
  117. const chunks = [];
  118. const headers = response.headers;
  119. const total = Number(headers.get("Content-Length") || packageSize);
  120. let loaded = 0;
  121. Module["setStatus"] && Module["setStatus"]("Downloading data...");
  122. const reader = response.body.getReader();
  123. while (1) {
  124. var {done, value} = await reader.read();
  125. if (done) break;
  126. chunks.push(value);
  127. loaded += value.length;
  128. Module["dataFileDownloads"][packageName] = {
  129. loaded,
  130. total
  131. };
  132. let totalLoaded = 0;
  133. let totalSize = 0;
  134. for (const download of Object.values(Module["dataFileDownloads"])) {
  135. totalLoaded += download.loaded;
  136. totalSize += download.total;
  137. }
  138. Module["setStatus"] && Module["setStatus"](`Downloading data... (${totalLoaded}/${totalSize})`);
  139. }
  140. const packageData = new Uint8Array(chunks.map(c => c.length).reduce((a, b) => a + b, 0));
  141. let offset = 0;
  142. for (const chunk of chunks) {
  143. packageData.set(chunk, offset);
  144. offset += chunk.length;
  145. }
  146. return packageData.buffer;
  147. }
  148. var fetchPromise;
  149. var fetched = Module["getPreloadedPackage"] && Module["getPreloadedPackage"](REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE);
  150. if (!fetched) {
  151. // Note that we don't use await here because we want to execute the
  152. // the rest of this function immediately.
  153. fetchPromise = fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE);
  154. }
  155. async function runWithFS(Module) {
  156. function assert(check, msg) {
  157. if (!check) throw new Error(msg);
  158. }
  159. Module["FS_createPath"]("/", "assets", true, true);
  160. async function processPackageData(arrayBuffer) {
  161. assert(arrayBuffer, "Loading data file failed.");
  162. assert(arrayBuffer.constructor.name === ArrayBuffer.name, "bad input to processPackageData " + arrayBuffer.constructor.name);
  163. var byteArray = new Uint8Array(arrayBuffer);
  164. var curr;
  165. // Reuse the bytearray from the XHR as the source for file reads.
  166. for (var file of metadata["files"]) {
  167. var name = file["filename"];
  168. var data = byteArray.subarray(file["start"], file["end"]);
  169. // canOwn this data in the filesystem, it is a slice into the heap that will never change
  170. Module["FS_createDataFile"](name, null, data, true, true, true);
  171. }
  172. Module["removeRunDependency"]("datafile_nimсity.data");
  173. }
  174. Module["addRunDependency"]("datafile_nimсity.data");
  175. if (!Module["preloadResults"]) Module["preloadResults"] = {};
  176. Module["preloadResults"][PACKAGE_NAME] = {
  177. fromCache: false
  178. };
  179. if (!fetched) {
  180. fetched = await fetchPromise;
  181. }
  182. await processPackageData(fetched);
  183. }
  184. // Detect whether the module JS file has already been loaded.
  185. if (Module["FS_createPath"]) {
  186. runWithFS(Module);
  187. } else {
  188. if (!Module["preRun"]) Module["preRun"] = [];
  189. Module["preRun"].push(runWithFS);
  190. }
  191. }
  192. loadPackage({
  193. "files": [ {
  194. "filename": "/assets/font.png",
  195. "start": 0,
  196. "end": 421
  197. }, {
  198. "filename": "/assets/font.png.dat",
  199. "start": 421,
  200. "end": 515
  201. }, {
  202. "filename": "/assets/icon.png",
  203. "start": 515,
  204. "end": 861
  205. } ],
  206. "remote_package_size": 861
  207. });
  208. })();
  209. // end include: /tmp/tmpzje_h4f0.js
  210. // include: /tmp/tmpb7xjyrz2.js
  211. // All the pre-js content up to here must remain later on, we need to run
  212. // it.
  213. if ((typeof ENVIRONMENT_IS_WASM_WORKER != "undefined" && ENVIRONMENT_IS_WASM_WORKER) || (typeof ENVIRONMENT_IS_PTHREAD != "undefined" && ENVIRONMENT_IS_PTHREAD) || (typeof ENVIRONMENT_IS_AUDIO_WORKLET != "undefined" && ENVIRONMENT_IS_AUDIO_WORKLET)) Module["preRun"] = [];
  214. var necessaryPreJSTasks = Module["preRun"].slice();
  215. // end include: /tmp/tmpb7xjyrz2.js
  216. // include: /tmp/tmpna887fkc.js
  217. if (!Module["preRun"]) throw "Module.preRun should exist because file support used it; did a pre-js delete it?";
  218. necessaryPreJSTasks.forEach(task => {
  219. if (Module["preRun"].indexOf(task) < 0) throw "All preRun tasks that exist before user pre-js code should remain after; did you replace Module or modify Module.preRun?";
  220. });
  221. // end include: /tmp/tmpna887fkc.js
  222. var programArgs = [];
  223. var thisProgram = "./this.program";
  224. var quit_ = (status, toThrow) => {
  225. throw toThrow;
  226. };
  227. // In MODULARIZE mode _scriptName needs to be captured already at the very top of the page immediately when the page is parsed, so it is generated there
  228. // before the page load. In non-MODULARIZE modes generate it here.
  229. var _scriptName = globalThis.document?.currentScript?.src;
  230. if (typeof __filename != "undefined") {
  231. // Node
  232. _scriptName = __filename;
  233. } else if (ENVIRONMENT_IS_WORKER) {
  234. _scriptName = self.location.href;
  235. }
  236. // `/` should be present at the end if `scriptDirectory` is not empty
  237. var scriptDirectory = "";
  238. function locateFile(path) {
  239. if (Module["locateFile"]) {
  240. return Module["locateFile"](path, scriptDirectory);
  241. }
  242. return scriptDirectory + path;
  243. }
  244. // Hooks that are implemented differently in different runtime environments.
  245. var readAsync, readBinary;
  246. if (ENVIRONMENT_IS_NODE) {
  247. const isNode = globalThis.process?.versions?.node && globalThis.process?.type != "renderer";
  248. if (!isNode) throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");
  249. // These modules will usually be used on Node.js. Load them eagerly to avoid
  250. // the complexity of lazy-loading.
  251. var fs = require("node:fs");
  252. scriptDirectory = __dirname + "/";
  253. // include: node_shell_read.js
  254. readBinary = filename => {
  255. // We need to re-wrap `file://` strings to URLs.
  256. filename = isFileURI(filename) ? new URL(filename) : filename;
  257. var ret = fs.readFileSync(filename);
  258. assert(Buffer.isBuffer(ret));
  259. return ret;
  260. };
  261. readAsync = async (filename, binary = true) => {
  262. // See the comment in the `readBinary` function.
  263. filename = isFileURI(filename) ? new URL(filename) : filename;
  264. var ret = fs.readFileSync(filename, binary ? undefined : "utf8");
  265. assert(binary ? Buffer.isBuffer(ret) : typeof ret == "string");
  266. return ret;
  267. };
  268. // end include: node_shell_read.js
  269. if (process.argv.length > 1) {
  270. thisProgram = process.argv[1].replace(/\\/g, "/");
  271. }
  272. programArgs = process.argv.slice(2);
  273. // MODULARIZE will export the module in the proper place outside, we don't need to export here
  274. if (typeof module != "undefined") {
  275. module["exports"] = Module;
  276. }
  277. quit_ = (status, toThrow) => {
  278. process.exitCode = status;
  279. throw toThrow;
  280. };
  281. } else if (ENVIRONMENT_IS_SHELL) {} else // Note that this includes Node.js workers when relevant (pthreads is enabled).
  282. // Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
  283. // ENVIRONMENT_IS_NODE.
  284. if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
  285. try {
  286. scriptDirectory = new URL(".", _scriptName).href;
  287. } catch {}
  288. if (!(globalThis.window || globalThis.WorkerGlobalScope)) throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");
  289. // Differentiate the Web Worker from the Node Worker case, as reading must
  290. // be done differently.
  291. if (!ENVIRONMENT_IS_NODE) {
  292. // include: web_or_worker_shell_read.js
  293. if (ENVIRONMENT_IS_WORKER) {
  294. readBinary = url => {
  295. var xhr = new XMLHttpRequest;
  296. xhr.open("GET", url, false);
  297. xhr.responseType = "arraybuffer";
  298. xhr.send(null);
  299. return new Uint8Array(/** @type{!ArrayBuffer} */ (xhr.response));
  300. };
  301. }
  302. readAsync = async url => {
  303. // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url.
  304. // See https://github.com/github/fetch/pull/92#issuecomment-140665932
  305. // Cordova or Electron apps are typically loaded from a file:// url.
  306. // So use XHR on webview if URL is a file URL.
  307. if (isFileURI(url)) {
  308. return new Promise((resolve, reject) => {
  309. var xhr = new XMLHttpRequest;
  310. xhr.open("GET", url, true);
  311. xhr.responseType = "arraybuffer";
  312. xhr.onload = () => {
  313. if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) {
  314. // file URLs can return 0
  315. resolve(xhr.response);
  316. return;
  317. }
  318. reject(xhr.status);
  319. };
  320. xhr.onerror = reject;
  321. xhr.send(null);
  322. });
  323. }
  324. var response = await fetch(url, {
  325. credentials: "same-origin"
  326. });
  327. if (response.ok) {
  328. return response.arrayBuffer();
  329. }
  330. throw new Error(response.status + " : " + response.url);
  331. };
  332. }
  333. } else {
  334. throw new Error("environment detection error");
  335. }
  336. // Set up the out() and err() hooks, which are how we can print to stdout or
  337. // stderr, respectively.
  338. // Normally just binding console.log/console.error here works fine, but
  339. // under node (with workers) we see missing/out-of-order messages so route
  340. // directly to stdout and stderr.
  341. // See https://github.com/emscripten-core/emscripten/issues/14804
  342. var defaultPrint = console.log.bind(console);
  343. var defaultPrintErr = console.error.bind(console);
  344. if (ENVIRONMENT_IS_NODE) {
  345. var utils = require("node:util");
  346. var stringify = a => typeof a == "object" ? utils.inspect(a) : a;
  347. defaultPrint = (...args) => fs.writeSync(1, args.map(stringify).join(" ") + "\n");
  348. defaultPrintErr = (...args) => fs.writeSync(2, args.map(stringify).join(" ") + "\n");
  349. }
  350. var out = defaultPrint;
  351. var err = defaultPrintErr;
  352. var PROXYFS = "PROXYFS is no longer included by default; build with -lproxyfs.js";
  353. var WORKERFS = "WORKERFS is no longer included by default; build with -lworkerfs.js";
  354. var FETCHFS = "FETCHFS is no longer included by default; build with -lfetchfs.js";
  355. var ICASEFS = "ICASEFS is no longer included by default; build with -licasefs.js";
  356. var JSFILEFS = "JSFILEFS is no longer included by default; build with -ljsfilefs.js";
  357. var OPFS = "OPFS is no longer included by default; build with -lopfs.js";
  358. var NODEFS = "NODEFS is no longer included by default; build with -lnodefs.js";
  359. // perform assertions in shell.js after we set up out() and err(), as otherwise
  360. // if an assertion fails it cannot print the message
  361. assert(ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER || ENVIRONMENT_IS_NODE, "pthreads do not work in this environment yet (need Web Workers, or an alternative to them)");
  362. assert(!ENVIRONMENT_IS_SHELL, "shell environment detected but not enabled at build time (add `shell` to `-sENVIRONMENT` to enable)");
  363. // end include: shell.js
  364. // include: preamble.js
  365. // === Preamble library stuff ===
  366. // Documentation for the public APIs defined in this file must be updated in:
  367. // site/source/docs/api_reference/preamble.js.rst
  368. // A prebuilt local version of the documentation is available at:
  369. // site/build/text/docs/api_reference/preamble.js.txt
  370. // You can also build docs locally as HTML or other formats in site/
  371. // An online HTML version (which may be of a different version of Emscripten)
  372. // is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
  373. var wasmBinary;
  374. if (!globalThis.WebAssembly) {
  375. err("no native wasm support detected");
  376. }
  377. // Wasm globals
  378. // For sending to workers.
  379. var wasmModule;
  380. //========================================
  381. // Runtime essentials
  382. //========================================
  383. // whether we are quitting the application. no code should run after this.
  384. // set in exit() and abort()
  385. var ABORT = false;
  386. // set by exit() and abort(). Passed to 'onExit' handler.
  387. // NOTE: This is also used as the process return code in shell environments
  388. // but only when noExitRuntime is false.
  389. var EXITSTATUS;
  390. // In STRICT mode, we only define assert() when ASSERTIONS is set. i.e. we
  391. // don't define it at all in release modes. This matches the behaviour of
  392. // MINIMAL_RUNTIME.
  393. // TODO(sbc): Make this the default even without STRICT enabled.
  394. /** @type {function(*, string=)} */ function assert(condition, text) {
  395. if (!condition) {
  396. abort("Assertion failed" + (text ? ": " + text : ""));
  397. }
  398. }
  399. // We used to include malloc/free by default in the past. Show a helpful error in
  400. // builds with assertions.
  401. /**
  402. * Indicates whether filename is delivered via file protocol (as opposed to http/https)
  403. * @noinline
  404. */ var isFileURI = filename => filename.startsWith("file://");
  405. // include: runtime_common.js
  406. // include: runtime_stack_check.js
  407. // Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
  408. function writeStackCookie() {
  409. var max = _emscripten_stack_get_end();
  410. assert((max & 3) == 0);
  411. // If the stack ends at address zero we write our cookies 4 bytes into the
  412. // stack. This prevents interference with SAFE_HEAP and ASAN which also
  413. // monitor writes to address zero.
  414. if (max == 0) {
  415. max += 4;
  416. }
  417. // The stack grow downwards towards _emscripten_stack_get_end.
  418. // We write cookies to the final two words in the stack and detect if they are
  419. // ever overwritten.
  420. (growMemViews(), HEAPU32)[((max) >> 2)] = 34821223;
  421. (growMemViews(), HEAPU32)[(((max) + (4)) >> 2)] = 2310721022;
  422. // Also test the global address 0 for integrity.
  423. (growMemViews(), HEAPU32)[((0) >> 2)] = 1668509029;
  424. }
  425. function checkStackCookie() {
  426. if (ABORT) return;
  427. var max = _emscripten_stack_get_end();
  428. // See writeStackCookie().
  429. if (max == 0) {
  430. max += 4;
  431. }
  432. var cookie1 = (growMemViews(), HEAPU32)[((max) >> 2)];
  433. var cookie2 = (growMemViews(), HEAPU32)[(((max) + (4)) >> 2)];
  434. if (cookie1 != 34821223 || cookie2 != 2310721022) {
  435. abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString(cookie2)} ${ptrToString(cookie1)}`);
  436. }
  437. // Also test the global address 0 for integrity.
  438. if ((growMemViews(), HEAPU32)[((0) >> 2)] != 1668509029) {
  439. abort("Runtime error: The application has corrupted its heap memory area (address zero)!");
  440. }
  441. }
  442. // end include: runtime_stack_check.js
  443. // include: runtime_exceptions.js
  444. // Base Emscripten EH error class
  445. class EmscriptenEH {}
  446. class EmscriptenSjLj extends EmscriptenEH {}
  447. // end include: runtime_exceptions.js
  448. // include: runtime_debug.js
  449. var runtimeDebug = true;
  450. // Switch to false at runtime to disable logging at the right times
  451. // Used by XXXXX_DEBUG settings to output debug messages.
  452. function dbg(...args) {
  453. if (!runtimeDebug && typeof runtimeDebug != "undefined") return;
  454. // Avoid using the console for debugging in multi-threaded node applications
  455. // See https://github.com/emscripten-core/emscripten/issues/14804
  456. if (ENVIRONMENT_IS_NODE) {
  457. // TODO(sbc): Unify with err/out implementation in shell.sh.
  458. var fs = require("node:fs");
  459. var utils = require("node:util");
  460. function stringify(a) {
  461. switch (typeof a) {
  462. case "object":
  463. return utils.inspect(a);
  464. case "undefined":
  465. return "undefined";
  466. }
  467. return a;
  468. }
  469. fs.writeSync(2, args.map(stringify).join(" ") + "\n");
  470. } else // TODO(sbc): Make this configurable somehow. Its not always convenient for
  471. // logging to show up as warnings.
  472. console.warn(...args);
  473. }
  474. // Endianness check
  475. (() => {
  476. var h16 = new Int16Array(1);
  477. var h8 = new Int8Array(h16.buffer);
  478. h16[0] = 25459;
  479. if (h8[0] !== 115 || h8[1] !== 99) abort("Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)");
  480. })();
  481. function consumedModuleProp(prop) {
  482. var value = Module[prop];
  483. var msg = `Attempt to modify \`Module.${prop}\` after it has already been processed. This can happen, for example, when code is injected via '--post-js' rather than '--pre-js'`;
  484. if (Array.isArray(value)) {
  485. value = new Proxy(value, {
  486. set(target, key, val) {
  487. abort(msg);
  488. return false;
  489. },
  490. defineProperty(target, key, descriptor) {
  491. abort(msg);
  492. return false;
  493. },
  494. deleteProperty(target, key) {
  495. abort(msg);
  496. return false;
  497. }
  498. });
  499. }
  500. Object.defineProperty(Module, prop, {
  501. configurable: true,
  502. get() {
  503. return value;
  504. },
  505. set() {
  506. abort(msg);
  507. }
  508. });
  509. }
  510. function makeInvalidEarlyAccess(name) {
  511. return () => assert(false, `call to '${name}' via reference taken before Wasm module initialization`);
  512. }
  513. function ignoredModuleProp(prop) {
  514. if (Object.getOwnPropertyDescriptor(Module, prop)) {
  515. abort(`\`Module.${prop}\` was supplied but \`${prop}\` not included in INCOMING_MODULE_JS_API`);
  516. }
  517. }
  518. // forcing the filesystem exports a few things by default
  519. function isExportedByForceFilesystem(name) {
  520. return name === "FS_createPath" || name === "FS_createDataFile" || name === "FS_createPreloadedFile" || name === "FS_preloadFile" || name === "FS_unlink" || name === "addRunDependency" || // The old FS has some functionality that WasmFS lacks.
  521. name === "FS_createLazyFile" || name === "FS_createDevice" || name === "removeRunDependency";
  522. }
  523. /**
  524. * Intercept access to a symbols in the global symbol. This enables us to give
  525. * informative warnings/errors when folks attempt to use symbols they did not
  526. * include in their build, or no symbols that no longer exist.
  527. *
  528. * We don't define this in MODULARIZE mode since in that mode emscripten symbols
  529. * are never placed in the global scope.
  530. */ function hookGlobalSymbolAccess(sym, func) {
  531. if (!Object.getOwnPropertyDescriptor(globalThis, sym)) {
  532. Object.defineProperty(globalThis, sym, {
  533. configurable: true,
  534. get() {
  535. func();
  536. return undefined;
  537. }
  538. });
  539. }
  540. }
  541. function missingGlobal(sym, msg) {
  542. hookGlobalSymbolAccess(sym, () => {
  543. warnOnce(`\`${sym}\` is no longer defined by emscripten. ${msg}`);
  544. });
  545. }
  546. missingGlobal("buffer", "Please use HEAP8.buffer or wasmMemory.buffer");
  547. missingGlobal("asm", "Please use wasmExports instead");
  548. function missingLibrarySymbol(sym) {
  549. hookGlobalSymbolAccess(sym, () => {
  550. // Can't `abort()` here because it would break code that does runtime
  551. // checks. e.g. `if (typeof SDL === 'undefined')`.
  552. var msg = `\`${sym}\` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line`;
  553. // DEFAULT_LIBRARY_FUNCS_TO_INCLUDE requires the name as it appears in
  554. // library.js, which means $name for a JS name with no prefix, or name
  555. // for a JS name like _name.
  556. var librarySymbol = sym;
  557. if (!librarySymbol.startsWith("_")) {
  558. librarySymbol = "$" + sym;
  559. }
  560. msg += ` (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='${librarySymbol}')`;
  561. if (isExportedByForceFilesystem(sym)) {
  562. msg += ". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you";
  563. }
  564. warnOnce(msg);
  565. });
  566. // Any symbol that is not included from the JS library is also (by definition)
  567. // not exported on the Module object.
  568. unexportedRuntimeSymbol(sym);
  569. }
  570. function unexportedRuntimeSymbol(sym) {
  571. if (ENVIRONMENT_IS_PTHREAD) {
  572. return;
  573. }
  574. if (!Object.getOwnPropertyDescriptor(Module, sym)) {
  575. Object.defineProperty(Module, sym, {
  576. configurable: true,
  577. get() {
  578. var msg = `'${sym}' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)`;
  579. if (isExportedByForceFilesystem(sym)) {
  580. msg += ". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you";
  581. }
  582. abort(msg);
  583. }
  584. });
  585. }
  586. }
  587. /**
  588. * Override `err`/`out`/`dbg` to report thread / worker information
  589. */ function initWorkerLogging() {
  590. function getLogPrefix() {
  591. var t = 0;
  592. if (runtimeInitialized && typeof _pthread_self != "undefined") {
  593. t = _pthread_self();
  594. }
  595. return `w:${workerID},t:${ptrToString(t)}:`;
  596. }
  597. // Prefix all dbg() messages with the calling thread info.
  598. var origDbg = dbg;
  599. dbg = (...args) => origDbg(getLogPrefix(), ...args);
  600. }
  601. initWorkerLogging();
  602. // end include: runtime_debug.js
  603. // Support for growable heap + pthreads, where the buffer may change, so JS views
  604. // must be updated.
  605. function growMemViews() {
  606. // `updateMemoryViews` updates all the views simultaneously, so it's enough to check any of them.
  607. if (wasmMemory.buffer != HEAP8.buffer) {
  608. updateMemoryViews();
  609. }
  610. }
  611. if (ENVIRONMENT_IS_NODE && (ENVIRONMENT_IS_PTHREAD)) {
  612. // Create as web-worker-like an environment as we can.
  613. globalThis.self = globalThis;
  614. var parentPort = worker_threads.parentPort;
  615. // Deno and Bun already have `postMessage` defined on the global scope and
  616. // deliver messages to `globalThis.onmessage`, so we must not duplicate that
  617. // behavior here if `postMessage` is already present.
  618. if (!globalThis.postMessage) {
  619. parentPort.on("message", msg => globalThis.onmessage?.({
  620. data: msg
  621. }));
  622. globalThis.postMessage = msg => parentPort.postMessage(msg);
  623. }
  624. // Node.js Workers do not pass postMessage()s and uncaught exception events to the parent
  625. // thread necessarily in the same order where they were generated in sequential program order.
  626. // See https://github.com/nodejs/node/issues/59617
  627. // To remedy this, capture all uncaughtExceptions in the Worker, and sequentialize those over
  628. // to the same postMessage pipe that other messages use.
  629. process.on("uncaughtException", err => {
  630. postMessage({
  631. cmd: 8,
  632. error: err
  633. });
  634. // Also shut down the Worker to match the same semantics as if this uncaughtException
  635. // handler was not registered.
  636. // (n.b. this will not shut down the whole Node.js app process, but just the Worker)
  637. process.exit(1);
  638. });
  639. }
  640. // include: runtime_pthread.js
  641. // Pthread Web Worker handling code.
  642. // This code runs only on pthread web workers and handles pthread setup
  643. // and communication with the main thread via postMessage.
  644. // Unique ID of the current pthread worker (zero on non-pthread-workers
  645. // including the main thread).
  646. var workerID = 0;
  647. var startWorker;
  648. if (ENVIRONMENT_IS_PTHREAD) {
  649. // Thread-local guard variable for one-time init of the JS state
  650. var initializedJS = false;
  651. // Turn unhandled rejected promises into errors so that the main thread will be
  652. // notified about them.
  653. self.onunhandledrejection = e => {
  654. throw e.reason || e;
  655. };
  656. function handleMessage(e) {
  657. try {
  658. var msgData = e.data;
  659. //dbg('msgData: ' + Object.keys(msgData));
  660. var cmd = msgData.cmd;
  661. if (cmd == 1) {
  662. // Preload command that is called once per worker to parse and load the Emscripten code.
  663. workerID = msgData.workerID;
  664. // Until we initialize the runtime, queue up any further incoming messages.
  665. let messageQueue = [];
  666. self.onmessage = e => messageQueue.push(e);
  667. // And add a callback for when the runtime is initialized.
  668. startWorker = () => {
  669. // Notify the main thread that this thread has loaded.
  670. postMessage({
  671. cmd: 3
  672. });
  673. // Process any messages that were queued before the thread was ready.
  674. for (let msg of messageQueue) {
  675. handleMessage(msg);
  676. }
  677. // Restore the real message handler.
  678. self.onmessage = handleMessage;
  679. };
  680. // Use `const` here to ensure that the variable is scoped only to
  681. // that iteration, allowing safe reference from a closure.
  682. for (const handler of msgData.handlers) {
  683. // If the main module has a handler for a certain event, but no
  684. // handler exists on the pthread worker, then proxy that handler
  685. // back to the main thread.
  686. if (!Module[handler] || Module[handler].proxy) {
  687. Module[handler] = (...args) => {
  688. postMessage({
  689. cmd: 9,
  690. handler,
  691. args
  692. });
  693. };
  694. // Rebind the out / err handlers if needed
  695. if (handler == "print") out = Module[handler];
  696. if (handler == "printErr") err = Module[handler];
  697. }
  698. }
  699. wasmMemory = msgData.wasmMemory;
  700. updateMemoryViews();
  701. wasmModule = msgData.wasmModule;
  702. createWasm();
  703. run();
  704. } else if (cmd == 2) {
  705. assert(msgData.pthread_ptr);
  706. assert(wasmMemory, "CMD_RUN received before CMD_LOAD");
  707. // Call inside JS module to set up the stack frame for this pthread in JS module scope.
  708. // This needs to be the first thing that we do, as we cannot call to any C/C++ functions
  709. // until the thread stack is initialized.
  710. establishStackSpace(msgData.pthread_ptr);
  711. // Pass the thread address to wasm to store it for fast access.
  712. __emscripten_thread_init(msgData.pthread_ptr, /*is_main=*/ 0, /*is_runtime=*/ 0, /*can_block=*/ 1, 0, 0);
  713. PThread.threadInitTLS();
  714. // Await mailbox notifications with `Atomics.waitAsync` so we can start
  715. // using the fast `Atomics.notify` notification path.
  716. __emscripten_thread_mailbox_await(msgData.pthread_ptr);
  717. if (!initializedJS) {
  718. initializedJS = true;
  719. }
  720. try {
  721. invokeEntryPoint(msgData.start_routine, msgData.arg);
  722. } catch (ex) {
  723. if (ex != "unwind") {
  724. // The pthread "crashed". Do not call `_emscripten_thread_exit` (which
  725. // would make this thread joinable). Instead, re-throw the exception
  726. // and let the top level handler propagate it back to the main thread.
  727. throw ex;
  728. }
  729. }
  730. } else if (cmd == 4) {
  731. if (initializedJS) {
  732. checkMailbox();
  733. }
  734. } else if (cmd) {
  735. // The received message looks like something that should be handled by this message
  736. // handler, (since there is a cmd field present), but is not one of the
  737. // recognized commands:
  738. err(`worker: received unknown command ${cmd}`);
  739. err(msgData);
  740. }
  741. } catch (ex) {
  742. err(`worker: onmessage() captured an uncaught exception: ${ex}`);
  743. if (ex?.stack) err(ex.stack);
  744. if (runtimeInitialized) __emscripten_thread_crashed();
  745. throw ex;
  746. }
  747. }
  748. self.onmessage = handleMessage;
  749. }
  750. // ENVIRONMENT_IS_PTHREAD
  751. // end include: runtime_pthread.js
  752. // Memory management
  753. var runtimeInitialized = false;
  754. // When ALLOW_MEMORY_GROWTH is enabled, the conversion from Wasm
  755. // memory to ArrayBuffer requires some additional logic.
  756. function getMemoryBuffer() {
  757. // Deserializing a growable SharedArrayBuffer was broken until Firefox 154
  758. // See: https://bugzilla.mozilla.org/show_bug.cgi?id=2021136
  759. var firefoxMatch = globalThis.navigator?.userAgent?.match(/Firefox\/(\d+)/);
  760. if (!firefoxMatch || Number(firefoxMatch[1]) >= 154) {
  761. try {
  762. // This method may be missing or could fail with `Memory must have a maximum`
  763. var b = wasmMemory.toResizableBuffer();
  764. growMemViews = () => {};
  765. return b;
  766. } catch {}
  767. }
  768. return wasmMemory.buffer;
  769. }
  770. function updateMemoryViews() {
  771. // If we already have a heap that is resizeable/growable buffer we don't
  772. // need to do anything in updateMemoryViews.
  773. if (HEAP8?.buffer?.growable) return;
  774. var b = getMemoryBuffer();
  775. HEAP8 = new Int8Array(b);
  776. HEAP16 = new Int16Array(b);
  777. HEAPU8 = new Uint8Array(b);
  778. HEAPU16 = new Uint16Array(b);
  779. HEAP32 = new Int32Array(b);
  780. HEAPU32 = new Uint32Array(b);
  781. HEAPF32 = new Float32Array(b);
  782. HEAPF64 = new Float64Array(b);
  783. HEAP64 = new BigInt64Array(b);
  784. HEAPU64 = new BigUint64Array(b);
  785. }
  786. // In non-standalone/normal mode, we create the memory here.
  787. // include: runtime_init_memory.js
  788. // Create the wasm memory. (Note: this only applies if IMPORTED_MEMORY is defined)
  789. // check for full engine support (use string 'subarray' to avoid closure compiler confusion)
  790. function initMemory() {
  791. if ((ENVIRONMENT_IS_PTHREAD)) {
  792. return;
  793. }
  794. {
  795. var INITIAL_MEMORY = 16777216;
  796. assert(INITIAL_MEMORY >= 65536, `INITIAL_MEMORY should be larger than STACK_SIZE, was ${INITIAL_MEMORY}! (STACK_SIZE=65536)`);
  797. /** @suppress {checkTypes} */ wasmMemory = new WebAssembly.Memory({
  798. "initial": INITIAL_MEMORY / 65536,
  799. // In theory we should not need to emit the maximum if we want "unlimited"
  800. // or 4GB of memory, but VMs error on that atm, see
  801. // https://github.com/emscripten-core/emscripten/issues/14130
  802. // And in the pthreads case we definitely need to emit a maximum. So
  803. // always emit one.
  804. "maximum": 32768,
  805. "shared": true
  806. });
  807. }
  808. updateMemoryViews();
  809. }
  810. // end include: runtime_init_memory.js
  811. // include: memoryprofiler.js
  812. // end include: memoryprofiler.js
  813. // end include: runtime_common.js
  814. assert(globalThis.Int32Array && globalThis.Float64Array && Int32Array.prototype.subarray && Int32Array.prototype.set, "JS engine does not provide full typed array support");
  815. function preRun() {
  816. assert(!ENVIRONMENT_IS_PTHREAD);
  817. // PThreads reuse the runtime from the main thread.
  818. var preRun = Module["preRun"];
  819. if (preRun) {
  820. if (typeof preRun == "function") preRun = [ preRun ];
  821. onPreRuns.push(...preRun);
  822. }
  823. consumedModuleProp("preRun");
  824. // Begin ATPRERUNS hooks
  825. callRuntimeCallbacks(onPreRuns);
  826. }
  827. function initRuntime() {
  828. assert(!runtimeInitialized);
  829. runtimeInitialized = true;
  830. if (ENVIRONMENT_IS_PTHREAD) return startWorker();
  831. checkStackCookie();
  832. // Begin ATINITS hooks
  833. if (!Module["noFSInit"] && !FS.initialized) FS.init();
  834. TTY.init();
  835. PIPEFS.root = FS.mount(PIPEFS, {}, null);
  836. // End ATINITS hooks
  837. wasmExports["__wasm_call_ctors"]();
  838. // Begin ATPOSTCTORS hooks
  839. FS.ignorePermissions = false;
  840. // End ATPOSTCTORS hooks
  841. checkStackCookie();
  842. }
  843. function postRun() {
  844. checkStackCookie();
  845. var postRun = Module["postRun"];
  846. if (postRun) {
  847. if (typeof postRun == "function") postRun = [ postRun ];
  848. onPostRuns.push(...postRun);
  849. }
  850. consumedModuleProp("postRun");
  851. // Begin ATPOSTRUNS hooks
  852. callRuntimeCallbacks(onPostRuns);
  853. }
  854. /**
  855. * @param {string|number=} what
  856. */ function abort(what) {
  857. Module["onAbort"]?.(what);
  858. what = `Aborted(${what})`;
  859. // TODO(sbc): Should we remove printing and leave it up to whoever
  860. // catches the exception?
  861. err(what);
  862. ABORT = true;
  863. // Use a wasm runtime error, because a JS error might be seen as a foreign
  864. // exception, which means we'd run destructors on it. We need the error to
  865. // simply make the program stop.
  866. // FIXME This approach does not work in Wasm EH because it currently does not assume
  867. // all RuntimeErrors are from traps; it decides whether a RuntimeError is from
  868. // a trap or not based on a hidden field within the object. So at the moment
  869. // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that
  870. // allows this in the wasm spec.
  871. // Suppress closure compiler warning here. Closure compiler's builtin extern
  872. // definition for WebAssembly.RuntimeError claims it takes no arguments even
  873. // though it can.
  874. // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.
  875. /** @suppress {checkTypes} */ var e = new WebAssembly.RuntimeError(what);
  876. // Throw the error whether or not MODULARIZE is set because abort is used
  877. // in code paths apart from instantiation where an exception is expected
  878. // to be thrown when abort is called.
  879. throw e;
  880. }
  881. function createExportWrapper(name, func, nargs) {
  882. assert(func);
  883. return (...args) => {
  884. assert(runtimeInitialized, `native function \`${name}\` called before runtime initialization`);
  885. // Only assert for too many arguments. Too few can be valid since the missing arguments will be zero filled.
  886. assert(args.length <= nargs, `native function \`${name}\` called with ${args.length} args but expects ${nargs}`);
  887. return func(...args);
  888. };
  889. }
  890. var wasmBinaryFile;
  891. function findWasmBinary() {
  892. return locateFile("nimсity.wasm");
  893. }
  894. function getBinarySync(file) {
  895. if (readBinary) {
  896. return readBinary(file);
  897. }
  898. // Throwing a plain string here, even though it not normally advisable since
  899. // this gets turning into an `abort` in instantiateArrayBuffer.
  900. throw "both async and sync fetching of the wasm failed";
  901. }
  902. async function getWasmBinary(binaryFile) {
  903. // If we don't have the binary yet, load it asynchronously using readAsync.
  904. if (!wasmBinary) {
  905. // Fetch the binary using readAsync
  906. try {
  907. var response = await readAsync(binaryFile);
  908. return new Uint8Array(response);
  909. } catch {}
  910. }
  911. // Otherwise, getBinarySync should be able to get it synchronously
  912. return getBinarySync(binaryFile);
  913. }
  914. async function instantiateArrayBuffer(binaryFile, imports) {
  915. try {
  916. var binary = await getWasmBinary(binaryFile);
  917. var instance = await WebAssembly.instantiate(binary, imports);
  918. return instance;
  919. } catch (reason) {
  920. err(`failed to asynchronously prepare wasm: ${reason}`);
  921. // Warn on some common problems.
  922. if (isFileURI(binaryFile)) {
  923. err(`warning: Loading from a file URI (${binaryFile}) is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing`);
  924. }
  925. abort(reason);
  926. }
  927. }
  928. async function instantiateAsync(binary, binaryFile, imports) {
  929. if (!binary && !isFileURI(binaryFile) && !ENVIRONMENT_IS_NODE) {
  930. try {
  931. var response = fetch(binaryFile, {
  932. credentials: "same-origin"
  933. });
  934. var instantiationResult = await WebAssembly.instantiateStreaming(response, imports);
  935. return instantiationResult;
  936. } catch (reason) {
  937. // We expect the most common failure cause to be a bad MIME type for the binary,
  938. // in which case falling back to ArrayBuffer instantiation should work.
  939. err(`wasm streaming compile failed: ${reason}`);
  940. err("falling back to ArrayBuffer instantiation");
  941. }
  942. }
  943. return instantiateArrayBuffer(binaryFile, imports);
  944. }
  945. function getWasmImports() {
  946. assignWasmImports();
  947. // prepare imports
  948. var imports = {
  949. "env": wasmImports,
  950. "wasi_snapshot_preview1": wasmImports
  951. };
  952. return imports;
  953. }
  954. // Create the wasm instance.
  955. // Receives the wasm imports, returns the exports.
  956. async function createWasm() {
  957. // Load the wasm module and create an instance of using native support in the JS engine.
  958. // handle a generated wasm instance, receiving its exports and
  959. // performing other necessary setup
  960. function receiveInstance(instance, module) {
  961. wasmExports = instance.exports;
  962. registerTLSInit(wasmExports["_emscripten_tls_init"]);
  963. assignWasmExports(wasmExports);
  964. // We now have the Wasm module loaded up, keep a reference to the compiled module so we can post it to the workers.
  965. wasmModule = module;
  966. return wasmExports;
  967. }
  968. // Prefer streaming instantiation if available.
  969. // Async compilation can be confusing when an error on the page overwrites Module
  970. // (for example, if the order of elements is wrong, and the one defining Module is
  971. // later), so we save Module and check it later.
  972. var trueModule = Module;
  973. function receiveInstantiationResult(result) {
  974. // 'result' is a ResultObject object which has both the module and instance.
  975. // receiveInstance() will swap in the exports (to Module.asm) so they can be called
  976. assert(Module === trueModule, "the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?");
  977. trueModule = null;
  978. return receiveInstance(result["instance"], result["module"]);
  979. }
  980. var info = getWasmImports();
  981. // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
  982. // to manually instantiate the Wasm module themselves. This allows pages to
  983. // run the instantiation parallel to any other async startup actions they are
  984. // performing.
  985. // Also pthreads and wasm workers initialize the wasm instance through this
  986. // path.
  987. var instantiateWasm = Module["instantiateWasm"];
  988. if (instantiateWasm) {
  989. return new Promise(resolve => {
  990. try {
  991. instantiateWasm(info, (inst, mod) => resolve(receiveInstance(inst, mod)));
  992. } catch (e) {
  993. err(`Module.instantiateWasm callback failed with error: ${e}`);
  994. throw e;
  995. }
  996. });
  997. }
  998. if ((ENVIRONMENT_IS_PTHREAD)) {
  999. // Instantiate from the module that was received via postMessage from
  1000. // the main thread. We can just use sync instantiation in the worker.
  1001. assert(wasmModule, "wasmModule should have been received via postMessage");
  1002. var instance = new WebAssembly.Instance(wasmModule, getWasmImports());
  1003. return receiveInstance(instance, wasmModule);
  1004. }
  1005. wasmBinaryFile ??= findWasmBinary();
  1006. var result = await instantiateAsync(wasmBinary, wasmBinaryFile, info);
  1007. var exports = receiveInstantiationResult(result);
  1008. return exports;
  1009. }
  1010. // end include: preamble.js
  1011. // Begin JS library code
  1012. class ExitStatus {
  1013. name="ExitStatus";
  1014. constructor(status) {
  1015. this.message = `Program terminated with exit(${status})`;
  1016. this.status = status;
  1017. }
  1018. }
  1019. /** @type {!Int16Array} */ var HEAP16;
  1020. /** @type {!Int32Array} */ var HEAP32;
  1021. /** not-@type {!BigInt64Array} */ var HEAP64;
  1022. /** @type {!Int8Array} */ var HEAP8;
  1023. /** @type {!Float32Array} */ var HEAPF32;
  1024. /** @type {!Float64Array} */ var HEAPF64;
  1025. /** @type {!Uint16Array} */ var HEAPU16;
  1026. /** @type {!Uint32Array} */ var HEAPU32;
  1027. /** not-@type {!BigUint64Array} */ var HEAPU64;
  1028. /** @type {!Uint8Array} */ var HEAPU8;
  1029. var terminateWorker = worker => {
  1030. worker.terminate();
  1031. // terminate() can be asynchronous, so in theory the worker can continue
  1032. // to run for some amount of time after termination. However from our POV
  1033. // the worker is now dead and we don't want to hear from it again, so we stub
  1034. // out its message handler here. This avoids having to check in each of
  1035. // the onmessage handlers if the message was coming from a valid worker.
  1036. worker.onmessage = e => {
  1037. var cmd = e.data.cmd;
  1038. err(`received "${cmd}" command from terminated worker: ${worker.workerID}`);
  1039. };
  1040. };
  1041. var cleanupThread = pthread_ptr => {
  1042. assert(!ENVIRONMENT_IS_PTHREAD, "cleanupThread() should only be called from the main thread");
  1043. assert(pthread_ptr, "null pthread_ptr passed to cleanupThread");
  1044. var worker = PThread.pthreads[pthread_ptr];
  1045. assert(worker);
  1046. PThread.returnWorkerToPool(worker);
  1047. };
  1048. var callRuntimeCallbacks = callbacks => {
  1049. while (callbacks.length > 0) {
  1050. // Pass the module as the first argument.
  1051. callbacks.shift()(Module);
  1052. }
  1053. };
  1054. var onPreRuns = [];
  1055. var addOnPreRun = cb => onPreRuns.push(cb);
  1056. var spawnThread = threadParams => {
  1057. assert(!ENVIRONMENT_IS_PTHREAD, "spawnThread() should only be called from the main thread");
  1058. assert(threadParams.pthread_ptr, "spawnThread called with null pthread ptr");
  1059. var worker = PThread.getNewWorker();
  1060. if (!worker) {
  1061. // No available workers in the PThread pool.
  1062. return 6;
  1063. }
  1064. assert(!worker.pthread_ptr);
  1065. // Add to pthreads map
  1066. PThread.pthreads[threadParams.pthread_ptr] = worker;
  1067. worker.pthread_ptr = threadParams.pthread_ptr;
  1068. var msg = {
  1069. cmd: 2,
  1070. start_routine: threadParams.startRoutine,
  1071. arg: threadParams.arg,
  1072. pthread_ptr: threadParams.pthread_ptr
  1073. };
  1074. // Ask the worker to start executing its pthread entry point function.
  1075. worker.postMessage(msg, threadParams.transferList);
  1076. return 0;
  1077. };
  1078. var runtimeKeepaliveCounter = 0;
  1079. var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0;
  1080. var stackSave = () => _emscripten_stack_get_current();
  1081. var stackRestore = val => __emscripten_stack_restore(val);
  1082. var stackAlloc = sz => __emscripten_stack_alloc(sz);
  1083. /** @type{function(number, (number|boolean), ...number)} */ var proxyToMainThread = (funcIndex, emAsmAddr, proxyMode, ...callArgs) => {
  1084. // EM_ASM proxying is done by passing a pointer to the address of the EM_ASM
  1085. // content as `emAsmAddr`. JS library proxying is done by passing an index
  1086. // into `proxiedJSCallArgs` as `funcIndex`. If `emAsmAddr` is non-zero then
  1087. // `funcIndex` will be ignored.
  1088. // Additional arguments are passed after the first three are the actual
  1089. // function arguments.
  1090. // The serialization buffer contains the number of call params, and then
  1091. // all the args here.
  1092. // We also pass 'proxyMode' to C separately, since C needs to look at it.
  1093. // Allocate a buffer (on the stack), which will be copied if necessary by
  1094. // the C code.
  1095. // First passed parameter specifies the number of arguments to the function.
  1096. // When BigInt support is enabled, we must handle types in a more complex
  1097. // way, detecting at runtime if a value is a BigInt or not (as we have no
  1098. // type info here). To do that, add a "prefix" before each value that
  1099. // indicates if it is a BigInt, which effectively doubles the number of
  1100. // values we serialize for proxying. TODO: pack this?
  1101. var bufSize = 8 * callArgs.length * 2;
  1102. var sp = stackSave();
  1103. var args = stackAlloc(bufSize);
  1104. var b = ((args) >> 3);
  1105. for (var arg of callArgs) {
  1106. if (typeof arg == "bigint") {
  1107. // The prefix is non-zero to indicate a bigint.
  1108. (growMemViews(), HEAP64)[b++] = 1n;
  1109. (growMemViews(), HEAP64)[b++] = arg;
  1110. } else {
  1111. // The prefix is zero to indicate a JS Number.
  1112. (growMemViews(), HEAP64)[b++] = 0n;
  1113. (growMemViews(), HEAPF64)[b++] = arg;
  1114. }
  1115. }
  1116. var rtn = __emscripten_run_js_on_main_thread(funcIndex, emAsmAddr, bufSize, args, proxyMode);
  1117. stackRestore(sp);
  1118. return rtn;
  1119. };
  1120. function _proc_exit(code) {
  1121. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(0, 0, 1, code);
  1122. EXITSTATUS = code;
  1123. if (!keepRuntimeAlive()) {
  1124. PThread.terminateAllThreads();
  1125. Module["onExit"]?.(code);
  1126. ABORT = true;
  1127. }
  1128. quit_(code, new ExitStatus(code));
  1129. }
  1130. function exitOnMainThread(returnCode) {
  1131. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(1, 0, 0, returnCode);
  1132. _exit(returnCode);
  1133. }
  1134. /** @param {boolean|number=} implicit */ var exitJS = (status, implicit) => {
  1135. EXITSTATUS = status;
  1136. checkUnflushedContent();
  1137. if (ENVIRONMENT_IS_PTHREAD) {
  1138. // implicit exit can never happen on a pthread
  1139. assert(!implicit);
  1140. // When running in a pthread we propagate the exit back to the main thread
  1141. // where it can decide if the whole process should be shut down or not.
  1142. // The pthread may have decided not to exit its own runtime, for example
  1143. // because it runs a main loop, but that doesn't affect the main thread.
  1144. exitOnMainThread(status);
  1145. throw "unwind";
  1146. }
  1147. // if exit() was called explicitly, warn the user if the runtime isn't actually being shut down
  1148. if (keepRuntimeAlive() && !implicit) {
  1149. var msg = `program exited (with status: ${status}), but keepRuntimeAlive() is set (counter=${runtimeKeepaliveCounter}) due to an async operation, so halting execution but not exiting the runtime or preventing further async execution (you can use emscripten_force_exit, if you want to force a true shutdown)`;
  1150. err(msg);
  1151. }
  1152. _proc_exit(status);
  1153. };
  1154. var _exit = exitJS;
  1155. var waitAsyncPolyfilled = (!Atomics.waitAsync || (globalThis.navigator?.userAgent && Number((navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./) || [])[2]) < 91));
  1156. function ptrToString(ptr) {
  1157. assert(typeof ptr === "number", `ptrToString expects a number, got ${typeof ptr}`);
  1158. // Convert to 32-bit unsigned value
  1159. ptr >>>= 0;
  1160. return "0x" + ptr.toString(16).padStart(8, "0");
  1161. }
  1162. var PThread = {
  1163. unusedWorkers: [],
  1164. tlsInitFunctions: [],
  1165. pthreads: {},
  1166. nextWorkerID: 1,
  1167. init() {
  1168. if ((!(ENVIRONMENT_IS_PTHREAD))) {
  1169. PThread.initMainThread();
  1170. }
  1171. },
  1172. initMainThread() {},
  1173. terminateAllThreads: () => {
  1174. assert(!ENVIRONMENT_IS_PTHREAD, "terminateAllThreads() should only be called from the main thread");
  1175. // Attempt to kill all workers. Sadly (at least on the web) there is no
  1176. // way to terminate a worker synchronously, or to be notified when a
  1177. // worker is actually terminated. This means there is some risk that
  1178. // pthreads will continue to be executing after `worker.terminate` has
  1179. // returned. For this reason, we don't call `returnWorkerToPool` here or
  1180. // free the underlying pthread data structures.
  1181. for (var worker of Object.values(PThread.pthreads)) {
  1182. terminateWorker(worker);
  1183. }
  1184. for (var worker of PThread.unusedWorkers) {
  1185. terminateWorker(worker);
  1186. }
  1187. PThread.unusedWorkers = [];
  1188. PThread.pthreads = {};
  1189. },
  1190. terminateRuntime: () => {
  1191. assert(!ENVIRONMENT_IS_PTHREAD, "terminateRuntime() should only be called from the main thread");
  1192. PThread.terminateAllThreads();
  1193. var pthread_ptr = _pthread_self();
  1194. ___set_thread_state(0, 0, 0, 1);
  1195. if (!waitAsyncPolyfilled) {
  1196. // Break the waitAsync loop. Note that checkMailbox will not
  1197. // re-register since the `___set_thread_state` above causes _pthread_self
  1198. // to return 0.
  1199. Atomics.notify((growMemViews(), HEAP32), ((pthread_ptr) >> 2));
  1200. }
  1201. },
  1202. returnWorkerToPool: worker => {
  1203. // We don't want to run main thread queued calls here, since we are doing
  1204. // some operations that leave the worker queue in an invalid state until
  1205. // we are completely done (it would be bad if free() ends up calling a
  1206. // queued pthread_create which looks at the global data structures we are
  1207. // modifying). To achieve that, defer the free() until the very end, when
  1208. // we are all done.
  1209. var pthread_ptr = worker.pthread_ptr;
  1210. delete PThread.pthreads[pthread_ptr];
  1211. // Note: worker is intentionally not terminated so the pool can
  1212. // dynamically grow.
  1213. PThread.unusedWorkers.push(worker);
  1214. // Not a running Worker anymore
  1215. // Detach the worker from the pthread object, and return it to the
  1216. // worker pool as an unused worker.
  1217. worker.pthread_ptr = 0;
  1218. // Finally, free the underlying (and now-unused) pthread structure in
  1219. // linear memory.
  1220. __emscripten_thread_free_data(pthread_ptr);
  1221. },
  1222. threadInitTLS() {
  1223. // Call thread init functions (these are the _emscripten_tls_init for each
  1224. // module loaded.
  1225. PThread.tlsInitFunctions.forEach(f => f());
  1226. },
  1227. loadWasmModuleToWorker: worker => new Promise(onFinishedLoading => {
  1228. worker.onmessage = e => {
  1229. var d = e.data;
  1230. var cmd = d.cmd;
  1231. // If this message is intended to a recipient that is not the main
  1232. // thread, forward it to the target thread. This is currently only
  1233. // used by `CMD_CHECK_MAILBOX`.
  1234. if (d.targetThread) {
  1235. // pthreads should not be relaying messages to themselves.
  1236. assert(d.targetThread != _pthread_self());
  1237. var targetWorker = PThread.pthreads[d.targetThread];
  1238. if (!targetWorker) err(`worker sent message (${cmd}) to pthread (${d.targetThread}) that no longer exists`);
  1239. targetWorker?.postMessage(d);
  1240. return;
  1241. }
  1242. if (d === "setimmediate" || d === "_si") {
  1243. // Worker wants to postMessage() to itself to implement setImmediate()
  1244. // emulation.
  1245. worker.postMessage(d);
  1246. return;
  1247. }
  1248. switch (cmd) {
  1249. case 4:
  1250. checkMailbox();
  1251. break;
  1252. case 5:
  1253. spawnThread(d);
  1254. break;
  1255. case 6:
  1256. // cleanupThread needs to be run via callUserCallback since it calls
  1257. // back into user code to free thread data. Without this it's possible
  1258. // the unwind or ExitStatus exception could escape here.
  1259. callUserCallback(() => cleanupThread(d.thread));
  1260. break;
  1261. case 3:
  1262. if (ENVIRONMENT_IS_NODE && !worker.strongref) {
  1263. // Once worker is loaded & idle, mark it as weakly referenced,
  1264. // so that mere existence of a Worker in the pool does not prevent
  1265. // Node.js from exiting the app.
  1266. worker.unref();
  1267. }
  1268. onFinishedLoading(worker);
  1269. break;
  1270. case 8:
  1271. // Message handler for Node.js specific out-of-order behavior:
  1272. // https://github.com/nodejs/node/issues/59617
  1273. // A pthread sent an uncaught exception event. Re-raise it on the main thread.
  1274. worker.onerror(d.error);
  1275. break;
  1276. case 9:
  1277. Module[d.handler](...d.args);
  1278. break;
  1279. default:
  1280. // The received message looks like something that should be handled by this message
  1281. // handler, (since there is a e.data.cmd field present), but is not one of the
  1282. // recognized commands:
  1283. if (cmd) err(`worker sent an unknown command ${cmd}`);
  1284. }
  1285. };
  1286. worker.onerror = e => {
  1287. var message = "worker sent an error!";
  1288. if (worker.pthread_ptr) {
  1289. message = `Pthread ${ptrToString(worker.pthread_ptr)} sent an error!`;
  1290. }
  1291. err(`${message} ${e.filename}:${e.lineno}: ${e.message}`);
  1292. throw e;
  1293. };
  1294. if (ENVIRONMENT_IS_NODE) {
  1295. worker.on("message", data => worker.onmessage({
  1296. data
  1297. }));
  1298. worker.on("error", e => worker.onerror(e));
  1299. }
  1300. assert(wasmMemory instanceof WebAssembly.Memory, "wasmMemory should have been loaded by now");
  1301. assert(wasmModule instanceof WebAssembly.Module, "wasmModule should have been loaded by now");
  1302. // When running on a pthread, none of the incoming parameters on the module
  1303. // object are present. Proxy known handlers back to the main thread if specified.
  1304. var handlers = [];
  1305. var knownHandlers = [ "onExit", "onAbort", "print", "printErr" ];
  1306. for (var handler of knownHandlers) {
  1307. if (Module.propertyIsEnumerable(handler)) {
  1308. handlers.push(handler);
  1309. }
  1310. }
  1311. // Ask the new worker to load up the Emscripten-compiled page. This is a heavy operation.
  1312. worker.postMessage({
  1313. cmd: 1,
  1314. handlers,
  1315. wasmMemory,
  1316. wasmModule,
  1317. workerID: worker.workerID
  1318. });
  1319. }),
  1320. allocateUnusedWorker() {
  1321. var worker;
  1322. var pthreadMainJs = _scriptName;
  1323. worker = new Worker(pthreadMainJs, {
  1324. // This is the way that we signal to the node worker that it is hosting
  1325. // a pthread.
  1326. "workerData": "em-pthread",
  1327. // This is the way that we signal to the Web Worker that it is hosting
  1328. // a pthread.
  1329. "name": "em-pthread-" + PThread.nextWorkerID
  1330. });
  1331. worker.workerID = PThread.nextWorkerID++;
  1332. PThread.unusedWorkers.push(worker);
  1333. return worker;
  1334. },
  1335. getNewWorker() {
  1336. if (PThread.unusedWorkers.length == 0) {
  1337. // PTHREAD_POOL_SIZE_STRICT should show a warning and, if set to level `2`, return from the function.
  1338. // However, if we're in Node.js, then we can create new workers on the fly and PTHREAD_POOL_SIZE_STRICT
  1339. // should be ignored altogether.
  1340. if (!ENVIRONMENT_IS_NODE) {
  1341. err("Tried to spawn a new thread, but the thread pool is exhausted.\n" + "This might result in a deadlock unless some threads eventually exit or the code explicitly breaks out to the event loop.\n" + "If you want to increase the pool size, use setting `-sPTHREAD_POOL_SIZE=...`." + "\nIf you want to throw an explicit error instead of the risk of deadlocking in those cases, use setting `-sPTHREAD_POOL_SIZE_STRICT=2`.");
  1342. }
  1343. var newWorker = PThread.allocateUnusedWorker();
  1344. PThread.loadWasmModuleToWorker(newWorker);
  1345. }
  1346. return PThread.unusedWorkers.pop();
  1347. }
  1348. };
  1349. var onPostRuns = [];
  1350. var addOnPostRun = cb => onPostRuns.push(cb);
  1351. function establishStackSpace(pthread_ptr) {
  1352. var stackHigh = (growMemViews(), HEAPU32)[(((pthread_ptr) + (48)) >> 2)];
  1353. var stackSize = (growMemViews(), HEAPU32)[(((pthread_ptr) + (52)) >> 2)];
  1354. var stackLow = stackHigh - stackSize;
  1355. assert(stackHigh != 0);
  1356. assert(stackLow != 0);
  1357. assert(stackHigh > stackLow, "stackHigh must be higher then stackLow");
  1358. // Set stack limits used by `emscripten/stack.h` function. These limits are
  1359. // cached in wasm-side globals to make checks as fast as possible.
  1360. _emscripten_stack_set_limits(stackHigh, stackLow);
  1361. // Call inside wasm module to set up the stack frame for this pthread in wasm module scope
  1362. stackRestore(stackHigh);
  1363. // Write the stack cookie last, after we have set up the proper bounds and
  1364. // current position of the stack.
  1365. writeStackCookie();
  1366. }
  1367. /**
  1368. * @param {number} ptr
  1369. * @param {string} type
  1370. */ function getValue(ptr, type = "i8") {
  1371. if (type.endsWith("*")) type = "*";
  1372. switch (type) {
  1373. case "i1":
  1374. return (growMemViews(), HEAP8)[ptr];
  1375. case "i8":
  1376. return (growMemViews(), HEAP8)[ptr];
  1377. case "i16":
  1378. return (growMemViews(), HEAP16)[((ptr) >> 1)];
  1379. case "i32":
  1380. return (growMemViews(), HEAP32)[((ptr) >> 2)];
  1381. case "i64":
  1382. return (growMemViews(), HEAP64)[((ptr) >> 3)];
  1383. case "float":
  1384. return (growMemViews(), HEAPF32)[((ptr) >> 2)];
  1385. case "double":
  1386. return (growMemViews(), HEAPF64)[((ptr) >> 3)];
  1387. case "*":
  1388. return (growMemViews(), HEAPU32)[((ptr) >> 2)];
  1389. default:
  1390. abort(`invalid type for getValue: ${type}`);
  1391. }
  1392. }
  1393. var wasmTableMirror = [];
  1394. var getWasmTableEntry = funcPtr => {
  1395. var func = wasmTableMirror[funcPtr];
  1396. if (!func) {
  1397. /** @suppress {checkTypes} */ wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
  1398. }
  1399. /** @suppress {checkTypes} */ assert(wasmTable.get(funcPtr) == func, "table mirror is out of date");
  1400. return func;
  1401. };
  1402. var invokeEntryPoint = (ptr, arg) => {
  1403. // An old thread on this worker may have been canceled without returning the
  1404. // `runtimeKeepaliveCounter` to zero. Reset it now so the new thread won't
  1405. // be affected.
  1406. runtimeKeepaliveCounter = 0;
  1407. // Same for noExitRuntime. The default for pthreads should always be false
  1408. // otherwise pthreads would never complete and attempts to pthread_join to
  1409. // them would block forever.
  1410. // pthreads can still choose to set `noExitRuntime` explicitly, or
  1411. // call emscripten_unwind_to_js_event_loop to extend their lifetime beyond
  1412. // their main function. See comment in src/runtime_pthread.js for more.
  1413. noExitRuntime = 0;
  1414. // pthread entry points are always of signature 'void *ThreadMain(void *arg)'
  1415. // Native codebases sometimes spawn threads with other thread entry point
  1416. // signatures, such as void ThreadMain(void *arg), void *ThreadMain(), or
  1417. // void ThreadMain(). That is not acceptable per C/C++ specification, but
  1418. // x86 compiler ABI extensions enable that to work. If you find the
  1419. // following line to crash, either change the signature to "proper" void
  1420. // *ThreadMain(void *arg) form, or try linking with the Emscripten linker
  1421. // flag -sEMULATE_FUNCTION_POINTER_CASTS to add in emulation for this x86
  1422. // ABI extension.
  1423. var result = getWasmTableEntry(ptr)(arg);
  1424. checkStackCookie();
  1425. function finish(result) {
  1426. // In MINIMAL_RUNTIME the noExitRuntime concept does not apply to
  1427. // pthreads. To exit a pthread with live runtime, use the function
  1428. // emscripten_unwind_to_js_event_loop() in the pthread body.
  1429. if (keepRuntimeAlive()) {
  1430. EXITSTATUS = result;
  1431. return;
  1432. }
  1433. __emscripten_thread_exit(result);
  1434. }
  1435. finish(result);
  1436. };
  1437. var noExitRuntime = true;
  1438. var registerTLSInit = tlsInitFunc => PThread.tlsInitFunctions.push(tlsInitFunc);
  1439. /**
  1440. * @param {number} ptr
  1441. * @param {number} value
  1442. * @param {string} type
  1443. */ function setValue(ptr, value, type = "i8") {
  1444. if (type.endsWith("*")) type = "*";
  1445. switch (type) {
  1446. case "i1":
  1447. (growMemViews(), HEAP8)[ptr] = value;
  1448. break;
  1449. case "i8":
  1450. (growMemViews(), HEAP8)[ptr] = value;
  1451. break;
  1452. case "i16":
  1453. (growMemViews(), HEAP16)[((ptr) >> 1)] = value;
  1454. break;
  1455. case "i32":
  1456. (growMemViews(), HEAP32)[((ptr) >> 2)] = value;
  1457. break;
  1458. case "i64":
  1459. (growMemViews(), HEAP64)[((ptr) >> 3)] = BigInt(value);
  1460. break;
  1461. case "float":
  1462. (growMemViews(), HEAPF32)[((ptr) >> 2)] = value;
  1463. break;
  1464. case "double":
  1465. (growMemViews(), HEAPF64)[((ptr) >> 3)] = value;
  1466. break;
  1467. case "*":
  1468. (growMemViews(), HEAPU32)[((ptr) >> 2)] = value;
  1469. break;
  1470. default:
  1471. abort(`invalid type for setValue: ${type}`);
  1472. }
  1473. }
  1474. var warnOnce = text => {
  1475. warnOnce.shown ||= {};
  1476. if (!warnOnce.shown[text]) {
  1477. warnOnce.shown[text] = 1;
  1478. if (ENVIRONMENT_IS_NODE) text = "warning: " + text;
  1479. err(text);
  1480. }
  1481. };
  1482. var wasmMemory;
  1483. var UTF8Decoder = globalThis.TextDecoder && new TextDecoder;
  1484. /**
  1485. * heapOrArray is either a regular array, or a JavaScript typed array view.
  1486. * @param {number} idx
  1487. * @param {number=} maxBytesToRead
  1488. * @param {boolean=} ignoreNul
  1489. * @return {number}
  1490. */ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
  1491. var maxIdx = idx + maxBytesToRead;
  1492. if (ignoreNul) return maxIdx;
  1493. // TextDecoder needs to know the byte length in advance, it doesn't stop on
  1494. // null terminator by itself.
  1495. // As a tiny code save trick, compare idx against maxIdx using a negation,
  1496. // so that maxBytesToRead=undefined/NaN means Infinity.
  1497. while (heapOrArray[idx] && !(idx >= maxIdx)) ++idx;
  1498. return idx;
  1499. };
  1500. /**
  1501. * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given
  1502. * array that contains uint8 values, returns a copy of that string as a
  1503. * Javascript String object.
  1504. * heapOrArray is either a regular array, or a JavaScript typed array view.
  1505. * @param {number=} idx
  1506. * @param {number=} maxBytesToRead
  1507. * @param {boolean=} ignoreNul - If true, the function will not stop on a NUL character.
  1508. * @return {string}
  1509. */ var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead, ignoreNul) => {
  1510. var endPtr = findStringEnd(heapOrArray, idx, maxBytesToRead, ignoreNul);
  1511. // When using conditional TextDecoder, skip it for short strings as the overhead of the native call is not worth it.
  1512. if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
  1513. return UTF8Decoder.decode(heapOrArray.buffer instanceof ArrayBuffer ? heapOrArray.subarray(idx, endPtr) : heapOrArray.slice(idx, endPtr));
  1514. }
  1515. var str = "";
  1516. while (idx < endPtr) {
  1517. // For UTF8 byte structure, see:
  1518. // http://en.wikipedia.org/wiki/UTF-8#Description
  1519. // https://www.ietf.org/rfc/rfc2279.txt
  1520. // https://tools.ietf.org/html/rfc3629
  1521. var u0 = heapOrArray[idx++];
  1522. if (!(u0 & 128)) {
  1523. str += String.fromCharCode(u0);
  1524. continue;
  1525. }
  1526. var u1 = heapOrArray[idx++] & 63;
  1527. if ((u0 & 224) == 192) {
  1528. str += String.fromCharCode(((u0 & 31) << 6) | u1);
  1529. continue;
  1530. }
  1531. var u2 = heapOrArray[idx++] & 63;
  1532. if ((u0 & 240) == 224) {
  1533. u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
  1534. } else {
  1535. if ((u0 & 248) != 240) warnOnce(`Invalid UTF-8 leading byte ${ptrToString(u0)} encountered when deserializing a UTF-8 string in wasm memory to a JS string!`);
  1536. u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);
  1537. }
  1538. if (u0 < 65536) {
  1539. str += String.fromCharCode(u0);
  1540. } else {
  1541. var ch = u0 - 65536;
  1542. str += String.fromCharCode(55296 | (ch >> 10), 56320 | (ch & 1023));
  1543. }
  1544. }
  1545. return str;
  1546. };
  1547. /**
  1548. * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
  1549. * emscripten HEAP, returns a copy of that string as a Javascript String object.
  1550. *
  1551. * @param {number} ptr
  1552. * @param {number=} maxBytesToRead - An optional length that specifies the
  1553. * maximum number of bytes to read. You can omit this parameter to scan the
  1554. * string until the first 0 byte. If maxBytesToRead is passed, and the string
  1555. * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
  1556. * string will cut short at that byte index.
  1557. * @param {boolean=} ignoreNul - If true, the function will not stop on a NUL character.
  1558. * @return {string}
  1559. */ var UTF8ToString = (ptr, maxBytesToRead, ignoreNul) => {
  1560. assert(typeof ptr == "number", `UTF8ToString expects a number (got ${typeof ptr})`);
  1561. return ptr ? UTF8ArrayToString((growMemViews(), HEAPU8), ptr, maxBytesToRead, ignoreNul) : "";
  1562. };
  1563. var ___assert_fail = (condition, filename, line, func) => abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [ filename ? UTF8ToString(filename) : "unknown filename", line, func ? UTF8ToString(func) : "unknown function" ]);
  1564. var ___call_sighandler = (fp, sig) => getWasmTableEntry(fp)(sig);
  1565. function pthreadCreateProxied(pthread_ptr, attr, startRoutine, arg) {
  1566. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(2, 0, 1, pthread_ptr, attr, startRoutine, arg);
  1567. return ___pthread_create_js(pthread_ptr, attr, startRoutine, arg);
  1568. }
  1569. var _emscripten_has_threading_support = () => !!globalThis.SharedArrayBuffer;
  1570. var ___pthread_create_js = (pthread_ptr, attr, startRoutine, arg) => {
  1571. if (!_emscripten_has_threading_support()) {
  1572. dbg("pthread_create: environment does not support SharedArrayBuffer, pthreads are not available");
  1573. return 6;
  1574. }
  1575. // List of JS objects that will transfer ownership to the Worker hosting the thread
  1576. var transferList = [];
  1577. var error = 0;
  1578. // Synchronously proxy the thread creation to main thread if possible. If we
  1579. // need to transfer ownership of objects, then proxy asynchronously via
  1580. // postMessage.
  1581. if (ENVIRONMENT_IS_PTHREAD && (transferList.length === 0 || error)) {
  1582. return pthreadCreateProxied(pthread_ptr, attr, startRoutine, arg);
  1583. }
  1584. // If on the main thread, and accessing Canvas/OffscreenCanvas failed, abort
  1585. // with the detected error.
  1586. if (error) return error;
  1587. var threadParams = {
  1588. startRoutine,
  1589. pthread_ptr,
  1590. arg,
  1591. transferList
  1592. };
  1593. if (ENVIRONMENT_IS_PTHREAD) {
  1594. // The prepopulated pool of web workers that can host pthreads is stored
  1595. // in the main JS thread. Therefore if a pthread is attempting to spawn a
  1596. // new thread, the thread creation must be deferred to the main JS thread.
  1597. threadParams.cmd = 5;
  1598. postMessage(threadParams, transferList);
  1599. // When we defer thread creation this way, we have no way to detect thread
  1600. // creation synchronously today, so we have to assume success and return 0.
  1601. return 0;
  1602. }
  1603. // We are the main thread, so we have the pthread warmup pool in this
  1604. // thread and can fire off JS thread creation directly ourselves.
  1605. return spawnThread(threadParams);
  1606. };
  1607. var PATH = {
  1608. isAbs: path => path.charAt(0) === "/",
  1609. splitPath: filename => {
  1610. var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
  1611. return splitPathRe.exec(filename).slice(1);
  1612. },
  1613. normalizeArray: (parts, allowAboveRoot) => {
  1614. // if the path tries to go above the root, `up` ends up > 0
  1615. var up = 0;
  1616. for (var i = parts.length - 1; i >= 0; i--) {
  1617. var last = parts[i];
  1618. if (last === ".") {
  1619. parts.splice(i, 1);
  1620. } else if (last === "..") {
  1621. parts.splice(i, 1);
  1622. up++;
  1623. } else if (up) {
  1624. parts.splice(i, 1);
  1625. up--;
  1626. }
  1627. }
  1628. // if the path is allowed to go above the root, restore leading ..s
  1629. if (allowAboveRoot) {
  1630. for (;up; up--) {
  1631. parts.unshift("..");
  1632. }
  1633. }
  1634. return parts;
  1635. },
  1636. normalize: path => {
  1637. var isAbsolute = PATH.isAbs(path), trailingSlash = path.slice(-1) === "/";
  1638. // Normalize the path
  1639. path = PATH.normalizeArray(path.split("/").filter(p => !!p), !isAbsolute).join("/");
  1640. if (!path && !isAbsolute) {
  1641. path = ".";
  1642. }
  1643. if (path && trailingSlash) {
  1644. path += "/";
  1645. }
  1646. return (isAbsolute ? "/" : "") + path;
  1647. },
  1648. dirname: path => {
  1649. var result = PATH.splitPath(path), root = result[0], dir = result[1];
  1650. if (!root && !dir) {
  1651. // No dirname whatsoever
  1652. return ".";
  1653. }
  1654. if (dir) {
  1655. // It has a dirname, strip trailing slash
  1656. dir = dir.slice(0, -1);
  1657. }
  1658. return root + dir;
  1659. },
  1660. basename: path => path && path.match(/([^\/]+|\/)\/*$/)[1],
  1661. join: (...paths) => PATH.normalize(paths.join("/")),
  1662. join2: (l, r) => PATH.normalize(l + "/" + r)
  1663. };
  1664. var initRandomFill = () => {
  1665. // This block is not needed on v19+ since crypto.getRandomValues is builtin
  1666. if (ENVIRONMENT_IS_NODE) {
  1667. var nodeCrypto = require("node:crypto");
  1668. return view => (nodeCrypto.randomFillSync(view), 0);
  1669. }
  1670. // like with most Web APIs, we can't use Web Crypto API directly on shared memory,
  1671. // so we need to create an intermediate buffer and copy it to the destination
  1672. return view => (view.set(crypto.getRandomValues(new Uint8Array(view.byteLength))),
  1673. 0);
  1674. };
  1675. var randomFill = view => (randomFill = initRandomFill())(view);
  1676. var PATH_FS = {
  1677. resolve: (...args) => {
  1678. var resolvedPath = "", resolvedAbsolute = false;
  1679. for (var i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
  1680. var path = (i >= 0) ? args[i] : FS.cwd();
  1681. // Skip empty and invalid entries
  1682. if (typeof path != "string") {
  1683. throw new TypeError("Arguments to path.resolve must be strings");
  1684. } else if (!path) {
  1685. return "";
  1686. }
  1687. resolvedPath = path + "/" + resolvedPath;
  1688. resolvedAbsolute = PATH.isAbs(path);
  1689. }
  1690. // At this point the path should be resolved to a full absolute path, but
  1691. // handle relative paths to be safe (might happen when process.cwd() fails)
  1692. resolvedPath = PATH.normalizeArray(resolvedPath.split("/").filter(p => !!p), !resolvedAbsolute).join("/");
  1693. return ((resolvedAbsolute ? "/" : "") + resolvedPath) || ".";
  1694. },
  1695. relative: (from, to) => {
  1696. from = PATH_FS.resolve(from).slice(1);
  1697. to = PATH_FS.resolve(to).slice(1);
  1698. function trim(arr) {
  1699. var start = 0;
  1700. for (;start < arr.length; start++) {
  1701. if (arr[start] !== "") break;
  1702. }
  1703. var end = arr.length - 1;
  1704. for (;end >= 0; end--) {
  1705. if (arr[end] !== "") break;
  1706. }
  1707. if (start > end) return [];
  1708. return arr.slice(start, end - start + 1);
  1709. }
  1710. var fromParts = trim(from.split("/"));
  1711. var toParts = trim(to.split("/"));
  1712. var length = Math.min(fromParts.length, toParts.length);
  1713. var samePartsLength = length;
  1714. for (var i = 0; i < length; i++) {
  1715. if (fromParts[i] !== toParts[i]) {
  1716. samePartsLength = i;
  1717. break;
  1718. }
  1719. }
  1720. var outputParts = [];
  1721. for (var i = samePartsLength; i < fromParts.length; i++) {
  1722. outputParts.push("..");
  1723. }
  1724. outputParts = outputParts.concat(toParts.slice(samePartsLength));
  1725. return outputParts.join("/");
  1726. }
  1727. };
  1728. var FS_stdin_getChar_buffer = [];
  1729. var lengthBytesUTF8 = str => {
  1730. var len = 0;
  1731. for (var i = 0; i < str.length; ++i) {
  1732. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
  1733. // unit, not a Unicode code point of the character! So decode
  1734. // UTF16->UTF32->UTF8.
  1735. // See http://unicode.org/faq/utf_bom.html#utf16-3
  1736. var c = str.charCodeAt(i);
  1737. // possibly a lead surrogate
  1738. if (c <= 127) {
  1739. len++;
  1740. } else if (c <= 2047) {
  1741. len += 2;
  1742. } else if (c >= 55296 && c <= 57343) {
  1743. len += 4;
  1744. ++i;
  1745. } else {
  1746. len += 3;
  1747. }
  1748. }
  1749. return len;
  1750. };
  1751. var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
  1752. assert(typeof str === "string", `stringToUTF8Array expects a string (got ${typeof str})`);
  1753. // Parameter maxBytesToWrite is not optional. Negative values, 0, null,
  1754. // undefined and false each don't write out any bytes.
  1755. if (!(maxBytesToWrite > 0)) return 0;
  1756. var startIdx = outIdx;
  1757. var endIdx = outIdx + maxBytesToWrite - 1;
  1758. // -1 for string null terminator.
  1759. for (var i = 0; i < str.length; ++i) {
  1760. // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description
  1761. // and https://www.ietf.org/rfc/rfc2279.txt
  1762. // and https://tools.ietf.org/html/rfc3629
  1763. var u = str.codePointAt(i);
  1764. if (u <= 127) {
  1765. if (outIdx >= endIdx) break;
  1766. heap[outIdx++] = u;
  1767. } else if (u <= 2047) {
  1768. if (outIdx + 1 >= endIdx) break;
  1769. heap[outIdx++] = 192 | (u >> 6);
  1770. heap[outIdx++] = 128 | (u & 63);
  1771. } else if (u <= 65535) {
  1772. if (outIdx + 2 >= endIdx) break;
  1773. heap[outIdx++] = 224 | (u >> 12);
  1774. heap[outIdx++] = 128 | ((u >> 6) & 63);
  1775. heap[outIdx++] = 128 | (u & 63);
  1776. } else {
  1777. if (outIdx + 3 >= endIdx) break;
  1778. if (u > 1114111) warnOnce(`Invalid Unicode code point ${ptrToString(u)} encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).`);
  1779. heap[outIdx++] = 240 | (u >> 18);
  1780. heap[outIdx++] = 128 | ((u >> 12) & 63);
  1781. heap[outIdx++] = 128 | ((u >> 6) & 63);
  1782. heap[outIdx++] = 128 | (u & 63);
  1783. // Gotcha: if codePoint is over 0xFFFF, it is represented as a surrogate pair in UTF-16.
  1784. // We need to manually skip over the second code unit for correct iteration.
  1785. i++;
  1786. }
  1787. }
  1788. // Null-terminate the pointer to the buffer.
  1789. heap[outIdx] = 0;
  1790. return outIdx - startIdx;
  1791. };
  1792. /** @type {function(string, boolean=, number=)} */ var intArrayFromString = (stringy, dontAddNull, length) => {
  1793. var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1;
  1794. var u8array = new Array(len);
  1795. var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
  1796. if (dontAddNull) u8array.length = numBytesWritten;
  1797. return u8array;
  1798. };
  1799. var FS_stdin_getChar = () => {
  1800. if (!FS_stdin_getChar_buffer.length) {
  1801. var result = null;
  1802. if (ENVIRONMENT_IS_NODE) {
  1803. // we will read data by chunks of BUFSIZE
  1804. var BUFSIZE = 256;
  1805. var buf = Buffer.alloc(BUFSIZE);
  1806. var bytesRead = 0;
  1807. // For some reason we must suppress a closure warning here, even though
  1808. // fd definitely exists on process.stdin, and is even the proper way to
  1809. // get the fd of stdin,
  1810. // https://github.com/nodejs/help/issues/2136#issuecomment-523649904
  1811. // This started to happen after moving this logic out of library_tty.js,
  1812. // so it is related to the surrounding code in some unclear manner.
  1813. /** @suppress {missingProperties} */ var fd = process.stdin.fd;
  1814. try {
  1815. bytesRead = fs.readSync(fd, buf, 0, BUFSIZE);
  1816. } catch (e) {
  1817. // Cross-platform differences: on Windows, reading EOF throws an
  1818. // exception, but on other OSes, reading EOF returns 0. Uniformize
  1819. // behavior by treating the EOF exception to return 0.
  1820. if (e.toString().includes("EOF")) bytesRead = 0; else throw e;
  1821. }
  1822. if (bytesRead > 0) {
  1823. result = buf.slice(0, bytesRead).toString("utf-8");
  1824. }
  1825. } else if (globalThis.window?.prompt) {
  1826. // Browser.
  1827. result = window.prompt("Input: ");
  1828. // returns null on cancel
  1829. if (result !== null) {
  1830. result += "\n";
  1831. }
  1832. } else {}
  1833. if (!result) {
  1834. return null;
  1835. }
  1836. FS_stdin_getChar_buffer = intArrayFromString(result, true);
  1837. }
  1838. return FS_stdin_getChar_buffer.shift();
  1839. };
  1840. var TTY = {
  1841. ttys: [],
  1842. init() {},
  1843. shutdown() {},
  1844. register(dev, ops) {
  1845. TTY.ttys[dev] = {
  1846. input: [],
  1847. output: [],
  1848. ops
  1849. };
  1850. FS.registerDevice(dev, TTY.stream_ops);
  1851. },
  1852. stream_ops: {
  1853. open(stream) {
  1854. var tty = TTY.ttys[stream.node.rdev];
  1855. if (!tty) {
  1856. throw new FS.ErrnoError(43);
  1857. }
  1858. stream.tty = tty;
  1859. stream.seekable = false;
  1860. },
  1861. close(stream) {
  1862. // flush any pending line data
  1863. stream.tty.ops.fsync(stream.tty);
  1864. },
  1865. fsync(stream) {
  1866. stream.tty.ops.fsync(stream.tty);
  1867. },
  1868. read(stream, buffer, offset, length, pos) {
  1869. if (!stream.tty || !stream.tty.ops.get_char) {
  1870. throw new FS.ErrnoError(60);
  1871. }
  1872. var bytesRead = 0;
  1873. for (var i = 0; i < length; i++) {
  1874. var result;
  1875. try {
  1876. result = stream.tty.ops.get_char(stream.tty);
  1877. } catch (e) {
  1878. throw new FS.ErrnoError(29);
  1879. }
  1880. if (result === undefined && bytesRead === 0) {
  1881. throw new FS.ErrnoError(6);
  1882. }
  1883. if (result === null || result === undefined) break;
  1884. bytesRead++;
  1885. buffer[offset + i] = result;
  1886. }
  1887. if (bytesRead) {
  1888. stream.node.atime = Date.now();
  1889. }
  1890. return bytesRead;
  1891. },
  1892. write(stream, buffer, offset, length, pos) {
  1893. if (!stream.tty || !stream.tty.ops.put_char) {
  1894. throw new FS.ErrnoError(60);
  1895. }
  1896. try {
  1897. for (var i = 0; i < length; i++) {
  1898. stream.tty.ops.put_char(stream.tty, buffer[offset + i]);
  1899. }
  1900. } catch (e) {
  1901. throw new FS.ErrnoError(29);
  1902. }
  1903. if (length) {
  1904. stream.node.mtime = stream.node.ctime = Date.now();
  1905. }
  1906. return i;
  1907. }
  1908. },
  1909. default_tty_ops: {
  1910. get_char(tty) {
  1911. return FS_stdin_getChar();
  1912. },
  1913. put_char(tty, val) {
  1914. if (val === null || val === 10) {
  1915. out(UTF8ArrayToString(tty.output));
  1916. tty.output = [];
  1917. } else {
  1918. if (val != 0) tty.output.push(val);
  1919. }
  1920. },
  1921. fsync(tty) {
  1922. if (tty.output?.length > 0) {
  1923. out(UTF8ArrayToString(tty.output));
  1924. tty.output = [];
  1925. }
  1926. },
  1927. ioctl_tcgets(tty) {
  1928. // typical setting
  1929. return {
  1930. c_iflag: 25856,
  1931. c_oflag: 5,
  1932. c_cflag: 191,
  1933. c_lflag: 35387,
  1934. c_cc: [ 3, 28, 127, 21, 4, 0, 1, 0, 17, 19, 26, 0, 18, 15, 23, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
  1935. };
  1936. },
  1937. ioctl_tcsets(tty, optional_actions, data) {
  1938. // currently just ignore
  1939. return 0;
  1940. },
  1941. ioctl_tiocgwinsz(tty) {
  1942. return [ 24, 80 ];
  1943. }
  1944. },
  1945. default_tty1_ops: {
  1946. put_char(tty, val) {
  1947. if (val === null || val === 10) {
  1948. err(UTF8ArrayToString(tty.output));
  1949. tty.output = [];
  1950. } else {
  1951. if (val != 0) tty.output.push(val);
  1952. }
  1953. },
  1954. fsync(tty) {
  1955. if (tty.output?.length > 0) {
  1956. err(UTF8ArrayToString(tty.output));
  1957. tty.output = [];
  1958. }
  1959. }
  1960. }
  1961. };
  1962. var zeroMemory = (ptr, size) => (growMemViews(), HEAPU8).fill(0, ptr, ptr + size);
  1963. var alignMemory = (size, alignment) => {
  1964. assert(alignment, "alignment argument is required");
  1965. return Math.ceil(size / alignment) * alignment;
  1966. };
  1967. var mmapAlloc = size => {
  1968. size = alignMemory(size, 65536);
  1969. var ptr = _emscripten_builtin_memalign(65536, size);
  1970. if (ptr) zeroMemory(ptr, size);
  1971. return ptr;
  1972. };
  1973. var MEMFS = {
  1974. ops_table: null,
  1975. mount(mount) {
  1976. return MEMFS.createNode(null, "/", 16895, 0);
  1977. },
  1978. createNode(parent, name, mode, dev) {
  1979. if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
  1980. // not supported
  1981. throw new FS.ErrnoError(63);
  1982. }
  1983. MEMFS.ops_table ||= {
  1984. dir: {
  1985. node: {
  1986. getattr: MEMFS.node_ops.getattr,
  1987. setattr: MEMFS.node_ops.setattr,
  1988. lookup: MEMFS.node_ops.lookup,
  1989. mknod: MEMFS.node_ops.mknod,
  1990. rename: MEMFS.node_ops.rename,
  1991. unlink: MEMFS.node_ops.unlink,
  1992. rmdir: MEMFS.node_ops.rmdir,
  1993. readdir: MEMFS.node_ops.readdir,
  1994. symlink: MEMFS.node_ops.symlink
  1995. },
  1996. stream: {
  1997. llseek: MEMFS.stream_ops.llseek
  1998. }
  1999. },
  2000. file: {
  2001. node: {
  2002. getattr: MEMFS.node_ops.getattr,
  2003. setattr: MEMFS.node_ops.setattr
  2004. },
  2005. stream: {
  2006. llseek: MEMFS.stream_ops.llseek,
  2007. read: MEMFS.stream_ops.read,
  2008. write: MEMFS.stream_ops.write,
  2009. mmap: MEMFS.stream_ops.mmap,
  2010. msync: MEMFS.stream_ops.msync
  2011. }
  2012. },
  2013. link: {
  2014. node: {
  2015. getattr: MEMFS.node_ops.getattr,
  2016. setattr: MEMFS.node_ops.setattr,
  2017. readlink: MEMFS.node_ops.readlink
  2018. },
  2019. stream: {}
  2020. },
  2021. chrdev: {
  2022. node: {
  2023. getattr: MEMFS.node_ops.getattr,
  2024. setattr: MEMFS.node_ops.setattr
  2025. },
  2026. stream: FS.chrdev_stream_ops
  2027. }
  2028. };
  2029. var node = FS.createNode(parent, name, mode, dev);
  2030. if (FS.isDir(node.mode)) {
  2031. node.node_ops = MEMFS.ops_table.dir.node;
  2032. node.stream_ops = MEMFS.ops_table.dir.stream;
  2033. node.contents = {};
  2034. } else if (FS.isFile(node.mode)) {
  2035. node.node_ops = MEMFS.ops_table.file.node;
  2036. node.stream_ops = MEMFS.ops_table.file.stream;
  2037. // The actual number of bytes used in the typed array, as opposed to
  2038. // contents.length which gives the whole capacity.
  2039. node.usedBytes = 0;
  2040. // The byte data of the file is stored in a typed array.
  2041. // Note: typed arrays are not resizable like normal JS arrays are, so
  2042. // there is a small penalty involved for appending file writes that
  2043. // continuously grow a file similar to std::vector capacity vs used.
  2044. node.contents = MEMFS.emptyFileContents ??= new Uint8Array(0);
  2045. } else if (FS.isLink(node.mode)) {
  2046. node.node_ops = MEMFS.ops_table.link.node;
  2047. node.stream_ops = MEMFS.ops_table.link.stream;
  2048. } else if (FS.isChrdev(node.mode)) {
  2049. node.node_ops = MEMFS.ops_table.chrdev.node;
  2050. node.stream_ops = MEMFS.ops_table.chrdev.stream;
  2051. }
  2052. node.atime = node.mtime = node.ctime = Date.now();
  2053. // add the new node to the parent
  2054. if (parent) {
  2055. parent.contents[name] = node;
  2056. parent.atime = parent.mtime = parent.ctime = node.atime;
  2057. }
  2058. return node;
  2059. },
  2060. getFileDataAsTypedArray(node) {
  2061. assert(FS.isFile(node.mode), "getFileDataAsTypedArray called on non-file");
  2062. return node.contents.subarray(0, node.usedBytes);
  2063. },
  2064. expandFileStorage(node, newCapacity) {
  2065. var prevCapacity = node.contents.length;
  2066. if (prevCapacity >= newCapacity) return;
  2067. // No need to expand, the storage was already large enough.
  2068. // Don't expand strictly to the given requested limit if it's only a very
  2069. // small increase, but instead geometrically grow capacity.
  2070. // For small filesizes (<1MB), perform size*2 geometric increase, but for
  2071. // large sizes, do a much more conservative size*1.125 increase to avoid
  2072. // overshooting the allocation cap by a very large margin.
  2073. var CAPACITY_DOUBLING_MAX = 1024 * 1024;
  2074. newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125)) >>> 0);
  2075. if (prevCapacity) newCapacity = Math.max(newCapacity, 256);
  2076. // At minimum allocate 256b for each file when expanding.
  2077. var oldContents = MEMFS.getFileDataAsTypedArray(node);
  2078. node.contents = new Uint8Array(newCapacity);
  2079. // Allocate new storage.
  2080. node.contents.set(oldContents);
  2081. },
  2082. resizeFileStorage(node, newSize) {
  2083. if (node.usedBytes == newSize) return;
  2084. var oldContents = node.contents;
  2085. node.contents = new Uint8Array(newSize);
  2086. // Allocate new storage.
  2087. node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes)));
  2088. // Copy old data over to the new storage.
  2089. node.usedBytes = newSize;
  2090. },
  2091. node_ops: {
  2092. getattr(node) {
  2093. var attr = {};
  2094. // device numbers reuse inode numbers.
  2095. attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
  2096. attr.ino = node.id;
  2097. attr.mode = node.mode;
  2098. attr.nlink = 1;
  2099. attr.uid = 0;
  2100. attr.gid = 0;
  2101. attr.rdev = node.rdev;
  2102. if (FS.isDir(node.mode)) {
  2103. attr.size = 4096;
  2104. } else if (FS.isFile(node.mode)) {
  2105. attr.size = node.usedBytes;
  2106. } else if (FS.isLink(node.mode)) {
  2107. attr.size = node.link.length;
  2108. } else {
  2109. attr.size = 0;
  2110. }
  2111. attr.atime = new Date(node.atime);
  2112. attr.mtime = new Date(node.mtime);
  2113. attr.ctime = new Date(node.ctime);
  2114. // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
  2115. // but this is not required by the standard.
  2116. attr.blksize = 4096;
  2117. attr.blocks = Math.ceil(attr.size / attr.blksize);
  2118. return attr;
  2119. },
  2120. setattr(node, attr) {
  2121. for (const key of [ "mode", "atime", "mtime", "ctime" ]) {
  2122. if (attr[key] != null) {
  2123. node[key] = attr[key];
  2124. }
  2125. }
  2126. if (attr.size !== undefined) {
  2127. MEMFS.resizeFileStorage(node, attr.size);
  2128. }
  2129. },
  2130. lookup(parent, name) {
  2131. throw new FS.ErrnoError(44);
  2132. },
  2133. mknod(parent, name, mode, dev) {
  2134. return MEMFS.createNode(parent, name, mode, dev);
  2135. },
  2136. rename(old_node, new_dir, new_name) {
  2137. var new_node;
  2138. try {
  2139. new_node = FS.lookupNode(new_dir, new_name);
  2140. } catch (e) {}
  2141. if (new_node) {
  2142. if (FS.isDir(old_node.mode)) {
  2143. // if we're overwriting a directory at new_name, make sure it's empty.
  2144. for (var i in new_node.contents) {
  2145. throw new FS.ErrnoError(55);
  2146. }
  2147. }
  2148. FS.hashRemoveNode(new_node);
  2149. }
  2150. // do the internal rewiring
  2151. delete old_node.parent.contents[old_node.name];
  2152. new_dir.contents[new_name] = old_node;
  2153. old_node.name = new_name;
  2154. new_dir.ctime = new_dir.mtime = old_node.parent.ctime = old_node.parent.mtime = Date.now();
  2155. },
  2156. unlink(parent, name) {
  2157. delete parent.contents[name];
  2158. parent.ctime = parent.mtime = Date.now();
  2159. },
  2160. rmdir(parent, name) {
  2161. var node = FS.lookupNode(parent, name);
  2162. for (var i in node.contents) {
  2163. throw new FS.ErrnoError(55);
  2164. }
  2165. delete parent.contents[name];
  2166. parent.ctime = parent.mtime = Date.now();
  2167. },
  2168. readdir(node) {
  2169. return [ ".", "..", ...Object.keys(node.contents) ];
  2170. },
  2171. symlink(parent, newname, oldpath) {
  2172. var node = MEMFS.createNode(parent, newname, 511 | 40960, 0);
  2173. node.link = oldpath;
  2174. return node;
  2175. },
  2176. readlink(node) {
  2177. if (!FS.isLink(node.mode)) {
  2178. throw new FS.ErrnoError(28);
  2179. }
  2180. return node.link;
  2181. }
  2182. },
  2183. stream_ops: {
  2184. read(stream, buffer, offset, length, position) {
  2185. var contents = stream.node.contents;
  2186. if (position >= stream.node.usedBytes) return 0;
  2187. var size = Math.min(stream.node.usedBytes - position, length);
  2188. assert(size >= 0);
  2189. buffer.set(contents.subarray(position, position + size), offset);
  2190. return size;
  2191. },
  2192. write(stream, buffer, offset, length, position, canOwn) {
  2193. assert(buffer.subarray, "FS.write expects a TypedArray");
  2194. // If the buffer is located in main memory (HEAP), and if
  2195. // memory can grow, we can't hold on to references of the
  2196. // memory buffer, as they may get invalidated. That means we
  2197. // need to copy its contents.
  2198. if (buffer.buffer === (growMemViews(), HEAP8).buffer) {
  2199. canOwn = false;
  2200. }
  2201. if (!length) return 0;
  2202. var node = stream.node;
  2203. node.mtime = node.ctime = Date.now();
  2204. if (canOwn) {
  2205. assert(position === 0, "canOwn must imply no weird position inside the file");
  2206. node.contents = buffer.subarray(offset, offset + length);
  2207. node.usedBytes = length;
  2208. } else if (node.usedBytes === 0 && position === 0) {
  2209. // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.
  2210. node.contents = buffer.slice(offset, offset + length);
  2211. node.usedBytes = length;
  2212. } else {
  2213. MEMFS.expandFileStorage(node, position + length);
  2214. // Use typed array write which is available.
  2215. node.contents.set(buffer.subarray(offset, offset + length), position);
  2216. node.usedBytes = Math.max(node.usedBytes, position + length);
  2217. }
  2218. return length;
  2219. },
  2220. llseek(stream, offset, whence) {
  2221. var position = offset;
  2222. if (whence === 1) {
  2223. position += stream.position;
  2224. } else if (whence === 2) {
  2225. if (FS.isFile(stream.node.mode)) {
  2226. position += stream.node.usedBytes;
  2227. }
  2228. }
  2229. if (position < 0) {
  2230. throw new FS.ErrnoError(28);
  2231. }
  2232. return position;
  2233. },
  2234. mmap(stream, length, position, prot, flags) {
  2235. if (!FS.isFile(stream.node.mode)) {
  2236. throw new FS.ErrnoError(43);
  2237. }
  2238. var ptr;
  2239. var allocated;
  2240. var contents = stream.node.contents;
  2241. // Only make a new copy when MAP_PRIVATE is specified.
  2242. if (!(flags & 2) && contents.buffer === (growMemViews(), HEAP8).buffer) {
  2243. // We can't emulate MAP_SHARED when the file is not backed by the
  2244. // buffer we're mapping to (e.g. the HEAP buffer).
  2245. allocated = false;
  2246. ptr = contents.byteOffset;
  2247. } else {
  2248. allocated = true;
  2249. ptr = mmapAlloc(length);
  2250. if (!ptr) {
  2251. throw new FS.ErrnoError(48);
  2252. }
  2253. if (contents) {
  2254. // Try to avoid unnecessary slices.
  2255. if (position > 0 || position + length < contents.length) {
  2256. if (contents.subarray) {
  2257. contents = contents.subarray(position, position + length);
  2258. } else {
  2259. contents = Array.prototype.slice.call(contents, position, position + length);
  2260. }
  2261. }
  2262. (growMemViews(), HEAP8).set(contents, ptr);
  2263. }
  2264. }
  2265. return {
  2266. ptr,
  2267. allocated
  2268. };
  2269. },
  2270. msync(stream, buffer, offset, length, mmapFlags) {
  2271. MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
  2272. // should we check if bytesWritten and length are the same?
  2273. return 0;
  2274. }
  2275. }
  2276. };
  2277. var FS_modeStringToFlags = str => {
  2278. if (typeof str != "string") return str;
  2279. var flagModes = {
  2280. "r": 0,
  2281. "r+": 2,
  2282. "w": 512 | 64 | 1,
  2283. "w+": 512 | 64 | 2,
  2284. "a": 1024 | 64 | 1,
  2285. "a+": 1024 | 64 | 2
  2286. };
  2287. var flags = flagModes[str];
  2288. if (typeof flags == "undefined") {
  2289. throw new Error(`Unknown file open mode: ${str}`);
  2290. }
  2291. return flags;
  2292. };
  2293. var FS_fileDataToTypedArray = data => {
  2294. if (typeof data == "string") {
  2295. data = intArrayFromString(data, true);
  2296. }
  2297. if (!data.subarray) {
  2298. data = new Uint8Array(data);
  2299. }
  2300. return data;
  2301. };
  2302. var FS_getMode = (canRead, canWrite) => {
  2303. var mode = 0;
  2304. if (canRead) mode |= 292 | 73;
  2305. if (canWrite) mode |= 146;
  2306. return mode;
  2307. };
  2308. var IDBFS = {
  2309. dbs: {},
  2310. indexedDB: () => {
  2311. assert(typeof indexedDB != "undefined", "IDBFS used, but indexedDB not supported");
  2312. return indexedDB;
  2313. },
  2314. DB_VERSION: 21,
  2315. DB_STORE_NAME: "FILE_DATA",
  2316. queuePersist: mount => {
  2317. function onPersistComplete() {
  2318. if (mount.idbPersistState === "again") startPersist(); else {
  2319. mount.idbPersistState = 0;
  2320. // Otherwise reset sync state back to idle to wait for a new sync later
  2321. IDBFS.onAutoPersistStateChanged?.(false);
  2322. }
  2323. }
  2324. function startPersist() {
  2325. mount.idbPersistState = "idb";
  2326. // Mark that we are currently running a sync operation
  2327. IDBFS.onAutoPersistStateChanged?.(true);
  2328. IDBFS.syncfs(mount, /*populate:*/ false, onPersistComplete);
  2329. }
  2330. if (!mount.idbPersistState) {
  2331. // Programs typically write/copy/move multiple files in the in-memory
  2332. // filesystem within a single app frame, so when a filesystem sync
  2333. // command is triggered, do not start it immediately, but only after
  2334. // the current frame is finished. This way all the modified files
  2335. // inside the main loop tick will be batched up to the same sync.
  2336. mount.idbPersistState = setTimeout(startPersist, 0);
  2337. } else if (mount.idbPersistState === "idb") {
  2338. // There is an active IndexedDB sync operation in-flight, but we now
  2339. // have accumulated more files to sync. We should therefore queue up
  2340. // a new sync after the current one finishes so that all writes
  2341. // will be properly persisted.
  2342. mount.idbPersistState = "again";
  2343. }
  2344. },
  2345. mount: mount => {
  2346. // reuse core MEMFS functionality
  2347. var mnt = MEMFS.mount(mount);
  2348. // If the automatic IDBFS persistence option has been selected, then automatically persist
  2349. // all modifications to the filesystem as they occur.
  2350. if (mount?.opts?.autoPersist) {
  2351. mount.idbPersistState = 0;
  2352. // IndexedDB sync starts in idle state
  2353. var memfs_node_ops = mnt.node_ops;
  2354. mnt.node_ops = {
  2355. ...mnt.node_ops
  2356. };
  2357. // Clone node_ops to inject write tracking
  2358. mnt.node_ops.mknod = (parent, name, mode, dev) => {
  2359. var node = memfs_node_ops.mknod(parent, name, mode, dev);
  2360. // Propagate injected node_ops to the newly created child node
  2361. node.node_ops = mnt.node_ops;
  2362. // Remember for each IDBFS node which IDBFS mount point they came from so we know which mount to persist on modification.
  2363. node.idbfs_mount = mnt.mount;
  2364. // Remember original MEMFS stream_ops for this node
  2365. node.memfs_stream_ops = node.stream_ops;
  2366. // Clone stream_ops to inject write tracking
  2367. node.stream_ops = {
  2368. ...node.stream_ops
  2369. };
  2370. // Track all file writes
  2371. node.stream_ops.write = (stream, buffer, offset, length, position, canOwn) => {
  2372. // This file has been modified, we must persist IndexedDB when this file closes
  2373. stream.node.isModified = true;
  2374. return node.memfs_stream_ops.write(stream, buffer, offset, length, position, canOwn);
  2375. };
  2376. // Persist IndexedDB on file close
  2377. node.stream_ops.close = stream => {
  2378. var n = stream.node;
  2379. if (n.isModified) {
  2380. IDBFS.queuePersist(n.idbfs_mount);
  2381. n.isModified = false;
  2382. }
  2383. if (n.memfs_stream_ops.close) return n.memfs_stream_ops.close(stream);
  2384. };
  2385. // Persist the node we just created to IndexedDB
  2386. IDBFS.queuePersist(mnt.mount);
  2387. return node;
  2388. };
  2389. // Also kick off persisting the filesystem on other operations that modify the filesystem.
  2390. mnt.node_ops.rmdir = (...args) => (IDBFS.queuePersist(mnt.mount), memfs_node_ops.rmdir(...args));
  2391. mnt.node_ops.symlink = (...args) => (IDBFS.queuePersist(mnt.mount), memfs_node_ops.symlink(...args));
  2392. mnt.node_ops.unlink = (...args) => (IDBFS.queuePersist(mnt.mount), memfs_node_ops.unlink(...args));
  2393. mnt.node_ops.rename = (...args) => (IDBFS.queuePersist(mnt.mount), memfs_node_ops.rename(...args));
  2394. }
  2395. return mnt;
  2396. },
  2397. syncfs: (mount, populate, callback) => {
  2398. IDBFS.getLocalSet(mount, (err, local) => {
  2399. if (err) return callback(err);
  2400. IDBFS.getRemoteSet(mount, (err, remote) => {
  2401. if (err) return callback(err);
  2402. var src = populate ? remote : local;
  2403. var dst = populate ? local : remote;
  2404. IDBFS.reconcile(src, dst, callback);
  2405. });
  2406. });
  2407. },
  2408. quit: () => {
  2409. for (var value of Object.values(IDBFS.dbs)) {
  2410. value.close();
  2411. }
  2412. IDBFS.dbs = {};
  2413. },
  2414. getDB: (name, callback) => {
  2415. // check the cache first
  2416. var db = IDBFS.dbs[name];
  2417. if (db) {
  2418. return callback(null, db);
  2419. }
  2420. var req;
  2421. try {
  2422. req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION);
  2423. } catch (e) {
  2424. return callback(e);
  2425. }
  2426. if (!req) {
  2427. return callback("Unable to connect to IndexedDB");
  2428. }
  2429. req.onupgradeneeded = e => {
  2430. var db = /** @type {IDBDatabase} */ (e.target.result);
  2431. var transaction = e.target.transaction;
  2432. var fileStore;
  2433. if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) {
  2434. fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME);
  2435. } else {
  2436. fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME);
  2437. }
  2438. if (!fileStore.indexNames.contains("timestamp")) {
  2439. fileStore.createIndex("timestamp", "timestamp", {
  2440. unique: false
  2441. });
  2442. }
  2443. };
  2444. req.onsuccess = () => {
  2445. db = /** @type {IDBDatabase} */ (req.result);
  2446. // add to the cache
  2447. IDBFS.dbs[name] = db;
  2448. callback(null, db);
  2449. };
  2450. req.onerror = e => {
  2451. callback(e.target.error);
  2452. e.preventDefault();
  2453. };
  2454. },
  2455. getLocalSet: (mount, callback) => {
  2456. var entries = {};
  2457. function isRealDir(p) {
  2458. return p !== "." && p !== "..";
  2459. }
  2460. function toAbsolute(root) {
  2461. return p => PATH.join2(root, p);
  2462. }
  2463. var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint));
  2464. while (check.length) {
  2465. var path = check.pop();
  2466. var stat;
  2467. try {
  2468. stat = FS.lstat(path);
  2469. } catch (e) {
  2470. return callback(e);
  2471. }
  2472. if (FS.isDir(stat.mode)) {
  2473. check.push(...FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
  2474. }
  2475. entries[path] = {
  2476. "timestamp": stat.mtime
  2477. };
  2478. }
  2479. return callback(null, {
  2480. type: "local",
  2481. entries
  2482. });
  2483. },
  2484. getRemoteSet: (mount, callback) => {
  2485. var entries = {};
  2486. IDBFS.getDB(mount.mountpoint, (err, db) => {
  2487. if (err) return callback(err);
  2488. try {
  2489. var transaction = db.transaction([ IDBFS.DB_STORE_NAME ], "readonly");
  2490. transaction.onerror = e => {
  2491. callback(e.target.error);
  2492. e.preventDefault();
  2493. };
  2494. var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
  2495. var index = store.index("timestamp");
  2496. index.openKeyCursor().onsuccess = event => {
  2497. var cursor = event.target.result;
  2498. if (!cursor) {
  2499. return callback(null, {
  2500. type: "remote",
  2501. db,
  2502. entries
  2503. });
  2504. }
  2505. entries[cursor.primaryKey] = {
  2506. "timestamp": cursor.key
  2507. };
  2508. cursor.continue();
  2509. };
  2510. } catch (e) {
  2511. return callback(e);
  2512. }
  2513. });
  2514. },
  2515. loadLocalEntry: (path, callback) => {
  2516. var stat, node;
  2517. try {
  2518. var lookup = FS.lookupPath(path);
  2519. node = lookup.node;
  2520. stat = FS.lstat(path);
  2521. } catch (e) {
  2522. return callback(e);
  2523. }
  2524. if (FS.isDir(stat.mode)) {
  2525. return callback(null, {
  2526. "timestamp": stat.mtime,
  2527. "mode": stat.mode
  2528. });
  2529. } else if (FS.isLink(stat.mode)) {
  2530. return callback(null, {
  2531. "timestamp": stat.mtime,
  2532. "mode": stat.mode,
  2533. "link": node.link
  2534. });
  2535. } else if (FS.isFile(stat.mode)) {
  2536. // Performance consideration: storing a normal JavaScript array to a IndexedDB is much slower than storing a typed array.
  2537. // Therefore always convert the file contents to a typed array first before writing the data to IndexedDB.
  2538. node.contents = MEMFS.getFileDataAsTypedArray(node);
  2539. return callback(null, {
  2540. "timestamp": stat.mtime,
  2541. "mode": stat.mode,
  2542. "contents": node.contents
  2543. });
  2544. } else {
  2545. return callback(new Error("node type not supported"));
  2546. }
  2547. },
  2548. storeLocalEntry: (path, entry, callback) => {
  2549. try {
  2550. if (FS.isDir(entry["mode"])) {
  2551. FS.mkdirTree(path, entry["mode"]);
  2552. } else if (FS.isLink(entry["mode"])) {
  2553. FS.symlink(entry["link"], path);
  2554. } else if (FS.isFile(entry["mode"])) {
  2555. FS.writeFile(path, entry["contents"], {
  2556. canOwn: true
  2557. });
  2558. } else {
  2559. return callback(new Error("node type not supported"));
  2560. }
  2561. FS.chmod(path, entry["mode"]);
  2562. FS.utime(path, entry["timestamp"], entry["timestamp"]);
  2563. } catch (e) {
  2564. return callback(e);
  2565. }
  2566. callback(null);
  2567. },
  2568. removeLocalEntry: (path, callback) => {
  2569. try {
  2570. var stat = FS.lstat(path);
  2571. if (FS.isDir(stat.mode)) {
  2572. FS.rmdir(path);
  2573. } else {
  2574. FS.unlink(path);
  2575. }
  2576. } catch (e) {
  2577. return callback(e);
  2578. }
  2579. callback(null);
  2580. },
  2581. loadRemoteEntry: (store, path, callback) => {
  2582. var req = store.get(path);
  2583. req.onsuccess = event => callback(null, event.target.result);
  2584. req.onerror = e => {
  2585. callback(e.target.error);
  2586. e.preventDefault();
  2587. };
  2588. },
  2589. storeRemoteEntry: (store, path, entry, callback) => {
  2590. try {
  2591. var req = store.put(entry, path);
  2592. } catch (e) {
  2593. callback(e);
  2594. return;
  2595. }
  2596. req.onsuccess = event => callback();
  2597. req.onerror = e => {
  2598. callback(e.target.error);
  2599. e.preventDefault();
  2600. };
  2601. },
  2602. removeRemoteEntry: (store, path, callback) => {
  2603. var req = store.delete(path);
  2604. req.onsuccess = event => callback();
  2605. req.onerror = e => {
  2606. callback(e.target.error);
  2607. e.preventDefault();
  2608. };
  2609. },
  2610. reconcile: (src, dst, callback) => {
  2611. var total = 0;
  2612. var create = [];
  2613. for (var [key, e] of Object.entries(src.entries)) {
  2614. var e2 = dst.entries[key];
  2615. if (!e2 || e["timestamp"].getTime() != e2["timestamp"].getTime()) {
  2616. create.push(key);
  2617. total++;
  2618. }
  2619. }
  2620. var remove = [];
  2621. for (var key of Object.keys(dst.entries)) {
  2622. if (!src.entries[key]) {
  2623. remove.push(key);
  2624. total++;
  2625. }
  2626. }
  2627. if (!total) {
  2628. return callback(null);
  2629. }
  2630. var errored = false;
  2631. var db = src.type === "remote" ? src.db : dst.db;
  2632. var transaction = db.transaction([ IDBFS.DB_STORE_NAME ], "readwrite");
  2633. var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
  2634. function done(err) {
  2635. if (err && !errored) {
  2636. errored = true;
  2637. return callback(err);
  2638. }
  2639. }
  2640. // transaction may abort if (for example) there is a QuotaExceededError
  2641. transaction.onerror = transaction.onabort = e => {
  2642. done(e.target.error);
  2643. e.preventDefault();
  2644. };
  2645. transaction.oncomplete = e => {
  2646. if (!errored) {
  2647. callback(null);
  2648. }
  2649. };
  2650. // sort paths in ascending order so directory entries are created
  2651. // before the files inside them
  2652. for (const path of create.sort()) {
  2653. if (dst.type === "local") {
  2654. IDBFS.loadRemoteEntry(store, path, (err, entry) => {
  2655. if (err) return done(err);
  2656. IDBFS.storeLocalEntry(path, entry, done);
  2657. });
  2658. } else {
  2659. IDBFS.loadLocalEntry(path, (err, entry) => {
  2660. if (err) return done(err);
  2661. IDBFS.storeRemoteEntry(store, path, entry, done);
  2662. });
  2663. }
  2664. }
  2665. // sort paths in descending order so files are deleted before their
  2666. // parent directories
  2667. for (var path of remove.sort().reverse()) {
  2668. if (dst.type === "local") {
  2669. IDBFS.removeLocalEntry(path, done);
  2670. } else {
  2671. IDBFS.removeRemoteEntry(store, path, done);
  2672. }
  2673. }
  2674. }
  2675. };
  2676. var strError = errno => UTF8ToString(_strerror(errno));
  2677. var ERRNO_CODES = {
  2678. "EPERM": 63,
  2679. "ENOENT": 44,
  2680. "ESRCH": 71,
  2681. "EINTR": 27,
  2682. "EIO": 29,
  2683. "ENXIO": 60,
  2684. "E2BIG": 1,
  2685. "ENOEXEC": 45,
  2686. "EBADF": 8,
  2687. "ECHILD": 12,
  2688. "EAGAIN": 6,
  2689. "EWOULDBLOCK": 6,
  2690. "ENOMEM": 48,
  2691. "EACCES": 2,
  2692. "EFAULT": 21,
  2693. "ENOTBLK": 105,
  2694. "EBUSY": 10,
  2695. "EEXIST": 20,
  2696. "EXDEV": 75,
  2697. "ENODEV": 43,
  2698. "ENOTDIR": 54,
  2699. "EISDIR": 31,
  2700. "EINVAL": 28,
  2701. "ENFILE": 41,
  2702. "EMFILE": 33,
  2703. "ENOTTY": 59,
  2704. "ETXTBSY": 74,
  2705. "EFBIG": 22,
  2706. "ENOSPC": 51,
  2707. "ESPIPE": 70,
  2708. "EROFS": 69,
  2709. "EMLINK": 34,
  2710. "EPIPE": 64,
  2711. "EDOM": 18,
  2712. "ERANGE": 68,
  2713. "ENOMSG": 49,
  2714. "EIDRM": 24,
  2715. "ECHRNG": 106,
  2716. "EL2NSYNC": 156,
  2717. "EL3HLT": 107,
  2718. "EL3RST": 108,
  2719. "ELNRNG": 109,
  2720. "EUNATCH": 110,
  2721. "ENOCSI": 111,
  2722. "EL2HLT": 112,
  2723. "EDEADLK": 16,
  2724. "ENOLCK": 46,
  2725. "EBADE": 113,
  2726. "EBADR": 114,
  2727. "EXFULL": 115,
  2728. "ENOANO": 104,
  2729. "EBADRQC": 103,
  2730. "EBADSLT": 102,
  2731. "EDEADLOCK": 16,
  2732. "EBFONT": 101,
  2733. "ENOSTR": 100,
  2734. "ENODATA": 116,
  2735. "ETIME": 117,
  2736. "ENOSR": 118,
  2737. "ENONET": 119,
  2738. "ENOPKG": 120,
  2739. "EREMOTE": 121,
  2740. "ENOLINK": 47,
  2741. "EADV": 122,
  2742. "ESRMNT": 123,
  2743. "ECOMM": 124,
  2744. "EPROTO": 65,
  2745. "EMULTIHOP": 36,
  2746. "EDOTDOT": 125,
  2747. "EBADMSG": 9,
  2748. "ENOTUNIQ": 126,
  2749. "EBADFD": 127,
  2750. "EREMCHG": 128,
  2751. "ELIBACC": 129,
  2752. "ELIBBAD": 130,
  2753. "ELIBSCN": 131,
  2754. "ELIBMAX": 132,
  2755. "ELIBEXEC": 133,
  2756. "ENOSYS": 52,
  2757. "ENOTEMPTY": 55,
  2758. "ENAMETOOLONG": 37,
  2759. "ELOOP": 32,
  2760. "EOPNOTSUPP": 138,
  2761. "EPFNOSUPPORT": 139,
  2762. "ECONNRESET": 15,
  2763. "ENOBUFS": 42,
  2764. "EAFNOSUPPORT": 5,
  2765. "EPROTOTYPE": 67,
  2766. "ENOTSOCK": 57,
  2767. "ENOPROTOOPT": 50,
  2768. "ESHUTDOWN": 140,
  2769. "ECONNREFUSED": 14,
  2770. "EADDRINUSE": 3,
  2771. "ECONNABORTED": 13,
  2772. "ENETUNREACH": 40,
  2773. "ENETDOWN": 38,
  2774. "ETIMEDOUT": 73,
  2775. "EHOSTDOWN": 142,
  2776. "EHOSTUNREACH": 23,
  2777. "EINPROGRESS": 26,
  2778. "EALREADY": 7,
  2779. "EDESTADDRREQ": 17,
  2780. "EMSGSIZE": 35,
  2781. "EPROTONOSUPPORT": 66,
  2782. "ESOCKTNOSUPPORT": 137,
  2783. "EADDRNOTAVAIL": 4,
  2784. "ENETRESET": 39,
  2785. "EISCONN": 30,
  2786. "ENOTCONN": 53,
  2787. "ETOOMANYREFS": 141,
  2788. "EUSERS": 136,
  2789. "EDQUOT": 19,
  2790. "ESTALE": 72,
  2791. "ENOTSUP": 138,
  2792. "ENOMEDIUM": 148,
  2793. "EILSEQ": 25,
  2794. "EOVERFLOW": 61,
  2795. "ECANCELED": 11,
  2796. "ENOTRECOVERABLE": 56,
  2797. "EOWNERDEAD": 62,
  2798. "ESTRPIPE": 135
  2799. };
  2800. var asyncLoad = async url => {
  2801. var arrayBuffer = await readAsync(url);
  2802. assert(arrayBuffer, `Loading data file "${url}" failed (no arrayBuffer).`);
  2803. return new Uint8Array(arrayBuffer);
  2804. };
  2805. var FS_createDataFile = (...args) => FS.createDataFile(...args);
  2806. var getUniqueRunDependency = id => {
  2807. var orig = id;
  2808. while (1) {
  2809. if (!runDependencyTracking[id]) return id;
  2810. id = orig + Math.random();
  2811. }
  2812. };
  2813. var dependenciesPromise = null;
  2814. var resolveRunDependencies = async () => dependenciesPromise;
  2815. var runDependencies = 0;
  2816. var runDependencyTracking = {};
  2817. var runDependencyWatcher = null;
  2818. var removeRunDependency = id => {
  2819. runDependencies--;
  2820. Module["monitorRunDependencies"]?.(runDependencies);
  2821. assert(id, "removeRunDependency requires an ID");
  2822. assert(runDependencyTracking[id]);
  2823. delete runDependencyTracking[id];
  2824. if (!runDependencies) {
  2825. if (runDependencyWatcher !== null) {
  2826. clearInterval(runDependencyWatcher);
  2827. runDependencyWatcher = null;
  2828. }
  2829. dependenciesPromise.resolve();
  2830. }
  2831. };
  2832. var addRunDependency = id => {
  2833. if (!runDependencies) {
  2834. var resolve;
  2835. dependenciesPromise = new Promise(r => resolve = r);
  2836. dependenciesPromise.resolve = resolve;
  2837. }
  2838. runDependencies++;
  2839. Module["monitorRunDependencies"]?.(runDependencies);
  2840. assert(id, "addRunDependency requires an ID");
  2841. assert(!runDependencyTracking[id]);
  2842. runDependencyTracking[id] = 1;
  2843. if (runDependencyWatcher === null && globalThis.setInterval) {
  2844. // Check for missing dependencies every few seconds
  2845. runDependencyWatcher = setInterval(() => {
  2846. if (ABORT) {
  2847. clearInterval(runDependencyWatcher);
  2848. runDependencyWatcher = null;
  2849. return;
  2850. }
  2851. var shown = false;
  2852. for (var dep in runDependencyTracking) {
  2853. if (!shown) {
  2854. shown = true;
  2855. err("still waiting on run dependencies:");
  2856. }
  2857. err(`dependency: ${dep}`);
  2858. }
  2859. if (shown) {
  2860. err("(end of list)");
  2861. }
  2862. }, 1e4);
  2863. // Prevent this timer from keeping the runtime alive if nothing
  2864. // else is.
  2865. runDependencyWatcher.unref?.();
  2866. }
  2867. };
  2868. var preloadPlugins = [];
  2869. var FS_handledByPreloadPlugin = async (byteArray, fullname) => {
  2870. // Ensure plugins are ready.
  2871. if (typeof Browser != "undefined") Browser.init();
  2872. for (var plugin of preloadPlugins) {
  2873. if (plugin["canHandle"](fullname)) {
  2874. assert(plugin["handle"].constructor.name === "AsyncFunction", "Filesystem plugin handlers must be async functions (See #24914)");
  2875. return plugin["handle"](byteArray, fullname);
  2876. }
  2877. }
  2878. // If no plugin handled this file then return the original/unmodified
  2879. // byteArray.
  2880. return byteArray;
  2881. };
  2882. var FS_preloadFile = async (parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish) => {
  2883. // TODO we should allow people to just pass in a complete filename instead
  2884. // of parent and name being that we just join them anyways
  2885. var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
  2886. var dep = getUniqueRunDependency(`cp ${fullname}`);
  2887. // might have several active requests for the same fullname
  2888. addRunDependency(dep);
  2889. try {
  2890. var byteArray = url;
  2891. if (typeof url == "string") {
  2892. byteArray = await asyncLoad(url);
  2893. }
  2894. byteArray = await FS_handledByPreloadPlugin(byteArray, fullname);
  2895. preFinish?.();
  2896. if (!dontCreateFile) {
  2897. FS_createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
  2898. }
  2899. } finally {
  2900. removeRunDependency(dep);
  2901. }
  2902. };
  2903. var FS_createPreloadedFile = (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => {
  2904. FS_preloadFile(parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish).then(onload).catch(onerror);
  2905. };
  2906. var FS = {
  2907. root: null,
  2908. mounts: [],
  2909. devices: {},
  2910. streams: [],
  2911. nextInode: 1,
  2912. nameTable: null,
  2913. currentPath: "/",
  2914. initialized: false,
  2915. ignorePermissions: true,
  2916. filesystems: null,
  2917. syncFSRequests: 0,
  2918. ErrnoError: class extends Error {
  2919. name="ErrnoError";
  2920. // We set the `name` property to be able to identify `FS.ErrnoError`
  2921. // - the `name` is a standard ECMA-262 property of error objects. Kind of good to have it anyway.
  2922. // - when using PROXYFS, an error can come from an underlying FS
  2923. // as different FS objects have their own FS.ErrnoError each,
  2924. // the test `err instanceof FS.ErrnoError` won't detect an error coming from another filesystem, causing bugs.
  2925. // we'll use the reliable test `err.name == "ErrnoError"` instead
  2926. constructor(errno) {
  2927. super(runtimeInitialized ? strError(errno) : "");
  2928. this.errno = errno;
  2929. for (var key in ERRNO_CODES) {
  2930. if (ERRNO_CODES[key] === errno) {
  2931. this.code = key;
  2932. break;
  2933. }
  2934. }
  2935. }
  2936. },
  2937. FSStream: class {
  2938. shared={};
  2939. get object() {
  2940. return this.node;
  2941. }
  2942. set object(val) {
  2943. this.node = val;
  2944. }
  2945. get isRead() {
  2946. return (this.flags & 2097155) !== 1;
  2947. }
  2948. get isWrite() {
  2949. return (this.flags & 2097155) !== 0;
  2950. }
  2951. get isAppend() {
  2952. return (this.flags & 1024);
  2953. }
  2954. get flags() {
  2955. return this.shared.flags;
  2956. }
  2957. set flags(val) {
  2958. this.shared.flags = val;
  2959. }
  2960. get position() {
  2961. return this.shared.position;
  2962. }
  2963. set position(val) {
  2964. this.shared.position = val;
  2965. }
  2966. },
  2967. FSNode: class {
  2968. node_ops={};
  2969. stream_ops={};
  2970. readMode=292 | 73;
  2971. writeMode=146;
  2972. mounted=null;
  2973. constructor(parent, name, mode, rdev) {
  2974. if (!parent) {
  2975. parent = this;
  2976. }
  2977. this.parent = parent;
  2978. this.mount = parent.mount;
  2979. this.id = FS.nextInode++;
  2980. this.name = name;
  2981. this.mode = mode;
  2982. this.rdev = rdev;
  2983. this.atime = this.mtime = this.ctime = Date.now();
  2984. }
  2985. get read() {
  2986. return (this.mode & this.readMode) === this.readMode;
  2987. }
  2988. set read(val) {
  2989. val ? this.mode |= this.readMode : this.mode &= ~this.readMode;
  2990. }
  2991. get write() {
  2992. return (this.mode & this.writeMode) === this.writeMode;
  2993. }
  2994. set write(val) {
  2995. val ? this.mode |= this.writeMode : this.mode &= ~this.writeMode;
  2996. }
  2997. get isFolder() {
  2998. return FS.isDir(this.mode);
  2999. }
  3000. get isDevice() {
  3001. return FS.isChrdev(this.mode);
  3002. }
  3003. },
  3004. lookupPath(path, opts = {}) {
  3005. if (!path) {
  3006. throw new FS.ErrnoError(44);
  3007. }
  3008. opts.follow_mount ??= true;
  3009. if (!PATH.isAbs(path)) {
  3010. path = FS.cwd() + "/" + path;
  3011. }
  3012. // limit max consecutive symlinks to SYMLOOP_MAX.
  3013. linkloop: for (var nlinks = 0; nlinks < 40; nlinks++) {
  3014. // split the absolute path
  3015. var parts = path.split("/").filter(p => !!p);
  3016. // start at the root
  3017. var current = FS.root;
  3018. var current_path = "/";
  3019. for (var i = 0; i < parts.length; i++) {
  3020. var islast = (i === parts.length - 1);
  3021. if (islast && opts.parent) {
  3022. // stop resolving
  3023. break;
  3024. }
  3025. if (parts[i] === ".") {
  3026. continue;
  3027. }
  3028. if (parts[i] === "..") {
  3029. current_path = PATH.dirname(current_path);
  3030. if (FS.isRoot(current)) {
  3031. path = current_path + "/" + parts.slice(i + 1).join("/");
  3032. // We're making progress here, don't let many consecutive ..'s
  3033. // lead to ELOOP
  3034. nlinks--;
  3035. continue linkloop;
  3036. } else {
  3037. current = current.parent;
  3038. }
  3039. continue;
  3040. }
  3041. current_path = PATH.join2(current_path, parts[i]);
  3042. try {
  3043. current = FS.lookupNode(current, parts[i]);
  3044. } catch (e) {
  3045. // if noent_okay is true, suppress a ENOENT in the last component
  3046. // and return an object with an undefined node. This is needed for
  3047. // resolving symlinks in the path when creating a file.
  3048. if ((e?.errno === 44) && islast && opts.noent_okay) {
  3049. return {
  3050. path: current_path
  3051. };
  3052. }
  3053. throw e;
  3054. }
  3055. // jump to the mount's root node if this is a mountpoint
  3056. if (FS.isMountpoint(current) && (!islast || opts.follow_mount)) {
  3057. current = current.mounted.root;
  3058. }
  3059. // by default, lookupPath will not follow a symlink if it is the final path component.
  3060. // setting opts.follow = true will override this behavior.
  3061. if (FS.isLink(current.mode) && (!islast || opts.follow)) {
  3062. if (!current.node_ops.readlink) {
  3063. throw new FS.ErrnoError(52);
  3064. }
  3065. var link = current.node_ops.readlink(current);
  3066. if (!PATH.isAbs(link)) {
  3067. link = PATH.dirname(current_path) + "/" + link;
  3068. }
  3069. path = link + "/" + parts.slice(i + 1).join("/");
  3070. continue linkloop;
  3071. }
  3072. }
  3073. return {
  3074. path: current_path,
  3075. node: current
  3076. };
  3077. }
  3078. throw new FS.ErrnoError(32);
  3079. },
  3080. getPath(node) {
  3081. var path;
  3082. while (true) {
  3083. if (FS.isRoot(node)) {
  3084. var mount = node.mount.mountpoint;
  3085. if (!path) return mount;
  3086. return mount[mount.length - 1] !== "/" ? `${mount}/${path}` : mount + path;
  3087. }
  3088. path = path ? `${node.name}/${path}` : node.name;
  3089. node = node.parent;
  3090. }
  3091. },
  3092. hashName(parentid, name) {
  3093. var hash = 0;
  3094. for (var i = 0; i < name.length; i++) {
  3095. hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
  3096. }
  3097. return ((parentid + hash) >>> 0) % FS.nameTable.length;
  3098. },
  3099. hashAddNode(node) {
  3100. var hash = FS.hashName(node.parent.id, node.name);
  3101. node.name_next = FS.nameTable[hash];
  3102. FS.nameTable[hash] = node;
  3103. },
  3104. hashRemoveNode(node) {
  3105. var hash = FS.hashName(node.parent.id, node.name);
  3106. if (FS.nameTable[hash] === node) {
  3107. FS.nameTable[hash] = node.name_next;
  3108. } else {
  3109. var current = FS.nameTable[hash];
  3110. while (current) {
  3111. if (current.name_next === node) {
  3112. current.name_next = node.name_next;
  3113. break;
  3114. }
  3115. current = current.name_next;
  3116. }
  3117. }
  3118. },
  3119. lookupNode(parent, name) {
  3120. var errCode = FS.mayLookup(parent);
  3121. if (errCode) {
  3122. throw new FS.ErrnoError(errCode);
  3123. }
  3124. var hash = FS.hashName(parent.id, name);
  3125. for (var node = FS.nameTable[hash]; node; node = node.name_next) {
  3126. var nodeName = node.name;
  3127. if (node.parent.id === parent.id && nodeName === name) {
  3128. return node;
  3129. }
  3130. }
  3131. // if we failed to find it in the cache, call into the VFS
  3132. return FS.lookup(parent, name);
  3133. },
  3134. createNode(parent, name, mode, rdev) {
  3135. assert(typeof parent == "object");
  3136. var node = new FS.FSNode(parent, name, mode, rdev);
  3137. FS.hashAddNode(node);
  3138. return node;
  3139. },
  3140. destroyNode(node) {
  3141. FS.hashRemoveNode(node);
  3142. },
  3143. isRoot(node) {
  3144. return node === node.parent;
  3145. },
  3146. isMountpoint(node) {
  3147. return !!node.mounted;
  3148. },
  3149. isFile(mode) {
  3150. return (mode & 61440) === 32768;
  3151. },
  3152. isDir(mode) {
  3153. return (mode & 61440) === 16384;
  3154. },
  3155. isLink(mode) {
  3156. return (mode & 61440) === 40960;
  3157. },
  3158. isChrdev(mode) {
  3159. return (mode & 61440) === 8192;
  3160. },
  3161. isBlkdev(mode) {
  3162. return (mode & 61440) === 24576;
  3163. },
  3164. isFIFO(mode) {
  3165. return (mode & 61440) === 4096;
  3166. },
  3167. isSocket(mode) {
  3168. return (mode & 49152) === 49152;
  3169. },
  3170. flagsToPermissionString(flag) {
  3171. var perms = [ "r", "w", "rw" ][flag & 3];
  3172. if ((flag & 512)) {
  3173. perms += "w";
  3174. }
  3175. return perms;
  3176. },
  3177. nodePermissions(node, perms) {
  3178. if (FS.ignorePermissions) {
  3179. return 0;
  3180. }
  3181. // return 0 if any user, group or owner bits are set.
  3182. if (perms.includes("r") && !(node.mode & 292)) {
  3183. return 2;
  3184. }
  3185. if (perms.includes("w") && !(node.mode & 146)) {
  3186. return 2;
  3187. }
  3188. if (perms.includes("x") && !(node.mode & 73)) {
  3189. return 2;
  3190. }
  3191. return 0;
  3192. },
  3193. mayLookup(dir) {
  3194. if (!FS.isDir(dir.mode)) return 54;
  3195. var errCode = FS.nodePermissions(dir, "x");
  3196. if (errCode) return errCode;
  3197. if (!dir.node_ops.lookup) return 2;
  3198. return 0;
  3199. },
  3200. mayCreate(dir, name) {
  3201. if (!FS.isDir(dir.mode)) {
  3202. return 54;
  3203. }
  3204. try {
  3205. var node = FS.lookupNode(dir, name);
  3206. return 20;
  3207. } catch (e) {}
  3208. return FS.nodePermissions(dir, "wx");
  3209. },
  3210. mayDelete(dir, name, isdir) {
  3211. var node;
  3212. try {
  3213. node = FS.lookupNode(dir, name);
  3214. } catch (e) {
  3215. return e.errno;
  3216. }
  3217. var errCode = FS.nodePermissions(dir, "wx");
  3218. if (errCode) {
  3219. return errCode;
  3220. }
  3221. if (isdir) {
  3222. if (!FS.isDir(node.mode)) {
  3223. return 54;
  3224. }
  3225. if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
  3226. return 10;
  3227. }
  3228. } else if (FS.isDir(node.mode)) {
  3229. return 31;
  3230. }
  3231. return 0;
  3232. },
  3233. mayOpen(node, flags) {
  3234. if (!node) {
  3235. return 44;
  3236. }
  3237. if (FS.isLink(node.mode)) {
  3238. return 32;
  3239. }
  3240. var mode = FS.flagsToPermissionString(flags);
  3241. if (FS.isDir(node.mode)) {
  3242. // opening for write
  3243. // TODO: check for O_SEARCH? (== search for dir only)
  3244. if (mode !== "r" || (flags & (512 | 64))) {
  3245. return 31;
  3246. }
  3247. }
  3248. return FS.nodePermissions(node, mode);
  3249. },
  3250. checkOpExists(op, err) {
  3251. if (!op) {
  3252. throw new FS.ErrnoError(err);
  3253. }
  3254. return op;
  3255. },
  3256. MAX_OPEN_FDS: 4096,
  3257. nextfd() {
  3258. for (var fd = 0; fd <= FS.MAX_OPEN_FDS; fd++) {
  3259. if (!FS.streams[fd]) {
  3260. return fd;
  3261. }
  3262. }
  3263. throw new FS.ErrnoError(33);
  3264. },
  3265. getStreamChecked(fd) {
  3266. var stream = FS.getStream(fd);
  3267. if (!stream) {
  3268. throw new FS.ErrnoError(8);
  3269. }
  3270. return stream;
  3271. },
  3272. getStream: fd => FS.streams[fd],
  3273. createStream(stream, fd = -1) {
  3274. assert(fd >= -1);
  3275. // clone it, so we can return an instance of FSStream
  3276. stream = Object.assign(new FS.FSStream, stream);
  3277. if (fd == -1) {
  3278. fd = FS.nextfd();
  3279. }
  3280. stream.fd = fd;
  3281. FS.streams[fd] = stream;
  3282. return stream;
  3283. },
  3284. closeStream(fd) {
  3285. FS.streams[fd] = null;
  3286. },
  3287. dupStream(origStream, fd = -1) {
  3288. var stream = FS.createStream(origStream, fd);
  3289. stream.stream_ops?.dup?.(stream);
  3290. return stream;
  3291. },
  3292. doSetAttr(stream, node, attr) {
  3293. var setattr = stream?.stream_ops.setattr;
  3294. var arg = setattr ? stream : node;
  3295. setattr ??= node.node_ops.setattr;
  3296. FS.checkOpExists(setattr, 63);
  3297. try {
  3298. setattr(arg, attr);
  3299. } catch (e) {
  3300. if (e instanceof RangeError) {
  3301. throw new FS.ErrnoError(22);
  3302. }
  3303. throw e;
  3304. }
  3305. },
  3306. chrdev_stream_ops: {
  3307. open(stream) {
  3308. var device = FS.getDevice(stream.node.rdev);
  3309. // override node's stream ops with the device's
  3310. stream.stream_ops = device.stream_ops;
  3311. // forward the open call
  3312. stream.stream_ops.open?.(stream);
  3313. },
  3314. llseek() {
  3315. throw new FS.ErrnoError(70);
  3316. }
  3317. },
  3318. major: dev => ((dev) >> 8),
  3319. minor: dev => ((dev) & 255),
  3320. makedev: (ma, mi) => ((ma) << 8 | (mi)),
  3321. registerDevice(dev, ops) {
  3322. FS.devices[dev] = {
  3323. stream_ops: ops
  3324. };
  3325. },
  3326. getDevice: dev => FS.devices[dev],
  3327. getMounts(mount) {
  3328. var mounts = [];
  3329. var check = [ mount ];
  3330. while (check.length) {
  3331. var m = check.pop();
  3332. mounts.push(m);
  3333. check.push(...m.mounts);
  3334. }
  3335. return mounts;
  3336. },
  3337. syncfs(populate, callback) {
  3338. if (typeof populate == "function") {
  3339. callback = populate;
  3340. populate = false;
  3341. }
  3342. FS.syncFSRequests++;
  3343. if (FS.syncFSRequests > 1) {
  3344. err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`);
  3345. }
  3346. var mounts = FS.getMounts(FS.root.mount);
  3347. var completed = 0;
  3348. function doCallback(errCode) {
  3349. assert(FS.syncFSRequests > 0);
  3350. FS.syncFSRequests--;
  3351. return callback(errCode);
  3352. }
  3353. function done(errCode) {
  3354. if (errCode) {
  3355. if (!done.errored) {
  3356. done.errored = true;
  3357. return doCallback(errCode);
  3358. }
  3359. return;
  3360. }
  3361. if (++completed >= mounts.length) {
  3362. doCallback(null);
  3363. }
  3364. }
  3365. // sync all mounts
  3366. for (var mount of mounts) {
  3367. if (mount.type.syncfs) {
  3368. mount.type.syncfs(mount, populate, done);
  3369. } else {
  3370. done(null);
  3371. }
  3372. }
  3373. },
  3374. mount(type, opts, mountpoint) {
  3375. if (typeof type == "string") {
  3376. // The filesystem was not included, and instead we have an error
  3377. // message stored in the variable.
  3378. throw type;
  3379. }
  3380. var root = mountpoint === "/";
  3381. var pseudo = !mountpoint;
  3382. var node;
  3383. if (root && FS.root) {
  3384. throw new FS.ErrnoError(10);
  3385. } else if (!root && !pseudo) {
  3386. var lookup = FS.lookupPath(mountpoint, {
  3387. follow_mount: false
  3388. });
  3389. mountpoint = lookup.path;
  3390. // use the absolute path
  3391. node = lookup.node;
  3392. if (FS.isMountpoint(node)) {
  3393. throw new FS.ErrnoError(10);
  3394. }
  3395. if (!FS.isDir(node.mode)) {
  3396. throw new FS.ErrnoError(54);
  3397. }
  3398. }
  3399. var mount = {
  3400. type,
  3401. opts,
  3402. mountpoint,
  3403. mounts: []
  3404. };
  3405. // create a root node for the fs
  3406. var mountRoot = type.mount(mount);
  3407. mountRoot.mount = mount;
  3408. mount.root = mountRoot;
  3409. if (root) {
  3410. FS.root = mountRoot;
  3411. } else if (node) {
  3412. // set as a mountpoint
  3413. node.mounted = mount;
  3414. // add the new mount to the current mount's children
  3415. if (node.mount) {
  3416. node.mount.mounts.push(mount);
  3417. }
  3418. }
  3419. return mountRoot;
  3420. },
  3421. unmount(mountpoint) {
  3422. var lookup = FS.lookupPath(mountpoint, {
  3423. follow_mount: false
  3424. });
  3425. if (!FS.isMountpoint(lookup.node)) {
  3426. throw new FS.ErrnoError(28);
  3427. }
  3428. // destroy the nodes for this mount, and all its child mounts
  3429. var node = lookup.node;
  3430. var mount = node.mounted;
  3431. var mounts = FS.getMounts(mount);
  3432. for (var [hash, current] of Object.entries(FS.nameTable)) {
  3433. while (current) {
  3434. var next = current.name_next;
  3435. if (mounts.includes(current.mount)) {
  3436. FS.destroyNode(current);
  3437. }
  3438. current = next;
  3439. }
  3440. }
  3441. // no longer a mountpoint
  3442. node.mounted = null;
  3443. // remove this mount from the child mounts
  3444. var idx = node.mount.mounts.indexOf(mount);
  3445. assert(idx !== -1);
  3446. node.mount.mounts.splice(idx, 1);
  3447. },
  3448. lookup(parent, name) {
  3449. return parent.node_ops.lookup(parent, name);
  3450. },
  3451. mknod(path, mode, dev) {
  3452. var lookup = FS.lookupPath(path, {
  3453. parent: true
  3454. });
  3455. var parent = lookup.node;
  3456. var name = PATH.basename(path);
  3457. if (!name) {
  3458. throw new FS.ErrnoError(28);
  3459. }
  3460. if (name === "." || name === "..") {
  3461. throw new FS.ErrnoError(20);
  3462. }
  3463. var errCode = FS.mayCreate(parent, name);
  3464. if (errCode) {
  3465. throw new FS.ErrnoError(errCode);
  3466. }
  3467. if (!parent.node_ops.mknod) {
  3468. throw new FS.ErrnoError(63);
  3469. }
  3470. return parent.node_ops.mknod(parent, name, mode, dev);
  3471. },
  3472. statfs(path) {
  3473. return FS.statfsNode(FS.lookupPath(path, {
  3474. follow: true
  3475. }).node);
  3476. },
  3477. statfsStream(stream) {
  3478. // We keep a separate statfsStream function because noderawfs overrides
  3479. // it. In noderawfs, stream.node is sometimes null. Instead, we need to
  3480. // look at stream.path.
  3481. return FS.statfsNode(stream.node);
  3482. },
  3483. statfsNode(node) {
  3484. // NOTE: None of the defaults here are true. We're just returning safe and
  3485. // sane values. Currently nodefs and rawfs replace these defaults,
  3486. // other file systems leave them alone.
  3487. var rtn = {
  3488. bsize: 4096,
  3489. frsize: 4096,
  3490. blocks: 1e6,
  3491. bfree: 5e5,
  3492. bavail: 5e5,
  3493. files: FS.nextInode,
  3494. ffree: FS.nextInode - 1,
  3495. fsid: 42,
  3496. flags: 2,
  3497. namelen: 255
  3498. };
  3499. if (node.node_ops.statfs) {
  3500. Object.assign(rtn, node.node_ops.statfs(node.mount.opts.root));
  3501. }
  3502. return rtn;
  3503. },
  3504. create(path, mode = 438) {
  3505. mode &= 4095;
  3506. mode |= 32768;
  3507. return FS.mknod(path, mode, 0);
  3508. },
  3509. mkdir(path, mode = 511) {
  3510. mode &= 511 | 512;
  3511. mode |= 16384;
  3512. return FS.mknod(path, mode, 0);
  3513. },
  3514. mkdirTree(path, mode) {
  3515. var dirs = path.split("/");
  3516. var d = "";
  3517. for (var dir of dirs) {
  3518. if (!dir) continue;
  3519. if (d || PATH.isAbs(path)) d += "/";
  3520. d += dir;
  3521. try {
  3522. FS.mkdir(d, mode);
  3523. } catch (e) {
  3524. if (e.errno != 20) throw e;
  3525. }
  3526. }
  3527. },
  3528. mkdev(path, mode, dev) {
  3529. if (typeof dev == "undefined") {
  3530. dev = mode;
  3531. mode = 438;
  3532. }
  3533. mode |= 8192;
  3534. return FS.mknod(path, mode, dev);
  3535. },
  3536. symlink(oldpath, newpath) {
  3537. if (!PATH_FS.resolve(oldpath)) {
  3538. throw new FS.ErrnoError(44);
  3539. }
  3540. var lookup = FS.lookupPath(newpath, {
  3541. parent: true
  3542. });
  3543. var parent = lookup.node;
  3544. if (!parent) {
  3545. throw new FS.ErrnoError(44);
  3546. }
  3547. var newname = PATH.basename(newpath);
  3548. var errCode = FS.mayCreate(parent, newname);
  3549. if (errCode) {
  3550. throw new FS.ErrnoError(errCode);
  3551. }
  3552. if (!parent.node_ops.symlink) {
  3553. throw new FS.ErrnoError(63);
  3554. }
  3555. return parent.node_ops.symlink(parent, newname, oldpath);
  3556. },
  3557. rename(old_path, new_path) {
  3558. var old_dirname = PATH.dirname(old_path);
  3559. var new_dirname = PATH.dirname(new_path);
  3560. var old_name = PATH.basename(old_path);
  3561. var new_name = PATH.basename(new_path);
  3562. // parents must exist
  3563. var lookup, old_dir, new_dir;
  3564. // let the errors from non existent directories percolate up
  3565. lookup = FS.lookupPath(old_path, {
  3566. parent: true
  3567. });
  3568. old_dir = lookup.node;
  3569. lookup = FS.lookupPath(new_path, {
  3570. parent: true
  3571. });
  3572. new_dir = lookup.node;
  3573. if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
  3574. // need to be part of the same mount
  3575. if (old_dir.mount !== new_dir.mount) {
  3576. throw new FS.ErrnoError(75);
  3577. }
  3578. // source must exist
  3579. var old_node = FS.lookupNode(old_dir, old_name);
  3580. // old path should not be an ancestor of the new path
  3581. var relative = PATH_FS.relative(old_path, new_dirname);
  3582. if (relative.charAt(0) !== ".") {
  3583. throw new FS.ErrnoError(28);
  3584. }
  3585. // new path should not be an ancestor of the old path
  3586. relative = PATH_FS.relative(new_path, old_dirname);
  3587. if (relative.charAt(0) !== ".") {
  3588. throw new FS.ErrnoError(55);
  3589. }
  3590. // see if the new path already exists
  3591. var new_node;
  3592. try {
  3593. new_node = FS.lookupNode(new_dir, new_name);
  3594. } catch (e) {}
  3595. // early out if nothing needs to change
  3596. if (old_node === new_node) {
  3597. return;
  3598. }
  3599. // we'll need to delete the old entry
  3600. var isdir = FS.isDir(old_node.mode);
  3601. var errCode = FS.mayDelete(old_dir, old_name, isdir);
  3602. if (errCode) {
  3603. throw new FS.ErrnoError(errCode);
  3604. }
  3605. // need delete permissions if we'll be overwriting.
  3606. // need create permissions if new doesn't already exist.
  3607. errCode = new_node ? FS.mayDelete(new_dir, new_name, isdir) : FS.mayCreate(new_dir, new_name);
  3608. if (errCode) {
  3609. throw new FS.ErrnoError(errCode);
  3610. }
  3611. if (!old_dir.node_ops.rename) {
  3612. throw new FS.ErrnoError(63);
  3613. }
  3614. if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
  3615. throw new FS.ErrnoError(10);
  3616. }
  3617. // if we are going to change the parent, check write permissions
  3618. if (new_dir !== old_dir) {
  3619. errCode = FS.nodePermissions(old_dir, "w");
  3620. if (errCode) {
  3621. throw new FS.ErrnoError(errCode);
  3622. }
  3623. }
  3624. // remove the node from the lookup hash
  3625. FS.hashRemoveNode(old_node);
  3626. // do the underlying fs rename
  3627. try {
  3628. old_dir.node_ops.rename(old_node, new_dir, new_name);
  3629. // update old node (we do this here to avoid each backend
  3630. // needing to)
  3631. old_node.parent = new_dir;
  3632. } catch (e) {
  3633. throw e;
  3634. } finally {
  3635. // add the node back to the hash (in case node_ops.rename
  3636. // changed its name)
  3637. FS.hashAddNode(old_node);
  3638. }
  3639. },
  3640. rmdir(path) {
  3641. var lookup = FS.lookupPath(path, {
  3642. parent: true
  3643. });
  3644. var parent = lookup.node;
  3645. var name = PATH.basename(path);
  3646. var node = FS.lookupNode(parent, name);
  3647. var errCode = FS.mayDelete(parent, name, true);
  3648. if (errCode) {
  3649. throw new FS.ErrnoError(errCode);
  3650. }
  3651. if (!parent.node_ops.rmdir) {
  3652. throw new FS.ErrnoError(63);
  3653. }
  3654. if (FS.isMountpoint(node)) {
  3655. throw new FS.ErrnoError(10);
  3656. }
  3657. parent.node_ops.rmdir(parent, name);
  3658. FS.destroyNode(node);
  3659. },
  3660. readdir(path) {
  3661. var lookup = FS.lookupPath(path, {
  3662. follow: true
  3663. });
  3664. var node = lookup.node;
  3665. var readdir = FS.checkOpExists(node.node_ops.readdir, 54);
  3666. return readdir(node);
  3667. },
  3668. unlink(path) {
  3669. var lookup = FS.lookupPath(path, {
  3670. parent: true
  3671. });
  3672. var parent = lookup.node;
  3673. if (!parent) {
  3674. throw new FS.ErrnoError(44);
  3675. }
  3676. var name = PATH.basename(path);
  3677. var node = FS.lookupNode(parent, name);
  3678. var errCode = FS.mayDelete(parent, name, false);
  3679. if (errCode) {
  3680. // According to POSIX, we should map EISDIR to EPERM, but
  3681. // we instead do what Linux does (and we must, as we use
  3682. // the musl linux libc).
  3683. throw new FS.ErrnoError(errCode);
  3684. }
  3685. if (!parent.node_ops.unlink) {
  3686. throw new FS.ErrnoError(63);
  3687. }
  3688. if (FS.isMountpoint(node)) {
  3689. throw new FS.ErrnoError(10);
  3690. }
  3691. parent.node_ops.unlink(parent, name);
  3692. FS.destroyNode(node);
  3693. },
  3694. readlink(path) {
  3695. var lookup = FS.lookupPath(path);
  3696. var link = lookup.node;
  3697. if (!link) {
  3698. throw new FS.ErrnoError(44);
  3699. }
  3700. if (!link.node_ops.readlink) {
  3701. throw new FS.ErrnoError(28);
  3702. }
  3703. return link.node_ops.readlink(link);
  3704. },
  3705. stat(path, dontFollow) {
  3706. var lookup = FS.lookupPath(path, {
  3707. follow: !dontFollow
  3708. });
  3709. var node = lookup.node;
  3710. var getattr = FS.checkOpExists(node.node_ops.getattr, 63);
  3711. return getattr(node);
  3712. },
  3713. fstat(fd) {
  3714. var stream = FS.getStreamChecked(fd);
  3715. var node = stream.node;
  3716. var getattr = stream.stream_ops.getattr;
  3717. var arg = getattr ? stream : node;
  3718. getattr ??= node.node_ops.getattr;
  3719. FS.checkOpExists(getattr, 63);
  3720. return getattr(arg);
  3721. },
  3722. lstat(path) {
  3723. return FS.stat(path, true);
  3724. },
  3725. doChmod(stream, node, mode, dontFollow) {
  3726. FS.doSetAttr(stream, node, {
  3727. mode: (mode & 4095) | (node.mode & ~4095),
  3728. ctime: Date.now(),
  3729. dontFollow
  3730. });
  3731. },
  3732. chmod(path, mode, dontFollow) {
  3733. var node;
  3734. if (typeof path == "string") {
  3735. var lookup = FS.lookupPath(path, {
  3736. follow: !dontFollow
  3737. });
  3738. node = lookup.node;
  3739. } else {
  3740. node = path;
  3741. }
  3742. FS.doChmod(null, node, mode, dontFollow);
  3743. },
  3744. lchmod(path, mode) {
  3745. FS.chmod(path, mode, true);
  3746. },
  3747. fchmod(fd, mode) {
  3748. var stream = FS.getStreamChecked(fd);
  3749. FS.doChmod(stream, stream.node, mode, false);
  3750. },
  3751. doChown(stream, node, dontFollow) {
  3752. FS.doSetAttr(stream, node, {
  3753. timestamp: Date.now(),
  3754. dontFollow
  3755. });
  3756. },
  3757. chown(path, uid, gid, dontFollow) {
  3758. var node;
  3759. if (typeof path == "string") {
  3760. var lookup = FS.lookupPath(path, {
  3761. follow: !dontFollow
  3762. });
  3763. node = lookup.node;
  3764. } else {
  3765. node = path;
  3766. }
  3767. FS.doChown(null, node, dontFollow);
  3768. },
  3769. lchown(path, uid, gid) {
  3770. FS.chown(path, uid, gid, true);
  3771. },
  3772. fchown(fd, uid, gid) {
  3773. var stream = FS.getStreamChecked(fd);
  3774. FS.doChown(stream, stream.node, false);
  3775. },
  3776. doTruncate(stream, node, len) {
  3777. if (FS.isDir(node.mode)) {
  3778. throw new FS.ErrnoError(31);
  3779. }
  3780. if (!FS.isFile(node.mode)) {
  3781. throw new FS.ErrnoError(28);
  3782. }
  3783. var errCode = FS.nodePermissions(node, "w");
  3784. if (errCode) {
  3785. throw new FS.ErrnoError(errCode);
  3786. }
  3787. FS.doSetAttr(stream, node, {
  3788. size: len,
  3789. timestamp: Date.now()
  3790. });
  3791. },
  3792. truncate(path, len) {
  3793. if (len < 0) {
  3794. throw new FS.ErrnoError(28);
  3795. }
  3796. var node;
  3797. if (typeof path == "string") {
  3798. var lookup = FS.lookupPath(path, {
  3799. follow: true
  3800. });
  3801. node = lookup.node;
  3802. } else {
  3803. node = path;
  3804. }
  3805. FS.doTruncate(null, node, len);
  3806. },
  3807. ftruncate(fd, len) {
  3808. var stream = FS.getStreamChecked(fd);
  3809. if (len < 0 || (stream.flags & 2097155) === 0) {
  3810. throw new FS.ErrnoError(28);
  3811. }
  3812. FS.doTruncate(stream, stream.node, len);
  3813. },
  3814. utime(path, atime, mtime) {
  3815. var lookup = FS.lookupPath(path, {
  3816. follow: true
  3817. });
  3818. var node = lookup.node;
  3819. var setattr = FS.checkOpExists(node.node_ops.setattr, 63);
  3820. setattr(node, {
  3821. atime,
  3822. mtime
  3823. });
  3824. },
  3825. open(path, flags, mode = 438) {
  3826. if (path === "") {
  3827. throw new FS.ErrnoError(44);
  3828. }
  3829. flags = FS_modeStringToFlags(flags);
  3830. if ((flags & 64)) {
  3831. mode = (mode & 4095) | 32768;
  3832. } else {
  3833. mode = 0;
  3834. }
  3835. var node;
  3836. var isDirPath;
  3837. if (typeof path == "object") {
  3838. node = path;
  3839. } else {
  3840. isDirPath = path.endsWith("/");
  3841. // noent_okay makes it so that if the final component of the path
  3842. // doesn't exist, lookupPath returns `node: undefined`. `path` will be
  3843. // updated to point to the target of all symlinks.
  3844. var lookup = FS.lookupPath(path, {
  3845. follow: !(flags & 131072),
  3846. noent_okay: true
  3847. });
  3848. node = lookup.node;
  3849. path = lookup.path;
  3850. }
  3851. // perhaps we need to create the node
  3852. var created = false;
  3853. if ((flags & 64)) {
  3854. if (node) {
  3855. // if O_CREAT and O_EXCL are set, error out if the node already exists
  3856. if ((flags & 128)) {
  3857. throw new FS.ErrnoError(20);
  3858. }
  3859. } else if (isDirPath) {
  3860. throw new FS.ErrnoError(31);
  3861. } else {
  3862. // node doesn't exist, try to create it
  3863. // Ignore the permission bits here to ensure we can `open` this new
  3864. // file below. We use chmod below to apply the permissions once the
  3865. // file is open.
  3866. node = FS.mknod(path, mode | 511, 0);
  3867. created = true;
  3868. }
  3869. }
  3870. if (!node) {
  3871. throw new FS.ErrnoError(44);
  3872. }
  3873. // can't truncate a device
  3874. if (FS.isChrdev(node.mode)) {
  3875. flags &= ~512;
  3876. }
  3877. // if asked only for a directory, then this must be one
  3878. if ((flags & 65536) && !FS.isDir(node.mode)) {
  3879. throw new FS.ErrnoError(54);
  3880. }
  3881. // check permissions, if this is not a file we just created now (it is ok to
  3882. // create and write to a file with read-only permissions; it is read-only
  3883. // for later use)
  3884. if (!created) {
  3885. var errCode = FS.mayOpen(node, flags);
  3886. if (errCode) {
  3887. throw new FS.ErrnoError(errCode);
  3888. }
  3889. }
  3890. // do truncation if necessary
  3891. if ((flags & 512) && !created) {
  3892. FS.truncate(node, 0);
  3893. }
  3894. // we've already handled these, don't pass down to the underlying vfs
  3895. flags &= ~(128 | 512 | 131072);
  3896. // register the stream with the filesystem
  3897. var stream = FS.createStream({
  3898. node,
  3899. path: FS.getPath(node),
  3900. // we want the absolute path to the node
  3901. flags,
  3902. seekable: true,
  3903. position: 0,
  3904. stream_ops: node.stream_ops,
  3905. // used by the file family libc calls (fopen, fwrite, ferror, etc.)
  3906. ungotten: [],
  3907. error: false
  3908. });
  3909. // call the new stream's open function
  3910. if (stream.stream_ops.open) {
  3911. stream.stream_ops.open(stream);
  3912. }
  3913. if (created) {
  3914. FS.chmod(node, mode & 511);
  3915. }
  3916. return stream;
  3917. },
  3918. close(stream) {
  3919. if (FS.isClosed(stream)) {
  3920. throw new FS.ErrnoError(8);
  3921. }
  3922. if (stream.getdents) stream.getdents = null;
  3923. // free readdir state
  3924. try {
  3925. if (stream.stream_ops.close) {
  3926. stream.stream_ops.close(stream);
  3927. }
  3928. } catch (e) {
  3929. throw e;
  3930. } finally {
  3931. FS.closeStream(stream.fd);
  3932. }
  3933. stream.fd = null;
  3934. },
  3935. isClosed(stream) {
  3936. return stream.fd === null;
  3937. },
  3938. llseek(stream, offset, whence) {
  3939. if (FS.isClosed(stream)) {
  3940. throw new FS.ErrnoError(8);
  3941. }
  3942. if (!stream.seekable || !stream.stream_ops.llseek) {
  3943. throw new FS.ErrnoError(70);
  3944. }
  3945. if (whence != 0 && whence != 1 && whence != 2) {
  3946. throw new FS.ErrnoError(28);
  3947. }
  3948. stream.position = stream.stream_ops.llseek(stream, offset, whence);
  3949. stream.ungotten = [];
  3950. return stream.position;
  3951. },
  3952. read(stream, buffer, offset, length, position) {
  3953. assert(offset >= 0);
  3954. if (length < 0 || position < 0) {
  3955. throw new FS.ErrnoError(28);
  3956. }
  3957. if (FS.isClosed(stream)) {
  3958. throw new FS.ErrnoError(8);
  3959. }
  3960. if ((stream.flags & 2097155) === 1) {
  3961. throw new FS.ErrnoError(8);
  3962. }
  3963. if (FS.isDir(stream.node.mode)) {
  3964. throw new FS.ErrnoError(31);
  3965. }
  3966. if (!stream.stream_ops.read) {
  3967. throw new FS.ErrnoError(28);
  3968. }
  3969. var seeking = typeof position != "undefined";
  3970. if (!seeking) {
  3971. position = stream.position;
  3972. } else if (!stream.seekable) {
  3973. throw new FS.ErrnoError(70);
  3974. }
  3975. var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
  3976. if (!seeking) stream.position += bytesRead;
  3977. return bytesRead;
  3978. },
  3979. write(stream, buffer, offset, length, position, canOwn) {
  3980. assert(offset >= 0);
  3981. assert(buffer.subarray, "FS.write expects a TypedArray");
  3982. if (length < 0 || position < 0) {
  3983. throw new FS.ErrnoError(28);
  3984. }
  3985. if (FS.isClosed(stream)) {
  3986. throw new FS.ErrnoError(8);
  3987. }
  3988. if ((stream.flags & 2097155) === 0) {
  3989. throw new FS.ErrnoError(8);
  3990. }
  3991. if (FS.isDir(stream.node.mode)) {
  3992. throw new FS.ErrnoError(31);
  3993. }
  3994. if (!stream.stream_ops.write) {
  3995. throw new FS.ErrnoError(28);
  3996. }
  3997. if (stream.seekable && stream.flags & 1024) {
  3998. // seek to the end before writing in append mode
  3999. FS.llseek(stream, 0, 2);
  4000. }
  4001. var seeking = typeof position != "undefined";
  4002. if (!seeking) {
  4003. position = stream.position;
  4004. } else if (!stream.seekable) {
  4005. throw new FS.ErrnoError(70);
  4006. }
  4007. var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
  4008. if (!seeking) stream.position += bytesWritten;
  4009. return bytesWritten;
  4010. },
  4011. mmap(stream, length, position, prot, flags) {
  4012. // User requests writing to file (prot & PROT_WRITE != 0).
  4013. // Checking if we have permissions to write to the file unless
  4014. // MAP_PRIVATE flag is set. According to POSIX spec it is possible
  4015. // to write to file opened in read-only mode with MAP_PRIVATE flag,
  4016. // as all modifications will be visible only in the memory of
  4017. // the current process.
  4018. if ((prot & 2) !== 0 && (flags & 2) === 0 && (stream.flags & 2097155) !== 2) {
  4019. throw new FS.ErrnoError(2);
  4020. }
  4021. if ((stream.flags & 2097155) === 1) {
  4022. throw new FS.ErrnoError(2);
  4023. }
  4024. if (!stream.stream_ops.mmap) {
  4025. throw new FS.ErrnoError(43);
  4026. }
  4027. if (!length) {
  4028. throw new FS.ErrnoError(28);
  4029. }
  4030. return stream.stream_ops.mmap(stream, length, position, prot, flags);
  4031. },
  4032. msync(stream, buffer, offset, length, mmapFlags) {
  4033. assert(offset >= 0);
  4034. if (!stream.stream_ops.msync) {
  4035. return 0;
  4036. }
  4037. return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags);
  4038. },
  4039. ioctl(stream, cmd, arg) {
  4040. if (!stream.stream_ops.ioctl) {
  4041. throw new FS.ErrnoError(59);
  4042. }
  4043. return stream.stream_ops.ioctl(stream, cmd, arg);
  4044. },
  4045. readFile(path, opts = {}) {
  4046. opts.flags = opts.flags ?? 0;
  4047. opts.encoding = opts.encoding ?? "binary";
  4048. if (opts.encoding !== "utf8" && opts.encoding !== "binary") {
  4049. abort(`Invalid encoding type "${opts.encoding}"`);
  4050. }
  4051. var stream = FS.open(path, opts.flags);
  4052. var stat = FS.stat(path);
  4053. var length = stat.size;
  4054. var buf = new Uint8Array(length);
  4055. FS.read(stream, buf, 0, length, 0);
  4056. if (opts.encoding === "utf8") {
  4057. buf = UTF8ArrayToString(buf);
  4058. }
  4059. FS.close(stream);
  4060. return buf;
  4061. },
  4062. writeFile(path, data, opts = {}) {
  4063. opts.flags = opts.flags ?? 577;
  4064. var stream = FS.open(path, opts.flags, opts.mode);
  4065. data = FS_fileDataToTypedArray(data);
  4066. FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
  4067. FS.close(stream);
  4068. },
  4069. cwd: () => FS.currentPath,
  4070. chdir(path) {
  4071. var lookup = FS.lookupPath(path, {
  4072. follow: true
  4073. });
  4074. if (lookup.node === null) {
  4075. throw new FS.ErrnoError(44);
  4076. }
  4077. if (!FS.isDir(lookup.node.mode)) {
  4078. throw new FS.ErrnoError(54);
  4079. }
  4080. var errCode = FS.nodePermissions(lookup.node, "x");
  4081. if (errCode) {
  4082. throw new FS.ErrnoError(errCode);
  4083. }
  4084. FS.currentPath = lookup.path;
  4085. },
  4086. createDefaultDirectories() {
  4087. FS.mkdir("/tmp");
  4088. FS.mkdir("/home");
  4089. FS.mkdir("/home/web_user");
  4090. },
  4091. createDefaultDevices() {
  4092. // create /dev
  4093. FS.mkdir("/dev");
  4094. // setup /dev/null
  4095. FS.registerDevice(FS.makedev(1, 3), {
  4096. read: () => 0,
  4097. write: (stream, buffer, offset, length, pos) => length,
  4098. llseek: () => 0
  4099. });
  4100. FS.mkdev("/dev/null", FS.makedev(1, 3));
  4101. // setup /dev/tty and /dev/tty1
  4102. // stderr needs to print output using err() rather than out()
  4103. // so we register a second tty just for it.
  4104. TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
  4105. TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
  4106. FS.mkdev("/dev/tty", FS.makedev(5, 0));
  4107. FS.mkdev("/dev/tty1", FS.makedev(6, 0));
  4108. // setup /dev/[u]random
  4109. // use a buffer to avoid overhead of individual crypto calls per byte
  4110. var randomBuffer = new Uint8Array(1024), randomLeft = 0;
  4111. var randomByte = () => {
  4112. if (randomLeft === 0) {
  4113. randomFill(randomBuffer);
  4114. randomLeft = randomBuffer.byteLength;
  4115. }
  4116. return randomBuffer[--randomLeft];
  4117. };
  4118. FS.createDevice("/dev", "random", randomByte);
  4119. FS.createDevice("/dev", "urandom", randomByte);
  4120. // we're not going to emulate the actual shm device,
  4121. // just create the tmp dirs that reside in it commonly
  4122. FS.mkdir("/dev/shm");
  4123. FS.mkdir("/dev/shm/tmp");
  4124. },
  4125. createSpecialDirectories() {
  4126. // create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the
  4127. // name of the stream for fd 6 (see test_unistd_ttyname)
  4128. FS.mkdir("/proc");
  4129. var proc_self = FS.mkdir("/proc/self");
  4130. FS.mkdir("/proc/self/fd");
  4131. FS.mount({
  4132. mount() {
  4133. var node = FS.createNode(proc_self, "fd", 16895, 73);
  4134. node.stream_ops = {
  4135. llseek: MEMFS.stream_ops.llseek
  4136. };
  4137. node.node_ops = {
  4138. lookup(parent, name) {
  4139. var fd = +name;
  4140. var stream = FS.getStreamChecked(fd);
  4141. var ret = {
  4142. parent: null,
  4143. mount: {
  4144. mountpoint: "fake"
  4145. },
  4146. node_ops: {
  4147. readlink: () => stream.path
  4148. },
  4149. id: fd + 1
  4150. };
  4151. ret.parent = ret;
  4152. // make it look like a simple root node
  4153. return ret;
  4154. },
  4155. readdir() {
  4156. return Array.from(FS.streams.entries()).filter(([k, v]) => v).map(([k, v]) => k.toString());
  4157. }
  4158. };
  4159. return node;
  4160. }
  4161. }, {}, "/proc/self/fd");
  4162. },
  4163. createStandardStreams(input, output, error) {
  4164. // TODO deprecate the old functionality of a single
  4165. // input / output callback and that utilizes FS.createDevice
  4166. // and instead require a unique set of stream ops
  4167. // by default, we symlink the standard streams to the
  4168. // default tty devices. however, if the standard streams
  4169. // have been overwritten we create a unique device for
  4170. // them instead.
  4171. if (input) {
  4172. FS.createDevice("/dev", "stdin", input);
  4173. } else {
  4174. FS.symlink("/dev/tty", "/dev/stdin");
  4175. }
  4176. if (output) {
  4177. FS.createDevice("/dev", "stdout", null, output);
  4178. } else {
  4179. FS.symlink("/dev/tty", "/dev/stdout");
  4180. }
  4181. if (error) {
  4182. FS.createDevice("/dev", "stderr", null, error);
  4183. } else {
  4184. FS.symlink("/dev/tty1", "/dev/stderr");
  4185. }
  4186. // open default streams for the stdin, stdout and stderr devices
  4187. var stdin = FS.open("/dev/stdin", 0);
  4188. var stdout = FS.open("/dev/stdout", 1);
  4189. var stderr = FS.open("/dev/stderr", 1);
  4190. assert(stdin.fd === 0, `invalid handle for stdin (${stdin.fd})`);
  4191. assert(stdout.fd === 1, `invalid handle for stdout (${stdout.fd})`);
  4192. assert(stderr.fd === 2, `invalid handle for stderr (${stderr.fd})`);
  4193. },
  4194. staticInit() {
  4195. FS.nameTable = new Array(4096);
  4196. FS.mount(MEMFS, {}, "/");
  4197. FS.createDefaultDirectories();
  4198. FS.createDefaultDevices();
  4199. FS.createSpecialDirectories();
  4200. FS.filesystems = {
  4201. "MEMFS": MEMFS,
  4202. "IDBFS": IDBFS
  4203. };
  4204. },
  4205. init(input, output, error) {
  4206. assert(!FS.initialized, "FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)");
  4207. FS.initialized = true;
  4208. // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
  4209. input ??= Module["stdin"];
  4210. output ??= Module["stdout"];
  4211. error ??= Module["stderr"];
  4212. FS.createStandardStreams(input, output, error);
  4213. },
  4214. quit() {
  4215. FS.initialized = false;
  4216. // force-flush all streams, so we get musl std streams printed out
  4217. _fflush(0);
  4218. // close all of our streams
  4219. for (var stream of FS.streams) {
  4220. if (stream) {
  4221. FS.close(stream);
  4222. }
  4223. }
  4224. },
  4225. findObject(path, dontResolveLastLink) {
  4226. var ret = FS.analyzePath(path, dontResolveLastLink);
  4227. if (!ret.exists) {
  4228. return null;
  4229. }
  4230. return ret.object;
  4231. },
  4232. analyzePath(path, dontResolveLastLink) {
  4233. // operate from within the context of the symlink's target
  4234. try {
  4235. var lookup = FS.lookupPath(path, {
  4236. follow: !dontResolveLastLink
  4237. });
  4238. path = lookup.path;
  4239. } catch (e) {}
  4240. var ret = {
  4241. isRoot: false,
  4242. exists: false,
  4243. error: 0,
  4244. name: null,
  4245. path: null,
  4246. object: null,
  4247. parentExists: false,
  4248. parentPath: null,
  4249. parentObject: null
  4250. };
  4251. try {
  4252. var lookup = FS.lookupPath(path, {
  4253. parent: true
  4254. });
  4255. ret.parentExists = true;
  4256. ret.parentPath = lookup.path;
  4257. ret.parentObject = lookup.node;
  4258. ret.name = PATH.basename(path);
  4259. lookup = FS.lookupPath(path, {
  4260. follow: !dontResolveLastLink
  4261. });
  4262. ret.exists = true;
  4263. ret.path = lookup.path;
  4264. ret.object = lookup.node;
  4265. ret.name = lookup.node.name;
  4266. ret.isRoot = lookup.path === "/";
  4267. } catch (e) {
  4268. ret.error = e.errno;
  4269. }
  4270. return ret;
  4271. },
  4272. createPath(parent, path, canRead, canWrite) {
  4273. parent = typeof parent == "string" ? parent : FS.getPath(parent);
  4274. var parts = path.split("/").reverse();
  4275. while (parts.length) {
  4276. var part = parts.pop();
  4277. if (!part) continue;
  4278. var current = PATH.join2(parent, part);
  4279. try {
  4280. FS.mkdir(current);
  4281. } catch (e) {
  4282. if (e.errno != 20) throw e;
  4283. }
  4284. parent = current;
  4285. }
  4286. return current;
  4287. },
  4288. createFile(parent, name, properties, canRead, canWrite) {
  4289. var path = PATH.join2(typeof parent == "string" ? parent : FS.getPath(parent), name);
  4290. var mode = FS_getMode(canRead, canWrite);
  4291. return FS.create(path, mode);
  4292. },
  4293. createDataFile(parent, name, data, canRead, canWrite, canOwn) {
  4294. var path = name;
  4295. if (parent) {
  4296. parent = typeof parent == "string" ? parent : FS.getPath(parent);
  4297. path = name ? PATH.join2(parent, name) : parent;
  4298. }
  4299. var mode = FS_getMode(canRead, canWrite);
  4300. var node = FS.create(path, mode);
  4301. if (data) {
  4302. data = FS_fileDataToTypedArray(data);
  4303. // make sure we can write to the file
  4304. FS.chmod(node, mode | 146);
  4305. var stream = FS.open(node, 577);
  4306. FS.write(stream, data, 0, data.length, 0, canOwn);
  4307. FS.close(stream);
  4308. FS.chmod(node, mode);
  4309. }
  4310. },
  4311. createDevice(parent, name, input, output) {
  4312. var path = PATH.join2(typeof parent == "string" ? parent : FS.getPath(parent), name);
  4313. var mode = FS_getMode(!!input, !!output);
  4314. FS.createDevice.major ??= 64;
  4315. var dev = FS.makedev(FS.createDevice.major++, 0);
  4316. // Create a fake device that a set of stream ops to emulate
  4317. // the old behavior.
  4318. FS.registerDevice(dev, {
  4319. open(stream) {
  4320. stream.seekable = false;
  4321. },
  4322. close(stream) {
  4323. // flush any pending line data
  4324. if (output?.buffer?.length) {
  4325. output(10);
  4326. }
  4327. },
  4328. read(stream, buffer, offset, length, pos) {
  4329. var bytesRead = 0;
  4330. for (var i = 0; i < length; i++) {
  4331. var result;
  4332. try {
  4333. result = input();
  4334. } catch (e) {
  4335. throw new FS.ErrnoError(29);
  4336. }
  4337. if (result === undefined && bytesRead === 0) {
  4338. throw new FS.ErrnoError(6);
  4339. }
  4340. if (result === null || result === undefined) break;
  4341. bytesRead++;
  4342. buffer[offset + i] = result;
  4343. }
  4344. if (bytesRead) {
  4345. stream.node.atime = Date.now();
  4346. }
  4347. return bytesRead;
  4348. },
  4349. write(stream, buffer, offset, length, pos) {
  4350. for (var i = 0; i < length; i++) {
  4351. try {
  4352. output(buffer[offset + i]);
  4353. } catch (e) {
  4354. throw new FS.ErrnoError(29);
  4355. }
  4356. }
  4357. if (length) {
  4358. stream.node.mtime = stream.node.ctime = Date.now();
  4359. }
  4360. return i;
  4361. }
  4362. });
  4363. return FS.mkdev(path, mode, dev);
  4364. },
  4365. forceLoadFile(obj) {
  4366. if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
  4367. if (globalThis.XMLHttpRequest) {
  4368. abort("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
  4369. } else {
  4370. // Command-line.
  4371. try {
  4372. obj.contents = readBinary(obj.url);
  4373. } catch (e) {
  4374. throw new FS.ErrnoError(29);
  4375. }
  4376. }
  4377. },
  4378. createLazyFile(parent, name, url, canRead, canWrite) {
  4379. // Lazy chunked Uint8Array (implements get and length from Uint8Array).
  4380. // Actual getting is abstracted away for eventual reuse.
  4381. class LazyUint8Array {
  4382. lengthKnown=false;
  4383. chunks=[];
  4384. // Loaded chunks. Index is the chunk number
  4385. get(idx) {
  4386. if (idx > this.length - 1 || idx < 0) {
  4387. return undefined;
  4388. }
  4389. var chunkOffset = idx % this.chunkSize;
  4390. var chunkNum = (idx / this.chunkSize) | 0;
  4391. return this.getter(chunkNum)[chunkOffset];
  4392. }
  4393. setDataGetter(getter) {
  4394. this.getter = getter;
  4395. }
  4396. cacheLength() {
  4397. // Find length
  4398. var xhr = new XMLHttpRequest;
  4399. xhr.open("HEAD", url, false);
  4400. xhr.send(null);
  4401. if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort("Couldn't load " + url + ". Status: " + xhr.status);
  4402. var datalength = Number(xhr.getResponseHeader("Content-length"));
  4403. var header;
  4404. var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
  4405. var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";
  4406. var chunkSize = 1024 * 1024;
  4407. // Chunk size in bytes
  4408. if (!hasByteServing) chunkSize = datalength;
  4409. // Function to get a range from the remote URL.
  4410. var doXHR = (from, to) => {
  4411. if (from > to) abort(`invalid range (${from}, ${to}) or no bytes requested!`);
  4412. if (to > datalength - 1) abort(`only ${datalength} bytes available! programmer error!`);
  4413. // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
  4414. var xhr = new XMLHttpRequest;
  4415. xhr.open("GET", url, false);
  4416. if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
  4417. // Some hints to the browser that we want binary data.
  4418. xhr.responseType = "arraybuffer";
  4419. if (xhr.overrideMimeType) {
  4420. xhr.overrideMimeType("text/plain; charset=x-user-defined");
  4421. }
  4422. xhr.send(null);
  4423. if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort("Couldn't load " + url + ". Status: " + xhr.status);
  4424. if (xhr.response !== undefined) {
  4425. return new Uint8Array(/** @type{Array<number>} */ (xhr.response || []));
  4426. }
  4427. return intArrayFromString(xhr.responseText ?? "", true);
  4428. };
  4429. var lazyArray = this;
  4430. lazyArray.setDataGetter(chunkNum => {
  4431. var start = chunkNum * chunkSize;
  4432. var end = (chunkNum + 1) * chunkSize - 1;
  4433. // including this byte
  4434. end = Math.min(end, datalength - 1);
  4435. // if datalength-1 is selected, this is the last block
  4436. if (typeof lazyArray.chunks[chunkNum] == "undefined") {
  4437. lazyArray.chunks[chunkNum] = doXHR(start, end);
  4438. }
  4439. if (typeof lazyArray.chunks[chunkNum] == "undefined") abort("doXHR failed!");
  4440. return lazyArray.chunks[chunkNum];
  4441. });
  4442. if (usesGzip || !datalength) {
  4443. // if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length
  4444. chunkSize = datalength = 1;
  4445. // this will force getter(0)/doXHR do download the whole file
  4446. datalength = this.getter(0).length;
  4447. chunkSize = datalength;
  4448. out("LazyFiles on gzip forces download of the whole file when length is accessed");
  4449. }
  4450. this._length = datalength;
  4451. this._chunkSize = chunkSize;
  4452. this.lengthKnown = true;
  4453. }
  4454. get length() {
  4455. if (!this.lengthKnown) {
  4456. this.cacheLength();
  4457. }
  4458. return this._length;
  4459. }
  4460. get chunkSize() {
  4461. if (!this.lengthKnown) {
  4462. this.cacheLength();
  4463. }
  4464. return this._chunkSize;
  4465. }
  4466. }
  4467. if (globalThis.XMLHttpRequest) {
  4468. if (!ENVIRONMENT_IS_WORKER) abort("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc");
  4469. var lazyArray = new LazyUint8Array;
  4470. var properties = {
  4471. isDevice: false,
  4472. contents: lazyArray
  4473. };
  4474. } else {
  4475. var properties = {
  4476. isDevice: false,
  4477. url
  4478. };
  4479. }
  4480. var node = FS.createFile(parent, name, properties, canRead, canWrite);
  4481. // This is a total hack, but I want to get this lazy file code out of the
  4482. // core of MEMFS. If we want to keep this lazy file concept I feel it should
  4483. // be its own thin LAZYFS proxying calls to MEMFS.
  4484. if (properties.contents) {
  4485. node.contents = properties.contents;
  4486. } else if (properties.url) {
  4487. node.contents = null;
  4488. node.url = properties.url;
  4489. }
  4490. // Add a function that defers querying the file size until it is asked the first time.
  4491. Object.defineProperties(node, {
  4492. usedBytes: {
  4493. get: function() {
  4494. return this.contents.length;
  4495. }
  4496. }
  4497. });
  4498. // override each stream op with one that tries to force load the lazy file first
  4499. var stream_ops = {};
  4500. for (const [key, fn] of Object.entries(node.stream_ops)) {
  4501. stream_ops[key] = (...args) => {
  4502. FS.forceLoadFile(node);
  4503. return fn(...args);
  4504. };
  4505. }
  4506. function writeChunks(stream, buffer, offset, length, position) {
  4507. var contents = stream.node.contents;
  4508. if (position >= contents.length) return 0;
  4509. var size = Math.min(contents.length - position, length);
  4510. assert(size >= 0);
  4511. if (contents.slice) {
  4512. // normal array
  4513. for (var i = 0; i < size; i++) {
  4514. buffer[offset + i] = contents[position + i];
  4515. }
  4516. } else {
  4517. for (var i = 0; i < size; i++) {
  4518. // LazyUint8Array from sync binary XHR
  4519. buffer[offset + i] = contents.get(position + i);
  4520. }
  4521. }
  4522. return size;
  4523. }
  4524. // use a custom read function
  4525. stream_ops.read = (stream, buffer, offset, length, position) => {
  4526. FS.forceLoadFile(node);
  4527. return writeChunks(stream, buffer, offset, length, position);
  4528. };
  4529. // use a custom mmap function
  4530. stream_ops.mmap = (stream, length, position, prot, flags) => {
  4531. FS.forceLoadFile(node);
  4532. var ptr = mmapAlloc(length);
  4533. if (!ptr) {
  4534. throw new FS.ErrnoError(48);
  4535. }
  4536. writeChunks(stream, (growMemViews(), HEAP8), ptr, length, position);
  4537. return {
  4538. ptr,
  4539. allocated: true
  4540. };
  4541. };
  4542. node.stream_ops = stream_ops;
  4543. return node;
  4544. }
  4545. };
  4546. var SYSCALLS = {
  4547. currentUmask: 18,
  4548. calculateAt(dirfd, path, allowEmpty) {
  4549. if (PATH.isAbs(path)) {
  4550. return path;
  4551. }
  4552. // relative path
  4553. var dir;
  4554. if (dirfd === -100) {
  4555. dir = FS.cwd();
  4556. } else {
  4557. var dirstream = SYSCALLS.getStreamFromFD(dirfd);
  4558. dir = dirstream.path;
  4559. }
  4560. if (path.length == 0) {
  4561. if (!allowEmpty) {
  4562. throw new FS.ErrnoError(44);
  4563. }
  4564. return dir;
  4565. }
  4566. return dir + "/" + path;
  4567. },
  4568. writeStat(buf, stat) {
  4569. (growMemViews(), HEAPU32)[((buf) >> 2)] = stat.dev;
  4570. (growMemViews(), HEAPU32)[(((buf) + (4)) >> 2)] = stat.mode;
  4571. (growMemViews(), HEAPU32)[(((buf) + (8)) >> 2)] = stat.nlink;
  4572. (growMemViews(), HEAPU32)[(((buf) + (12)) >> 2)] = stat.uid;
  4573. (growMemViews(), HEAPU32)[(((buf) + (16)) >> 2)] = stat.gid;
  4574. (growMemViews(), HEAPU32)[(((buf) + (20)) >> 2)] = stat.rdev;
  4575. (growMemViews(), HEAP64)[(((buf) + (24)) >> 3)] = BigInt(stat.size);
  4576. (growMemViews(), HEAP32)[(((buf) + (32)) >> 2)] = 4096;
  4577. (growMemViews(), HEAP32)[(((buf) + (36)) >> 2)] = stat.blocks;
  4578. var atime = stat.atime.getTime();
  4579. var mtime = stat.mtime.getTime();
  4580. var ctime = stat.ctime.getTime();
  4581. (growMemViews(), HEAP64)[(((buf) + (40)) >> 3)] = BigInt(Math.floor(atime / 1e3));
  4582. (growMemViews(), HEAPU32)[(((buf) + (48)) >> 2)] = (atime % 1e3) * 1e3 * 1e3;
  4583. (growMemViews(), HEAP64)[(((buf) + (56)) >> 3)] = BigInt(Math.floor(mtime / 1e3));
  4584. (growMemViews(), HEAPU32)[(((buf) + (64)) >> 2)] = (mtime % 1e3) * 1e3 * 1e3;
  4585. (growMemViews(), HEAP64)[(((buf) + (72)) >> 3)] = BigInt(Math.floor(ctime / 1e3));
  4586. (growMemViews(), HEAPU32)[(((buf) + (80)) >> 2)] = (ctime % 1e3) * 1e3 * 1e3;
  4587. (growMemViews(), HEAP64)[(((buf) + (88)) >> 3)] = BigInt(stat.ino);
  4588. return 0;
  4589. },
  4590. writeStatFs(buf, stats) {
  4591. (growMemViews(), HEAPU32)[(((buf) + (4)) >> 2)] = stats.bsize;
  4592. (growMemViews(), HEAPU32)[(((buf) + (60)) >> 2)] = stats.bsize;
  4593. (growMemViews(), HEAP64)[(((buf) + (8)) >> 3)] = BigInt(stats.blocks);
  4594. (growMemViews(), HEAP64)[(((buf) + (16)) >> 3)] = BigInt(stats.bfree);
  4595. (growMemViews(), HEAP64)[(((buf) + (24)) >> 3)] = BigInt(stats.bavail);
  4596. (growMemViews(), HEAP64)[(((buf) + (32)) >> 3)] = BigInt(stats.files);
  4597. (growMemViews(), HEAP64)[(((buf) + (40)) >> 3)] = BigInt(stats.ffree);
  4598. (growMemViews(), HEAPU32)[(((buf) + (48)) >> 2)] = stats.fsid;
  4599. (growMemViews(), HEAPU32)[(((buf) + (64)) >> 2)] = stats.flags;
  4600. // ST_NOSUID
  4601. (growMemViews(), HEAPU32)[(((buf) + (56)) >> 2)] = stats.namelen;
  4602. },
  4603. doMsync(addr, stream, len, flags, offset) {
  4604. if (!FS.isFile(stream.node.mode)) {
  4605. throw new FS.ErrnoError(43);
  4606. }
  4607. if (flags & 2) {
  4608. // MAP_PRIVATE calls need not to be synced back to underlying fs
  4609. return 0;
  4610. }
  4611. var buffer = (growMemViews(), HEAPU8).subarray(addr, addr + len);
  4612. FS.msync(stream, buffer, offset, len, flags);
  4613. },
  4614. getStreamFromFD(fd) {
  4615. var stream = FS.getStreamChecked(fd);
  4616. return stream;
  4617. },
  4618. varargs: undefined,
  4619. getStr(ptr) {
  4620. var ret = UTF8ToString(ptr);
  4621. return ret;
  4622. }
  4623. };
  4624. function ___syscall_chdir(path) {
  4625. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(3, 0, 1, path);
  4626. try {
  4627. path = SYSCALLS.getStr(path);
  4628. FS.chdir(path);
  4629. return 0;
  4630. } catch (e) {
  4631. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  4632. return -e.errno;
  4633. }
  4634. }
  4635. var syscallGetVarargI = () => {
  4636. assert(SYSCALLS.varargs != undefined);
  4637. // the `+` prepended here is necessary to convince the JSCompiler that varargs is indeed a number.
  4638. var ret = (growMemViews(), HEAP32)[((+SYSCALLS.varargs) >> 2)];
  4639. SYSCALLS.varargs += 4;
  4640. return ret;
  4641. };
  4642. var syscallGetVarargP = syscallGetVarargI;
  4643. function ___syscall_fcntl64(fd, cmd, varargs) {
  4644. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(4, 0, 1, fd, cmd, varargs);
  4645. SYSCALLS.varargs = varargs;
  4646. try {
  4647. var stream = SYSCALLS.getStreamFromFD(fd);
  4648. switch (cmd) {
  4649. case 0:
  4650. {
  4651. var arg = syscallGetVarargI();
  4652. if (arg < 0) {
  4653. return -28;
  4654. }
  4655. while (FS.streams[arg]) {
  4656. arg++;
  4657. }
  4658. var newStream;
  4659. newStream = FS.dupStream(stream, arg);
  4660. return newStream.fd;
  4661. }
  4662. case 1:
  4663. case 2:
  4664. return 0;
  4665. // FD_CLOEXEC makes no sense for a single process.
  4666. case 3:
  4667. return stream.flags;
  4668. case 4:
  4669. {
  4670. var arg = syscallGetVarargI();
  4671. var mask = 289792;
  4672. stream.flags = (stream.flags & ~mask) | (arg & mask);
  4673. return 0;
  4674. }
  4675. case 12:
  4676. {
  4677. var arg = syscallGetVarargP();
  4678. var offset = 0;
  4679. // We're always unlocked.
  4680. (growMemViews(), HEAP16)[(((arg) + (offset)) >> 1)] = 2;
  4681. return 0;
  4682. }
  4683. case 13:
  4684. case 14:
  4685. // Pretend that the locking is successful. These are process-level locks,
  4686. // and Emscripten programs are a single process. If we supported linking a
  4687. // filesystem between programs, we'd need to do more here.
  4688. // See https://github.com/emscripten-core/emscripten/issues/23697
  4689. return 0;
  4690. }
  4691. return -28;
  4692. } catch (e) {
  4693. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  4694. return -e.errno;
  4695. }
  4696. }
  4697. function ___syscall_fstat64(fd, buf) {
  4698. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(5, 0, 1, fd, buf);
  4699. try {
  4700. return SYSCALLS.writeStat(buf, FS.fstat(fd));
  4701. } catch (e) {
  4702. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  4703. return -e.errno;
  4704. }
  4705. }
  4706. var stringToUTF8 = (str, outPtr, maxBytesToWrite) => {
  4707. assert(typeof maxBytesToWrite == "number", "stringToUTF8 requires a third parameter that specifies the length of the output buffer");
  4708. return stringToUTF8Array(str, (growMemViews(), HEAPU8), outPtr, maxBytesToWrite);
  4709. };
  4710. function ___syscall_getcwd(buf, size) {
  4711. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(6, 0, 1, buf, size);
  4712. try {
  4713. if (size === 0) return -28;
  4714. var cwd = FS.cwd();
  4715. var cwdLengthInBytes = lengthBytesUTF8(cwd) + 1;
  4716. if (size < cwdLengthInBytes) return -68;
  4717. stringToUTF8(cwd, buf, size);
  4718. return cwdLengthInBytes;
  4719. } catch (e) {
  4720. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  4721. return -e.errno;
  4722. }
  4723. }
  4724. function ___syscall_ioctl(fd, op, varargs) {
  4725. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(7, 0, 1, fd, op, varargs);
  4726. SYSCALLS.varargs = varargs;
  4727. try {
  4728. var stream = SYSCALLS.getStreamFromFD(fd);
  4729. switch (op) {
  4730. case 21509:
  4731. {
  4732. if (!stream.tty) return -59;
  4733. return 0;
  4734. }
  4735. case 21505:
  4736. {
  4737. if (!stream.tty) return -59;
  4738. if (stream.tty.ops.ioctl_tcgets) {
  4739. var termios = stream.tty.ops.ioctl_tcgets(stream);
  4740. var argp = syscallGetVarargP();
  4741. (growMemViews(), HEAP32)[((argp) >> 2)] = termios.c_iflag || 0;
  4742. (growMemViews(), HEAP32)[(((argp) + (4)) >> 2)] = termios.c_oflag || 0;
  4743. (growMemViews(), HEAP32)[(((argp) + (8)) >> 2)] = termios.c_cflag || 0;
  4744. (growMemViews(), HEAP32)[(((argp) + (12)) >> 2)] = termios.c_lflag || 0;
  4745. for (var i = 0; i < 32; i++) {
  4746. (growMemViews(), HEAP8)[(argp + i) + (17)] = termios.c_cc[i] || 0;
  4747. }
  4748. return 0;
  4749. }
  4750. return 0;
  4751. }
  4752. case 21510:
  4753. case 21511:
  4754. case 21512:
  4755. {
  4756. if (!stream.tty) return -59;
  4757. return 0;
  4758. }
  4759. case 21506:
  4760. case 21507:
  4761. case 21508:
  4762. {
  4763. if (!stream.tty) return -59;
  4764. if (stream.tty.ops.ioctl_tcsets) {
  4765. var argp = syscallGetVarargP();
  4766. var c_iflag = (growMemViews(), HEAP32)[((argp) >> 2)];
  4767. var c_oflag = (growMemViews(), HEAP32)[(((argp) + (4)) >> 2)];
  4768. var c_cflag = (growMemViews(), HEAP32)[(((argp) + (8)) >> 2)];
  4769. var c_lflag = (growMemViews(), HEAP32)[(((argp) + (12)) >> 2)];
  4770. var c_cc = [];
  4771. for (var i = 0; i < 32; i++) {
  4772. c_cc.push((growMemViews(), HEAP8)[(argp + i) + (17)]);
  4773. }
  4774. return stream.tty.ops.ioctl_tcsets(stream.tty, op, {
  4775. c_iflag,
  4776. c_oflag,
  4777. c_cflag,
  4778. c_lflag,
  4779. c_cc
  4780. });
  4781. }
  4782. return 0;
  4783. }
  4784. case 21519:
  4785. {
  4786. if (!stream.tty) return -59;
  4787. var argp = syscallGetVarargP();
  4788. (growMemViews(), HEAP32)[((argp) >> 2)] = 0;
  4789. return 0;
  4790. }
  4791. case 21520:
  4792. {
  4793. if (!stream.tty) return -59;
  4794. return -28;
  4795. }
  4796. case 21537:
  4797. case 21531:
  4798. {
  4799. var argp = syscallGetVarargP();
  4800. return FS.ioctl(stream, op, argp);
  4801. }
  4802. case 21523:
  4803. {
  4804. // TODO: in theory we should write to the winsize struct that gets
  4805. // passed in, but for now musl doesn't read anything on it
  4806. if (!stream.tty) return -59;
  4807. if (stream.tty.ops.ioctl_tiocgwinsz) {
  4808. var winsize = stream.tty.ops.ioctl_tiocgwinsz(stream.tty);
  4809. var argp = syscallGetVarargP();
  4810. (growMemViews(), HEAP16)[((argp) >> 1)] = winsize[0];
  4811. (growMemViews(), HEAP16)[(((argp) + (2)) >> 1)] = winsize[1];
  4812. }
  4813. return 0;
  4814. }
  4815. case 21524:
  4816. {
  4817. // TODO: technically, this ioctl call should change the window size.
  4818. // but, since emscripten doesn't have any concept of a terminal window
  4819. // yet, we'll just silently throw it away as we do TIOCGWINSZ
  4820. if (!stream.tty) return -59;
  4821. return 0;
  4822. }
  4823. case 21515:
  4824. {
  4825. if (!stream.tty) return -59;
  4826. return 0;
  4827. }
  4828. default:
  4829. return -28;
  4830. }
  4831. } catch (e) {
  4832. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  4833. return -e.errno;
  4834. }
  4835. }
  4836. function ___syscall_lstat64(path, buf) {
  4837. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(8, 0, 1, path, buf);
  4838. try {
  4839. path = SYSCALLS.getStr(path);
  4840. return SYSCALLS.writeStat(buf, FS.lstat(path));
  4841. } catch (e) {
  4842. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  4843. return -e.errno;
  4844. }
  4845. }
  4846. function ___syscall_mkdirat(dirfd, path, mode) {
  4847. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(9, 0, 1, dirfd, path, mode);
  4848. try {
  4849. path = SYSCALLS.getStr(path);
  4850. path = SYSCALLS.calculateAt(dirfd, path);
  4851. mode &= ~SYSCALLS.currentUmask;
  4852. FS.mkdir(path, mode, 0);
  4853. return 0;
  4854. } catch (e) {
  4855. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  4856. return -e.errno;
  4857. }
  4858. }
  4859. function ___syscall_newfstatat(dirfd, path, buf, flags) {
  4860. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(10, 0, 1, dirfd, path, buf, flags);
  4861. try {
  4862. path = SYSCALLS.getStr(path);
  4863. var nofollow = flags & 256;
  4864. var allowEmpty = flags & 4096;
  4865. flags = flags & (~6400);
  4866. assert(!flags, `unknown flags in __syscall_newfstatat: ${flags}`);
  4867. path = SYSCALLS.calculateAt(dirfd, path, allowEmpty);
  4868. return SYSCALLS.writeStat(buf, nofollow ? FS.lstat(path) : FS.stat(path));
  4869. } catch (e) {
  4870. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  4871. return -e.errno;
  4872. }
  4873. }
  4874. function ___syscall_openat(dirfd, path, flags, varargs) {
  4875. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(11, 0, 1, dirfd, path, flags, varargs);
  4876. SYSCALLS.varargs = varargs;
  4877. try {
  4878. path = SYSCALLS.getStr(path);
  4879. path = SYSCALLS.calculateAt(dirfd, path);
  4880. var mode = varargs ? syscallGetVarargI() : 0;
  4881. if (flags & 64) {
  4882. mode &= ~SYSCALLS.currentUmask;
  4883. }
  4884. return FS.open(path, flags, mode).fd;
  4885. } catch (e) {
  4886. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  4887. return -e.errno;
  4888. }
  4889. }
  4890. var PIPEFS = {
  4891. BUCKET_BUFFER_SIZE: 8192,
  4892. mount(mount) {
  4893. // Do not pollute the real root directory or its child nodes with pipes
  4894. // Looks like it is OK to create another pseudo-root node not linked to the FS.root hierarchy this way
  4895. return FS.createNode(null, "/", 16384 | 511, 0);
  4896. },
  4897. createPipe() {
  4898. var pipe = {
  4899. buckets: [],
  4900. // refcnt 2 because pipe has a read end and a write end. We need to be
  4901. // able to read from the read end after write end is closed.
  4902. refcnt: 2,
  4903. timestamp: new Date,
  4904. readableHandlers: [],
  4905. registerReadableHandler: callback => {
  4906. callback.registerCleanupFunc(() => {
  4907. const i = pipe.readableHandlers.indexOf(callback);
  4908. if (i !== -1) pipe.readableHandlers.splice(i, 1);
  4909. });
  4910. pipe.readableHandlers.push(callback);
  4911. },
  4912. notifyReadableHandlers: () => {
  4913. while (pipe.readableHandlers.length > 0) {
  4914. const cb = pipe.readableHandlers.shift();
  4915. if (cb) cb(64 | 1);
  4916. }
  4917. pipe.readableHandlers = [];
  4918. }
  4919. };
  4920. pipe.buckets.push({
  4921. buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
  4922. offset: 0,
  4923. roffset: 0
  4924. });
  4925. var rName = PIPEFS.nextname();
  4926. var wName = PIPEFS.nextname();
  4927. var rNode = FS.createNode(PIPEFS.root, rName, 4096, 0);
  4928. var wNode = FS.createNode(PIPEFS.root, wName, 4096, 0);
  4929. rNode.pipe = pipe;
  4930. wNode.pipe = pipe;
  4931. var readableStream = FS.createStream({
  4932. path: rName,
  4933. node: rNode,
  4934. flags: 0,
  4935. seekable: false,
  4936. stream_ops: PIPEFS.stream_ops
  4937. });
  4938. rNode.stream = readableStream;
  4939. var writableStream = FS.createStream({
  4940. path: wName,
  4941. node: wNode,
  4942. flags: 1,
  4943. seekable: false,
  4944. stream_ops: PIPEFS.stream_ops
  4945. });
  4946. wNode.stream = writableStream;
  4947. return {
  4948. readable_fd: readableStream.fd,
  4949. writable_fd: writableStream.fd
  4950. };
  4951. },
  4952. stream_ops: {
  4953. getattr(stream) {
  4954. var node = stream.node;
  4955. var timestamp = node.pipe.timestamp;
  4956. return {
  4957. dev: 14,
  4958. ino: node.id,
  4959. mode: 4480,
  4960. nlink: 1,
  4961. uid: 0,
  4962. gid: 0,
  4963. rdev: 0,
  4964. size: 0,
  4965. atime: timestamp,
  4966. mtime: timestamp,
  4967. ctime: timestamp,
  4968. blksize: 4096,
  4969. blocks: 0
  4970. };
  4971. },
  4972. poll(stream, timeout, notifyCallback) {
  4973. var pipe = stream.node.pipe;
  4974. if ((stream.flags & 2097155) === 1) {
  4975. return (256 | 4);
  4976. }
  4977. for (var bucket of pipe.buckets) {
  4978. if (bucket.offset - bucket.roffset > 0) {
  4979. return (64 | 1);
  4980. }
  4981. }
  4982. if (notifyCallback) pipe.registerReadableHandler(notifyCallback);
  4983. return 0;
  4984. },
  4985. dup(stream) {
  4986. stream.node.pipe.refcnt++;
  4987. },
  4988. ioctl(stream, request, argp) {
  4989. if (request == 21531) {
  4990. var pipe = stream.node.pipe;
  4991. var currentLength = 0;
  4992. for (var bucket of pipe.buckets) {
  4993. currentLength += bucket.offset - bucket.roffset;
  4994. }
  4995. (growMemViews(), HEAP32)[((argp) >> 2)] = currentLength;
  4996. return 0;
  4997. }
  4998. return 28;
  4999. },
  5000. fsync(stream) {
  5001. return 28;
  5002. },
  5003. read(stream, buffer, offset, length, position) {
  5004. var pipe = stream.node.pipe;
  5005. var currentLength = 0;
  5006. for (var bucket of pipe.buckets) {
  5007. currentLength += bucket.offset - bucket.roffset;
  5008. }
  5009. assert(buffer instanceof ArrayBuffer || buffer instanceof SharedArrayBuffer || ArrayBuffer.isView(buffer));
  5010. var data = buffer.subarray(offset, offset + length);
  5011. if (length <= 0) {
  5012. return 0;
  5013. }
  5014. if (currentLength == 0) {
  5015. // Behave as if the read end is always non-blocking
  5016. throw new FS.ErrnoError(6);
  5017. }
  5018. var toRead = Math.min(currentLength, length);
  5019. var totalRead = toRead;
  5020. var toRemove = 0;
  5021. for (var bucket of pipe.buckets) {
  5022. var bucketSize = bucket.offset - bucket.roffset;
  5023. if (toRead <= bucketSize) {
  5024. var tmpSlice = bucket.buffer.subarray(bucket.roffset, bucket.offset);
  5025. if (toRead < bucketSize) {
  5026. tmpSlice = tmpSlice.subarray(0, toRead);
  5027. bucket.roffset += toRead;
  5028. } else {
  5029. toRemove++;
  5030. }
  5031. data.set(tmpSlice);
  5032. break;
  5033. } else {
  5034. var tmpSlice = bucket.buffer.subarray(bucket.roffset, bucket.offset);
  5035. data.set(tmpSlice);
  5036. data = data.subarray(tmpSlice.byteLength);
  5037. toRead -= tmpSlice.byteLength;
  5038. toRemove++;
  5039. }
  5040. }
  5041. if (toRemove && toRemove == pipe.buckets.length) {
  5042. // Do not generate excessive garbage in use cases such as
  5043. // write several bytes, read everything, write several bytes, read everything...
  5044. toRemove--;
  5045. pipe.buckets[toRemove].offset = 0;
  5046. pipe.buckets[toRemove].roffset = 0;
  5047. }
  5048. pipe.buckets.splice(0, toRemove);
  5049. return totalRead;
  5050. },
  5051. write(stream, buffer, offset, length, position) {
  5052. var pipe = stream.node.pipe;
  5053. assert(buffer instanceof ArrayBuffer || buffer instanceof SharedArrayBuffer || ArrayBuffer.isView(buffer));
  5054. var data = buffer.subarray(offset, offset + length);
  5055. var dataLen = data.byteLength;
  5056. if (dataLen <= 0) {
  5057. return 0;
  5058. }
  5059. var currBucket = null;
  5060. if (pipe.buckets.length == 0) {
  5061. currBucket = {
  5062. buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
  5063. offset: 0,
  5064. roffset: 0
  5065. };
  5066. pipe.buckets.push(currBucket);
  5067. } else {
  5068. currBucket = pipe.buckets[pipe.buckets.length - 1];
  5069. }
  5070. assert(currBucket.offset <= PIPEFS.BUCKET_BUFFER_SIZE);
  5071. var freeBytesInCurrBuffer = PIPEFS.BUCKET_BUFFER_SIZE - currBucket.offset;
  5072. if (freeBytesInCurrBuffer >= dataLen) {
  5073. currBucket.buffer.set(data, currBucket.offset);
  5074. currBucket.offset += dataLen;
  5075. pipe.notifyReadableHandlers();
  5076. return dataLen;
  5077. } else if (freeBytesInCurrBuffer > 0) {
  5078. currBucket.buffer.set(data.subarray(0, freeBytesInCurrBuffer), currBucket.offset);
  5079. currBucket.offset += freeBytesInCurrBuffer;
  5080. data = data.subarray(freeBytesInCurrBuffer, data.byteLength);
  5081. }
  5082. var numBuckets = (data.byteLength / PIPEFS.BUCKET_BUFFER_SIZE) | 0;
  5083. var remElements = data.byteLength % PIPEFS.BUCKET_BUFFER_SIZE;
  5084. for (var i = 0; i < numBuckets; i++) {
  5085. var newBucket = {
  5086. buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
  5087. offset: PIPEFS.BUCKET_BUFFER_SIZE,
  5088. roffset: 0
  5089. };
  5090. pipe.buckets.push(newBucket);
  5091. newBucket.buffer.set(data.subarray(0, PIPEFS.BUCKET_BUFFER_SIZE));
  5092. data = data.subarray(PIPEFS.BUCKET_BUFFER_SIZE, data.byteLength);
  5093. }
  5094. if (remElements > 0) {
  5095. var newBucket = {
  5096. buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
  5097. offset: data.byteLength,
  5098. roffset: 0
  5099. };
  5100. pipe.buckets.push(newBucket);
  5101. newBucket.buffer.set(data);
  5102. }
  5103. pipe.notifyReadableHandlers();
  5104. return dataLen;
  5105. },
  5106. close(stream) {
  5107. var pipe = stream.node.pipe;
  5108. pipe.refcnt--;
  5109. if (pipe.refcnt === 0) {
  5110. pipe.buckets = null;
  5111. }
  5112. }
  5113. },
  5114. nextname() {
  5115. if (!PIPEFS.nextname.current) {
  5116. PIPEFS.nextname.current = 0;
  5117. }
  5118. return "pipe[" + (PIPEFS.nextname.current++) + "]";
  5119. }
  5120. };
  5121. function ___syscall_pipe2(fdPtr, flags) {
  5122. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(12, 0, 1, fdPtr, flags);
  5123. try {
  5124. if (fdPtr == 0) {
  5125. throw new FS.ErrnoError(21);
  5126. }
  5127. var validFlags = 524288 | 2048;
  5128. if (flags & ~validFlags) {
  5129. throw new FS.ErrnoError(138);
  5130. }
  5131. var res = PIPEFS.createPipe();
  5132. if (flags & 2048) {
  5133. FS.getStream(res.readable_fd).flags |= 2048;
  5134. FS.getStream(res.writable_fd).flags |= 2048;
  5135. }
  5136. (growMemViews(), HEAP32)[((fdPtr) >> 2)] = res.readable_fd;
  5137. (growMemViews(), HEAP32)[(((fdPtr) + (4)) >> 2)] = res.writable_fd;
  5138. return 0;
  5139. } catch (e) {
  5140. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  5141. return -e.errno;
  5142. }
  5143. }
  5144. function ___syscall_stat64(path, buf) {
  5145. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(13, 0, 1, path, buf);
  5146. try {
  5147. path = SYSCALLS.getStr(path);
  5148. return SYSCALLS.writeStat(buf, FS.stat(path));
  5149. } catch (e) {
  5150. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  5151. return -e.errno;
  5152. }
  5153. }
  5154. var __abort_js = () => abort("native code called abort()");
  5155. var __emscripten_init_main_thread_js = tb => {
  5156. var can_block = !ENVIRONMENT_IS_WEB;
  5157. // Feature detect whether the main thread can block.
  5158. try {
  5159. Atomics.wait((growMemViews(), HEAP32), 0, 0, 0);
  5160. can_block = true;
  5161. } catch (e) {}
  5162. // Pass the thread address to the native code where they are stored in wasm
  5163. // globals which act as a form of TLS. Global constructors trying
  5164. // to access this value will read the wrong value, but that is UB anyway.
  5165. __emscripten_thread_init(tb, /*is_main=*/ !ENVIRONMENT_IS_WORKER, /*is_runtime=*/ 1, can_block, /*default_stacksize=*/ 65536, /*start_profiling=*/ false);
  5166. PThread.threadInitTLS();
  5167. };
  5168. var handleException = e => {
  5169. // Certain exception types we do not treat as errors since they are used for
  5170. // internal control flow.
  5171. // 1. ExitStatus, which is thrown by exit()
  5172. // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others
  5173. // that wish to return to JS event loop.
  5174. if (e instanceof ExitStatus || e == "unwind") {
  5175. return EXITSTATUS;
  5176. }
  5177. checkStackCookie();
  5178. if (e instanceof WebAssembly.RuntimeError) {
  5179. if (_emscripten_stack_get_current() <= 0) {
  5180. err("Stack overflow detected. You can try increasing -sSTACK_SIZE (currently set to 65536)");
  5181. }
  5182. }
  5183. quit_(1, e);
  5184. };
  5185. var maybeExit = () => {
  5186. if (!keepRuntimeAlive()) {
  5187. try {
  5188. if (ENVIRONMENT_IS_PTHREAD) {
  5189. // exit the current thread, but only if there is one active.
  5190. // TODO(https://github.com/emscripten-core/emscripten/issues/25076):
  5191. // Unify this check with the runtimeExited check above
  5192. if (_pthread_self()) __emscripten_thread_exit(EXITSTATUS);
  5193. return;
  5194. }
  5195. _exit(EXITSTATUS);
  5196. } catch (e) {
  5197. handleException(e);
  5198. }
  5199. }
  5200. };
  5201. var callUserCallback = func => {
  5202. if (ABORT) {
  5203. err("user callback triggered after runtime exited or application aborted. Ignoring.");
  5204. return;
  5205. }
  5206. try {
  5207. return func();
  5208. } catch (e) {
  5209. handleException(e);
  5210. } finally {
  5211. maybeExit();
  5212. }
  5213. };
  5214. var __emscripten_thread_mailbox_await = pthread_ptr => {
  5215. if (!waitAsyncPolyfilled) {
  5216. // Wait on the pthread's initial self-pointer field because it is easy and
  5217. // safe to access from sending threads that need to notify the waiting
  5218. // thread.
  5219. // Note: Under wasm64 only the low 32-bit of the pthread_ptr are
  5220. // read/compared here, but we don't actually care about the exact values
  5221. // here as long as they match.
  5222. var wait = Atomics.waitAsync((growMemViews(), HEAP32), ((pthread_ptr) >> 2), pthread_ptr);
  5223. assert(wait.async);
  5224. wait.value.then(checkMailbox);
  5225. var waitingAsync = pthread_ptr + 112;
  5226. Atomics.store((growMemViews(), HEAP32), ((waitingAsync) >> 2), 1);
  5227. }
  5228. };
  5229. var checkMailbox = () => {
  5230. // checkMailbox can be called after the pthread has shut down. See
  5231. // Pthread.terminateRuntime().
  5232. // In this case we return silently without re-registering using waitAsync.
  5233. // Perhaps there is a more universal way we can detect runtime has exited.
  5234. // TODO(https://github.com/emscripten-core/emscripten/issues/25076)
  5235. var pthread_ptr = _pthread_self();
  5236. if (!pthread_ptr) return;
  5237. callUserCallback(() => {
  5238. // If we are using Atomics.waitAsync as our notification mechanism, wait
  5239. // for a notification before processing the mailbox to avoid missing any
  5240. // work that could otherwise arrive after we've finished processing the
  5241. // mailbox and before we're ready for the next notification.
  5242. __emscripten_thread_mailbox_await(pthread_ptr);
  5243. __emscripten_check_mailbox();
  5244. });
  5245. };
  5246. var __emscripten_notify_mailbox_postmessage = (targetThread, currThreadId) => {
  5247. if (targetThread == currThreadId) {
  5248. setTimeout(checkMailbox);
  5249. } else if (ENVIRONMENT_IS_PTHREAD) {
  5250. postMessage({
  5251. targetThread,
  5252. cmd: 4
  5253. });
  5254. } else {
  5255. var worker = PThread.pthreads[targetThread];
  5256. if (!worker) {
  5257. err(`Cannot send message to thread with ID ${targetThread}, unknown thread ID!`);
  5258. return;
  5259. }
  5260. worker.postMessage({
  5261. cmd: 4
  5262. });
  5263. }
  5264. };
  5265. var proxiedJSCallArgs = [];
  5266. var __emscripten_receive_on_main_thread_js = (funcIndex, emAsmAddr, callingThread, bufSize, args, ctx, ctxArgs) => {
  5267. // Sometimes we need to backproxy events to the calling thread (e.g.
  5268. // HTML5 DOM events handlers such as
  5269. // emscripten_set_mousemove_callback()), so keep track in a globally
  5270. // accessible variable about the thread that initiated the proxying.
  5271. proxiedJSCallArgs.length = 0;
  5272. var b = ((args) >> 3);
  5273. var end = ((args + bufSize) >> 3);
  5274. while (b < end) {
  5275. var arg;
  5276. if ((growMemViews(), HEAP64)[b++]) {
  5277. // It's a BigInt.
  5278. arg = (growMemViews(), HEAP64)[b++];
  5279. } else {
  5280. // It's a Number.
  5281. arg = (growMemViews(), HEAPF64)[b++];
  5282. }
  5283. proxiedJSCallArgs.push(arg);
  5284. }
  5285. // Proxied JS library funcs use funcIndex and EM_ASM functions use emAsmAddr
  5286. var func = emAsmAddr ? ASM_CONSTS[emAsmAddr] : proxiedFunctionTable[funcIndex];
  5287. assert(!(funcIndex && emAsmAddr));
  5288. assert(func.length == proxiedJSCallArgs.length, "Call args mismatch in _emscripten_receive_on_main_thread_js");
  5289. PThread.currentProxiedOperationCallerThread = callingThread;
  5290. var rtn = func(...proxiedJSCallArgs);
  5291. PThread.currentProxiedOperationCallerThread = 0;
  5292. if (ctx) {
  5293. rtn.then(rtn => __emscripten_run_js_on_main_thread_done(ctx, ctxArgs, rtn));
  5294. return;
  5295. }
  5296. // Proxied functions can return any type except bigint. All other types
  5297. // coerce to f64/double (the return type of this function in C) but not
  5298. // bigint.
  5299. assert(typeof rtn != "bigint");
  5300. return rtn;
  5301. };
  5302. var __emscripten_runtime_keepalive_clear = () => {
  5303. noExitRuntime = false;
  5304. runtimeKeepaliveCounter = 0;
  5305. };
  5306. var __emscripten_thread_cleanup = thread => {
  5307. // Called when a thread needs to be cleaned up so it can be reused.
  5308. // A thread is considered reusable when it either returns from its
  5309. // entry point, calls pthread_exit, or acts upon a cancellation.
  5310. // Detached threads are responsible for calling this themselves,
  5311. // otherwise pthread_join is responsible for calling this.
  5312. if (!ENVIRONMENT_IS_PTHREAD) cleanupThread(thread); else postMessage({
  5313. cmd: 6,
  5314. thread
  5315. });
  5316. };
  5317. var __emscripten_thread_set_strongref = thread => {
  5318. // Called when a thread needs to be strongly referenced.
  5319. // Currently only used for:
  5320. // - keeping the "main" thread alive in PROXY_TO_PTHREAD mode;
  5321. // - crashed threads that need to propagate the uncaught exception
  5322. // back to the main thread.
  5323. if (ENVIRONMENT_IS_NODE) {
  5324. var worker = PThread.pthreads[thread];
  5325. worker.ref();
  5326. // Also, record that we called strongref, in case this function is called
  5327. // bafore the 'loaded' callback from the thread (where we would normally
  5328. // `unref` it.
  5329. worker.strongref = 1;
  5330. }
  5331. };
  5332. var isLeapYear = year => year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
  5333. var MONTH_DAYS_LEAP_CUMULATIVE = [ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 ];
  5334. var MONTH_DAYS_REGULAR_CUMULATIVE = [ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 ];
  5335. var ydayFromDate = date => {
  5336. var leap = isLeapYear(date.getFullYear());
  5337. var monthDaysCumulative = (leap ? MONTH_DAYS_LEAP_CUMULATIVE : MONTH_DAYS_REGULAR_CUMULATIVE);
  5338. var yday = monthDaysCumulative[date.getMonth()] + date.getDate() - 1;
  5339. // -1 since it's days since Jan 1
  5340. return yday;
  5341. };
  5342. var INT53_MAX = 9007199254740992;
  5343. var INT53_MIN = -9007199254740992;
  5344. var bigintToI53Checked = num => (num < INT53_MIN || num > INT53_MAX) ? NaN : Number(num);
  5345. function __localtime_js(time, tmPtr) {
  5346. time = bigintToI53Checked(time);
  5347. var date = new Date(time * 1e3);
  5348. if (isNaN(date.getTime())) {
  5349. return 1;
  5350. }
  5351. (growMemViews(), HEAP32)[((tmPtr) >> 2)] = date.getSeconds();
  5352. (growMemViews(), HEAP32)[(((tmPtr) + (4)) >> 2)] = date.getMinutes();
  5353. (growMemViews(), HEAP32)[(((tmPtr) + (8)) >> 2)] = date.getHours();
  5354. (growMemViews(), HEAP32)[(((tmPtr) + (12)) >> 2)] = date.getDate();
  5355. (growMemViews(), HEAP32)[(((tmPtr) + (16)) >> 2)] = date.getMonth();
  5356. (growMemViews(), HEAP32)[(((tmPtr) + (20)) >> 2)] = date.getFullYear() - 1900;
  5357. (growMemViews(), HEAP32)[(((tmPtr) + (24)) >> 2)] = date.getDay();
  5358. var yday = ydayFromDate(date) | 0;
  5359. (growMemViews(), HEAP32)[(((tmPtr) + (28)) >> 2)] = yday;
  5360. (growMemViews(), HEAP32)[(((tmPtr) + (36)) >> 2)] = -(date.getTimezoneOffset() * 60);
  5361. // Attention: DST is in December in South, and some regions don't have DST at all.
  5362. var start = new Date(date.getFullYear(), 0, 1);
  5363. var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset();
  5364. var winterOffset = start.getTimezoneOffset();
  5365. var dst = (summerOffset != winterOffset && date.getTimezoneOffset() == Math.min(winterOffset, summerOffset)) | 0;
  5366. (growMemViews(), HEAP32)[(((tmPtr) + (32)) >> 2)] = dst;
  5367. return 0;
  5368. }
  5369. function __mmap_js(len, prot, flags, fd, offset, allocated, addr) {
  5370. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(14, 0, 1, len, prot, flags, fd, offset, allocated, addr);
  5371. offset = bigintToI53Checked(offset);
  5372. try {
  5373. // musl's mmap doesn't allow values over a certain limit
  5374. // see OFF_MASK in mmap.c.
  5375. assert(!isNaN(offset));
  5376. var stream = SYSCALLS.getStreamFromFD(fd);
  5377. var res = FS.mmap(stream, len, offset, prot, flags);
  5378. var ptr = res.ptr;
  5379. (growMemViews(), HEAP32)[((allocated) >> 2)] = res.allocated;
  5380. (growMemViews(), HEAPU32)[((addr) >> 2)] = ptr;
  5381. return 0;
  5382. } catch (e) {
  5383. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  5384. return -e.errno;
  5385. }
  5386. }
  5387. function __munmap_js(addr, len, prot, flags, fd, offset) {
  5388. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(15, 0, 1, addr, len, prot, flags, fd, offset);
  5389. offset = bigintToI53Checked(offset);
  5390. try {
  5391. var stream = SYSCALLS.getStreamFromFD(fd);
  5392. if (prot & 2) {
  5393. SYSCALLS.doMsync(addr, stream, len, flags, offset);
  5394. }
  5395. } catch (e) {
  5396. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  5397. return -e.errno;
  5398. }
  5399. }
  5400. var __tzset_js = (timezone, daylight, std_name, dst_name) => {
  5401. // TODO: Use (malleable) environment variables instead of system settings.
  5402. var currentYear = (new Date).getFullYear();
  5403. var winter = new Date(currentYear, 0, 1);
  5404. var summer = new Date(currentYear, 6, 1);
  5405. var winterOffset = winter.getTimezoneOffset();
  5406. var summerOffset = summer.getTimezoneOffset();
  5407. // Local standard timezone offset. Local standard time is not adjusted for
  5408. // daylight savings. This code uses the fact that getTimezoneOffset returns
  5409. // a greater value during Standard Time versus Daylight Saving Time (DST).
  5410. // Thus it determines the expected output during Standard Time, and it
  5411. // compares whether the output of the given date the same (Standard) or less
  5412. // (DST).
  5413. var stdTimezoneOffset = Math.max(winterOffset, summerOffset);
  5414. // timezone is specified as seconds west of UTC ("The external variable
  5415. // `timezone` shall be set to the difference, in seconds, between
  5416. // Coordinated Universal Time (UTC) and local standard time."), the same
  5417. // as returned by stdTimezoneOffset.
  5418. // See http://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html
  5419. (growMemViews(), HEAPU32)[((timezone) >> 2)] = stdTimezoneOffset * 60;
  5420. (growMemViews(), HEAP32)[((daylight) >> 2)] = Number(winterOffset != summerOffset);
  5421. var extractZone = timezoneOffset => {
  5422. // Why inverse sign?
  5423. // Read here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset
  5424. var sign = timezoneOffset >= 0 ? "-" : "+";
  5425. var absOffset = Math.abs(timezoneOffset);
  5426. var hours = String(Math.floor(absOffset / 60)).padStart(2, "0");
  5427. var minutes = String(absOffset % 60).padStart(2, "0");
  5428. return `UTC${sign}${hours}${minutes}`;
  5429. };
  5430. var winterName = extractZone(winterOffset);
  5431. var summerName = extractZone(summerOffset);
  5432. assert(winterName);
  5433. assert(summerName);
  5434. assert(lengthBytesUTF8(winterName) <= 16, `timezone name truncated to fit in TZNAME_MAX (${winterName})`);
  5435. assert(lengthBytesUTF8(summerName) <= 16, `timezone name truncated to fit in TZNAME_MAX (${summerName})`);
  5436. if (summerOffset < winterOffset) {
  5437. // Northern hemisphere
  5438. stringToUTF8(winterName, std_name, 17);
  5439. stringToUTF8(summerName, dst_name, 17);
  5440. } else {
  5441. stringToUTF8(winterName, dst_name, 17);
  5442. stringToUTF8(summerName, std_name, 17);
  5443. }
  5444. };
  5445. var _emscripten_get_now = () => performance.timeOrigin + performance.now();
  5446. var _emscripten_date_now = () => Date.now();
  5447. var nowIsMonotonic = 1;
  5448. var checkWasiClock = clock_id => clock_id >= 0 && clock_id <= 3;
  5449. function _clock_time_get(clk_id, ignored_precision, ptime) {
  5450. ignored_precision = bigintToI53Checked(ignored_precision);
  5451. if (!checkWasiClock(clk_id)) {
  5452. return 28;
  5453. }
  5454. var now;
  5455. // all wasi clocks but realtime are monotonic
  5456. if (clk_id === 0) {
  5457. now = _emscripten_date_now();
  5458. } else if (nowIsMonotonic) {
  5459. now = _emscripten_get_now();
  5460. } else {
  5461. return 52;
  5462. }
  5463. // "now" is in ms, and wasi times are in ns.
  5464. var nsec = Math.round(now * 1e3 * 1e3);
  5465. (growMemViews(), HEAP64)[((ptime) >> 3)] = BigInt(nsec);
  5466. return 0;
  5467. }
  5468. function getFullscreenElement() {
  5469. return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.webkitCurrentFullScreenElement || document.msFullscreenElement;
  5470. }
  5471. var runtimeKeepalivePush = () => {
  5472. runtimeKeepaliveCounter += 1;
  5473. };
  5474. var runtimeKeepalivePop = () => {
  5475. assert(runtimeKeepaliveCounter > 0);
  5476. runtimeKeepaliveCounter -= 1;
  5477. };
  5478. /** @param {number=} timeout */ var safeSetTimeout = (func, timeout) => {
  5479. runtimeKeepalivePush();
  5480. return setTimeout(() => {
  5481. runtimeKeepalivePop();
  5482. callUserCallback(func);
  5483. }, timeout);
  5484. };
  5485. var Browser = {
  5486. useWebGL: false,
  5487. isFullscreen: false,
  5488. pointerLock: false,
  5489. moduleContextCreatedCallbacks: [],
  5490. preloadedImages: {},
  5491. preloadedAudios: {},
  5492. getCanvas: () => Module["canvas"],
  5493. init() {
  5494. if (Browser.initted) return;
  5495. Browser.initted = true;
  5496. // Support for plugins that can process preloaded files. You can add more of these to
  5497. // your app by creating and appending to preloadPlugins.
  5498. // Each plugin is asked if it can handle a file based on the file's name. If it can,
  5499. // it is given the file's raw data. When it is done, it calls a callback with the file's
  5500. // (possibly modified) data. For example, a plugin might decompress a file, or it
  5501. // might create some side data structure for use later (like an Image element, etc.).
  5502. var imagePlugin = {};
  5503. imagePlugin["canHandle"] = name => !Module["noImageDecoding"] && /\.(jpg|jpeg|png|bmp|webp)$/i.test(name);
  5504. imagePlugin["handle"] = async (byteArray, name) => {
  5505. var b = new Blob([ byteArray ], {
  5506. type: Browser.getMimetype(name)
  5507. });
  5508. if (b.size !== byteArray.length) {
  5509. // Safari bug #118630
  5510. // Safari's Blob can only take an ArrayBuffer
  5511. b = new Blob([ (new Uint8Array(byteArray)).buffer ], {
  5512. type: Browser.getMimetype(name)
  5513. });
  5514. }
  5515. var url = URL.createObjectURL(b);
  5516. return new Promise((resolve, reject) => {
  5517. var img = new Image;
  5518. img.onload = () => {
  5519. assert(img.complete, `Image ${name} could not be decoded`);
  5520. var canvas = /** @type {!HTMLCanvasElement} */ (document.createElement("canvas"));
  5521. canvas.width = img.width;
  5522. canvas.height = img.height;
  5523. var ctx = canvas.getContext("2d");
  5524. ctx.drawImage(img, 0, 0);
  5525. Browser.preloadedImages[name] = canvas;
  5526. URL.revokeObjectURL(url);
  5527. resolve(byteArray);
  5528. };
  5529. img.onerror = event => {
  5530. err(`Image ${url} could not be decoded`);
  5531. reject();
  5532. };
  5533. img.src = url;
  5534. });
  5535. };
  5536. preloadPlugins.push(imagePlugin);
  5537. var audioPlugin = {};
  5538. audioPlugin["canHandle"] = name => !Module["noAudioDecoding"] && name.slice(-4) in {
  5539. ".ogg": 1,
  5540. ".wav": 1,
  5541. ".mp3": 1
  5542. };
  5543. audioPlugin["handle"] = async (byteArray, name) => new Promise((resolve, reject) => {
  5544. var done = false;
  5545. function finish(audio) {
  5546. if (done) return;
  5547. done = true;
  5548. Browser.preloadedAudios[name] = audio;
  5549. resolve(byteArray);
  5550. }
  5551. var b = new Blob([ byteArray ], {
  5552. type: Browser.getMimetype(name)
  5553. });
  5554. var url = URL.createObjectURL(b);
  5555. // XXX we never revoke this!
  5556. var audio = new Audio;
  5557. audio.addEventListener("canplaythrough", () => finish(audio));
  5558. // use addEventListener due to chromium bug 124926
  5559. audio.onerror = event => {
  5560. if (done) return;
  5561. err(`warning: browser could not fully decode audio ${name}, trying slower base64 approach`);
  5562. function encode64(data) {
  5563. var BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  5564. var PAD = "=";
  5565. var ret = "";
  5566. var leftchar = 0;
  5567. var leftbits = 0;
  5568. for (var i = 0; i < data.length; i++) {
  5569. leftchar = (leftchar << 8) | data[i];
  5570. leftbits += 8;
  5571. while (leftbits >= 6) {
  5572. var curr = (leftchar >> (leftbits - 6)) & 63;
  5573. leftbits -= 6;
  5574. ret += BASE[curr];
  5575. }
  5576. }
  5577. if (leftbits == 2) {
  5578. ret += BASE[(leftchar & 3) << 4];
  5579. ret += PAD + PAD;
  5580. } else if (leftbits == 4) {
  5581. ret += BASE[(leftchar & 15) << 2];
  5582. ret += PAD;
  5583. }
  5584. return ret;
  5585. }
  5586. audio.src = "data:audio/x-" + name.slice(-3) + ";base64," + encode64(byteArray);
  5587. finish(audio);
  5588. };
  5589. audio.src = url;
  5590. // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
  5591. safeSetTimeout(() => {
  5592. finish(audio);
  5593. }, 1e4);
  5594. });
  5595. preloadPlugins.push(audioPlugin);
  5596. // Canvas event setup
  5597. function pointerLockChange() {
  5598. var canvas = Browser.getCanvas();
  5599. Browser.pointerLock = document.pointerLockElement === canvas;
  5600. }
  5601. var canvas = Browser.getCanvas();
  5602. if (canvas) {
  5603. // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
  5604. // Module['forcedAspectRatio'] = 4 / 3;
  5605. document.addEventListener("pointerlockchange", pointerLockChange);
  5606. if (Module["elementPointerLock"]) {
  5607. canvas.addEventListener("click", ev => {
  5608. if (!Browser.pointerLock && Browser.getCanvas().requestPointerLock) {
  5609. Browser.getCanvas().requestPointerLock();
  5610. ev.preventDefault();
  5611. }
  5612. });
  5613. }
  5614. }
  5615. },
  5616. createContext(/** @type {HTMLCanvasElement} */ canvas, useWebGL, setInModule, webGLContextAttributes) {
  5617. if (useWebGL && Module["ctx"] && canvas == Browser.getCanvas()) return Module["ctx"];
  5618. // no need to recreate GL context if it's already been created for this canvas.
  5619. var ctx;
  5620. var contextHandle;
  5621. if (useWebGL) {
  5622. // For GLES2/desktop GL compatibility, adjust a few defaults to be different to WebGL defaults, so that they align better with the desktop defaults.
  5623. var contextAttributes = {
  5624. antialias: false,
  5625. alpha: false,
  5626. majorVersion: 1
  5627. };
  5628. if (webGLContextAttributes) {
  5629. for (var attribute in webGLContextAttributes) {
  5630. contextAttributes[attribute] = webGLContextAttributes[attribute];
  5631. }
  5632. }
  5633. // This check of existence of GL is here to satisfy Closure compiler, which yells if variable GL is referenced below but GL object is not
  5634. // actually compiled in because application is not doing any GL operations. TODO: Ideally if GL is not being used, this function
  5635. // Browser.createContext() should not even be emitted.
  5636. if (typeof GL != "undefined") {
  5637. contextHandle = GL.createContext(canvas, contextAttributes);
  5638. if (contextHandle) {
  5639. ctx = GL.getContext(contextHandle).GLctx;
  5640. }
  5641. }
  5642. } else {
  5643. ctx = canvas.getContext("2d");
  5644. }
  5645. if (!ctx) return null;
  5646. if (setInModule) {
  5647. if (!useWebGL) assert(typeof GLctx == "undefined", "cannot set in module if GLctx is used, but we are a non-GL context that would replace it");
  5648. Module["ctx"] = ctx;
  5649. if (useWebGL) GL.makeContextCurrent(contextHandle);
  5650. Browser.useWebGL = useWebGL;
  5651. Browser.moduleContextCreatedCallbacks.forEach(callback => callback());
  5652. Browser.init();
  5653. }
  5654. return ctx;
  5655. },
  5656. fullscreenHandlersInstalled: false,
  5657. lockPointer: undefined,
  5658. resizeCanvas: undefined,
  5659. requestFullscreen(lockPointer, resizeCanvas) {
  5660. Browser.lockPointer = lockPointer;
  5661. Browser.resizeCanvas = resizeCanvas;
  5662. if (typeof Browser.lockPointer == "undefined") Browser.lockPointer = true;
  5663. if (typeof Browser.resizeCanvas == "undefined") Browser.resizeCanvas = false;
  5664. var canvas = Browser.getCanvas();
  5665. function fullscreenChange() {
  5666. Browser.isFullscreen = false;
  5667. var canvasContainer = canvas.parentNode;
  5668. if (getFullscreenElement() === canvasContainer) {
  5669. canvas.exitFullscreen = Browser.exitFullscreen;
  5670. if (Browser.lockPointer) canvas.requestPointerLock();
  5671. Browser.isFullscreen = true;
  5672. if (Browser.resizeCanvas) {
  5673. Browser.setFullscreenCanvasSize();
  5674. } else {
  5675. Browser.updateCanvasDimensions(canvas);
  5676. }
  5677. } else {
  5678. // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
  5679. canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
  5680. canvasContainer.parentNode.removeChild(canvasContainer);
  5681. if (Browser.resizeCanvas) {
  5682. Browser.setWindowedCanvasSize();
  5683. } else {
  5684. Browser.updateCanvasDimensions(canvas);
  5685. }
  5686. }
  5687. }
  5688. if (!Browser.fullscreenHandlersInstalled) {
  5689. Browser.fullscreenHandlersInstalled = true;
  5690. document.addEventListener("fullscreenchange", fullscreenChange);
  5691. document.addEventListener("mozfullscreenchange", fullscreenChange);
  5692. document.addEventListener("webkitfullscreenchange", fullscreenChange);
  5693. document.addEventListener("MSFullscreenChange", fullscreenChange);
  5694. }
  5695. // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root
  5696. var canvasContainer = document.createElement("div");
  5697. canvas.parentNode.insertBefore(canvasContainer, canvas);
  5698. canvasContainer.appendChild(canvas);
  5699. // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
  5700. canvasContainer.requestFullscreen = canvasContainer["requestFullscreen"] || canvasContainer["mozRequestFullScreen"] || canvasContainer["msRequestFullscreen"] || (canvasContainer["webkitRequestFullscreen"] ? () => canvasContainer["webkitRequestFullscreen"](Element["ALLOW_KEYBOARD_INPUT"]) : null) || (canvasContainer["webkitRequestFullScreen"] ? () => canvasContainer["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"]) : null);
  5701. canvasContainer.requestFullscreen();
  5702. },
  5703. requestFullScreen() {
  5704. abort("Module.requestFullScreen has been replaced by Module.requestFullscreen (without a capital S)");
  5705. },
  5706. exitFullscreen() {
  5707. // This is workaround for chrome. Trying to exit from fullscreen
  5708. // not in fullscreen state will cause "TypeError: Document not active"
  5709. // in chrome. See https://github.com/emscripten-core/emscripten/pull/8236
  5710. if (!Browser.isFullscreen) {
  5711. return false;
  5712. }
  5713. var CFS = document["exitFullscreen"] || document["cancelFullScreen"] || document["mozCancelFullScreen"] || document["msExitFullscreen"] || document["webkitCancelFullScreen"] || (() => {});
  5714. CFS.apply(document, []);
  5715. return true;
  5716. },
  5717. safeSetTimeout(func, timeout) {
  5718. // Legacy function, this is used by the SDL2 port so we need to keep it
  5719. // around at least until that is updated.
  5720. // See https://github.com/libsdl-org/SDL/pull/6304
  5721. return safeSetTimeout(func, timeout);
  5722. },
  5723. getMimetype(name) {
  5724. return {
  5725. "jpg": "image/jpeg",
  5726. "jpeg": "image/jpeg",
  5727. "png": "image/png",
  5728. "bmp": "image/bmp",
  5729. "ogg": "audio/ogg",
  5730. "wav": "audio/wav",
  5731. "mp3": "audio/mpeg"
  5732. }[name.slice(name.lastIndexOf(".") + 1)];
  5733. },
  5734. getUserMedia(func) {
  5735. window.getUserMedia ||= navigator["getUserMedia"] || navigator["mozGetUserMedia"];
  5736. window.getUserMedia(func);
  5737. },
  5738. getMovementX(event) {
  5739. return event["movementX"] || event["mozMovementX"] || event["webkitMovementX"] || 0;
  5740. },
  5741. getMovementY(event) {
  5742. return event["movementY"] || event["mozMovementY"] || event["webkitMovementY"] || 0;
  5743. },
  5744. getMouseWheelDelta(event) {
  5745. var delta = 0;
  5746. switch (event.type) {
  5747. case "DOMMouseScroll":
  5748. // 3 lines make up a step
  5749. delta = event.detail / 3;
  5750. break;
  5751. case "mousewheel":
  5752. // 120 units make up a step
  5753. delta = event.wheelDelta / 120;
  5754. break;
  5755. case "wheel":
  5756. delta = event.deltaY;
  5757. switch (event.deltaMode) {
  5758. case 0:
  5759. // DOM_DELTA_PIXEL: 100 pixels make up a step
  5760. delta /= 100;
  5761. break;
  5762. case 1:
  5763. // DOM_DELTA_LINE: 3 lines make up a step
  5764. delta /= 3;
  5765. break;
  5766. case 2:
  5767. // DOM_DELTA_PAGE: A page makes up 80 steps
  5768. delta *= 80;
  5769. break;
  5770. default:
  5771. abort("unrecognized mouse wheel delta mode: " + event.deltaMode);
  5772. }
  5773. break;
  5774. default:
  5775. abort("unrecognized mouse wheel event: " + event.type);
  5776. }
  5777. return delta;
  5778. },
  5779. mouseX: 0,
  5780. mouseY: 0,
  5781. mouseMovementX: 0,
  5782. mouseMovementY: 0,
  5783. touches: {},
  5784. lastTouches: {},
  5785. calculateMouseCoords(pageX, pageY) {
  5786. // Calculate the movement based on the changes
  5787. // in the coordinates.
  5788. var canvas = Browser.getCanvas();
  5789. var rect = canvas.getBoundingClientRect();
  5790. var adjustedX = pageX - (window.scrollX + rect.left);
  5791. var adjustedY = pageY - (window.scrollY + rect.top);
  5792. // the canvas might be CSS-scaled compared to its backbuffer;
  5793. // SDL-using content will want mouse coordinates in terms
  5794. // of backbuffer units.
  5795. adjustedX = adjustedX * (canvas.width / rect.width);
  5796. adjustedY = adjustedY * (canvas.height / rect.height);
  5797. return {
  5798. x: adjustedX,
  5799. y: adjustedY
  5800. };
  5801. },
  5802. setMouseCoords(pageX, pageY) {
  5803. const {x, y} = Browser.calculateMouseCoords(pageX, pageY);
  5804. Browser.mouseMovementX = x - Browser.mouseX;
  5805. Browser.mouseMovementY = y - Browser.mouseY;
  5806. Browser.mouseX = x;
  5807. Browser.mouseY = y;
  5808. },
  5809. calculateMouseEvent(event) {
  5810. // event should be mousemove, mousedown or mouseup
  5811. if (Browser.pointerLock) {
  5812. // When the pointer is locked, calculate the coordinates
  5813. // based on the movement of the mouse.
  5814. // Workaround for Firefox bug 764498
  5815. if (event.type != "mousemove" && ("mozMovementX" in event)) {
  5816. Browser.mouseMovementX = Browser.mouseMovementY = 0;
  5817. } else {
  5818. Browser.mouseMovementX = Browser.getMovementX(event);
  5819. Browser.mouseMovementY = Browser.getMovementY(event);
  5820. }
  5821. // add the mouse delta to the current absolute mouse position
  5822. Browser.mouseX += Browser.mouseMovementX;
  5823. Browser.mouseY += Browser.mouseMovementY;
  5824. } else {
  5825. if (event.type === "touchstart" || event.type === "touchend" || event.type === "touchmove") {
  5826. var touch = event.touch;
  5827. if (touch === undefined) {
  5828. return;
  5829. }
  5830. var coords = Browser.calculateMouseCoords(touch.pageX, touch.pageY);
  5831. if (event.type === "touchstart") {
  5832. Browser.lastTouches[touch.identifier] = coords;
  5833. Browser.touches[touch.identifier] = coords;
  5834. } else if (event.type === "touchend" || event.type === "touchmove") {
  5835. var last = Browser.touches[touch.identifier];
  5836. last ||= coords;
  5837. Browser.lastTouches[touch.identifier] = last;
  5838. Browser.touches[touch.identifier] = coords;
  5839. }
  5840. return;
  5841. }
  5842. Browser.setMouseCoords(event.pageX, event.pageY);
  5843. }
  5844. },
  5845. resizeListeners: [],
  5846. updateResizeListeners() {
  5847. var canvas = Browser.getCanvas();
  5848. Browser.resizeListeners.forEach(listener => listener(canvas.width, canvas.height));
  5849. },
  5850. setCanvasSize(width, height, noUpdates) {
  5851. var canvas = Browser.getCanvas();
  5852. Browser.updateCanvasDimensions(canvas, width, height);
  5853. if (!noUpdates) Browser.updateResizeListeners();
  5854. },
  5855. windowedWidth: 0,
  5856. windowedHeight: 0,
  5857. setFullscreenCanvasSize() {
  5858. // check if SDL is available
  5859. if (typeof SDL != "undefined") {
  5860. var flags = (growMemViews(), HEAPU32)[((SDL.screen) >> 2)];
  5861. flags = flags | 8388608;
  5862. // set SDL_FULLSCREEN flag
  5863. (growMemViews(), HEAP32)[((SDL.screen) >> 2)] = flags;
  5864. }
  5865. Browser.updateCanvasDimensions(Browser.getCanvas());
  5866. Browser.updateResizeListeners();
  5867. },
  5868. setWindowedCanvasSize() {
  5869. // check if SDL is available
  5870. if (typeof SDL != "undefined") {
  5871. var flags = (growMemViews(), HEAPU32)[((SDL.screen) >> 2)];
  5872. flags = flags & ~8388608;
  5873. // clear SDL_FULLSCREEN flag
  5874. (growMemViews(), HEAP32)[((SDL.screen) >> 2)] = flags;
  5875. }
  5876. Browser.updateCanvasDimensions(Browser.getCanvas());
  5877. Browser.updateResizeListeners();
  5878. },
  5879. updateCanvasDimensions(canvas, wNative, hNative) {
  5880. if (wNative && hNative) {
  5881. canvas.widthNative = wNative;
  5882. canvas.heightNative = hNative;
  5883. } else {
  5884. wNative = canvas.widthNative;
  5885. hNative = canvas.heightNative;
  5886. }
  5887. var w = wNative;
  5888. var h = hNative;
  5889. if ((getFullscreenElement() === canvas.parentNode) && (typeof screen != "undefined")) {
  5890. var factor = Math.min(screen.width / w, screen.height / h);
  5891. w = Math.round(w * factor);
  5892. h = Math.round(h * factor);
  5893. }
  5894. if (Browser.resizeCanvas) {
  5895. if (canvas.width != w) canvas.width = w;
  5896. if (canvas.height != h) canvas.height = h;
  5897. if (typeof canvas.style != "undefined") {
  5898. canvas.style.removeProperty("width");
  5899. canvas.style.removeProperty("height");
  5900. }
  5901. } else {
  5902. if (canvas.width != wNative) canvas.width = wNative;
  5903. if (canvas.height != hNative) canvas.height = hNative;
  5904. if (typeof canvas.style != "undefined") {
  5905. if (w != wNative || h != hNative) {
  5906. canvas.style.setProperty("width", w + "px", "important");
  5907. canvas.style.setProperty("height", h + "px", "important");
  5908. } else {
  5909. canvas.style.removeProperty("width");
  5910. canvas.style.removeProperty("height");
  5911. }
  5912. }
  5913. }
  5914. }
  5915. };
  5916. var EGL = {
  5917. errorCode: 12288,
  5918. defaultDisplayInitialized: false,
  5919. currentContext: 0,
  5920. currentReadSurface: 0,
  5921. currentDrawSurface: 0,
  5922. contextAttributes: {
  5923. alpha: false,
  5924. depth: false,
  5925. stencil: false,
  5926. antialias: false
  5927. },
  5928. stringCache: {},
  5929. setErrorCode(code) {
  5930. EGL.errorCode = code;
  5931. },
  5932. chooseConfig(display, attribList, config, config_size, numConfigs) {
  5933. if (display != 62e3) {
  5934. EGL.setErrorCode(12296);
  5935. return 0;
  5936. }
  5937. if (attribList) {
  5938. // read attribList if it is non-null
  5939. for (;;) {
  5940. var param = (growMemViews(), HEAP32)[((attribList) >> 2)];
  5941. if (param == 12321) {
  5942. var alphaSize = (growMemViews(), HEAP32)[(((attribList) + (4)) >> 2)];
  5943. EGL.contextAttributes.alpha = (alphaSize > 0);
  5944. } else if (param == 12325) {
  5945. var depthSize = (growMemViews(), HEAP32)[(((attribList) + (4)) >> 2)];
  5946. EGL.contextAttributes.depth = (depthSize > 0);
  5947. } else if (param == 12326) {
  5948. var stencilSize = (growMemViews(), HEAP32)[(((attribList) + (4)) >> 2)];
  5949. EGL.contextAttributes.stencil = (stencilSize > 0);
  5950. } else if (param == 12337) {
  5951. var samples = (growMemViews(), HEAP32)[(((attribList) + (4)) >> 2)];
  5952. EGL.contextAttributes.antialias = (samples > 0);
  5953. } else if (param == 12338) {
  5954. var samples = (growMemViews(), HEAP32)[(((attribList) + (4)) >> 2)];
  5955. EGL.contextAttributes.antialias = (samples == 1);
  5956. } else if (param == 12544) {
  5957. var requestedPriority = (growMemViews(), HEAP32)[(((attribList) + (4)) >> 2)];
  5958. EGL.contextAttributes.lowLatency = (requestedPriority != 12547);
  5959. } else if (param == 12344) {
  5960. break;
  5961. }
  5962. attribList += 8;
  5963. }
  5964. }
  5965. if ((!config || !config_size) && !numConfigs) {
  5966. EGL.setErrorCode(12300);
  5967. return 0;
  5968. }
  5969. if (numConfigs) {
  5970. (growMemViews(), HEAP32)[((numConfigs) >> 2)] = 1;
  5971. }
  5972. if (config && config_size > 0) {
  5973. (growMemViews(), HEAPU32)[((config) >> 2)] = 62002;
  5974. }
  5975. EGL.setErrorCode(12288);
  5976. return 1;
  5977. }
  5978. };
  5979. function _eglBindAPI(api) {
  5980. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(16, 0, 1, api);
  5981. if (api == 12448) {
  5982. EGL.setErrorCode(12288);
  5983. return 1;
  5984. }
  5985. // if (api == 0x30A1 /* EGL_OPENVG_API */ || api == 0x30A2 /* EGL_OPENGL_API */) {
  5986. EGL.setErrorCode(12300);
  5987. return 0;
  5988. }
  5989. function _eglChooseConfig(display, attrib_list, configs, config_size, numConfigs) {
  5990. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(17, 0, 1, display, attrib_list, configs, config_size, numConfigs);
  5991. return EGL.chooseConfig(display, attrib_list, configs, config_size, numConfigs);
  5992. }
  5993. var GLctx;
  5994. var webgl_enable_ANGLE_instanced_arrays = ctx => {
  5995. // Extension available in WebGL 1 from Firefox 26 and Google Chrome 30 onwards. Core feature in WebGL 2.
  5996. var ext = ctx.getExtension("ANGLE_instanced_arrays");
  5997. // Because this extension is a core function in WebGL 2, assign the extension entry points in place of
  5998. // where the core functions will reside in WebGL 2. This way the calling code can call these without
  5999. // having to dynamically branch depending if running against WebGL 1 or WebGL 2.
  6000. if (ext) {
  6001. ctx["vertexAttribDivisor"] = (index, divisor) => ext["vertexAttribDivisorANGLE"](index, divisor);
  6002. ctx["drawArraysInstanced"] = (mode, first, count, primcount) => ext["drawArraysInstancedANGLE"](mode, first, count, primcount);
  6003. ctx["drawElementsInstanced"] = (mode, count, type, indices, primcount) => ext["drawElementsInstancedANGLE"](mode, count, type, indices, primcount);
  6004. return 1;
  6005. }
  6006. };
  6007. var webgl_enable_OES_vertex_array_object = ctx => {
  6008. // Extension available in WebGL 1 from Firefox 25 and WebKit 536.28/desktop Safari 6.0.3 onwards. Core feature in WebGL 2.
  6009. var ext = ctx.getExtension("OES_vertex_array_object");
  6010. if (ext) {
  6011. ctx["createVertexArray"] = () => ext["createVertexArrayOES"]();
  6012. ctx["deleteVertexArray"] = vao => ext["deleteVertexArrayOES"](vao);
  6013. ctx["bindVertexArray"] = vao => ext["bindVertexArrayOES"](vao);
  6014. ctx["isVertexArray"] = vao => ext["isVertexArrayOES"](vao);
  6015. return 1;
  6016. }
  6017. };
  6018. var webgl_enable_WEBGL_draw_buffers = ctx => {
  6019. // Extension available in WebGL 1 from Firefox 28 onwards. Core feature in WebGL 2.
  6020. var ext = ctx.getExtension("WEBGL_draw_buffers");
  6021. if (ext) {
  6022. ctx["drawBuffers"] = (n, bufs) => ext["drawBuffersWEBGL"](n, bufs);
  6023. return 1;
  6024. }
  6025. };
  6026. var webgl_enable_EXT_polygon_offset_clamp = ctx => !!(ctx.extPolygonOffsetClamp = ctx.getExtension("EXT_polygon_offset_clamp"));
  6027. var webgl_enable_EXT_clip_control = ctx => !!(ctx.extClipControl = ctx.getExtension("EXT_clip_control"));
  6028. var webgl_enable_WEBGL_polygon_mode = ctx => !!(ctx.webglPolygonMode = ctx.getExtension("WEBGL_polygon_mode"));
  6029. var webgl_enable_WEBGL_multi_draw = ctx => // Closure is expected to be allowed to minify the '.multiDrawWebgl' property, so not accessing it quoted.
  6030. !!(ctx.multiDrawWebgl = ctx.getExtension("WEBGL_multi_draw"));
  6031. var getEmscriptenSupportedExtensions = ctx => {
  6032. // Restrict the list of advertised extensions to those that we actually
  6033. // support.
  6034. var supportedExtensions = [ // WebGL 1 extensions
  6035. "ANGLE_instanced_arrays", "EXT_blend_minmax", "EXT_disjoint_timer_query", "EXT_frag_depth", "EXT_shader_texture_lod", "EXT_sRGB", "OES_element_index_uint", "OES_fbo_render_mipmap", "OES_standard_derivatives", "OES_texture_float", "OES_texture_half_float", "OES_texture_half_float_linear", "OES_vertex_array_object", "WEBGL_color_buffer_float", "WEBGL_depth_texture", "WEBGL_draw_buffers", // WebGL 1 and WebGL 2 extensions
  6036. "EXT_clip_control", "EXT_color_buffer_half_float", "EXT_depth_clamp", "EXT_float_blend", "EXT_polygon_offset_clamp", "EXT_texture_compression_bptc", "EXT_texture_compression_rgtc", "EXT_texture_filter_anisotropic", "KHR_parallel_shader_compile", "OES_texture_float_linear", "WEBGL_blend_func_extended", "WEBGL_compressed_texture_astc", "WEBGL_compressed_texture_etc", "WEBGL_compressed_texture_etc1", "WEBGL_compressed_texture_s3tc", "WEBGL_compressed_texture_s3tc_srgb", "WEBGL_debug_renderer_info", "WEBGL_debug_shaders", "WEBGL_lose_context", "WEBGL_multi_draw", "WEBGL_polygon_mode" ];
  6037. // .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
  6038. return ctx.getSupportedExtensions()?.filter(ext => supportedExtensions.includes(ext)) ?? [];
  6039. };
  6040. var GL = {
  6041. counter: 1,
  6042. buffers: [],
  6043. programs: [],
  6044. framebuffers: [],
  6045. renderbuffers: [],
  6046. textures: [],
  6047. shaders: [],
  6048. vaos: [],
  6049. contexts: {},
  6050. offscreenCanvases: {},
  6051. queries: [],
  6052. stringCache: {},
  6053. unpackAlignment: 4,
  6054. unpackRowLength: 0,
  6055. recordError: errorCode => {
  6056. if (!GL.lastError) {
  6057. GL.lastError = errorCode;
  6058. }
  6059. },
  6060. getNewId: table => {
  6061. var ret = GL.counter++;
  6062. for (var i = table.length; i < ret; i++) {
  6063. table[i] = null;
  6064. }
  6065. return ret;
  6066. },
  6067. genObject: (n, buffers, createFunction, objectTable) => {
  6068. for (var i = 0; i < n; i++) {
  6069. var buffer = GLctx[createFunction]();
  6070. var id = buffer && GL.getNewId(objectTable);
  6071. if (buffer) {
  6072. buffer.name = id;
  6073. objectTable[id] = buffer;
  6074. } else {
  6075. GL.recordError(1282);
  6076. }
  6077. (growMemViews(), HEAP32)[(((buffers) + (i * 4)) >> 2)] = id;
  6078. }
  6079. },
  6080. getSource: (shader, count, string, length) => {
  6081. var source = "";
  6082. for (var i = 0; i < count; ++i) {
  6083. var len = length ? (growMemViews(), HEAPU32)[(((length) + (i * 4)) >> 2)] : undefined;
  6084. source += UTF8ToString((growMemViews(), HEAPU32)[(((string) + (i * 4)) >> 2)], len);
  6085. }
  6086. return source;
  6087. },
  6088. createContext: (/** @type {HTMLCanvasElement} */ canvas, webGLContextAttributes) => {
  6089. // BUG: Workaround Safari WebGL issue: After successfully acquiring WebGL
  6090. // context on a canvas, calling .getContext() will always return that
  6091. // context independent of which 'webgl' or 'webgl2'
  6092. // context version was passed. See:
  6093. // https://webkit.org/b/222758
  6094. // and:
  6095. // https://github.com/emscripten-core/emscripten/issues/13295.
  6096. // TODO: Once the bug is fixed and shipped in Safari, adjust the Safari
  6097. // version field in above check.
  6098. if (!canvas.getContextSafariWebGL2Fixed) {
  6099. canvas.getContextSafariWebGL2Fixed = canvas.getContext;
  6100. /** @type {function(this:HTMLCanvasElement, string, (Object|null)=): (Object|null)} */ function fixedGetContext(ver, attrs) {
  6101. var gl = canvas.getContextSafariWebGL2Fixed(ver, attrs);
  6102. return ((ver == "webgl") == (gl instanceof WebGLRenderingContext)) ? gl : null;
  6103. }
  6104. canvas.getContext = fixedGetContext;
  6105. }
  6106. var ctx = canvas.getContext("webgl", webGLContextAttributes);
  6107. if (!ctx) return 0;
  6108. var handle = GL.registerContext(ctx, webGLContextAttributes);
  6109. return handle;
  6110. },
  6111. registerContext: (ctx, webGLContextAttributes) => {
  6112. // with pthreads a context is a location in memory with some synchronized
  6113. // data between threads
  6114. var handle = _malloc(8);
  6115. (growMemViews(), HEAPU32)[(((handle) + (4)) >> 2)] = _pthread_self();
  6116. // the thread pointer of the thread that owns the control of the context
  6117. var context = {
  6118. handle,
  6119. attributes: webGLContextAttributes,
  6120. version: webGLContextAttributes.majorVersion,
  6121. GLctx: ctx
  6122. };
  6123. // Store the created context object so that we can access the context
  6124. // given a canvas without having to pass the parameters again.
  6125. if (ctx.canvas) ctx.canvas.GLctxObject = context;
  6126. GL.contexts[handle] = context;
  6127. if (typeof webGLContextAttributes.enableExtensionsByDefault == "undefined" || webGLContextAttributes.enableExtensionsByDefault) {
  6128. GL.initExtensions(context);
  6129. }
  6130. return handle;
  6131. },
  6132. makeContextCurrent: contextHandle => {
  6133. // Active Emscripten GL layer context object.
  6134. GL.currentContext = GL.contexts[contextHandle];
  6135. // Active WebGL context object.
  6136. Module["ctx"] = GLctx = GL.currentContext?.GLctx;
  6137. return !(contextHandle && !GLctx);
  6138. },
  6139. getContext: contextHandle => GL.contexts[contextHandle],
  6140. deleteContext: contextHandle => {
  6141. if (GL.currentContext === GL.contexts[contextHandle]) {
  6142. GL.currentContext = null;
  6143. }
  6144. if (typeof JSEvents == "object") {
  6145. // Release all JS event handlers on the DOM element that the GL context is
  6146. // associated with since the context is now deleted.
  6147. JSEvents.removeAllHandlersOnTarget(GL.contexts[contextHandle].GLctx.canvas);
  6148. }
  6149. // Make sure the canvas object no longer refers to the context object so
  6150. // there are no GC surprises.
  6151. if (GL.contexts[contextHandle]?.GLctx.canvas) {
  6152. GL.contexts[contextHandle].GLctx.canvas.GLctxObject = undefined;
  6153. }
  6154. _free(GL.contexts[contextHandle].handle);
  6155. GL.contexts[contextHandle] = null;
  6156. },
  6157. initExtensions: context => {
  6158. // If this function is called without a specific context object, init the
  6159. // extensions of the currently active context.
  6160. context ||= GL.currentContext;
  6161. if (context.initExtensionsDone) return;
  6162. context.initExtensionsDone = true;
  6163. var GLctx = context.GLctx;
  6164. // Detect the presence of a few extensions manually, since the GL interop
  6165. // layer itself will need to know if they exist.
  6166. // Extensions that are available in both WebGL 1 and WebGL 2
  6167. webgl_enable_WEBGL_multi_draw(GLctx);
  6168. webgl_enable_EXT_polygon_offset_clamp(GLctx);
  6169. webgl_enable_EXT_clip_control(GLctx);
  6170. webgl_enable_WEBGL_polygon_mode(GLctx);
  6171. // Extensions that are only available in WebGL 1 (the calls will be no-ops
  6172. // if called on a WebGL 2 context active)
  6173. webgl_enable_ANGLE_instanced_arrays(GLctx);
  6174. webgl_enable_OES_vertex_array_object(GLctx);
  6175. webgl_enable_WEBGL_draw_buffers(GLctx);
  6176. {
  6177. GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query");
  6178. }
  6179. for (var ext of getEmscriptenSupportedExtensions(GLctx)) {
  6180. // WEBGL_lose_context, WEBGL_debug_renderer_info and WEBGL_debug_shaders
  6181. // are not enabled by default.
  6182. if (!ext.includes("lose_context") && !ext.includes("debug")) {
  6183. // Call .getExtension() to enable that extension permanently.
  6184. GLctx.getExtension(ext);
  6185. }
  6186. }
  6187. }
  6188. };
  6189. function _eglCreateContext(display, config, hmm, contextAttribs) {
  6190. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(18, 0, 1, display, config, hmm, contextAttribs);
  6191. if (display != 62e3) {
  6192. EGL.setErrorCode(12296);
  6193. return 0;
  6194. }
  6195. // EGL 1.4 spec says default EGL_CONTEXT_CLIENT_VERSION is GLES1, but this is not supported by Emscripten.
  6196. // So user must pass EGL_CONTEXT_CLIENT_VERSION == 2 to initialize EGL.
  6197. var glesContextVersion = 1;
  6198. for (;;) {
  6199. var param = (growMemViews(), HEAP32)[((contextAttribs) >> 2)];
  6200. if (param == 12440) {
  6201. glesContextVersion = (growMemViews(), HEAP32)[(((contextAttribs) + (4)) >> 2)];
  6202. } else if (param == 12344) {
  6203. break;
  6204. } else {
  6205. /* EGL1.4 specifies only EGL_CONTEXT_CLIENT_VERSION as supported attribute */ EGL.setErrorCode(12292);
  6206. return 0;
  6207. }
  6208. contextAttribs += 8;
  6209. }
  6210. if (glesContextVersion != 2) {
  6211. EGL.setErrorCode(12293);
  6212. return 0;
  6213. }
  6214. EGL.contextAttributes.majorVersion = glesContextVersion - 1;
  6215. // WebGL 1 is GLES 2, WebGL2 is GLES3
  6216. EGL.contextAttributes.minorVersion = 0;
  6217. EGL.context = GL.createContext(Browser.getCanvas(), EGL.contextAttributes);
  6218. if (EGL.context != 0) {
  6219. EGL.setErrorCode(12288);
  6220. // Run callbacks so that GL emulation works
  6221. GL.makeContextCurrent(EGL.context);
  6222. Browser.useWebGL = true;
  6223. Browser.moduleContextCreatedCallbacks.forEach(callback => callback());
  6224. // Note: This function only creates a context, but it shall not make it active.
  6225. GL.makeContextCurrent(null);
  6226. return 62004;
  6227. } else {
  6228. EGL.setErrorCode(12297);
  6229. // By the EGL 1.4 spec, an implementation that does not support GLES2 (WebGL in this case), this error code is set.
  6230. return 0;
  6231. }
  6232. }
  6233. function _eglCreateWindowSurface(display, config, win, attrib_list) {
  6234. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(19, 0, 1, display, config, win, attrib_list);
  6235. if (display != 62e3) {
  6236. EGL.setErrorCode(12296);
  6237. return 0;
  6238. }
  6239. if (config != 62002) {
  6240. EGL.setErrorCode(12293);
  6241. return 0;
  6242. }
  6243. // TODO: Examine attrib_list! Parameters that can be present there are:
  6244. // - EGL_RENDER_BUFFER (must be EGL_BACK_BUFFER)
  6245. // - EGL_VG_COLORSPACE (can't be set)
  6246. // - EGL_VG_ALPHA_FORMAT (can't be set)
  6247. EGL.setErrorCode(12288);
  6248. return 62006;
  6249. }
  6250. function _eglDestroyContext(display, context) {
  6251. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(20, 0, 1, display, context);
  6252. if (display != 62e3) {
  6253. EGL.setErrorCode(12296);
  6254. return 0;
  6255. }
  6256. if (context != 62004) {
  6257. EGL.setErrorCode(12294);
  6258. return 0;
  6259. }
  6260. GL.deleteContext(EGL.context);
  6261. EGL.setErrorCode(12288);
  6262. if (EGL.currentContext == context) {
  6263. EGL.currentContext = 0;
  6264. }
  6265. return 1;
  6266. }
  6267. function _eglDestroySurface(display, surface) {
  6268. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(21, 0, 1, display, surface);
  6269. if (display != 62e3) {
  6270. EGL.setErrorCode(12296);
  6271. return 0;
  6272. }
  6273. if (surface != 62006) {
  6274. EGL.setErrorCode(12301);
  6275. return 1;
  6276. }
  6277. if (EGL.currentReadSurface == surface) {
  6278. EGL.currentReadSurface = 0;
  6279. }
  6280. if (EGL.currentDrawSurface == surface) {
  6281. EGL.currentDrawSurface = 0;
  6282. }
  6283. EGL.setErrorCode(12288);
  6284. return 1;
  6285. }
  6286. function _eglGetConfigAttrib(display, config, attribute, value) {
  6287. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(22, 0, 1, display, config, attribute, value);
  6288. if (display != 62e3) {
  6289. EGL.setErrorCode(12296);
  6290. return 0;
  6291. }
  6292. if (config != 62002) {
  6293. EGL.setErrorCode(12293);
  6294. return 0;
  6295. }
  6296. if (!value) {
  6297. EGL.setErrorCode(12300);
  6298. return 0;
  6299. }
  6300. EGL.setErrorCode(12288);
  6301. switch (attribute) {
  6302. case 12320:
  6303. // EGL_BUFFER_SIZE
  6304. (growMemViews(), HEAP32)[((value) >> 2)] = EGL.contextAttributes.alpha ? 32 : 24;
  6305. return 1;
  6306. case 12321:
  6307. // EGL_ALPHA_SIZE
  6308. (growMemViews(), HEAP32)[((value) >> 2)] = EGL.contextAttributes.alpha ? 8 : 0;
  6309. return 1;
  6310. case 12322:
  6311. // EGL_BLUE_SIZE
  6312. (growMemViews(), HEAP32)[((value) >> 2)] = 8;
  6313. return 1;
  6314. case 12323:
  6315. // EGL_GREEN_SIZE
  6316. (growMemViews(), HEAP32)[((value) >> 2)] = 8;
  6317. return 1;
  6318. case 12324:
  6319. // EGL_RED_SIZE
  6320. (growMemViews(), HEAP32)[((value) >> 2)] = 8;
  6321. return 1;
  6322. case 12325:
  6323. // EGL_DEPTH_SIZE
  6324. (growMemViews(), HEAP32)[((value) >> 2)] = EGL.contextAttributes.depth ? 24 : 0;
  6325. return 1;
  6326. case 12326:
  6327. // EGL_STENCIL_SIZE
  6328. (growMemViews(), HEAP32)[((value) >> 2)] = EGL.contextAttributes.stencil ? 8 : 0;
  6329. return 1;
  6330. case 12327:
  6331. // EGL_CONFIG_CAVEAT
  6332. // We can return here one of EGL_NONE (0x3038), EGL_SLOW_CONFIG (0x3050) or EGL_NON_CONFORMANT_CONFIG (0x3051).
  6333. (growMemViews(), HEAP32)[((value) >> 2)] = 12344;
  6334. return 1;
  6335. case 12328:
  6336. // EGL_CONFIG_ID
  6337. (growMemViews(), HEAP32)[((value) >> 2)] = 62002;
  6338. return 1;
  6339. case 12329:
  6340. // EGL_LEVEL
  6341. (growMemViews(), HEAP32)[((value) >> 2)] = 0;
  6342. return 1;
  6343. case 12330:
  6344. // EGL_MAX_PBUFFER_HEIGHT
  6345. (growMemViews(), HEAP32)[((value) >> 2)] = 4096;
  6346. return 1;
  6347. case 12331:
  6348. // EGL_MAX_PBUFFER_PIXELS
  6349. (growMemViews(), HEAP32)[((value) >> 2)] = 16777216;
  6350. return 1;
  6351. case 12332:
  6352. // EGL_MAX_PBUFFER_WIDTH
  6353. (growMemViews(), HEAP32)[((value) >> 2)] = 4096;
  6354. return 1;
  6355. case 12333:
  6356. // EGL_NATIVE_RENDERABLE
  6357. (growMemViews(), HEAP32)[((value) >> 2)] = 0;
  6358. return 1;
  6359. case 12334:
  6360. // EGL_NATIVE_VISUAL_ID
  6361. (growMemViews(), HEAP32)[((value) >> 2)] = 0;
  6362. return 1;
  6363. case 12335:
  6364. // EGL_NATIVE_VISUAL_TYPE
  6365. (growMemViews(), HEAP32)[((value) >> 2)] = 12344;
  6366. return 1;
  6367. case 12337:
  6368. // EGL_SAMPLES
  6369. (growMemViews(), HEAP32)[((value) >> 2)] = EGL.contextAttributes.antialias ? 4 : 0;
  6370. return 1;
  6371. case 12338:
  6372. // EGL_SAMPLE_BUFFERS
  6373. (growMemViews(), HEAP32)[((value) >> 2)] = EGL.contextAttributes.antialias ? 1 : 0;
  6374. return 1;
  6375. case 12339:
  6376. // EGL_SURFACE_TYPE
  6377. (growMemViews(), HEAP32)[((value) >> 2)] = 4;
  6378. return 1;
  6379. case 12340:
  6380. // EGL_TRANSPARENT_TYPE
  6381. // If this returns EGL_TRANSPARENT_RGB (0x3052), transparency is used through color-keying. No such thing applies to Emscripten canvas.
  6382. (growMemViews(), HEAP32)[((value) >> 2)] = 12344;
  6383. return 1;
  6384. case 12341:
  6385. // EGL_TRANSPARENT_BLUE_VALUE
  6386. case 12342:
  6387. // EGL_TRANSPARENT_GREEN_VALUE
  6388. case 12343:
  6389. // EGL_TRANSPARENT_RED_VALUE
  6390. // "If EGL_TRANSPARENT_TYPE is EGL_NONE, then the values for EGL_TRANSPARENT_RED_VALUE, EGL_TRANSPARENT_GREEN_VALUE, and EGL_TRANSPARENT_BLUE_VALUE are undefined."
  6391. (growMemViews(), HEAP32)[((value) >> 2)] = -1;
  6392. return 1;
  6393. case 12345:
  6394. // EGL_BIND_TO_TEXTURE_RGB
  6395. case 12346:
  6396. // EGL_BIND_TO_TEXTURE_RGBA
  6397. (growMemViews(), HEAP32)[((value) >> 2)] = 0;
  6398. return 1;
  6399. case 12347:
  6400. // EGL_MIN_SWAP_INTERVAL
  6401. (growMemViews(), HEAP32)[((value) >> 2)] = 0;
  6402. return 1;
  6403. case 12348:
  6404. // EGL_MAX_SWAP_INTERVAL
  6405. (growMemViews(), HEAP32)[((value) >> 2)] = 1;
  6406. return 1;
  6407. case 12349:
  6408. // EGL_LUMINANCE_SIZE
  6409. case 12350:
  6410. // EGL_ALPHA_MASK_SIZE
  6411. (growMemViews(), HEAP32)[((value) >> 2)] = 0;
  6412. return 1;
  6413. case 12351:
  6414. // EGL_COLOR_BUFFER_TYPE
  6415. // EGL has two types of buffers: EGL_RGB_BUFFER and EGL_LUMINANCE_BUFFER.
  6416. (growMemViews(), HEAP32)[((value) >> 2)] = 12430;
  6417. return 1;
  6418. case 12352:
  6419. // EGL_RENDERABLE_TYPE
  6420. // A bit combination of EGL_OPENGL_ES_BIT,EGL_OPENVG_BIT,EGL_OPENGL_ES2_BIT and EGL_OPENGL_BIT.
  6421. (growMemViews(), HEAP32)[((value) >> 2)] = 4;
  6422. return 1;
  6423. case 12354:
  6424. // EGL_CONFORMANT
  6425. // "EGL_CONFORMANT is a mask indicating if a client API context created with respect to the corresponding EGLConfig will pass the required conformance tests for that API."
  6426. (growMemViews(), HEAP32)[((value) >> 2)] = 0;
  6427. return 1;
  6428. default:
  6429. EGL.setErrorCode(12292);
  6430. return 0;
  6431. }
  6432. }
  6433. function _eglGetDisplay(nativeDisplayType) {
  6434. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(23, 0, 1, nativeDisplayType);
  6435. EGL.setErrorCode(12288);
  6436. // Emscripten EGL implementation "emulates" X11, and eglGetDisplay is
  6437. // expected to accept/receive a pointer to an X11 Display object (or
  6438. // EGL_DEFAULT_DISPLAY).
  6439. if (nativeDisplayType != 0 && nativeDisplayType != 1) {
  6440. return 0;
  6441. }
  6442. return 62e3;
  6443. }
  6444. function _eglGetError() {
  6445. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(24, 0, 1);
  6446. return EGL.errorCode;
  6447. }
  6448. function _eglInitialize(display, majorVersion, minorVersion) {
  6449. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(25, 0, 1, display, majorVersion, minorVersion);
  6450. if (display != 62e3) {
  6451. EGL.setErrorCode(12296);
  6452. return 0;
  6453. }
  6454. if (majorVersion) {
  6455. (growMemViews(), HEAP32)[((majorVersion) >> 2)] = 1;
  6456. }
  6457. if (minorVersion) {
  6458. (growMemViews(), HEAP32)[((minorVersion) >> 2)] = 4;
  6459. }
  6460. EGL.defaultDisplayInitialized = true;
  6461. EGL.setErrorCode(12288);
  6462. return 1;
  6463. }
  6464. function _eglMakeCurrent(display, draw, read, context) {
  6465. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(26, 0, 1, display, draw, read, context);
  6466. if (display != 62e3) {
  6467. EGL.setErrorCode(12296);
  6468. return 0;
  6469. }
  6470. //\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy.
  6471. if (context != 0 && context != 62004) {
  6472. EGL.setErrorCode(12294);
  6473. return 0;
  6474. }
  6475. if ((read != 0 && read != 62006) || (draw != 0 && draw != 62006)) {
  6476. EGL.setErrorCode(12301);
  6477. return 0;
  6478. }
  6479. GL.makeContextCurrent(context ? EGL.context : null);
  6480. EGL.currentContext = context;
  6481. EGL.currentDrawSurface = draw;
  6482. EGL.currentReadSurface = read;
  6483. EGL.setErrorCode(12288);
  6484. return 1;
  6485. }
  6486. var stringToNewUTF8 = str => {
  6487. var size = lengthBytesUTF8(str) + 1;
  6488. var ret = _malloc(size);
  6489. if (ret) stringToUTF8(str, ret, size);
  6490. return ret;
  6491. };
  6492. function _eglQueryString(display, name) {
  6493. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(27, 0, 1, display, name);
  6494. if (display != 62e3) {
  6495. EGL.setErrorCode(12296);
  6496. return 0;
  6497. }
  6498. //\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy.
  6499. EGL.setErrorCode(12288);
  6500. if (EGL.stringCache[name]) return EGL.stringCache[name];
  6501. var ret;
  6502. switch (name) {
  6503. case 12371:
  6504. ret = stringToNewUTF8("Emscripten");
  6505. break;
  6506. case 12372:
  6507. ret = stringToNewUTF8("1.4 Emscripten EGL");
  6508. break;
  6509. case 12373:
  6510. ret = stringToNewUTF8("");
  6511. break;
  6512. // Currently not supporting any EGL extensions.
  6513. case 12429:
  6514. ret = stringToNewUTF8("OpenGL_ES");
  6515. break;
  6516. default:
  6517. EGL.setErrorCode(12300);
  6518. return 0;
  6519. }
  6520. EGL.stringCache[name] = ret;
  6521. return ret;
  6522. }
  6523. function _eglSwapBuffers(dpy, surface) {
  6524. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(28, 0, 1, dpy, surface);
  6525. if (!EGL.defaultDisplayInitialized) {
  6526. EGL.setErrorCode(12289);
  6527. } else if (!GLctx) {
  6528. EGL.setErrorCode(12290);
  6529. } else if (GLctx.isContextLost()) {
  6530. EGL.setErrorCode(12302);
  6531. } else {
  6532. // According to documentation this does an implicit flush.
  6533. // Due to discussion at https://github.com/emscripten-core/emscripten/pull/1871
  6534. // the flush was removed since this _may_ result in slowing code down.
  6535. //_glFlush();
  6536. EGL.setErrorCode(12288);
  6537. return 1;
  6538. }
  6539. return 0;
  6540. }
  6541. /**
  6542. * @param {number=} arg
  6543. * @param {boolean=} noSetTiming
  6544. */ var setMainLoop = (iterFunc, fps, simulateInfiniteLoop, arg, noSetTiming) => {
  6545. assert(!MainLoop.func, "emscripten_set_main_loop: there can only be one main loop function at once");
  6546. MainLoop.func = iterFunc;
  6547. MainLoop.arg = arg;
  6548. var thisMainLoopId = MainLoop.currentlyRunningMainloop;
  6549. function checkIsRunning() {
  6550. if (thisMainLoopId < MainLoop.currentlyRunningMainloop) {
  6551. runtimeKeepalivePop();
  6552. maybeExit();
  6553. return false;
  6554. }
  6555. return true;
  6556. }
  6557. // We create the loop runner here but it is not actually running until
  6558. // _emscripten_set_main_loop_timing is called (which might happen at a
  6559. // later time). This member signifies that the current runner has not
  6560. // yet been started so that we can call runtimeKeepalivePush when it
  6561. // gets its timing set for the first time.
  6562. MainLoop.running = false;
  6563. MainLoop.runner = function MainLoop_runner() {
  6564. if (ABORT) return;
  6565. if (MainLoop.queue.length > 0) {
  6566. var start = Date.now();
  6567. var blocker = MainLoop.queue.shift();
  6568. blocker.func(blocker.arg);
  6569. if (MainLoop.remainingBlockers) {
  6570. var remaining = MainLoop.remainingBlockers;
  6571. var next = remaining % 1 == 0 ? remaining - 1 : Math.floor(remaining);
  6572. if (blocker.counted) {
  6573. MainLoop.remainingBlockers = next;
  6574. } else {
  6575. // not counted, but move the progress along a tiny bit
  6576. next = next + .5;
  6577. // do not steal all the next one's progress
  6578. MainLoop.remainingBlockers = (8 * remaining + next) / 9;
  6579. }
  6580. }
  6581. MainLoop.updateStatus();
  6582. // catches pause/resume main loop from blocker execution
  6583. if (!checkIsRunning()) return;
  6584. setTimeout(MainLoop.runner, 0);
  6585. return;
  6586. }
  6587. // catch pauses from non-main loop sources
  6588. if (!checkIsRunning()) return;
  6589. // Implement very basic swap interval control
  6590. MainLoop.currentFrameNumber = MainLoop.currentFrameNumber + 1 | 0;
  6591. if (MainLoop.timingMode == 1 && MainLoop.timingValue > 1 && MainLoop.currentFrameNumber % MainLoop.timingValue != 0) {
  6592. // Not the scheduled time to render this frame - skip.
  6593. MainLoop.scheduler();
  6594. return;
  6595. } else if (MainLoop.timingMode == 0) {
  6596. MainLoop.tickStartTime = _emscripten_get_now();
  6597. if (Module["ctx"]) {
  6598. warnOnce("Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!");
  6599. }
  6600. }
  6601. MainLoop.runIter(iterFunc);
  6602. // catch pauses from the main loop itself
  6603. if (!checkIsRunning()) return;
  6604. MainLoop.scheduler();
  6605. };
  6606. if (!noSetTiming) {
  6607. if (fps > 0) {
  6608. _emscripten_set_main_loop_timing(0, 1e3 / fps);
  6609. } else {
  6610. // Do rAF by rendering each frame (no decimating)
  6611. _emscripten_set_main_loop_timing(1, 1);
  6612. }
  6613. MainLoop.scheduler();
  6614. }
  6615. if (simulateInfiniteLoop) {
  6616. throw "unwind";
  6617. }
  6618. };
  6619. var MainLoop = {
  6620. running: false,
  6621. scheduler: null,
  6622. currentlyRunningMainloop: 0,
  6623. func: null,
  6624. arg: 0,
  6625. timingMode: 0,
  6626. timingValue: 0,
  6627. currentFrameNumber: 0,
  6628. queue: [],
  6629. preMainLoop: [],
  6630. postMainLoop: [],
  6631. pause() {
  6632. MainLoop.scheduler = null;
  6633. // Incrementing this signals the previous main loop that it's now become old, and it must return.
  6634. MainLoop.currentlyRunningMainloop++;
  6635. },
  6636. resume() {
  6637. MainLoop.currentlyRunningMainloop++;
  6638. var timingMode = MainLoop.timingMode;
  6639. var timingValue = MainLoop.timingValue;
  6640. var func = MainLoop.func;
  6641. MainLoop.func = null;
  6642. // do not set timing and call scheduler, we will do it on the next lines
  6643. setMainLoop(func, 0, false, MainLoop.arg, true);
  6644. _emscripten_set_main_loop_timing(timingMode, timingValue);
  6645. MainLoop.scheduler();
  6646. },
  6647. updateStatus() {
  6648. if (Module["setStatus"]) {
  6649. var message = Module["statusMessage"] || "Please wait...";
  6650. var remaining = MainLoop.remainingBlockers ?? 0;
  6651. var expected = MainLoop.expectedBlockers ?? 0;
  6652. if (remaining) {
  6653. if (remaining < expected) {
  6654. Module["setStatus"](`{message} ({expected - remaining}/{expected})`);
  6655. } else {
  6656. Module["setStatus"](message);
  6657. }
  6658. } else {
  6659. Module["setStatus"]("");
  6660. }
  6661. }
  6662. },
  6663. init() {},
  6664. runIter(func) {
  6665. if (ABORT) return;
  6666. for (var pre of MainLoop.preMainLoop) {
  6667. if (pre() === false) {
  6668. return;
  6669. }
  6670. }
  6671. callUserCallback(func);
  6672. for (var post of MainLoop.postMainLoop) {
  6673. post();
  6674. }
  6675. checkStackCookie();
  6676. },
  6677. nextRAF: 0,
  6678. fakeRequestAnimationFrame(func) {
  6679. // try to keep 60fps between calls to here
  6680. var now = Date.now();
  6681. if (MainLoop.nextRAF === 0) {
  6682. MainLoop.nextRAF = now + 1e3 / 60;
  6683. } else {
  6684. while (now + 2 >= MainLoop.nextRAF) {
  6685. // fudge a little, to avoid timer jitter causing us to do lots of delay:0
  6686. MainLoop.nextRAF += 1e3 / 60;
  6687. }
  6688. }
  6689. var delay = Math.max(MainLoop.nextRAF - now, 0);
  6690. setTimeout(func, delay);
  6691. },
  6692. requestAnimationFrame(func) {
  6693. if (globalThis.requestAnimationFrame) {
  6694. requestAnimationFrame(func);
  6695. } else {
  6696. MainLoop.fakeRequestAnimationFrame(func);
  6697. }
  6698. }
  6699. };
  6700. var _emscripten_set_main_loop_timing = (mode, value) => {
  6701. MainLoop.timingMode = mode;
  6702. MainLoop.timingValue = value;
  6703. if (!MainLoop.func) {
  6704. err("emscripten_set_main_loop_timing: Cannot set timing mode for main loop since a main loop does not exist! Call emscripten_set_main_loop first to set one up.");
  6705. return 1;
  6706. }
  6707. if (!MainLoop.running) {
  6708. runtimeKeepalivePush();
  6709. MainLoop.running = true;
  6710. }
  6711. if (mode == 0) {
  6712. MainLoop.scheduler = function MainLoop_scheduler_setTimeout() {
  6713. var timeUntilNextTick = Math.max(0, MainLoop.tickStartTime + value - _emscripten_get_now()) | 0;
  6714. setTimeout(MainLoop.runner, timeUntilNextTick);
  6715. };
  6716. } else if (mode == 1) {
  6717. MainLoop.scheduler = function MainLoop_scheduler_rAF() {
  6718. MainLoop.requestAnimationFrame(MainLoop.runner);
  6719. };
  6720. } else {
  6721. assert(mode == 2);
  6722. if (!MainLoop.setImmediate) {
  6723. if (globalThis.scheduler) {
  6724. // Some modern browsers implement scheduler.postTask, but not all.
  6725. MainLoop.setImmediate = scheduler.postTask.bind(scheduler);
  6726. } else if (globalThis.setImmediate) {
  6727. MainLoop.setImmediate = setImmediate;
  6728. } else {
  6729. // Emulate setImmediate. (note: not a complete polyfill, we don't emulate clearImmediate() to keep code size to minimum, since not needed)
  6730. var setImmediates = [];
  6731. var emscriptenMainLoopMessageId = "setimmediate";
  6732. /** @param {Event} event */ var MainLoop_setImmediate_messageHandler = event => {
  6733. if (event.data === emscriptenMainLoopMessageId) {
  6734. event.stopPropagation();
  6735. setImmediates.shift()();
  6736. }
  6737. };
  6738. addEventListener("message", MainLoop_setImmediate_messageHandler, true);
  6739. MainLoop.setImmediate = /** @type{function(function(): ?, ...?): number} */ (func => {
  6740. setImmediates.push(func);
  6741. if (ENVIRONMENT_IS_WORKER) {
  6742. // The postMessge API in a Worker, sends message to the main
  6743. // thread and does not support the `targetOrigin` (*) argument.
  6744. postMessage(emscriptenMainLoopMessageId);
  6745. } else {
  6746. postMessage(emscriptenMainLoopMessageId, "*");
  6747. }
  6748. });
  6749. }
  6750. }
  6751. MainLoop.scheduler = function MainLoop_scheduler_setImmediate() {
  6752. MainLoop.setImmediate(MainLoop.runner);
  6753. };
  6754. }
  6755. return 0;
  6756. };
  6757. function _eglSwapInterval(display, interval) {
  6758. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(29, 0, 1, display, interval);
  6759. if (display != 62e3) {
  6760. EGL.setErrorCode(12296);
  6761. return 0;
  6762. }
  6763. if (interval == 0) _emscripten_set_main_loop_timing(0, 0); else _emscripten_set_main_loop_timing(1, interval);
  6764. EGL.setErrorCode(12288);
  6765. return 1;
  6766. }
  6767. function _eglTerminate(display) {
  6768. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(30, 0, 1, display);
  6769. if (display != 62e3) {
  6770. EGL.setErrorCode(12296);
  6771. return 0;
  6772. }
  6773. EGL.currentContext = 0;
  6774. EGL.currentReadSurface = 0;
  6775. EGL.currentDrawSurface = 0;
  6776. EGL.defaultDisplayInitialized = false;
  6777. EGL.setErrorCode(12288);
  6778. return 1;
  6779. }
  6780. function _eglWaitClient() {
  6781. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(31, 0, 1);
  6782. EGL.setErrorCode(12288);
  6783. return 1;
  6784. }
  6785. var _eglWaitGL = _eglWaitClient;
  6786. function _eglWaitNative(nativeEngineId) {
  6787. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(32, 0, 1, nativeEngineId);
  6788. EGL.setErrorCode(12288);
  6789. return 1;
  6790. }
  6791. var readEmAsmArgsArray = [];
  6792. var readEmAsmArgs = (sigPtr, buf) => {
  6793. // Nobody should have mutated _readEmAsmArgsArray underneath us to be something else than an array.
  6794. assert(Array.isArray(readEmAsmArgsArray));
  6795. // The input buffer is allocated on the stack, so it must be stack-aligned.
  6796. assert(buf % 16 == 0);
  6797. readEmAsmArgsArray.length = 0;
  6798. var ch;
  6799. // Most arguments are i32s, so shift the buffer pointer so it is a plain
  6800. // index into HEAP32.
  6801. while (ch = (growMemViews(), HEAPU8)[sigPtr++]) {
  6802. var chr = String.fromCharCode(ch);
  6803. var validChars = [ "d", "f", "i", "p" ];
  6804. // In WASM_BIGINT mode we support passing i64 values as bigint.
  6805. validChars.push("j");
  6806. assert(validChars.includes(chr), `Invalid character ${ch}("${chr}") in readEmAsmArgs! Use only [${validChars}], and do not specify "v" for void return argument.`);
  6807. // Floats are always passed as doubles, so all types except for 'i'
  6808. // are 8 bytes and require alignment.
  6809. var wide = (ch != 105);
  6810. wide &= (ch != 112);
  6811. buf += wide && (buf % 8) ? 4 : 0;
  6812. readEmAsmArgsArray.push(// Special case for pointers under wasm64 or CAN_ADDRESS_2GB mode.
  6813. ch == 112 ? (growMemViews(), HEAPU32)[((buf) >> 2)] : ch == 106 ? (growMemViews(),
  6814. HEAP64)[((buf) >> 3)] : ch == 105 ? (growMemViews(), HEAP32)[((buf) >> 2)] : (growMemViews(),
  6815. HEAPF64)[((buf) >> 3)]);
  6816. buf += wide ? 8 : 4;
  6817. }
  6818. return readEmAsmArgsArray;
  6819. };
  6820. var runEmAsmFunction = (code, sigPtr, argbuf) => {
  6821. var args = readEmAsmArgs(sigPtr, argbuf);
  6822. assert(ASM_CONSTS.hasOwnProperty(code), `No EM_ASM constant found at address ${code}. The loaded WebAssembly file is likely out of sync with the generated JavaScript.`);
  6823. return ASM_CONSTS[code](...args);
  6824. };
  6825. var _emscripten_asm_const_int = (code, sigPtr, argbuf) => runEmAsmFunction(code, sigPtr, argbuf);
  6826. var runMainThreadEmAsm = (emAsmAddr, sigPtr, argbuf, sync) => {
  6827. var args = readEmAsmArgs(sigPtr, argbuf);
  6828. if (ENVIRONMENT_IS_PTHREAD) {
  6829. // EM_ASM functions are variadic, receiving the actual arguments as a buffer
  6830. // in memory. the last parameter (argBuf) points to that data. We need to
  6831. // always un-variadify that, *before proxying*, as in the async case this
  6832. // is a stack allocation that LLVM made, which may go away before the main
  6833. // thread gets the message. For that reason we handle proxying *after* the
  6834. // call to readEmAsmArgs, and therefore we do that manually here instead
  6835. // of using __proxy. (And for simplicity, do the same in the sync
  6836. // case as well, even though it's not strictly necessary, to keep the two
  6837. // code paths as similar as possible on both sides.)
  6838. return proxyToMainThread(0, emAsmAddr, sync, ...args);
  6839. }
  6840. assert(ASM_CONSTS.hasOwnProperty(emAsmAddr), `No EM_ASM constant found at address ${emAsmAddr}. The loaded WebAssembly file is likely out of sync with the generated JavaScript.`);
  6841. return ASM_CONSTS[emAsmAddr](...args);
  6842. };
  6843. var _emscripten_asm_const_int_sync_on_main_thread = (emAsmAddr, sigPtr, argbuf) => runMainThreadEmAsm(emAsmAddr, sigPtr, argbuf, 1);
  6844. var _emscripten_asm_const_ptr_sync_on_main_thread = (emAsmAddr, sigPtr, argbuf) => runMainThreadEmAsm(emAsmAddr, sigPtr, argbuf, 1);
  6845. var _emscripten_cancel_main_loop = () => {
  6846. MainLoop.pause();
  6847. MainLoop.func = null;
  6848. };
  6849. var _emscripten_check_blocking_allowed = () => {
  6850. if (ENVIRONMENT_IS_NODE) return;
  6851. if (ENVIRONMENT_IS_WORKER) return;
  6852. // Blocking in a worker/pthread is fine.
  6853. warnOnce("Blocking on the main thread is very dangerous, see https://emscripten.org/docs/porting/pthreads.html#blocking-on-the-main-browser-thread");
  6854. };
  6855. var onExits = [];
  6856. var addOnExit = cb => onExits.push(cb);
  6857. var JSEvents = {
  6858. removeAllEventListeners() {
  6859. while (JSEvents.eventHandlers.length) {
  6860. JSEvents._removeHandler(JSEvents.eventHandlers.length - 1);
  6861. }
  6862. JSEvents.deferredCalls = [];
  6863. },
  6864. inEventHandler: 0,
  6865. deferredCalls: [],
  6866. deferCall(targetFunction, precedence, argsList) {
  6867. function arraysHaveEqualContent(arrA, arrB) {
  6868. if (arrA.length != arrB.length) return false;
  6869. for (var i in arrA) {
  6870. if (arrA[i] != arrB[i]) return false;
  6871. }
  6872. return true;
  6873. }
  6874. // Test if the given call was already queued, and if so, don't add it again.
  6875. for (var call of JSEvents.deferredCalls) {
  6876. if (call.targetFunction == targetFunction && arraysHaveEqualContent(call.argsList, argsList)) {
  6877. return;
  6878. }
  6879. }
  6880. JSEvents.deferredCalls.push({
  6881. targetFunction,
  6882. precedence,
  6883. argsList
  6884. });
  6885. JSEvents.deferredCalls.sort((x, y) => x.precedence - y.precedence);
  6886. },
  6887. removeDeferredCalls(targetFunction) {
  6888. JSEvents.deferredCalls = JSEvents.deferredCalls.filter(call => call.targetFunction != targetFunction);
  6889. },
  6890. canPerformEventHandlerRequests() {
  6891. // Browsers that support navigator.userActivation.isActive: https://developer.mozilla.org/en-US/docs/Web/API/UserActivation/isActive
  6892. if (navigator.userActivation) {
  6893. // Verify against transient activation status from UserActivation API
  6894. // whether it is possible to perform a request here without needing to defer. See
  6895. // https://developer.mozilla.org/en-US/docs/Web/Security/User_activation#transient_activation
  6896. // and https://caniuse.com/mdn-api_useractivation
  6897. return navigator.userActivation.isActive;
  6898. }
  6899. return JSEvents.inEventHandler && JSEvents.currentEventHandler.allowsDeferredCalls;
  6900. },
  6901. runDeferredCalls() {
  6902. if (!JSEvents.canPerformEventHandlerRequests()) {
  6903. return;
  6904. }
  6905. var deferredCalls = JSEvents.deferredCalls;
  6906. JSEvents.deferredCalls = [];
  6907. for (var call of deferredCalls) {
  6908. call.targetFunction(...call.argsList);
  6909. }
  6910. },
  6911. eventHandlers: [],
  6912. removeAllHandlersOnTarget: (target, eventTypeString) => {
  6913. for (var i = 0; i < JSEvents.eventHandlers.length; ++i) {
  6914. if (JSEvents.eventHandlers[i].target == target && (!eventTypeString || eventTypeString == JSEvents.eventHandlers[i].eventTypeString)) {
  6915. JSEvents._removeHandler(i--);
  6916. }
  6917. }
  6918. },
  6919. _removeHandler(i) {
  6920. var h = JSEvents.eventHandlers[i];
  6921. h.target.removeEventListener(h.eventTypeString, h.eventListenerFunc, h.useCapture);
  6922. JSEvents.eventHandlers.splice(i, 1);
  6923. },
  6924. registerOrRemoveHandler(eventHandler) {
  6925. if (!eventHandler.target) {
  6926. err("registerOrRemoveHandler: the target element for event handler registration does not exist, when processing the following event handler registration:");
  6927. console.dir(eventHandler);
  6928. return -4;
  6929. }
  6930. if (eventHandler.callbackfunc) {
  6931. eventHandler.eventListenerFunc = function(event) {
  6932. // Increment nesting count for the event handler.
  6933. ++JSEvents.inEventHandler;
  6934. JSEvents.currentEventHandler = eventHandler;
  6935. // Process any old deferred calls the user has placed.
  6936. JSEvents.runDeferredCalls();
  6937. // Process the actual event, calls back to user C code handler.
  6938. eventHandler.handlerFunc(event);
  6939. // Process any new deferred calls that were placed right now from this event handler.
  6940. JSEvents.runDeferredCalls();
  6941. // Out of event handler - restore nesting count.
  6942. --JSEvents.inEventHandler;
  6943. };
  6944. eventHandler.target.addEventListener(eventHandler.eventTypeString, eventHandler.eventListenerFunc, eventHandler.useCapture);
  6945. JSEvents.eventHandlers.push(eventHandler);
  6946. } else {
  6947. for (var i = 0; i < JSEvents.eventHandlers.length; ++i) {
  6948. if (JSEvents.eventHandlers[i].target == eventHandler.target && JSEvents.eventHandlers[i].eventTypeString == eventHandler.eventTypeString) {
  6949. JSEvents._removeHandler(i--);
  6950. }
  6951. }
  6952. }
  6953. return 0;
  6954. },
  6955. removeSingleHandler(eventHandler) {
  6956. let success = false;
  6957. for (let i = 0; i < JSEvents.eventHandlers.length; ++i) {
  6958. const handler = JSEvents.eventHandlers[i];
  6959. if (handler.target === eventHandler.target && handler.eventTypeId === eventHandler.eventTypeId && handler.callbackfunc === eventHandler.callbackfunc && handler.userData === eventHandler.userData) {
  6960. // in some very rare cases (ex: Safari / fullscreen events), there is more than 1 handler (eventTypeString is different)
  6961. JSEvents._removeHandler(i--);
  6962. success = true;
  6963. }
  6964. }
  6965. return success ? 0 : -5;
  6966. },
  6967. getTargetThreadForEventCallback(targetThread) {
  6968. switch (targetThread) {
  6969. case 1:
  6970. // The event callback for the current event should be called on the
  6971. // main browser thread. (0 == don't proxy)
  6972. return 0;
  6973. case 2:
  6974. // The event callback for the current event should be backproxied to
  6975. // the thread that is registering the event.
  6976. // This can be 0 in the case that the caller uses
  6977. // EM_CALLBACK_THREAD_CONTEXT_CALLING_THREAD but on the main thread
  6978. // itself.
  6979. return PThread.currentProxiedOperationCallerThread;
  6980. default:
  6981. // The event callback for the current event should be proxied to the
  6982. // given specific thread.
  6983. return targetThread;
  6984. }
  6985. },
  6986. getNodeNameForTarget(target) {
  6987. if (target == window) return "#window";
  6988. if (target == screen) return "#screen";
  6989. return target?.nodeName ?? "";
  6990. },
  6991. fullscreenEnabled() {
  6992. return document.fullscreenEnabled || document.webkitFullscreenEnabled;
  6993. }
  6994. };
  6995. /** @type {Object} */ var specialHTMLTargets = [ 0, globalThis.document ?? 0, globalThis.window ?? 0 ];
  6996. var maybeCStringToJsString = cString => cString > 2 ? UTF8ToString(cString) : cString;
  6997. var findEventTarget = target => {
  6998. target = maybeCStringToJsString(target);
  6999. var domElement = specialHTMLTargets[target] || globalThis.document?.querySelector(target);
  7000. return domElement;
  7001. };
  7002. var findCanvasEventTarget = findEventTarget;
  7003. var getCanvasSizeCallingThread = (target, width, height) => {
  7004. var canvas = findCanvasEventTarget(target);
  7005. if (!canvas) return -4;
  7006. if (!canvas.controlTransferredOffscreen) {
  7007. (growMemViews(), HEAP32)[((width) >> 2)] = canvas.width;
  7008. (growMemViews(), HEAP32)[((height) >> 2)] = canvas.height;
  7009. } else {
  7010. return -4;
  7011. }
  7012. return 0;
  7013. };
  7014. function getCanvasSizeMainThread(target, width, height) {
  7015. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(34, 0, 1, target, width, height);
  7016. return getCanvasSizeCallingThread(target, width, height);
  7017. }
  7018. var _emscripten_get_canvas_element_size = (target, width, height) => {
  7019. var canvas = findCanvasEventTarget(target);
  7020. if (canvas) {
  7021. return getCanvasSizeCallingThread(target, width, height);
  7022. }
  7023. return getCanvasSizeMainThread(target, width, height);
  7024. };
  7025. var stringToUTF8OnStack = str => {
  7026. var size = lengthBytesUTF8(str) + 1;
  7027. var ret = stackAlloc(size);
  7028. stringToUTF8(str, ret, size);
  7029. return ret;
  7030. };
  7031. var getCanvasElementSize = target => {
  7032. var sp = stackSave();
  7033. var w = stackAlloc(8);
  7034. var h = w + 4;
  7035. var targetInt = stringToUTF8OnStack(target.id);
  7036. var ret = _emscripten_get_canvas_element_size(targetInt, w, h);
  7037. var size = [ (growMemViews(), HEAP32)[((w) >> 2)], (growMemViews(), HEAP32)[((h) >> 2)] ];
  7038. stackRestore(sp);
  7039. return size;
  7040. };
  7041. var setCanvasElementSizeCallingThread = (target, width, height) => {
  7042. var canvas = findCanvasEventTarget(target);
  7043. if (!canvas) return -4;
  7044. if (!canvas.controlTransferredOffscreen) {
  7045. var autoResizeViewport = false;
  7046. if (canvas.GLctxObject?.GLctx) {
  7047. var prevViewport = canvas.GLctxObject.GLctx.getParameter(2978);
  7048. // TODO: Perhaps autoResizeViewport should only be true if FBO 0 is currently active?
  7049. autoResizeViewport = (prevViewport[0] === 0 && prevViewport[1] === 0 && prevViewport[2] === canvas.width && prevViewport[3] === canvas.height);
  7050. }
  7051. canvas.width = width;
  7052. canvas.height = height;
  7053. if (autoResizeViewport) {
  7054. // TODO: Add -sCANVAS_RESIZE_SETS_GL_VIEWPORT=0/1 option (default=1). This is commonly done and several graphics engines depend on this,
  7055. // but this can be quite disruptive.
  7056. canvas.GLctxObject.GLctx.viewport(0, 0, width, height);
  7057. }
  7058. } else {
  7059. return -4;
  7060. }
  7061. return 0;
  7062. };
  7063. function setCanvasElementSizeMainThread(target, width, height) {
  7064. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(35, 0, 1, target, width, height);
  7065. return setCanvasElementSizeCallingThread(target, width, height);
  7066. }
  7067. var _emscripten_set_canvas_element_size = (target, width, height) => {
  7068. var canvas = findCanvasEventTarget(target);
  7069. if (canvas) {
  7070. return setCanvasElementSizeCallingThread(target, width, height);
  7071. }
  7072. return setCanvasElementSizeMainThread(target, width, height);
  7073. };
  7074. var setCanvasElementSize = (target, width, height) => {
  7075. if (!target.controlTransferredOffscreen) {
  7076. target.width = width;
  7077. target.height = height;
  7078. } else {
  7079. // This function is being called from high-level JavaScript code instead of asm.js/Wasm,
  7080. // and it needs to synchronously proxy over to another thread, so marshal the string onto the heap to do the call.
  7081. var sp = stackSave();
  7082. var targetInt = stringToUTF8OnStack(target.id);
  7083. _emscripten_set_canvas_element_size(targetInt, width, height);
  7084. stackRestore(sp);
  7085. }
  7086. };
  7087. var currentFullscreenStrategy = {};
  7088. var registerRestoreOldStyle = canvas => {
  7089. var canvasSize = getCanvasElementSize(canvas);
  7090. var oldWidth = canvasSize[0];
  7091. var oldHeight = canvasSize[1];
  7092. var oldCssWidth = canvas.style.width;
  7093. var oldCssHeight = canvas.style.height;
  7094. var oldBackgroundColor = canvas.style.backgroundColor;
  7095. // Chrome reads color from here.
  7096. var oldDocumentBackgroundColor = document.body.style.backgroundColor;
  7097. // IE11 reads color from here.
  7098. // Firefox always has black background color.
  7099. var oldPaddingLeft = canvas.style.paddingLeft;
  7100. // Chrome, FF, Safari
  7101. var oldPaddingRight = canvas.style.paddingRight;
  7102. var oldPaddingTop = canvas.style.paddingTop;
  7103. var oldPaddingBottom = canvas.style.paddingBottom;
  7104. var oldMarginLeft = canvas.style.marginLeft;
  7105. // IE11
  7106. var oldMarginRight = canvas.style.marginRight;
  7107. var oldMarginTop = canvas.style.marginTop;
  7108. var oldMarginBottom = canvas.style.marginBottom;
  7109. var oldDocumentBodyMargin = document.body.style.margin;
  7110. var oldDocumentOverflow = document.documentElement.style.overflow;
  7111. // Chrome, Firefox
  7112. var oldDocumentScroll = document.body.scroll;
  7113. // IE
  7114. var oldImageRendering = canvas.style.imageRendering;
  7115. function restoreOldStyle() {
  7116. if (!getFullscreenElement()) {
  7117. document.removeEventListener("fullscreenchange", restoreOldStyle);
  7118. // As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version.
  7119. document.removeEventListener("webkitfullscreenchange", restoreOldStyle);
  7120. setCanvasElementSize(canvas, oldWidth, oldHeight);
  7121. canvas.style.width = oldCssWidth;
  7122. canvas.style.height = oldCssHeight;
  7123. canvas.style.backgroundColor = oldBackgroundColor;
  7124. // Chrome
  7125. // IE11 hack: assigning 'undefined' or an empty string to document.body.style.backgroundColor has no effect, so first assign back the default color
  7126. // before setting the undefined value. Setting undefined value is also important, or otherwise we would later treat that as something that the user
  7127. // had explicitly set so subsequent fullscreen transitions would not set background color properly.
  7128. if (!oldDocumentBackgroundColor) document.body.style.backgroundColor = "white";
  7129. document.body.style.backgroundColor = oldDocumentBackgroundColor;
  7130. // IE11
  7131. canvas.style.paddingLeft = oldPaddingLeft;
  7132. // Chrome, FF, Safari
  7133. canvas.style.paddingRight = oldPaddingRight;
  7134. canvas.style.paddingTop = oldPaddingTop;
  7135. canvas.style.paddingBottom = oldPaddingBottom;
  7136. canvas.style.marginLeft = oldMarginLeft;
  7137. // IE11
  7138. canvas.style.marginRight = oldMarginRight;
  7139. canvas.style.marginTop = oldMarginTop;
  7140. canvas.style.marginBottom = oldMarginBottom;
  7141. document.body.style.margin = oldDocumentBodyMargin;
  7142. document.documentElement.style.overflow = oldDocumentOverflow;
  7143. // Chrome, Firefox
  7144. document.body.scroll = oldDocumentScroll;
  7145. // IE
  7146. canvas.style.imageRendering = oldImageRendering;
  7147. if (canvas.GLctxObject) canvas.GLctxObject.GLctx.viewport(0, 0, oldWidth, oldHeight);
  7148. if (currentFullscreenStrategy.canvasResizedCallback) {
  7149. if (currentFullscreenStrategy.canvasResizedCallbackTargetThread) __emscripten_run_callback_on_thread(currentFullscreenStrategy.canvasResizedCallbackTargetThread, currentFullscreenStrategy.canvasResizedCallback, 37, 0, currentFullscreenStrategy.canvasResizedCallbackUserData); else getWasmTableEntry(currentFullscreenStrategy.canvasResizedCallback)(37, 0, currentFullscreenStrategy.canvasResizedCallbackUserData);
  7150. }
  7151. }
  7152. }
  7153. document.addEventListener("fullscreenchange", restoreOldStyle);
  7154. // As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version.
  7155. document.addEventListener("webkitfullscreenchange", restoreOldStyle);
  7156. return restoreOldStyle;
  7157. };
  7158. var setLetterbox = (element, topBottom, leftRight) => {
  7159. // Cannot use margin to specify letterboxes in FF or Chrome, since those ignore margins in fullscreen mode.
  7160. element.style.paddingLeft = element.style.paddingRight = leftRight + "px";
  7161. element.style.paddingTop = element.style.paddingBottom = topBottom + "px";
  7162. };
  7163. var getBoundingClientRect = e => specialHTMLTargets.indexOf(e) < 0 ? e.getBoundingClientRect() : {
  7164. "left": 0,
  7165. "top": 0
  7166. };
  7167. var JSEvents_resizeCanvasForFullscreen = (target, strategy) => {
  7168. var restoreOldStyle = registerRestoreOldStyle(target);
  7169. var cssWidth = strategy.softFullscreen ? innerWidth : screen.width;
  7170. var cssHeight = strategy.softFullscreen ? innerHeight : screen.height;
  7171. var rect = getBoundingClientRect(target);
  7172. var windowedCssWidth = rect.width;
  7173. var windowedCssHeight = rect.height;
  7174. var canvasSize = getCanvasElementSize(target);
  7175. var windowedRttWidth = canvasSize[0];
  7176. var windowedRttHeight = canvasSize[1];
  7177. if (strategy.scaleMode == 3) {
  7178. setLetterbox(target, (cssHeight - windowedCssHeight) / 2, (cssWidth - windowedCssWidth) / 2);
  7179. cssWidth = windowedCssWidth;
  7180. cssHeight = windowedCssHeight;
  7181. } else if (strategy.scaleMode == 2) {
  7182. if (cssWidth * windowedRttHeight < windowedRttWidth * cssHeight) {
  7183. var desiredCssHeight = windowedRttHeight * cssWidth / windowedRttWidth;
  7184. setLetterbox(target, (cssHeight - desiredCssHeight) / 2, 0);
  7185. cssHeight = desiredCssHeight;
  7186. } else {
  7187. var desiredCssWidth = windowedRttWidth * cssHeight / windowedRttHeight;
  7188. setLetterbox(target, 0, (cssWidth - desiredCssWidth) / 2);
  7189. cssWidth = desiredCssWidth;
  7190. }
  7191. }
  7192. // If we are adding padding, must choose a background color or otherwise Chrome will give the
  7193. // padding a default white color. Do it only if user has not customized their own background color.
  7194. target.style.backgroundColor ||= "black";
  7195. // IE11 does the same, but requires the color to be set in the document body.
  7196. document.body.style.backgroundColor ||= "black";
  7197. // IE11
  7198. // Firefox always shows black letterboxes independent of style color.
  7199. target.style.width = cssWidth + "px";
  7200. target.style.height = cssHeight + "px";
  7201. if (strategy.filteringMode == 1) {
  7202. target.style.imageRendering = "optimizeSpeed";
  7203. target.style.imageRendering = "-moz-crisp-edges";
  7204. target.style.imageRendering = "-o-crisp-edges";
  7205. target.style.imageRendering = "-webkit-optimize-contrast";
  7206. target.style.imageRendering = "optimize-contrast";
  7207. target.style.imageRendering = "crisp-edges";
  7208. target.style.imageRendering = "pixelated";
  7209. }
  7210. var dpiScale = (strategy.canvasResolutionScaleMode == 2) ? devicePixelRatio : 1;
  7211. if (strategy.canvasResolutionScaleMode != 0) {
  7212. var newWidth = (cssWidth * dpiScale) | 0;
  7213. var newHeight = (cssHeight * dpiScale) | 0;
  7214. setCanvasElementSize(target, newWidth, newHeight);
  7215. if (target.GLctxObject) target.GLctxObject.GLctx.viewport(0, 0, newWidth, newHeight);
  7216. }
  7217. return restoreOldStyle;
  7218. };
  7219. var JSEvents_requestFullscreen = (target, strategy) => {
  7220. // EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT + EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE is a mode where no extra logic is performed to the DOM elements.
  7221. if (strategy.scaleMode != 0 || strategy.canvasResolutionScaleMode != 0) {
  7222. JSEvents_resizeCanvasForFullscreen(target, strategy);
  7223. }
  7224. if (target.requestFullscreen) {
  7225. target.requestFullscreen();
  7226. } else if (target.webkitRequestFullscreen) {
  7227. target.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
  7228. } else {
  7229. return JSEvents.fullscreenEnabled() ? -3 : -1;
  7230. }
  7231. currentFullscreenStrategy = strategy;
  7232. if (strategy.canvasResizedCallback) {
  7233. if (strategy.canvasResizedCallbackTargetThread) __emscripten_run_callback_on_thread(strategy.canvasResizedCallbackTargetThread, strategy.canvasResizedCallback, 37, 0, strategy.canvasResizedCallbackUserData); else getWasmTableEntry(strategy.canvasResizedCallback)(37, 0, strategy.canvasResizedCallbackUserData);
  7234. }
  7235. return 0;
  7236. };
  7237. function _emscripten_exit_fullscreen() {
  7238. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(33, 0, 1);
  7239. if (!JSEvents.fullscreenEnabled()) return -1;
  7240. // Make sure no queued up calls will fire after this.
  7241. JSEvents.removeDeferredCalls(JSEvents_requestFullscreen);
  7242. var d = specialHTMLTargets[1];
  7243. if (d.exitFullscreen) {
  7244. d.fullscreenElement && d.exitFullscreen();
  7245. } else if (d.webkitExitFullscreen) {
  7246. d.webkitFullscreenElement && d.webkitExitFullscreen();
  7247. } else {
  7248. return -1;
  7249. }
  7250. return 0;
  7251. }
  7252. var requestPointerLock = target => {
  7253. if (target.requestPointerLock) {
  7254. target.requestPointerLock();
  7255. } else {
  7256. // document.body is known to accept pointer lock, so use that to differentiate if the user passed a bad element,
  7257. // or if the whole browser just doesn't support the feature.
  7258. if (document.body.requestPointerLock) {
  7259. return -3;
  7260. }
  7261. return -1;
  7262. }
  7263. return 0;
  7264. };
  7265. function _emscripten_exit_pointerlock() {
  7266. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(36, 0, 1);
  7267. // Make sure no queued up calls will fire after this.
  7268. JSEvents.removeDeferredCalls(requestPointerLock);
  7269. if (!document.exitPointerLock) return -1;
  7270. document.exitPointerLock();
  7271. return 0;
  7272. }
  7273. var _emscripten_exit_with_live_runtime = () => {
  7274. runtimeKeepalivePush();
  7275. throw "unwind";
  7276. };
  7277. function _emscripten_force_exit(status) {
  7278. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(37, 0, 1, status);
  7279. warnOnce("emscripten_force_exit cannot actually shut down the runtime, as the build does not have EXIT_RUNTIME set");
  7280. __emscripten_runtime_keepalive_clear();
  7281. _exit(status);
  7282. }
  7283. function _emscripten_get_device_pixel_ratio() {
  7284. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(38, 0, 1);
  7285. return globalThis.devicePixelRatio ?? 1;
  7286. }
  7287. function _emscripten_get_element_css_size(target, width, height) {
  7288. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(39, 0, 1, target, width, height);
  7289. target = findEventTarget(target);
  7290. if (!target) return -4;
  7291. var rect = getBoundingClientRect(target);
  7292. (growMemViews(), HEAPF64)[((width) >> 3)] = rect.width;
  7293. (growMemViews(), HEAPF64)[((height) >> 3)] = rect.height;
  7294. return 0;
  7295. }
  7296. var fillGamepadEventData = (eventStruct, e) => {
  7297. (growMemViews(), HEAPF64)[((eventStruct) >> 3)] = e.timestamp;
  7298. for (var i = 0; i < e.axes.length; ++i) {
  7299. (growMemViews(), HEAPF64)[(((eventStruct + i * 8) + (16)) >> 3)] = e.axes[i];
  7300. }
  7301. for (var i = 0; i < e.buttons.length; ++i) {
  7302. if (typeof e.buttons[i] == "object") {
  7303. (growMemViews(), HEAPF64)[(((eventStruct + i * 8) + (528)) >> 3)] = e.buttons[i].value;
  7304. } else {
  7305. (growMemViews(), HEAPF64)[(((eventStruct + i * 8) + (528)) >> 3)] = e.buttons[i];
  7306. }
  7307. }
  7308. for (var i = 0; i < e.buttons.length; ++i) {
  7309. if (typeof e.buttons[i] == "object") {
  7310. (growMemViews(), HEAP8)[(eventStruct + i) + (1040)] = e.buttons[i].pressed;
  7311. } else {
  7312. // Assigning a boolean to HEAP32, that's ok, but Closure would like to warn about it:
  7313. /** @suppress {checkTypes} */ (growMemViews(), HEAP8)[(eventStruct + i) + (1040)] = e.buttons[i] == 1;
  7314. }
  7315. }
  7316. (growMemViews(), HEAP8)[(eventStruct) + (1104)] = e.connected;
  7317. (growMemViews(), HEAP32)[(((eventStruct) + (1108)) >> 2)] = e.index;
  7318. (growMemViews(), HEAP32)[(((eventStruct) + (8)) >> 2)] = e.axes.length;
  7319. (growMemViews(), HEAP32)[(((eventStruct) + (12)) >> 2)] = e.buttons.length;
  7320. stringToUTF8(e.id, eventStruct + 1112, 64);
  7321. stringToUTF8(e.mapping, eventStruct + 1176, 64);
  7322. };
  7323. function _emscripten_get_gamepad_status(index, gamepadState) {
  7324. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(40, 0, 1, index, gamepadState);
  7325. assert(JSEvents.lastGamepadState, "emscripten_get_gamepad_status() called before emscripten_sample_gamepad_data()");
  7326. // INVALID_PARAM is returned on a Gamepad index that never was there.
  7327. if (index < 0 || index >= JSEvents.lastGamepadState.length) return -5;
  7328. // NO_DATA is returned on a Gamepad index that was removed.
  7329. // For previously disconnected gamepads there should be an empty slot (null/undefined/false) at the index.
  7330. // This is because gamepads must keep their original position in the array.
  7331. // For example, removing the first of two gamepads produces [null/undefined/false, gamepad].
  7332. if (!JSEvents.lastGamepadState[index]) return -7;
  7333. fillGamepadEventData(gamepadState, JSEvents.lastGamepadState[index]);
  7334. return 0;
  7335. }
  7336. function _emscripten_get_num_gamepads() {
  7337. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(41, 0, 1);
  7338. assert(JSEvents.lastGamepadState, "emscripten_get_num_gamepads() called before emscripten_sample_gamepad_data()");
  7339. // N.B. Do not call emscripten_get_num_gamepads() unless having first called emscripten_sample_gamepad_data(), and that has returned EMSCRIPTEN_RESULT_SUCCESS.
  7340. // Otherwise the following line will throw an exception.
  7341. return JSEvents.lastGamepadState.length;
  7342. }
  7343. function _emscripten_get_screen_size(width, height) {
  7344. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(42, 0, 1, width, height);
  7345. (growMemViews(), HEAP32)[((width) >> 2)] = screen.width;
  7346. (growMemViews(), HEAP32)[((height) >> 2)] = screen.height;
  7347. }
  7348. var _emscripten_glActiveTexture = x0 => GLctx.activeTexture(x0);
  7349. var _emscripten_glAttachShader = (program, shader) => {
  7350. GLctx.attachShader(GL.programs[program], GL.shaders[shader]);
  7351. };
  7352. var _emscripten_glBeginQueryEXT = (target, id) => {
  7353. GLctx.disjointTimerQueryExt["beginQueryEXT"](target, GL.queries[id]);
  7354. };
  7355. var _emscripten_glBindAttribLocation = (program, index, name) => {
  7356. GLctx.bindAttribLocation(GL.programs[program], index, UTF8ToString(name));
  7357. };
  7358. var _emscripten_glBindBuffer = (target, buffer) => {
  7359. GLctx.bindBuffer(target, GL.buffers[buffer]);
  7360. };
  7361. var _emscripten_glBindFramebuffer = (target, framebuffer) => {
  7362. GLctx.bindFramebuffer(target, GL.framebuffers[framebuffer]);
  7363. };
  7364. var _emscripten_glBindRenderbuffer = (target, renderbuffer) => {
  7365. GLctx.bindRenderbuffer(target, GL.renderbuffers[renderbuffer]);
  7366. };
  7367. var _emscripten_glBindTexture = (target, texture) => {
  7368. GLctx.bindTexture(target, GL.textures[texture]);
  7369. };
  7370. var _emscripten_glBindVertexArray = vao => {
  7371. GLctx.bindVertexArray(GL.vaos[vao]);
  7372. };
  7373. var _glBindVertexArray = _emscripten_glBindVertexArray;
  7374. var _emscripten_glBindVertexArrayOES = _glBindVertexArray;
  7375. var _emscripten_glBlendColor = (x0, x1, x2, x3) => GLctx.blendColor(x0, x1, x2, x3);
  7376. var _emscripten_glBlendEquation = x0 => GLctx.blendEquation(x0);
  7377. var _emscripten_glBlendEquationSeparate = (x0, x1) => GLctx.blendEquationSeparate(x0, x1);
  7378. var _emscripten_glBlendFunc = (x0, x1) => GLctx.blendFunc(x0, x1);
  7379. var _emscripten_glBlendFuncSeparate = (x0, x1, x2, x3) => GLctx.blendFuncSeparate(x0, x1, x2, x3);
  7380. var _emscripten_glBufferData = (target, size, data, usage) => {
  7381. // N.b. here first form specifies a heap subarray, second form an integer
  7382. // size, so the ?: code here is polymorphic. It is advised to avoid
  7383. // randomly mixing both uses in calling code, to avoid any potential JS
  7384. // engine JIT issues.
  7385. GLctx.bufferData(target, data ? (growMemViews(), HEAPU8).subarray(data, data + size) : size, usage);
  7386. };
  7387. var webglBufferSubData = (target, offset, size, data, src = (growMemViews(), HEAPU8)) => {
  7388. GLctx.bufferSubData(target, offset, src.subarray(data, data + size));
  7389. };
  7390. var _emscripten_glBufferSubData = (target, offset, size, data) => webglBufferSubData(target, offset, size, data);
  7391. var _emscripten_glCheckFramebufferStatus = x0 => GLctx.checkFramebufferStatus(x0);
  7392. var _emscripten_glClear = x0 => GLctx.clear(x0);
  7393. var _emscripten_glClearColor = (x0, x1, x2, x3) => GLctx.clearColor(x0, x1, x2, x3);
  7394. var _emscripten_glClearDepthf = x0 => GLctx.clearDepth(x0);
  7395. var _emscripten_glClearStencil = x0 => GLctx.clearStencil(x0);
  7396. var _emscripten_glClipControlEXT = (origin, depth) => {
  7397. GLctx.extClipControl["clipControlEXT"](origin, depth);
  7398. };
  7399. var _emscripten_glColorMask = (red, green, blue, alpha) => {
  7400. GLctx.colorMask(!!red, !!green, !!blue, !!alpha);
  7401. };
  7402. var _emscripten_glCompileShader = shader => {
  7403. GLctx.compileShader(GL.shaders[shader]);
  7404. };
  7405. var _emscripten_glCompressedTexImage2D = (target, level, internalFormat, width, height, border, imageSize, data) => {
  7406. // `data` may be null here, which means "allocate uninitialized space but
  7407. // don't upload" in GLES parlance, but `compressedTexImage2D` requires the
  7408. // final data parameter, so we simply pass a heap view starting at zero
  7409. // effectively uploading whatever happens to be near address zero. See
  7410. // https://github.com/emscripten-core/emscripten/issues/19300.
  7411. GLctx.compressedTexImage2D(target, level, internalFormat, width, height, border, (growMemViews(),
  7412. HEAPU8).subarray(data, data + imageSize));
  7413. };
  7414. var _emscripten_glCompressedTexSubImage2D = (target, level, xoffset, yoffset, width, height, format, imageSize, data) => {
  7415. GLctx.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, (growMemViews(),
  7416. HEAPU8).subarray(data, data + imageSize));
  7417. };
  7418. var _emscripten_glCopyTexImage2D = (x0, x1, x2, x3, x4, x5, x6, x7) => GLctx.copyTexImage2D(x0, x1, x2, x3, x4, x5, x6, x7);
  7419. var _emscripten_glCopyTexSubImage2D = (x0, x1, x2, x3, x4, x5, x6, x7) => GLctx.copyTexSubImage2D(x0, x1, x2, x3, x4, x5, x6, x7);
  7420. var _emscripten_glCreateProgram = () => {
  7421. var id = GL.getNewId(GL.programs);
  7422. var program = GLctx.createProgram();
  7423. // Store additional information needed for each shader program:
  7424. program.name = id;
  7425. // Lazy cache results of
  7426. // glGetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH/GL_ACTIVE_ATTRIBUTE_MAX_LENGTH/GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH)
  7427. program.maxUniformLength = program.maxAttributeLength = program.maxUniformBlockNameLength = 0;
  7428. program.uniformIdCounter = 1;
  7429. GL.programs[id] = program;
  7430. return id;
  7431. };
  7432. var _emscripten_glCreateShader = shaderType => {
  7433. var id = GL.getNewId(GL.shaders);
  7434. GL.shaders[id] = GLctx.createShader(shaderType);
  7435. return id;
  7436. };
  7437. var _emscripten_glCullFace = x0 => GLctx.cullFace(x0);
  7438. var _emscripten_glDeleteBuffers = (n, buffers) => {
  7439. for (var i = 0; i < n; i++) {
  7440. var id = (growMemViews(), HEAP32)[(((buffers) + (i * 4)) >> 2)];
  7441. var buffer = GL.buffers[id];
  7442. // From spec: "glDeleteBuffers silently ignores 0's and names that do not
  7443. // correspond to existing buffer objects."
  7444. if (!buffer) continue;
  7445. GLctx.deleteBuffer(buffer);
  7446. buffer.name = 0;
  7447. GL.buffers[id] = null;
  7448. }
  7449. };
  7450. var _emscripten_glDeleteFramebuffers = (n, framebuffers) => {
  7451. for (var i = 0; i < n; ++i) {
  7452. var id = (growMemViews(), HEAP32)[(((framebuffers) + (i * 4)) >> 2)];
  7453. var framebuffer = GL.framebuffers[id];
  7454. if (!framebuffer) continue;
  7455. // GL spec: "glDeleteFramebuffers silently ignores 0s and names that do not correspond to existing framebuffer objects".
  7456. GLctx.deleteFramebuffer(framebuffer);
  7457. framebuffer.name = 0;
  7458. GL.framebuffers[id] = null;
  7459. }
  7460. };
  7461. var _emscripten_glDeleteProgram = id => {
  7462. if (!id) return;
  7463. var program = GL.programs[id];
  7464. if (!program) {
  7465. // glDeleteProgram actually signals an error when deleting a nonexisting
  7466. // object, unlike some other GL delete functions.
  7467. GL.recordError(1281);
  7468. return;
  7469. }
  7470. GLctx.deleteProgram(program);
  7471. program.name = 0;
  7472. GL.programs[id] = null;
  7473. };
  7474. var _emscripten_glDeleteQueriesEXT = (n, ids) => {
  7475. for (var i = 0; i < n; i++) {
  7476. var id = (growMemViews(), HEAP32)[(((ids) + (i * 4)) >> 2)];
  7477. var query = GL.queries[id];
  7478. if (!query) continue;
  7479. // GL spec: "unused names in ids are ignored, as is the name zero."
  7480. GLctx.disjointTimerQueryExt["deleteQueryEXT"](query);
  7481. GL.queries[id] = null;
  7482. }
  7483. };
  7484. var _emscripten_glDeleteRenderbuffers = (n, renderbuffers) => {
  7485. for (var i = 0; i < n; i++) {
  7486. var id = (growMemViews(), HEAP32)[(((renderbuffers) + (i * 4)) >> 2)];
  7487. var renderbuffer = GL.renderbuffers[id];
  7488. if (!renderbuffer) continue;
  7489. // GL spec: "glDeleteRenderbuffers silently ignores 0s and names that do not correspond to existing renderbuffer objects".
  7490. GLctx.deleteRenderbuffer(renderbuffer);
  7491. renderbuffer.name = 0;
  7492. GL.renderbuffers[id] = null;
  7493. }
  7494. };
  7495. var _emscripten_glDeleteShader = id => {
  7496. if (!id) return;
  7497. var shader = GL.shaders[id];
  7498. if (!shader) {
  7499. // glDeleteShader actually signals an error when deleting a nonexisting
  7500. // object, unlike some other GL delete functions.
  7501. GL.recordError(1281);
  7502. return;
  7503. }
  7504. GLctx.deleteShader(shader);
  7505. GL.shaders[id] = null;
  7506. };
  7507. var _emscripten_glDeleteTextures = (n, textures) => {
  7508. for (var i = 0; i < n; i++) {
  7509. var id = (growMemViews(), HEAP32)[(((textures) + (i * 4)) >> 2)];
  7510. var texture = GL.textures[id];
  7511. // GL spec: "glDeleteTextures silently ignores 0s and names that do not
  7512. // correspond to existing textures".
  7513. if (!texture) continue;
  7514. GLctx.deleteTexture(texture);
  7515. texture.name = 0;
  7516. GL.textures[id] = null;
  7517. }
  7518. };
  7519. var _emscripten_glDeleteVertexArrays = (n, vaos) => {
  7520. for (var i = 0; i < n; i++) {
  7521. var id = (growMemViews(), HEAP32)[(((vaos) + (i * 4)) >> 2)];
  7522. GLctx.deleteVertexArray(GL.vaos[id]);
  7523. GL.vaos[id] = null;
  7524. }
  7525. };
  7526. var _glDeleteVertexArrays = _emscripten_glDeleteVertexArrays;
  7527. var _emscripten_glDeleteVertexArraysOES = _glDeleteVertexArrays;
  7528. var _emscripten_glDepthFunc = x0 => GLctx.depthFunc(x0);
  7529. var _emscripten_glDepthMask = flag => {
  7530. GLctx.depthMask(!!flag);
  7531. };
  7532. var _emscripten_glDepthRangef = (x0, x1) => GLctx.depthRange(x0, x1);
  7533. var _emscripten_glDetachShader = (program, shader) => {
  7534. GLctx.detachShader(GL.programs[program], GL.shaders[shader]);
  7535. };
  7536. var _emscripten_glDisable = x0 => GLctx.disable(x0);
  7537. var _emscripten_glDisableVertexAttribArray = index => {
  7538. GLctx.disableVertexAttribArray(index);
  7539. };
  7540. var _emscripten_glDrawArrays = (mode, first, count) => {
  7541. GLctx.drawArrays(mode, first, count);
  7542. };
  7543. var _emscripten_glDrawArraysInstanced = (mode, first, count, primcount) => {
  7544. GLctx.drawArraysInstanced(mode, first, count, primcount);
  7545. };
  7546. var _glDrawArraysInstanced = _emscripten_glDrawArraysInstanced;
  7547. var _emscripten_glDrawArraysInstancedANGLE = _glDrawArraysInstanced;
  7548. var tempFixedLengthArray = [];
  7549. var _emscripten_glDrawBuffers = (n, bufs) => {
  7550. var bufArray = tempFixedLengthArray[n];
  7551. for (var i = 0; i < n; i++) {
  7552. bufArray[i] = (growMemViews(), HEAP32)[(((bufs) + (i * 4)) >> 2)];
  7553. }
  7554. GLctx.drawBuffers(bufArray);
  7555. };
  7556. var _glDrawBuffers = _emscripten_glDrawBuffers;
  7557. var _emscripten_glDrawBuffersWEBGL = _glDrawBuffers;
  7558. var _emscripten_glDrawElements = (mode, count, type, indices) => {
  7559. GLctx.drawElements(mode, count, type, indices);
  7560. };
  7561. var _emscripten_glDrawElementsInstanced = (mode, count, type, indices, primcount) => {
  7562. GLctx.drawElementsInstanced(mode, count, type, indices, primcount);
  7563. };
  7564. var _glDrawElementsInstanced = _emscripten_glDrawElementsInstanced;
  7565. var _emscripten_glDrawElementsInstancedANGLE = _glDrawElementsInstanced;
  7566. var _emscripten_glEnable = x0 => GLctx.enable(x0);
  7567. var _emscripten_glEnableVertexAttribArray = index => {
  7568. GLctx.enableVertexAttribArray(index);
  7569. };
  7570. var _emscripten_glEndQueryEXT = target => {
  7571. GLctx.disjointTimerQueryExt["endQueryEXT"](target);
  7572. };
  7573. var _emscripten_glFinish = () => GLctx.finish();
  7574. var _emscripten_glFlush = () => GLctx.flush();
  7575. var _emscripten_glFramebufferRenderbuffer = (target, attachment, renderbuffertarget, renderbuffer) => {
  7576. GLctx.framebufferRenderbuffer(target, attachment, renderbuffertarget, GL.renderbuffers[renderbuffer]);
  7577. };
  7578. var _emscripten_glFramebufferTexture2D = (target, attachment, textarget, texture, level) => {
  7579. GLctx.framebufferTexture2D(target, attachment, textarget, GL.textures[texture], level);
  7580. };
  7581. var _emscripten_glFrontFace = x0 => GLctx.frontFace(x0);
  7582. var _emscripten_glGenBuffers = (n, buffers) => {
  7583. GL.genObject(n, buffers, "createBuffer", GL.buffers);
  7584. };
  7585. var _emscripten_glGenFramebuffers = (n, ids) => {
  7586. GL.genObject(n, ids, "createFramebuffer", GL.framebuffers);
  7587. };
  7588. var _emscripten_glGenQueriesEXT = (n, ids) => {
  7589. for (var i = 0; i < n; i++) {
  7590. var query = GLctx.disjointTimerQueryExt["createQueryEXT"]();
  7591. if (!query) {
  7592. GL.recordError(1282);
  7593. while (i < n) (growMemViews(), HEAP32)[(((ids) + (i++ * 4)) >> 2)] = 0;
  7594. return;
  7595. }
  7596. var id = GL.getNewId(GL.queries);
  7597. query.name = id;
  7598. GL.queries[id] = query;
  7599. (growMemViews(), HEAP32)[(((ids) + (i * 4)) >> 2)] = id;
  7600. }
  7601. };
  7602. var _emscripten_glGenRenderbuffers = (n, renderbuffers) => {
  7603. GL.genObject(n, renderbuffers, "createRenderbuffer", GL.renderbuffers);
  7604. };
  7605. var _emscripten_glGenTextures = (n, textures) => {
  7606. GL.genObject(n, textures, "createTexture", GL.textures);
  7607. };
  7608. var _emscripten_glGenVertexArrays = (n, arrays) => {
  7609. GL.genObject(n, arrays, "createVertexArray", GL.vaos);
  7610. };
  7611. var _glGenVertexArrays = _emscripten_glGenVertexArrays;
  7612. var _emscripten_glGenVertexArraysOES = _glGenVertexArrays;
  7613. var _emscripten_glGenerateMipmap = x0 => GLctx.generateMipmap(x0);
  7614. var __glGetActiveAttribOrUniform = (funcName, program, index, bufSize, length, size, type, name) => {
  7615. program = GL.programs[program];
  7616. var info = GLctx[funcName](program, index);
  7617. if (info) {
  7618. // If an error occurs, nothing will be written to length, size and type and name.
  7619. var numBytesWrittenExclNull = name && stringToUTF8(info.name, name, bufSize);
  7620. if (length) (growMemViews(), HEAP32)[((length) >> 2)] = numBytesWrittenExclNull;
  7621. if (size) (growMemViews(), HEAP32)[((size) >> 2)] = info.size;
  7622. if (type) (growMemViews(), HEAP32)[((type) >> 2)] = info.type;
  7623. }
  7624. };
  7625. var _emscripten_glGetActiveAttrib = (program, index, bufSize, length, size, type, name) => __glGetActiveAttribOrUniform("getActiveAttrib", program, index, bufSize, length, size, type, name);
  7626. var _emscripten_glGetActiveUniform = (program, index, bufSize, length, size, type, name) => __glGetActiveAttribOrUniform("getActiveUniform", program, index, bufSize, length, size, type, name);
  7627. var _emscripten_glGetAttachedShaders = (program, maxCount, count, shaders) => {
  7628. var result = GLctx.getAttachedShaders(GL.programs[program]);
  7629. var len = result.length;
  7630. if (len > maxCount) {
  7631. len = maxCount;
  7632. }
  7633. (growMemViews(), HEAP32)[((count) >> 2)] = len;
  7634. for (var i = 0; i < len; ++i) {
  7635. var id = GL.shaders.indexOf(result[i]);
  7636. (growMemViews(), HEAP32)[(((shaders) + (i * 4)) >> 2)] = id;
  7637. }
  7638. };
  7639. var _emscripten_glGetAttribLocation = (program, name) => GLctx.getAttribLocation(GL.programs[program], UTF8ToString(name));
  7640. var readI53FromI64 = ptr => (growMemViews(), HEAPU32)[((ptr) >> 2)] + (growMemViews(),
  7641. HEAP32)[(((ptr) + (4)) >> 2)] * 4294967296;
  7642. var readI53FromU64 = ptr => (growMemViews(), HEAPU32)[((ptr) >> 2)] + (growMemViews(),
  7643. HEAPU32)[(((ptr) + (4)) >> 2)] * 4294967296;
  7644. var writeI53ToI64 = (ptr, num) => {
  7645. (growMemViews(), HEAPU32)[((ptr) >> 2)] = num;
  7646. var lower = (growMemViews(), HEAPU32)[((ptr) >> 2)];
  7647. (growMemViews(), HEAPU32)[(((ptr) + (4)) >> 2)] = (num - lower) / 4294967296;
  7648. var deserialized = (num >= 0) ? readI53FromU64(ptr) : readI53FromI64(ptr);
  7649. var offset = ((ptr) >> 2);
  7650. if (deserialized != num) warnOnce(`writeI53ToI64() out of range: serialized JS Number ${num} to Wasm heap as bytes lo=${ptrToString((growMemViews(),
  7651. HEAPU32)[offset])}, hi=${ptrToString((growMemViews(), HEAPU32)[offset + 1])}, which deserializes back to ${deserialized} instead!`);
  7652. };
  7653. var emscriptenWebGLGet = (name_, p, type) => {
  7654. // Guard against user passing a null pointer.
  7655. // Note that GLES2 spec does not say anything about how passing a null
  7656. // pointer should be treated. Testing on desktop core GL 3, the application
  7657. // crashes on glGetIntegerv to a null pointer, but better to report an error
  7658. // instead of doing anything random.
  7659. if (!p) {
  7660. GL.recordError(1281);
  7661. return;
  7662. }
  7663. var ret = undefined;
  7664. switch (name_) {
  7665. // Handle a few trivial GLES values
  7666. case 36346:
  7667. // GL_SHADER_COMPILER
  7668. ret = 1;
  7669. break;
  7670. case 36344:
  7671. // GL_SHADER_BINARY_FORMATS
  7672. if (type != 0 && type != 1) {
  7673. GL.recordError(1280);
  7674. }
  7675. // Do not write anything to the out pointer, since no binary formats are
  7676. // supported.
  7677. return;
  7678. case 36345:
  7679. // GL_NUM_SHADER_BINARY_FORMATS
  7680. ret = 0;
  7681. break;
  7682. case 34466:
  7683. // GL_NUM_COMPRESSED_TEXTURE_FORMATS
  7684. // WebGL doesn't have GL_NUM_COMPRESSED_TEXTURE_FORMATS (it's obsolete
  7685. // since GL_COMPRESSED_TEXTURE_FORMATS returns a JS array that can be
  7686. // queried for length), so implement it ourselves to allow C++ GLES2
  7687. // code to get the length.
  7688. var formats = GLctx.getParameter(34467);
  7689. ret = formats ? formats.length : 0;
  7690. break;
  7691. }
  7692. if (ret === undefined) {
  7693. var result = GLctx.getParameter(name_);
  7694. switch (typeof result) {
  7695. case "number":
  7696. ret = result;
  7697. break;
  7698. case "boolean":
  7699. ret = result ? 1 : 0;
  7700. break;
  7701. case "string":
  7702. GL.recordError(1280);
  7703. // GL_INVALID_ENUM
  7704. return;
  7705. case "object":
  7706. if (result === null) {
  7707. // null is a valid result for some (e.g., which buffer is bound -
  7708. // perhaps nothing is bound), but otherwise can mean an invalid
  7709. // name_, which we need to report as an error
  7710. switch (name_) {
  7711. case 34964:
  7712. // ARRAY_BUFFER_BINDING
  7713. case 35725:
  7714. // CURRENT_PROGRAM
  7715. case 34965:
  7716. // ELEMENT_ARRAY_BUFFER_BINDING
  7717. case 36006:
  7718. // FRAMEBUFFER_BINDING or DRAW_FRAMEBUFFER_BINDING
  7719. case 36007:
  7720. // RENDERBUFFER_BINDING
  7721. case 32873:
  7722. // TEXTURE_BINDING_2D
  7723. case 34229:
  7724. // WebGL 2 GL_VERTEX_ARRAY_BINDING, or WebGL 1 extension OES_vertex_array_object GL_VERTEX_ARRAY_BINDING_OES
  7725. case 34068:
  7726. {
  7727. // TEXTURE_BINDING_CUBE_MAP
  7728. ret = 0;
  7729. break;
  7730. }
  7731. default:
  7732. {
  7733. GL.recordError(1280);
  7734. // GL_INVALID_ENUM
  7735. return;
  7736. }
  7737. }
  7738. } else if (result instanceof Float32Array || result instanceof Uint32Array || result instanceof Int32Array || result instanceof Array) {
  7739. for (var i = 0; i < result.length; ++i) {
  7740. switch (type) {
  7741. case 0:
  7742. (growMemViews(), HEAP32)[(((p) + (i * 4)) >> 2)] = result[i];
  7743. break;
  7744. case 2:
  7745. (growMemViews(), HEAPF32)[(((p) + (i * 4)) >> 2)] = result[i];
  7746. break;
  7747. case 4:
  7748. (growMemViews(), HEAP8)[(p) + (i)] = result[i] ? 1 : 0;
  7749. break;
  7750. }
  7751. }
  7752. return;
  7753. } else {
  7754. try {
  7755. ret = result.name | 0;
  7756. } catch (e) {
  7757. GL.recordError(1280);
  7758. // GL_INVALID_ENUM
  7759. err(`GL_INVALID_ENUM in glGet${type}v: Unknown object returned from WebGL getParameter(${name_})! (error: ${e})`);
  7760. return;
  7761. }
  7762. }
  7763. break;
  7764. default:
  7765. GL.recordError(1280);
  7766. // GL_INVALID_ENUM
  7767. err(`GL_INVALID_ENUM in glGet${type}v: Native code calling glGet${type}v(${name_}) and it returns ${result} of type ${typeof (result)}!`);
  7768. return;
  7769. }
  7770. }
  7771. switch (type) {
  7772. case 1:
  7773. writeI53ToI64(p, ret);
  7774. break;
  7775. case 0:
  7776. (growMemViews(), HEAP32)[((p) >> 2)] = ret;
  7777. break;
  7778. case 2:
  7779. (growMemViews(), HEAPF32)[((p) >> 2)] = ret;
  7780. break;
  7781. case 4:
  7782. (growMemViews(), HEAP8)[p] = ret ? 1 : 0;
  7783. break;
  7784. }
  7785. };
  7786. var _emscripten_glGetBooleanv = (name_, p) => emscriptenWebGLGet(name_, p, 4);
  7787. var _emscripten_glGetBufferParameteriv = (target, value, data) => {
  7788. if (!data) {
  7789. // GLES2 specification does not specify how to behave if data is a null
  7790. // pointer. Since calling this function does not make sense if data ==
  7791. // null, issue a GL error to notify user about it.
  7792. GL.recordError(1281);
  7793. return;
  7794. }
  7795. (growMemViews(), HEAP32)[((data) >> 2)] = GLctx.getBufferParameter(target, value);
  7796. };
  7797. var _emscripten_glGetError = () => {
  7798. var error = GLctx.getError() || GL.lastError;
  7799. GL.lastError = 0;
  7800. return error;
  7801. };
  7802. var _emscripten_glGetFloatv = (name_, p) => emscriptenWebGLGet(name_, p, 2);
  7803. var _emscripten_glGetFramebufferAttachmentParameteriv = (target, attachment, pname, params) => {
  7804. var result = GLctx.getFramebufferAttachmentParameter(target, attachment, pname);
  7805. if (result instanceof WebGLRenderbuffer || result instanceof WebGLTexture) {
  7806. result = result.name | 0;
  7807. }
  7808. (growMemViews(), HEAP32)[((params) >> 2)] = result;
  7809. };
  7810. var _emscripten_glGetIntegerv = (name_, p) => emscriptenWebGLGet(name_, p, 0);
  7811. var _emscripten_glGetProgramInfoLog = (program, maxLength, length, infoLog) => {
  7812. var log = GLctx.getProgramInfoLog(GL.programs[program]);
  7813. if (log === null) log = "(unknown error)";
  7814. var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0;
  7815. if (length) (growMemViews(), HEAP32)[((length) >> 2)] = numBytesWrittenExclNull;
  7816. };
  7817. var _emscripten_glGetProgramiv = (program, pname, p) => {
  7818. if (!p) {
  7819. // GLES2 specification does not specify how to behave if p is a null
  7820. // pointer. Since calling this function does not make sense if p == null,
  7821. // issue a GL error to notify user about it.
  7822. GL.recordError(1281);
  7823. return;
  7824. }
  7825. if (program >= GL.counter) {
  7826. GL.recordError(1281);
  7827. return;
  7828. }
  7829. program = GL.programs[program];
  7830. if (pname == 35716) {
  7831. // GL_INFO_LOG_LENGTH
  7832. var log = GLctx.getProgramInfoLog(program);
  7833. if (log === null) log = "(unknown error)";
  7834. (growMemViews(), HEAP32)[((p) >> 2)] = log.length + 1;
  7835. } else if (pname == 35719) {
  7836. if (!program.maxUniformLength) {
  7837. var numActiveUniforms = GLctx.getProgramParameter(program, 35718);
  7838. for (var i = 0; i < numActiveUniforms; ++i) {
  7839. program.maxUniformLength = Math.max(program.maxUniformLength, GLctx.getActiveUniform(program, i).name.length + 1);
  7840. }
  7841. }
  7842. (growMemViews(), HEAP32)[((p) >> 2)] = program.maxUniformLength;
  7843. } else if (pname == 35722) {
  7844. if (!program.maxAttributeLength) {
  7845. var numActiveAttributes = GLctx.getProgramParameter(program, 35721);
  7846. for (var i = 0; i < numActiveAttributes; ++i) {
  7847. program.maxAttributeLength = Math.max(program.maxAttributeLength, GLctx.getActiveAttrib(program, i).name.length + 1);
  7848. }
  7849. }
  7850. (growMemViews(), HEAP32)[((p) >> 2)] = program.maxAttributeLength;
  7851. } else if (pname == 35381) {
  7852. if (!program.maxUniformBlockNameLength) {
  7853. var numActiveUniformBlocks = GLctx.getProgramParameter(program, 35382);
  7854. for (var i = 0; i < numActiveUniformBlocks; ++i) {
  7855. program.maxUniformBlockNameLength = Math.max(program.maxUniformBlockNameLength, GLctx.getActiveUniformBlockName(program, i).length + 1);
  7856. }
  7857. }
  7858. (growMemViews(), HEAP32)[((p) >> 2)] = program.maxUniformBlockNameLength;
  7859. } else {
  7860. (growMemViews(), HEAP32)[((p) >> 2)] = GLctx.getProgramParameter(program, pname);
  7861. }
  7862. };
  7863. var _emscripten_glGetQueryObjecti64vEXT = (id, pname, params) => {
  7864. if (!params) {
  7865. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  7866. // if p == null, issue a GL error to notify user about it.
  7867. GL.recordError(1281);
  7868. return;
  7869. }
  7870. var query = GL.queries[id];
  7871. var param;
  7872. {
  7873. param = GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query, pname);
  7874. }
  7875. var ret;
  7876. if (typeof param == "boolean") {
  7877. ret = param ? 1 : 0;
  7878. } else {
  7879. ret = param;
  7880. }
  7881. writeI53ToI64(params, ret);
  7882. };
  7883. var _emscripten_glGetQueryObjectivEXT = (id, pname, params) => {
  7884. if (!params) {
  7885. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  7886. // if p == null, issue a GL error to notify user about it.
  7887. GL.recordError(1281);
  7888. return;
  7889. }
  7890. var query = GL.queries[id];
  7891. var param = GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query, pname);
  7892. var ret;
  7893. if (typeof param == "boolean") {
  7894. ret = param ? 1 : 0;
  7895. } else {
  7896. ret = param;
  7897. }
  7898. (growMemViews(), HEAP32)[((params) >> 2)] = ret;
  7899. };
  7900. var _glGetQueryObjecti64vEXT = _emscripten_glGetQueryObjecti64vEXT;
  7901. var _emscripten_glGetQueryObjectui64vEXT = _glGetQueryObjecti64vEXT;
  7902. var _glGetQueryObjectivEXT = _emscripten_glGetQueryObjectivEXT;
  7903. var _emscripten_glGetQueryObjectuivEXT = _glGetQueryObjectivEXT;
  7904. var _emscripten_glGetQueryivEXT = (target, pname, params) => {
  7905. if (!params) {
  7906. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  7907. // if p == null, issue a GL error to notify user about it.
  7908. GL.recordError(1281);
  7909. return;
  7910. }
  7911. (growMemViews(), HEAP32)[((params) >> 2)] = GLctx.disjointTimerQueryExt["getQueryEXT"](target, pname);
  7912. };
  7913. var _emscripten_glGetRenderbufferParameteriv = (target, pname, params) => {
  7914. if (!params) {
  7915. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  7916. // if params == null, issue a GL error to notify user about it.
  7917. GL.recordError(1281);
  7918. return;
  7919. }
  7920. (growMemViews(), HEAP32)[((params) >> 2)] = GLctx.getRenderbufferParameter(target, pname);
  7921. };
  7922. var _emscripten_glGetShaderInfoLog = (shader, maxLength, length, infoLog) => {
  7923. var log = GLctx.getShaderInfoLog(GL.shaders[shader]);
  7924. if (log === null) log = "(unknown error)";
  7925. var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0;
  7926. if (length) (growMemViews(), HEAP32)[((length) >> 2)] = numBytesWrittenExclNull;
  7927. };
  7928. var _emscripten_glGetShaderPrecisionFormat = (shaderType, precisionType, range, precision) => {
  7929. var result = GLctx.getShaderPrecisionFormat(shaderType, precisionType);
  7930. (growMemViews(), HEAP32)[((range) >> 2)] = result.rangeMin;
  7931. (growMemViews(), HEAP32)[(((range) + (4)) >> 2)] = result.rangeMax;
  7932. (growMemViews(), HEAP32)[((precision) >> 2)] = result.precision;
  7933. };
  7934. var _emscripten_glGetShaderSource = (shader, bufSize, length, source) => {
  7935. var result = GLctx.getShaderSource(GL.shaders[shader]);
  7936. if (!result) return;
  7937. // If an error occurs, nothing will be written to length or source.
  7938. var numBytesWrittenExclNull = (bufSize > 0 && source) ? stringToUTF8(result, source, bufSize) : 0;
  7939. if (length) (growMemViews(), HEAP32)[((length) >> 2)] = numBytesWrittenExclNull;
  7940. };
  7941. var _emscripten_glGetShaderiv = (shader, pname, p) => {
  7942. if (!p) {
  7943. // GLES2 specification does not specify how to behave if p is a null
  7944. // pointer. Since calling this function does not make sense if p == null,
  7945. // issue a GL error to notify user about it.
  7946. GL.recordError(1281);
  7947. return;
  7948. }
  7949. if (pname == 35716) {
  7950. // GL_INFO_LOG_LENGTH
  7951. var log = GLctx.getShaderInfoLog(GL.shaders[shader]);
  7952. if (log === null) log = "(unknown error)";
  7953. // The GLES2 specification says that if the shader has an empty info log,
  7954. // a value of 0 is returned. Otherwise the log has a null char appended.
  7955. // (An empty string is falsey, so we can just check that instead of
  7956. // looking at log.length.)
  7957. var logLength = log ? log.length + 1 : 0;
  7958. (growMemViews(), HEAP32)[((p) >> 2)] = logLength;
  7959. } else if (pname == 35720) {
  7960. // GL_SHADER_SOURCE_LENGTH
  7961. var source = GLctx.getShaderSource(GL.shaders[shader]);
  7962. // source may be a null, or the empty string, both of which are falsey
  7963. // values that we report a 0 length for.
  7964. var sourceLength = source ? source.length + 1 : 0;
  7965. (growMemViews(), HEAP32)[((p) >> 2)] = sourceLength;
  7966. } else {
  7967. (growMemViews(), HEAP32)[((p) >> 2)] = GLctx.getShaderParameter(GL.shaders[shader], pname);
  7968. }
  7969. };
  7970. var webglGetExtensions = () => {
  7971. var exts = getEmscriptenSupportedExtensions(GLctx);
  7972. exts = exts.concat(exts.map(e => "GL_" + e));
  7973. return exts;
  7974. };
  7975. var _emscripten_glGetString = name_ => {
  7976. var ret = GL.stringCache[name_];
  7977. if (!ret) {
  7978. switch (name_) {
  7979. case 7939:
  7980. ret = stringToNewUTF8(webglGetExtensions().join(" "));
  7981. break;
  7982. case 7936:
  7983. case 7937:
  7984. case 37445:
  7985. case 37446:
  7986. var s = GLctx.getParameter(name_);
  7987. if (!s) {
  7988. GL.recordError(1280);
  7989. }
  7990. ret = s ? stringToNewUTF8(s) : 0;
  7991. break;
  7992. case 7938:
  7993. var webGLVersion = GLctx.getParameter(7938);
  7994. // return GLES version string corresponding to the version of the WebGL context
  7995. var glVersion = `OpenGL ES 2.0 (${webGLVersion})`;
  7996. ret = stringToNewUTF8(glVersion);
  7997. break;
  7998. case 35724:
  7999. var glslVersion = GLctx.getParameter(35724);
  8000. // extract the version number 'N.M' from the string 'WebGL GLSL ES N.M ...'
  8001. var ver_re = /^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;
  8002. var ver_num = glslVersion.match(ver_re);
  8003. if (ver_num !== null) {
  8004. if (ver_num[1].length == 3) ver_num[1] = ver_num[1] + "0";
  8005. // ensure minor version has 2 digits
  8006. glslVersion = `OpenGL ES GLSL ES ${ver_num[1]} (${glslVersion})`;
  8007. }
  8008. ret = stringToNewUTF8(glslVersion);
  8009. break;
  8010. default:
  8011. GL.recordError(1280);
  8012. }
  8013. GL.stringCache[name_] = ret;
  8014. }
  8015. return ret;
  8016. };
  8017. var _emscripten_glGetTexParameterfv = (target, pname, params) => {
  8018. if (!params) {
  8019. // GLES2 specification does not specify how to behave if params is a null
  8020. // pointer. Since calling this function does not make sense if p == null,
  8021. // issue a GL error to notify user about it.
  8022. GL.recordError(1281);
  8023. return;
  8024. }
  8025. (growMemViews(), HEAPF32)[((params) >> 2)] = GLctx.getTexParameter(target, pname);
  8026. };
  8027. var _emscripten_glGetTexParameteriv = (target, pname, params) => {
  8028. if (!params) {
  8029. // GLES2 specification does not specify how to behave if params is a null
  8030. // pointer. Since calling this function does not make sense if p == null,
  8031. // issue a GL error to notify user about it.
  8032. GL.recordError(1281);
  8033. return;
  8034. }
  8035. (growMemViews(), HEAP32)[((params) >> 2)] = GLctx.getTexParameter(target, pname);
  8036. };
  8037. /** @suppress {checkTypes} */ var jstoi_q = str => parseInt(str);
  8038. /** @noinline */ var webglGetLeftBracePos = name => name.slice(-1) == "]" && name.lastIndexOf("[");
  8039. var webglPrepareUniformLocationsBeforeFirstUse = program => {
  8040. var uniformLocsById = program.uniformLocsById, // Maps GLuint -> WebGLUniformLocation
  8041. uniformSizeAndIdsByName = program.uniformSizeAndIdsByName, // Maps name -> [uniform array length, GLuint]
  8042. i, j;
  8043. // On the first time invocation of glGetUniformLocation on this shader program:
  8044. // initialize cache data structures and discover which uniforms are arrays.
  8045. if (!uniformLocsById) {
  8046. // maps GLint integer locations to WebGLUniformLocations
  8047. program.uniformLocsById = uniformLocsById = {};
  8048. // maps integer locations back to uniform name strings, so that we can lazily fetch uniform array locations
  8049. program.uniformArrayNamesById = {};
  8050. var numActiveUniforms = GLctx.getProgramParameter(program, 35718);
  8051. for (i = 0; i < numActiveUniforms; ++i) {
  8052. var u = GLctx.getActiveUniform(program, i);
  8053. var nm = u.name;
  8054. var sz = u.size;
  8055. var lb = webglGetLeftBracePos(nm);
  8056. var arrayName = lb > 0 ? nm.slice(0, lb) : nm;
  8057. // Assign a new location.
  8058. var id = program.uniformIdCounter;
  8059. program.uniformIdCounter += sz;
  8060. // Eagerly get the location of the uniformArray[0] base element.
  8061. // The remaining indices >0 will be left for lazy evaluation to
  8062. // improve performance. Those may never be needed to fetch, if the
  8063. // application fills arrays always in full starting from the first
  8064. // element of the array.
  8065. uniformSizeAndIdsByName[arrayName] = [ sz, id ];
  8066. // Store placeholder integers in place that highlight that these
  8067. // >0 index locations are array indices pending population.
  8068. for (j = 0; j < sz; ++j) {
  8069. uniformLocsById[id] = j;
  8070. program.uniformArrayNamesById[id++] = arrayName;
  8071. }
  8072. }
  8073. }
  8074. };
  8075. var _emscripten_glGetUniformLocation = (program, name) => {
  8076. name = UTF8ToString(name);
  8077. if (program = GL.programs[program]) {
  8078. webglPrepareUniformLocationsBeforeFirstUse(program);
  8079. var uniformLocsById = program.uniformLocsById;
  8080. // Maps GLuint -> WebGLUniformLocation
  8081. var arrayIndex = 0;
  8082. var uniformBaseName = name;
  8083. // Invariant: when populating integer IDs for uniform locations, we must
  8084. // maintain the precondition that arrays reside in contiguous addresses,
  8085. // i.e. for a 'vec4 colors[10];', colors[4] must be at location
  8086. // colors[0]+4. However, user might call glGetUniformLocation(program,
  8087. // "colors") for an array, so we cannot discover based on the user input
  8088. // arguments whether the uniform we are dealing with is an array. The only
  8089. // way to discover which uniforms are arrays is to enumerate over all the
  8090. // active uniforms in the program.
  8091. var leftBrace = webglGetLeftBracePos(name);
  8092. // If user passed an array accessor "[index]", parse the array index off the accessor.
  8093. if (leftBrace > 0) {
  8094. arrayIndex = jstoi_q(name.slice(leftBrace + 1)) >>> 0;
  8095. // "index]", coerce parseInt(']') with >>>0 to treat "foo[]" as "foo[0]" and foo[-1] as unsigned out-of-bounds.
  8096. uniformBaseName = name.slice(0, leftBrace);
  8097. }
  8098. // Have we cached the location of this uniform before?
  8099. // A pair [array length, GLint of the uniform location]
  8100. var sizeAndId = program.uniformSizeAndIdsByName[uniformBaseName];
  8101. // If a uniform with this name exists, and if its index is within the
  8102. // array limits (if it's even an array), query the WebGLlocation, or
  8103. // return an existing cached location.
  8104. if (sizeAndId && arrayIndex < sizeAndId[0]) {
  8105. arrayIndex += sizeAndId[1];
  8106. // Add the base location of the uniform to the array index offset.
  8107. if ((uniformLocsById[arrayIndex] = uniformLocsById[arrayIndex] || GLctx.getUniformLocation(program, name))) {
  8108. return arrayIndex;
  8109. }
  8110. }
  8111. } else {
  8112. // N.b. we are currently unable to distinguish between GL program IDs that
  8113. // never existed vs GL program IDs that have been deleted, so report
  8114. // GL_INVALID_VALUE in both cases.
  8115. GL.recordError(1281);
  8116. }
  8117. return -1;
  8118. };
  8119. var webglGetProgramUniformLocation = (program, location) => {
  8120. if (program) {
  8121. var webglLoc = program.uniformLocsById[location];
  8122. // program.uniformLocsById[location] stores either an integer, or a
  8123. // WebGLUniformLocation.
  8124. // If an integer, we have not yet bound the location, so do it now. The
  8125. // integer value specifies the array index we should bind to.
  8126. if (typeof webglLoc == "number") {
  8127. program.uniformLocsById[location] = webglLoc = GLctx.getUniformLocation(program, program.uniformArrayNamesById[location] + (webglLoc > 0 ? `[${webglLoc}]` : ""));
  8128. }
  8129. // Else an already cached WebGLUniformLocation, return it.
  8130. return webglLoc;
  8131. } else {
  8132. GL.recordError(1282);
  8133. }
  8134. };
  8135. /** @suppress{checkTypes} */ var emscriptenWebGLGetUniform = (program, location, params, type) => {
  8136. if (!params) {
  8137. // GLES2 specification does not specify how to behave if params is a null
  8138. // pointer. Since calling this function does not make sense if params ==
  8139. // null, issue a GL error to notify user about it.
  8140. GL.recordError(1281);
  8141. return;
  8142. }
  8143. program = GL.programs[program];
  8144. webglPrepareUniformLocationsBeforeFirstUse(program);
  8145. var data = GLctx.getUniform(program, webglGetProgramUniformLocation(program, location));
  8146. if (typeof data == "number" || typeof data == "boolean") {
  8147. switch (type) {
  8148. case 0:
  8149. (growMemViews(), HEAP32)[((params) >> 2)] = data;
  8150. break;
  8151. case 2:
  8152. (growMemViews(), HEAPF32)[((params) >> 2)] = data;
  8153. break;
  8154. }
  8155. } else {
  8156. for (var i = 0; i < data.length; i++) {
  8157. switch (type) {
  8158. case 0:
  8159. (growMemViews(), HEAP32)[(((params) + (i * 4)) >> 2)] = data[i];
  8160. break;
  8161. case 2:
  8162. (growMemViews(), HEAPF32)[(((params) + (i * 4)) >> 2)] = data[i];
  8163. break;
  8164. }
  8165. }
  8166. }
  8167. };
  8168. var _emscripten_glGetUniformfv = (program, location, params) => {
  8169. emscriptenWebGLGetUniform(program, location, params, 2);
  8170. };
  8171. var _emscripten_glGetUniformiv = (program, location, params) => {
  8172. emscriptenWebGLGetUniform(program, location, params, 0);
  8173. };
  8174. var _emscripten_glGetVertexAttribPointerv = (index, pname, pointer) => {
  8175. if (!pointer) {
  8176. // GLES2 specification does not specify how to behave if pointer is a null
  8177. // pointer. Since calling this function does not make sense if pointer ==
  8178. // null, issue a GL error to notify user about it.
  8179. GL.recordError(1281);
  8180. return;
  8181. }
  8182. (growMemViews(), HEAP32)[((pointer) >> 2)] = GLctx.getVertexAttribOffset(index, pname);
  8183. };
  8184. /** @suppress{checkTypes} */ var emscriptenWebGLGetVertexAttrib = (index, pname, params, type) => {
  8185. if (!params) {
  8186. // GLES2 specification does not specify how to behave if params is a null
  8187. // pointer. Since calling this function does not make sense if params ==
  8188. // null, issue a GL error to notify user about it.
  8189. GL.recordError(1281);
  8190. return;
  8191. }
  8192. var data = GLctx.getVertexAttrib(index, pname);
  8193. if (pname == 34975) {
  8194. (growMemViews(), HEAP32)[((params) >> 2)] = data && data["name"];
  8195. } else if (typeof data == "number" || typeof data == "boolean") {
  8196. switch (type) {
  8197. case 0:
  8198. (growMemViews(), HEAP32)[((params) >> 2)] = data;
  8199. break;
  8200. case 2:
  8201. (growMemViews(), HEAPF32)[((params) >> 2)] = data;
  8202. break;
  8203. case 5:
  8204. (growMemViews(), HEAP32)[((params) >> 2)] = Math.fround(data);
  8205. break;
  8206. }
  8207. } else {
  8208. for (var i = 0; i < data.length; i++) {
  8209. switch (type) {
  8210. case 0:
  8211. (growMemViews(), HEAP32)[(((params) + (i * 4)) >> 2)] = data[i];
  8212. break;
  8213. case 2:
  8214. (growMemViews(), HEAPF32)[(((params) + (i * 4)) >> 2)] = data[i];
  8215. break;
  8216. case 5:
  8217. (growMemViews(), HEAP32)[(((params) + (i * 4)) >> 2)] = Math.fround(data[i]);
  8218. break;
  8219. }
  8220. }
  8221. }
  8222. };
  8223. var _emscripten_glGetVertexAttribfv = (index, pname, params) => {
  8224. // N.B. This function may only be called if the vertex attribute was
  8225. // specified using the function glVertexAttrib*f(), otherwise the results
  8226. // are undefined. (GLES3 spec 6.1.12)
  8227. emscriptenWebGLGetVertexAttrib(index, pname, params, 2);
  8228. };
  8229. var _emscripten_glGetVertexAttribiv = (index, pname, params) => {
  8230. // N.B. This function may only be called if the vertex attribute was
  8231. // specified using the function glVertexAttrib*f(), otherwise the results
  8232. // are undefined. (GLES3 spec 6.1.12)
  8233. emscriptenWebGLGetVertexAttrib(index, pname, params, 5);
  8234. };
  8235. var _emscripten_glHint = (x0, x1) => GLctx.hint(x0, x1);
  8236. var _emscripten_glIsBuffer = buffer => {
  8237. var b = GL.buffers[buffer];
  8238. if (!b) return 0;
  8239. return GLctx.isBuffer(b);
  8240. };
  8241. var _emscripten_glIsEnabled = x0 => GLctx.isEnabled(x0);
  8242. var _emscripten_glIsFramebuffer = framebuffer => {
  8243. var fb = GL.framebuffers[framebuffer];
  8244. if (!fb) return 0;
  8245. return GLctx.isFramebuffer(fb);
  8246. };
  8247. var _emscripten_glIsProgram = program => {
  8248. program = GL.programs[program];
  8249. if (!program) return 0;
  8250. return GLctx.isProgram(program);
  8251. };
  8252. var _emscripten_glIsQueryEXT = id => {
  8253. var query = GL.queries[id];
  8254. if (!query) return 0;
  8255. return GLctx.disjointTimerQueryExt["isQueryEXT"](query);
  8256. };
  8257. var _emscripten_glIsRenderbuffer = renderbuffer => {
  8258. var rb = GL.renderbuffers[renderbuffer];
  8259. if (!rb) return 0;
  8260. return GLctx.isRenderbuffer(rb);
  8261. };
  8262. var _emscripten_glIsShader = shader => {
  8263. var s = GL.shaders[shader];
  8264. if (!s) return 0;
  8265. return GLctx.isShader(s);
  8266. };
  8267. var _emscripten_glIsTexture = id => {
  8268. var texture = GL.textures[id];
  8269. if (!texture) return 0;
  8270. return GLctx.isTexture(texture);
  8271. };
  8272. var _emscripten_glIsVertexArray = array => {
  8273. var vao = GL.vaos[array];
  8274. if (!vao) return 0;
  8275. return GLctx.isVertexArray(vao);
  8276. };
  8277. var _glIsVertexArray = _emscripten_glIsVertexArray;
  8278. var _emscripten_glIsVertexArrayOES = _glIsVertexArray;
  8279. var _emscripten_glLineWidth = x0 => GLctx.lineWidth(x0);
  8280. var _emscripten_glLinkProgram = program => {
  8281. program = GL.programs[program];
  8282. GLctx.linkProgram(program);
  8283. // Invalidate earlier computed uniform->ID mappings, those have now become stale
  8284. program.uniformLocsById = 0;
  8285. // Mark as null-like so that glGetUniformLocation() knows to populate this again.
  8286. program.uniformSizeAndIdsByName = {};
  8287. };
  8288. var _emscripten_glPixelStorei = (pname, param) => {
  8289. if (pname == 3317) {
  8290. GL.unpackAlignment = param;
  8291. } else if (pname == 3314) {
  8292. GL.unpackRowLength = param;
  8293. }
  8294. GLctx.pixelStorei(pname, param);
  8295. };
  8296. var _emscripten_glPolygonModeWEBGL = (face, mode) => {
  8297. GLctx.webglPolygonMode["polygonModeWEBGL"](face, mode);
  8298. };
  8299. var _emscripten_glPolygonOffset = (x0, x1) => GLctx.polygonOffset(x0, x1);
  8300. var _emscripten_glPolygonOffsetClampEXT = (factor, units, clamp) => {
  8301. GLctx.extPolygonOffsetClamp["polygonOffsetClampEXT"](factor, units, clamp);
  8302. };
  8303. var _emscripten_glQueryCounterEXT = (id, target) => {
  8304. GLctx.disjointTimerQueryExt["queryCounterEXT"](GL.queries[id], target);
  8305. };
  8306. var computeUnpackAlignedImageSize = (width, height, sizePerPixel) => {
  8307. function roundedToNextMultipleOf(x, y) {
  8308. return (x + y - 1) & -y;
  8309. }
  8310. var plainRowSize = (GL.unpackRowLength || width) * sizePerPixel;
  8311. var alignedRowSize = roundedToNextMultipleOf(plainRowSize, GL.unpackAlignment);
  8312. return height * alignedRowSize;
  8313. };
  8314. var colorChannelsInGlTextureFormat = format => {
  8315. // Micro-optimizations for size: map format to size by subtracting smallest
  8316. // enum value (0x1902) from all values first. Also omit the most common
  8317. // size value (1) from the list, which is assumed by formats not on the
  8318. // list.
  8319. var colorChannels = {
  8320. // 0x1902 /* GL_DEPTH_COMPONENT */ - 0x1902: 1,
  8321. // 0x1906 /* GL_ALPHA */ - 0x1902: 1,
  8322. 5: 3,
  8323. 6: 4,
  8324. // 0x1909 /* GL_LUMINANCE */ - 0x1902: 1,
  8325. 8: 2,
  8326. 29502: 3,
  8327. 29504: 4
  8328. };
  8329. return colorChannels[format - 6402] || 1;
  8330. };
  8331. var heapObjectForWebGLType = type => {
  8332. // Micro-optimization for size: Subtract lowest GL enum number (0x1400/* GL_BYTE */) from type to compare
  8333. // smaller values for the heap, for shorter generated code size.
  8334. // Also the type HEAPU16 is not tested for explicitly, but any unrecognized type will return out HEAPU16.
  8335. // (since most types are HEAPU16)
  8336. type -= 5120;
  8337. if (type == 1) return (growMemViews(), HEAPU8);
  8338. if (type == 4) return (growMemViews(), HEAP32);
  8339. if (type == 6) return (growMemViews(), HEAPF32);
  8340. if (type == 5 || type == 28922) return (growMemViews(), HEAPU32);
  8341. return (growMemViews(), HEAPU16);
  8342. };
  8343. var toTypedArrayIndex = (pointer, heap) => pointer >>> (31 - Math.clz32(heap.BYTES_PER_ELEMENT));
  8344. var emscriptenWebGLGetTexPixelData = (type, format, width, height, pixels) => {
  8345. var heap = heapObjectForWebGLType(type);
  8346. var sizePerPixel = colorChannelsInGlTextureFormat(format) * heap.BYTES_PER_ELEMENT;
  8347. var bytes = computeUnpackAlignedImageSize(width, height, sizePerPixel);
  8348. return heap.subarray(toTypedArrayIndex(pixels, heap), toTypedArrayIndex(pixels + bytes, heap));
  8349. };
  8350. var _emscripten_glReadPixels = (x, y, width, height, format, type, pixels) => {
  8351. var pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels);
  8352. if (!pixelData) {
  8353. GL.recordError(1280);
  8354. return;
  8355. }
  8356. GLctx.readPixels(x, y, width, height, format, type, pixelData);
  8357. };
  8358. var _emscripten_glReleaseShaderCompiler = () => {};
  8359. var _emscripten_glRenderbufferStorage = (x0, x1, x2, x3) => GLctx.renderbufferStorage(x0, x1, x2, x3);
  8360. var _emscripten_glSampleCoverage = (value, invert) => {
  8361. GLctx.sampleCoverage(value, !!invert);
  8362. };
  8363. var _emscripten_glScissor = (x0, x1, x2, x3) => GLctx.scissor(x0, x1, x2, x3);
  8364. var _emscripten_glShaderBinary = (count, shaders, binaryformat, binary, length) => {
  8365. GL.recordError(1280);
  8366. };
  8367. var _emscripten_glShaderSource = (shader, count, string, length) => {
  8368. var source = GL.getSource(shader, count, string, length);
  8369. GLctx.shaderSource(GL.shaders[shader], source);
  8370. };
  8371. var _emscripten_glStencilFunc = (x0, x1, x2) => GLctx.stencilFunc(x0, x1, x2);
  8372. var _emscripten_glStencilFuncSeparate = (x0, x1, x2, x3) => GLctx.stencilFuncSeparate(x0, x1, x2, x3);
  8373. var _emscripten_glStencilMask = x0 => GLctx.stencilMask(x0);
  8374. var _emscripten_glStencilMaskSeparate = (x0, x1) => GLctx.stencilMaskSeparate(x0, x1);
  8375. var _emscripten_glStencilOp = (x0, x1, x2) => GLctx.stencilOp(x0, x1, x2);
  8376. var _emscripten_glStencilOpSeparate = (x0, x1, x2, x3) => GLctx.stencilOpSeparate(x0, x1, x2, x3);
  8377. var _emscripten_glTexImage2D = (target, level, internalFormat, width, height, border, format, type, pixels) => {
  8378. var pixelData = pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels) : null;
  8379. GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixelData);
  8380. };
  8381. var _emscripten_glTexParameterf = (x0, x1, x2) => GLctx.texParameterf(x0, x1, x2);
  8382. var _emscripten_glTexParameterfv = (target, pname, params) => {
  8383. var param = (growMemViews(), HEAPF32)[((params) >> 2)];
  8384. GLctx.texParameterf(target, pname, param);
  8385. };
  8386. var _emscripten_glTexParameteri = (x0, x1, x2) => GLctx.texParameteri(x0, x1, x2);
  8387. var _emscripten_glTexParameteriv = (target, pname, params) => {
  8388. var param = (growMemViews(), HEAP32)[((params) >> 2)];
  8389. GLctx.texParameteri(target, pname, param);
  8390. };
  8391. var _emscripten_glTexSubImage2D = (target, level, xoffset, yoffset, width, height, format, type, pixels) => {
  8392. var pixelData = pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels) : null;
  8393. GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixelData);
  8394. };
  8395. var webglGetUniformLocation = location => webglGetProgramUniformLocation(GLctx.currentProgram, location);
  8396. var _emscripten_glUniform1f = (location, v0) => {
  8397. GLctx.uniform1f(webglGetUniformLocation(location), v0);
  8398. };
  8399. var miniTempWebGLFloatBuffers = [];
  8400. var _emscripten_glUniform1fv = (location, count, value) => {
  8401. if (count <= 288) {
  8402. // avoid allocation when uploading few enough uniforms
  8403. var view = miniTempWebGLFloatBuffers[count];
  8404. for (var i = 0; i < count; ++i) {
  8405. view[i] = (growMemViews(), HEAPF32)[(((value) + (4 * i)) >> 2)];
  8406. }
  8407. } else {
  8408. var view = (growMemViews(), HEAPF32).subarray((((value) >> 2)), ((value + count * 4) >> 2));
  8409. }
  8410. GLctx.uniform1fv(webglGetUniformLocation(location), view);
  8411. };
  8412. var _emscripten_glUniform1i = (location, v0) => {
  8413. GLctx.uniform1i(webglGetUniformLocation(location), v0);
  8414. };
  8415. var miniTempWebGLIntBuffers = [];
  8416. var _emscripten_glUniform1iv = (location, count, value) => {
  8417. if (count <= 288) {
  8418. // avoid allocation when uploading few enough uniforms
  8419. var view = miniTempWebGLIntBuffers[count];
  8420. for (var i = 0; i < count; ++i) {
  8421. view[i] = (growMemViews(), HEAP32)[(((value) + (4 * i)) >> 2)];
  8422. }
  8423. } else {
  8424. var view = (growMemViews(), HEAP32).subarray((((value) >> 2)), ((value + count * 4) >> 2));
  8425. }
  8426. GLctx.uniform1iv(webglGetUniformLocation(location), view);
  8427. };
  8428. var _emscripten_glUniform2f = (location, v0, v1) => {
  8429. GLctx.uniform2f(webglGetUniformLocation(location), v0, v1);
  8430. };
  8431. var _emscripten_glUniform2fv = (location, count, value) => {
  8432. if (count <= 144) {
  8433. // avoid allocation when uploading few enough uniforms
  8434. count *= 2;
  8435. var view = miniTempWebGLFloatBuffers[count];
  8436. for (var i = 0; i < count; i += 2) {
  8437. view[i] = (growMemViews(), HEAPF32)[(((value) + (4 * i)) >> 2)];
  8438. view[i + 1] = (growMemViews(), HEAPF32)[(((value) + (4 * i + 4)) >> 2)];
  8439. }
  8440. } else {
  8441. var view = (growMemViews(), HEAPF32).subarray((((value) >> 2)), ((value + count * 8) >> 2));
  8442. }
  8443. GLctx.uniform2fv(webglGetUniformLocation(location), view);
  8444. };
  8445. var _emscripten_glUniform2i = (location, v0, v1) => {
  8446. GLctx.uniform2i(webglGetUniformLocation(location), v0, v1);
  8447. };
  8448. var _emscripten_glUniform2iv = (location, count, value) => {
  8449. if (count <= 144) {
  8450. // avoid allocation when uploading few enough uniforms
  8451. count *= 2;
  8452. var view = miniTempWebGLIntBuffers[count];
  8453. for (var i = 0; i < count; i += 2) {
  8454. view[i] = (growMemViews(), HEAP32)[(((value) + (4 * i)) >> 2)];
  8455. view[i + 1] = (growMemViews(), HEAP32)[(((value) + (4 * i + 4)) >> 2)];
  8456. }
  8457. } else {
  8458. var view = (growMemViews(), HEAP32).subarray((((value) >> 2)), ((value + count * 8) >> 2));
  8459. }
  8460. GLctx.uniform2iv(webglGetUniformLocation(location), view);
  8461. };
  8462. var _emscripten_glUniform3f = (location, v0, v1, v2) => {
  8463. GLctx.uniform3f(webglGetUniformLocation(location), v0, v1, v2);
  8464. };
  8465. var _emscripten_glUniform3fv = (location, count, value) => {
  8466. if (count <= 96) {
  8467. // avoid allocation when uploading few enough uniforms
  8468. count *= 3;
  8469. var view = miniTempWebGLFloatBuffers[count];
  8470. for (var i = 0; i < count; i += 3) {
  8471. view[i] = (growMemViews(), HEAPF32)[(((value) + (4 * i)) >> 2)];
  8472. view[i + 1] = (growMemViews(), HEAPF32)[(((value) + (4 * i + 4)) >> 2)];
  8473. view[i + 2] = (growMemViews(), HEAPF32)[(((value) + (4 * i + 8)) >> 2)];
  8474. }
  8475. } else {
  8476. var view = (growMemViews(), HEAPF32).subarray((((value) >> 2)), ((value + count * 12) >> 2));
  8477. }
  8478. GLctx.uniform3fv(webglGetUniformLocation(location), view);
  8479. };
  8480. var _emscripten_glUniform3i = (location, v0, v1, v2) => {
  8481. GLctx.uniform3i(webglGetUniformLocation(location), v0, v1, v2);
  8482. };
  8483. var _emscripten_glUniform3iv = (location, count, value) => {
  8484. if (count <= 96) {
  8485. // avoid allocation when uploading few enough uniforms
  8486. count *= 3;
  8487. var view = miniTempWebGLIntBuffers[count];
  8488. for (var i = 0; i < count; i += 3) {
  8489. view[i] = (growMemViews(), HEAP32)[(((value) + (4 * i)) >> 2)];
  8490. view[i + 1] = (growMemViews(), HEAP32)[(((value) + (4 * i + 4)) >> 2)];
  8491. view[i + 2] = (growMemViews(), HEAP32)[(((value) + (4 * i + 8)) >> 2)];
  8492. }
  8493. } else {
  8494. var view = (growMemViews(), HEAP32).subarray((((value) >> 2)), ((value + count * 12) >> 2));
  8495. }
  8496. GLctx.uniform3iv(webglGetUniformLocation(location), view);
  8497. };
  8498. var _emscripten_glUniform4f = (location, v0, v1, v2, v3) => {
  8499. GLctx.uniform4f(webglGetUniformLocation(location), v0, v1, v2, v3);
  8500. };
  8501. var _emscripten_glUniform4fv = (location, count, value) => {
  8502. if (count <= 72) {
  8503. // avoid allocation when uploading few enough uniforms
  8504. var view = miniTempWebGLFloatBuffers[4 * count];
  8505. // hoist the heap out of the loop for size and for pthreads+growth.
  8506. var heap = (growMemViews(), HEAPF32);
  8507. value = ((value) >> 2);
  8508. count *= 4;
  8509. for (var i = 0; i < count; i += 4) {
  8510. var dst = value + i;
  8511. view[i] = heap[dst];
  8512. view[i + 1] = heap[dst + 1];
  8513. view[i + 2] = heap[dst + 2];
  8514. view[i + 3] = heap[dst + 3];
  8515. }
  8516. } else {
  8517. var view = (growMemViews(), HEAPF32).subarray((((value) >> 2)), ((value + count * 16) >> 2));
  8518. }
  8519. GLctx.uniform4fv(webglGetUniformLocation(location), view);
  8520. };
  8521. var _emscripten_glUniform4i = (location, v0, v1, v2, v3) => {
  8522. GLctx.uniform4i(webglGetUniformLocation(location), v0, v1, v2, v3);
  8523. };
  8524. var _emscripten_glUniform4iv = (location, count, value) => {
  8525. if (count <= 72) {
  8526. // avoid allocation when uploading few enough uniforms
  8527. count *= 4;
  8528. var view = miniTempWebGLIntBuffers[count];
  8529. for (var i = 0; i < count; i += 4) {
  8530. view[i] = (growMemViews(), HEAP32)[(((value) + (4 * i)) >> 2)];
  8531. view[i + 1] = (growMemViews(), HEAP32)[(((value) + (4 * i + 4)) >> 2)];
  8532. view[i + 2] = (growMemViews(), HEAP32)[(((value) + (4 * i + 8)) >> 2)];
  8533. view[i + 3] = (growMemViews(), HEAP32)[(((value) + (4 * i + 12)) >> 2)];
  8534. }
  8535. } else {
  8536. var view = (growMemViews(), HEAP32).subarray((((value) >> 2)), ((value + count * 16) >> 2));
  8537. }
  8538. GLctx.uniform4iv(webglGetUniformLocation(location), view);
  8539. };
  8540. var _emscripten_glUniformMatrix2fv = (location, count, transpose, value) => {
  8541. if (count <= 72) {
  8542. // avoid allocation when uploading few enough uniforms
  8543. count *= 4;
  8544. var view = miniTempWebGLFloatBuffers[count];
  8545. for (var i = 0; i < count; i += 4) {
  8546. view[i] = (growMemViews(), HEAPF32)[(((value) + (4 * i)) >> 2)];
  8547. view[i + 1] = (growMemViews(), HEAPF32)[(((value) + (4 * i + 4)) >> 2)];
  8548. view[i + 2] = (growMemViews(), HEAPF32)[(((value) + (4 * i + 8)) >> 2)];
  8549. view[i + 3] = (growMemViews(), HEAPF32)[(((value) + (4 * i + 12)) >> 2)];
  8550. }
  8551. } else {
  8552. var view = (growMemViews(), HEAPF32).subarray((((value) >> 2)), ((value + count * 16) >> 2));
  8553. }
  8554. GLctx.uniformMatrix2fv(webglGetUniformLocation(location), !!transpose, view);
  8555. };
  8556. var _emscripten_glUniformMatrix3fv = (location, count, transpose, value) => {
  8557. if (count <= 32) {
  8558. // avoid allocation when uploading few enough uniforms
  8559. count *= 9;
  8560. var view = miniTempWebGLFloatBuffers[count];
  8561. for (var i = 0; i < count; i += 9) {
  8562. view[i] = (growMemViews(), HEAPF32)[(((value) + (4 * i)) >> 2)];
  8563. view[i + 1] = (growMemViews(), HEAPF32)[(((value) + (4 * i + 4)) >> 2)];
  8564. view[i + 2] = (growMemViews(), HEAPF32)[(((value) + (4 * i + 8)) >> 2)];
  8565. view[i + 3] = (growMemViews(), HEAPF32)[(((value) + (4 * i + 12)) >> 2)];
  8566. view[i + 4] = (growMemViews(), HEAPF32)[(((value) + (4 * i + 16)) >> 2)];
  8567. view[i + 5] = (growMemViews(), HEAPF32)[(((value) + (4 * i + 20)) >> 2)];
  8568. view[i + 6] = (growMemViews(), HEAPF32)[(((value) + (4 * i + 24)) >> 2)];
  8569. view[i + 7] = (growMemViews(), HEAPF32)[(((value) + (4 * i + 28)) >> 2)];
  8570. view[i + 8] = (growMemViews(), HEAPF32)[(((value) + (4 * i + 32)) >> 2)];
  8571. }
  8572. } else {
  8573. var view = (growMemViews(), HEAPF32).subarray((((value) >> 2)), ((value + count * 36) >> 2));
  8574. }
  8575. GLctx.uniformMatrix3fv(webglGetUniformLocation(location), !!transpose, view);
  8576. };
  8577. var _emscripten_glUniformMatrix4fv = (location, count, transpose, value) => {
  8578. if (count <= 18) {
  8579. // avoid allocation when uploading few enough uniforms
  8580. var view = miniTempWebGLFloatBuffers[16 * count];
  8581. // hoist the heap out of the loop for size and for pthreads+growth.
  8582. var heap = (growMemViews(), HEAPF32);
  8583. value = ((value) >> 2);
  8584. count *= 16;
  8585. for (var i = 0; i < count; i += 16) {
  8586. var dst = value + i;
  8587. view[i] = heap[dst];
  8588. view[i + 1] = heap[dst + 1];
  8589. view[i + 2] = heap[dst + 2];
  8590. view[i + 3] = heap[dst + 3];
  8591. view[i + 4] = heap[dst + 4];
  8592. view[i + 5] = heap[dst + 5];
  8593. view[i + 6] = heap[dst + 6];
  8594. view[i + 7] = heap[dst + 7];
  8595. view[i + 8] = heap[dst + 8];
  8596. view[i + 9] = heap[dst + 9];
  8597. view[i + 10] = heap[dst + 10];
  8598. view[i + 11] = heap[dst + 11];
  8599. view[i + 12] = heap[dst + 12];
  8600. view[i + 13] = heap[dst + 13];
  8601. view[i + 14] = heap[dst + 14];
  8602. view[i + 15] = heap[dst + 15];
  8603. }
  8604. } else {
  8605. var view = (growMemViews(), HEAPF32).subarray((((value) >> 2)), ((value + count * 64) >> 2));
  8606. }
  8607. GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, view);
  8608. };
  8609. var _emscripten_glUseProgram = program => {
  8610. program = GL.programs[program];
  8611. GLctx.useProgram(program);
  8612. // Record the currently active program so that we can access the uniform
  8613. // mapping table of that program.
  8614. GLctx.currentProgram = program;
  8615. };
  8616. var _emscripten_glValidateProgram = program => {
  8617. GLctx.validateProgram(GL.programs[program]);
  8618. };
  8619. var _emscripten_glVertexAttrib1f = (x0, x1) => GLctx.vertexAttrib1f(x0, x1);
  8620. var _emscripten_glVertexAttrib1fv = (index, v) => {
  8621. GLctx.vertexAttrib1f(index, (growMemViews(), HEAPF32)[v >> 2]);
  8622. };
  8623. var _emscripten_glVertexAttrib2f = (x0, x1, x2) => GLctx.vertexAttrib2f(x0, x1, x2);
  8624. var _emscripten_glVertexAttrib2fv = (index, v) => {
  8625. GLctx.vertexAttrib2f(index, (growMemViews(), HEAPF32)[v >> 2], (growMemViews(),
  8626. HEAPF32)[v + 4 >> 2]);
  8627. };
  8628. var _emscripten_glVertexAttrib3f = (x0, x1, x2, x3) => GLctx.vertexAttrib3f(x0, x1, x2, x3);
  8629. var _emscripten_glVertexAttrib3fv = (index, v) => {
  8630. GLctx.vertexAttrib3f(index, (growMemViews(), HEAPF32)[v >> 2], (growMemViews(),
  8631. HEAPF32)[v + 4 >> 2], (growMemViews(), HEAPF32)[v + 8 >> 2]);
  8632. };
  8633. var _emscripten_glVertexAttrib4f = (x0, x1, x2, x3, x4) => GLctx.vertexAttrib4f(x0, x1, x2, x3, x4);
  8634. var _emscripten_glVertexAttrib4fv = (index, v) => {
  8635. GLctx.vertexAttrib4f(index, (growMemViews(), HEAPF32)[v >> 2], (growMemViews(),
  8636. HEAPF32)[v + 4 >> 2], (growMemViews(), HEAPF32)[v + 8 >> 2], (growMemViews(), HEAPF32)[v + 12 >> 2]);
  8637. };
  8638. var _emscripten_glVertexAttribDivisor = (index, divisor) => {
  8639. GLctx.vertexAttribDivisor(index, divisor);
  8640. };
  8641. var _glVertexAttribDivisor = _emscripten_glVertexAttribDivisor;
  8642. var _emscripten_glVertexAttribDivisorANGLE = _glVertexAttribDivisor;
  8643. var _emscripten_glVertexAttribPointer = (index, size, type, normalized, stride, ptr) => {
  8644. GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr);
  8645. };
  8646. var _emscripten_glViewport = (x0, x1, x2, x3) => GLctx.viewport(x0, x1, x2, x3);
  8647. var _emscripten_has_asyncify = () => 0;
  8648. var doRequestFullscreen = (target, strategy) => {
  8649. if (!JSEvents.fullscreenEnabled()) return -1;
  8650. target = findEventTarget(target);
  8651. if (!target) return -4;
  8652. if (!target.requestFullscreen && !target.webkitRequestFullscreen) {
  8653. return -3;
  8654. }
  8655. // Queue this function call if we're not currently in an event handler and
  8656. // the user saw it appropriate to do so.
  8657. if (!JSEvents.canPerformEventHandlerRequests()) {
  8658. if (strategy.deferUntilInEventHandler) {
  8659. JSEvents.deferCall(JSEvents_requestFullscreen, 1, [ target, strategy ]);
  8660. return 1;
  8661. }
  8662. return -2;
  8663. }
  8664. return JSEvents_requestFullscreen(target, strategy);
  8665. };
  8666. function _emscripten_request_fullscreen_strategy(target, deferUntilInEventHandler, fullscreenStrategy) {
  8667. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(43, 0, 1, target, deferUntilInEventHandler, fullscreenStrategy);
  8668. var strategy = {
  8669. scaleMode: (growMemViews(), HEAP32)[((fullscreenStrategy) >> 2)],
  8670. canvasResolutionScaleMode: (growMemViews(), HEAP32)[(((fullscreenStrategy) + (4)) >> 2)],
  8671. filteringMode: (growMemViews(), HEAP32)[(((fullscreenStrategy) + (8)) >> 2)],
  8672. deferUntilInEventHandler,
  8673. canvasResizedCallbackTargetThread: (growMemViews(), HEAP32)[(((fullscreenStrategy) + (20)) >> 2)],
  8674. canvasResizedCallback: (growMemViews(), HEAP32)[(((fullscreenStrategy) + (12)) >> 2)],
  8675. canvasResizedCallbackUserData: (growMemViews(), HEAP32)[(((fullscreenStrategy) + (16)) >> 2)]
  8676. };
  8677. return doRequestFullscreen(target, strategy);
  8678. }
  8679. function _emscripten_request_pointerlock(target, deferUntilInEventHandler) {
  8680. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(44, 0, 1, target, deferUntilInEventHandler);
  8681. target = findEventTarget(target);
  8682. if (!target) return -4;
  8683. if (!target.requestPointerLock) {
  8684. return -1;
  8685. }
  8686. // Queue this function call if we're not currently in an event handler and
  8687. // the user saw it appropriate to do so.
  8688. if (!JSEvents.canPerformEventHandlerRequests()) {
  8689. if (deferUntilInEventHandler) {
  8690. JSEvents.deferCall(requestPointerLock, 2, [ target ]);
  8691. return 1;
  8692. }
  8693. return -2;
  8694. }
  8695. return requestPointerLock(target);
  8696. }
  8697. var getHeapMax = () => // Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate
  8698. // full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side
  8699. // for any code that deals with heap sizes, which would require special
  8700. // casing all heap size related code to treat 0 specially.
  8701. 2147483648;
  8702. var growMemory = size => {
  8703. var oldHeapSize = wasmMemory.buffer.byteLength;
  8704. var pages = ((size - oldHeapSize + 65535) / 65536) | 0;
  8705. try {
  8706. // round size grow request up to wasm page size (fixed 64KB per spec)
  8707. wasmMemory.grow(pages);
  8708. // .grow() takes a delta compared to the previous size
  8709. updateMemoryViews();
  8710. return 1;
  8711. } catch (e) {
  8712. err(`growMemory: Attempted to grow heap from ${oldHeapSize} bytes to ${size} bytes, but got error: ${e}`);
  8713. }
  8714. };
  8715. var _emscripten_resize_heap = requestedSize => {
  8716. var oldSize = (growMemViews(), HEAPU8).length;
  8717. // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
  8718. requestedSize >>>= 0;
  8719. // With multithreaded builds, races can happen (another thread might increase the size
  8720. // in between), so return a failure, and let the caller retry.
  8721. if (requestedSize <= oldSize) {
  8722. return false;
  8723. }
  8724. // Memory resize rules:
  8725. // 1. Always increase heap size to at least the requested size, rounded up
  8726. // to next page multiple.
  8727. // 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap
  8728. // geometrically: increase the heap size according to
  8729. // MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), At most
  8730. // overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB).
  8731. // 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap
  8732. // linearly: increase the heap size by at least
  8733. // MEMORY_GROWTH_LINEAR_STEP bytes.
  8734. // 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by
  8735. // MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest
  8736. // 4. If we were unable to allocate as much memory, it may be due to
  8737. // over-eager decision to excessively reserve due to (3) above.
  8738. // Hence if an allocation fails, cut down on the amount of excess
  8739. // growth, in an attempt to succeed to perform a smaller allocation.
  8740. // A limit is set for how much we can grow. We should not exceed that
  8741. // (the wasm binary specifies it, so if we tried, we'd fail anyhow).
  8742. var maxHeapSize = getHeapMax();
  8743. if (requestedSize > maxHeapSize) {
  8744. err(`Cannot enlarge memory, requested ${requestedSize} bytes, but the limit is ${maxHeapSize} bytes!`);
  8745. return false;
  8746. }
  8747. // Loop through potential heap size increases. If we attempt a too eager
  8748. // reservation that fails, cut down on the attempted size and reserve a
  8749. // smaller bump instead. (max 3 times, chosen somewhat arbitrarily)
  8750. for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
  8751. var overGrownHeapSize = oldSize * (1 + .2 / cutDown);
  8752. // ensure geometric growth
  8753. // but limit overreserving (default to capping at +96MB overgrowth at most)
  8754. overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296);
  8755. var newSize = Math.min(maxHeapSize, alignMemory(Math.max(requestedSize, overGrownHeapSize), 65536));
  8756. var replacement = growMemory(newSize);
  8757. if (replacement) {
  8758. return true;
  8759. }
  8760. }
  8761. err(`Failed to grow the heap from ${oldSize} bytes to ${newSize} bytes, not enough memory!`);
  8762. return false;
  8763. };
  8764. /** @suppress {checkTypes} */ function _emscripten_sample_gamepad_data() {
  8765. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(45, 0, 1);
  8766. try {
  8767. if (navigator.getGamepads) return (JSEvents.lastGamepadState = navigator.getGamepads()) ? 0 : -1;
  8768. } catch (e) {
  8769. err(`navigator.getGamepads() exists, but failed to execute with exception ${e}. Disabling Gamepad access.`);
  8770. navigator.getGamepads = null;
  8771. }
  8772. return -1;
  8773. }
  8774. var registerBeforeUnloadEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString) => {
  8775. var beforeUnloadEventHandlerFunc = e => {
  8776. // Note: This is always called on the main browser thread, since it needs synchronously return a value!
  8777. var confirmationMessage = getWasmTableEntry(callbackfunc)(eventTypeId, 0, userData);
  8778. if (confirmationMessage) {
  8779. confirmationMessage = UTF8ToString(confirmationMessage);
  8780. }
  8781. if (confirmationMessage) {
  8782. e.preventDefault();
  8783. e.returnValue = confirmationMessage;
  8784. return confirmationMessage;
  8785. }
  8786. };
  8787. var eventHandler = {
  8788. target: findEventTarget(target),
  8789. eventTypeString,
  8790. eventTypeId,
  8791. userData,
  8792. callbackfunc,
  8793. handlerFunc: beforeUnloadEventHandlerFunc,
  8794. useCapture
  8795. };
  8796. return JSEvents.registerOrRemoveHandler(eventHandler);
  8797. };
  8798. function _emscripten_set_beforeunload_callback_on_thread(userData, callbackfunc, targetThread) {
  8799. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(46, 0, 1, userData, callbackfunc, targetThread);
  8800. if (typeof onbeforeunload == "undefined") return -1;
  8801. // beforeunload callback can only be registered on the main browser thread, because the page will go away immediately after returning from the handler,
  8802. // and there is no time to start proxying it anywhere.
  8803. if (targetThread !== 1) return -5;
  8804. return registerBeforeUnloadEventCallback(2, userData, true, callbackfunc, 28, "beforeunload");
  8805. }
  8806. var registerFocusEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  8807. targetThread = JSEvents.getTargetThreadForEventCallback(targetThread);
  8808. var eventSize = 256;
  8809. JSEvents.focusEvent ||= _malloc(eventSize);
  8810. var focusEventHandlerFunc = e => {
  8811. var nodeName = JSEvents.getNodeNameForTarget(e.target);
  8812. var id = e.target.id ?? "";
  8813. var focusEvent = JSEvents.focusEvent;
  8814. stringToUTF8(nodeName, focusEvent + 0, 128);
  8815. stringToUTF8(id, focusEvent + 128, 128);
  8816. if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, focusEvent, eventSize, userData); else if (getWasmTableEntry(callbackfunc)(eventTypeId, focusEvent, userData)) e.preventDefault();
  8817. };
  8818. var eventHandler = {
  8819. target: findEventTarget(target),
  8820. eventTypeString,
  8821. eventTypeId,
  8822. userData,
  8823. callbackfunc,
  8824. handlerFunc: focusEventHandlerFunc,
  8825. useCapture
  8826. };
  8827. return JSEvents.registerOrRemoveHandler(eventHandler);
  8828. };
  8829. function _emscripten_set_blur_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  8830. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(47, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  8831. return registerFocusEventCallback(target, userData, useCapture, callbackfunc, 12, "blur", targetThread);
  8832. }
  8833. function _emscripten_set_element_css_size(target, width, height) {
  8834. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(48, 0, 1, target, width, height);
  8835. target = findEventTarget(target);
  8836. if (!target) return -4;
  8837. target.style.width = width + "px";
  8838. target.style.height = height + "px";
  8839. return 0;
  8840. }
  8841. function _emscripten_set_focus_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  8842. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(49, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  8843. return registerFocusEventCallback(target, userData, useCapture, callbackfunc, 13, "focus", targetThread);
  8844. }
  8845. var fillFullscreenChangeEventData = eventStruct => {
  8846. var fullscreenElement = getFullscreenElement();
  8847. var isFullscreen = !!fullscreenElement;
  8848. // Assigning a boolean to HEAP32 with expected type coercion.
  8849. /** @suppress{checkTypes} */ (growMemViews(), HEAP8)[eventStruct] = isFullscreen;
  8850. (growMemViews(), HEAP8)[(eventStruct) + (1)] = JSEvents.fullscreenEnabled();
  8851. // If transitioning to fullscreen, report info about the element that is now fullscreen.
  8852. // If transitioning to windowed mode, report info about the element that just was fullscreen.
  8853. var reportedElement = isFullscreen ? fullscreenElement : JSEvents.previousFullscreenElement;
  8854. var nodeName = JSEvents.getNodeNameForTarget(reportedElement);
  8855. var id = reportedElement?.id ?? "";
  8856. stringToUTF8(nodeName, eventStruct + 2, 128);
  8857. stringToUTF8(id, eventStruct + 130, 128);
  8858. (growMemViews(), HEAP32)[(((eventStruct) + (260)) >> 2)] = reportedElement?.clientWidth ?? 0;
  8859. (growMemViews(), HEAP32)[(((eventStruct) + (264)) >> 2)] = reportedElement?.clientHeight ?? 0;
  8860. (growMemViews(), HEAP32)[(((eventStruct) + (268)) >> 2)] = screen.width;
  8861. (growMemViews(), HEAP32)[(((eventStruct) + (272)) >> 2)] = screen.height;
  8862. if (isFullscreen) {
  8863. JSEvents.previousFullscreenElement = fullscreenElement;
  8864. }
  8865. };
  8866. var registerFullscreenChangeEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  8867. targetThread = JSEvents.getTargetThreadForEventCallback(targetThread);
  8868. var eventSize = 276;
  8869. JSEvents.fullscreenChangeEvent ||= _malloc(eventSize);
  8870. var fullscreenChangeEventHandlerFunc = e => {
  8871. var fullscreenChangeEvent = JSEvents.fullscreenChangeEvent;
  8872. fillFullscreenChangeEventData(fullscreenChangeEvent);
  8873. if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, fullscreenChangeEvent, eventSize, userData); else if (getWasmTableEntry(callbackfunc)(eventTypeId, fullscreenChangeEvent, userData)) e.preventDefault();
  8874. };
  8875. var eventHandler = {
  8876. target,
  8877. eventTypeString,
  8878. eventTypeId,
  8879. userData,
  8880. callbackfunc,
  8881. handlerFunc: fullscreenChangeEventHandlerFunc,
  8882. useCapture
  8883. };
  8884. return JSEvents.registerOrRemoveHandler(eventHandler);
  8885. };
  8886. function _emscripten_set_fullscreenchange_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  8887. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(50, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  8888. if (!JSEvents.fullscreenEnabled()) return -1;
  8889. target = findEventTarget(target);
  8890. if (!target) return -4;
  8891. // As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version.
  8892. // TODO: When this block is removed, also change test/test_html5_remove_event_listener.c test expectation on emscripten_set_fullscreenchange_callback().
  8893. registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "webkitfullscreenchange", targetThread);
  8894. return registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "fullscreenchange", targetThread);
  8895. }
  8896. var registerGamepadEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  8897. targetThread = JSEvents.getTargetThreadForEventCallback(targetThread);
  8898. var eventSize = 1240;
  8899. JSEvents.gamepadEvent ||= _malloc(eventSize);
  8900. var gamepadEventHandlerFunc = e => {
  8901. var gamepadEvent = JSEvents.gamepadEvent;
  8902. fillGamepadEventData(gamepadEvent, e["gamepad"]);
  8903. if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, gamepadEvent, eventSize, userData); else if (getWasmTableEntry(callbackfunc)(eventTypeId, gamepadEvent, userData)) e.preventDefault();
  8904. };
  8905. var eventHandler = {
  8906. target: findEventTarget(target),
  8907. allowsDeferredCalls: true,
  8908. eventTypeString,
  8909. eventTypeId,
  8910. userData,
  8911. callbackfunc,
  8912. handlerFunc: gamepadEventHandlerFunc,
  8913. useCapture
  8914. };
  8915. return JSEvents.registerOrRemoveHandler(eventHandler);
  8916. };
  8917. function _emscripten_set_gamepadconnected_callback_on_thread(userData, useCapture, callbackfunc, targetThread) {
  8918. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(51, 0, 1, userData, useCapture, callbackfunc, targetThread);
  8919. if (_emscripten_sample_gamepad_data()) return -1;
  8920. return registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 26, "gamepadconnected", targetThread);
  8921. }
  8922. function _emscripten_set_gamepaddisconnected_callback_on_thread(userData, useCapture, callbackfunc, targetThread) {
  8923. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(52, 0, 1, userData, useCapture, callbackfunc, targetThread);
  8924. if (_emscripten_sample_gamepad_data()) return -1;
  8925. return registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 27, "gamepaddisconnected", targetThread);
  8926. }
  8927. var registerKeyEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  8928. targetThread = JSEvents.getTargetThreadForEventCallback(targetThread);
  8929. var eventSize = 160;
  8930. JSEvents.keyEvent ||= _malloc(eventSize);
  8931. var keyEventHandlerFunc = e => {
  8932. assert(e);
  8933. var keyEventData = JSEvents.keyEvent;
  8934. (growMemViews(), HEAPF64)[((keyEventData) >> 3)] = e.timeStamp;
  8935. var idx = ((keyEventData) >> 2);
  8936. (growMemViews(), HEAP32)[idx + 2] = e.location;
  8937. (growMemViews(), HEAP8)[keyEventData + 12] = e.ctrlKey;
  8938. (growMemViews(), HEAP8)[keyEventData + 13] = e.shiftKey;
  8939. (growMemViews(), HEAP8)[keyEventData + 14] = e.altKey;
  8940. (growMemViews(), HEAP8)[keyEventData + 15] = e.metaKey;
  8941. (growMemViews(), HEAP8)[keyEventData + 16] = e.repeat;
  8942. (growMemViews(), HEAP32)[idx + 5] = e.charCode;
  8943. (growMemViews(), HEAP32)[idx + 6] = e.keyCode;
  8944. (growMemViews(), HEAP32)[idx + 7] = e.which;
  8945. stringToUTF8(e.key ?? "", keyEventData + 32, 32);
  8946. stringToUTF8(e.code ?? "", keyEventData + 64, 32);
  8947. stringToUTF8(e.char ?? "", keyEventData + 96, 32);
  8948. stringToUTF8(e.locale ?? "", keyEventData + 128, 32);
  8949. if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, keyEventData, eventSize, userData); else if (getWasmTableEntry(callbackfunc)(eventTypeId, keyEventData, userData)) e.preventDefault();
  8950. };
  8951. var eventHandler = {
  8952. target: findEventTarget(target),
  8953. eventTypeString,
  8954. eventTypeId,
  8955. userData,
  8956. callbackfunc,
  8957. handlerFunc: keyEventHandlerFunc,
  8958. useCapture
  8959. };
  8960. return JSEvents.registerOrRemoveHandler(eventHandler);
  8961. };
  8962. function _emscripten_set_keydown_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  8963. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(53, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  8964. return registerKeyEventCallback(target, userData, useCapture, callbackfunc, 2, "keydown", targetThread);
  8965. }
  8966. function _emscripten_set_keypress_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  8967. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(54, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  8968. return registerKeyEventCallback(target, userData, useCapture, callbackfunc, 1, "keypress", targetThread);
  8969. }
  8970. function _emscripten_set_keyup_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  8971. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(55, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  8972. return registerKeyEventCallback(target, userData, useCapture, callbackfunc, 3, "keyup", targetThread);
  8973. }
  8974. var _emscripten_set_main_loop = (func, fps, simulateInfiniteLoop) => {
  8975. var iterFunc = getWasmTableEntry(func);
  8976. setMainLoop(iterFunc, fps, simulateInfiniteLoop);
  8977. };
  8978. var fillMouseEventData = (eventStruct, e, target) => {
  8979. assert(eventStruct % 4 == 0);
  8980. (growMemViews(), HEAPF64)[((eventStruct) >> 3)] = e.timeStamp;
  8981. var idx = ((eventStruct) >> 2);
  8982. (growMemViews(), HEAP32)[idx + 2] = e.screenX;
  8983. (growMemViews(), HEAP32)[idx + 3] = e.screenY;
  8984. (growMemViews(), HEAP32)[idx + 4] = e.clientX;
  8985. (growMemViews(), HEAP32)[idx + 5] = e.clientY;
  8986. (growMemViews(), HEAP8)[eventStruct + 24] = e.ctrlKey;
  8987. (growMemViews(), HEAP8)[eventStruct + 25] = e.shiftKey;
  8988. (growMemViews(), HEAP8)[eventStruct + 26] = e.altKey;
  8989. (growMemViews(), HEAP8)[eventStruct + 27] = e.metaKey;
  8990. (growMemViews(), HEAP16)[idx * 2 + 14] = e.button;
  8991. (growMemViews(), HEAP16)[idx * 2 + 15] = e.buttons;
  8992. (growMemViews(), HEAP32)[idx + 8] = e["movementX"];
  8993. (growMemViews(), HEAP32)[idx + 9] = e["movementY"];
  8994. // Note: rect contains doubles (truncated to placate SAFE_HEAP, which is the same behaviour when writing to HEAP32 anyway)
  8995. var rect = getBoundingClientRect(target);
  8996. (growMemViews(), HEAP32)[idx + 10] = e.clientX - (rect.left | 0);
  8997. (growMemViews(), HEAP32)[idx + 11] = e.clientY - (rect.top | 0);
  8998. };
  8999. var registerMouseEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  9000. targetThread = JSEvents.getTargetThreadForEventCallback(targetThread);
  9001. var eventSize = 64;
  9002. JSEvents.mouseEvent ||= _malloc(eventSize);
  9003. target = findEventTarget(target);
  9004. var mouseEventHandlerFunc = e => {
  9005. // TODO: Make this access thread safe, or this could update live while app is reading it.
  9006. fillMouseEventData(JSEvents.mouseEvent, e, target);
  9007. if (targetThread) {
  9008. __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, JSEvents.mouseEvent, eventSize, userData);
  9009. } else if (getWasmTableEntry(callbackfunc)(eventTypeId, JSEvents.mouseEvent, userData)) e.preventDefault();
  9010. };
  9011. var eventHandler = {
  9012. target,
  9013. allowsDeferredCalls: eventTypeString != "mousemove" && eventTypeString != "mouseenter" && eventTypeString != "mouseleave",
  9014. // Mouse move events do not allow fullscreen/pointer lock requests to be handled in them!
  9015. eventTypeString,
  9016. eventTypeId,
  9017. userData,
  9018. callbackfunc,
  9019. handlerFunc: mouseEventHandlerFunc,
  9020. useCapture
  9021. };
  9022. return JSEvents.registerOrRemoveHandler(eventHandler);
  9023. };
  9024. function _emscripten_set_mousedown_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  9025. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(56, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  9026. return registerMouseEventCallback(target, userData, useCapture, callbackfunc, 5, "mousedown", targetThread);
  9027. }
  9028. function _emscripten_set_mouseenter_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  9029. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(57, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  9030. return registerMouseEventCallback(target, userData, useCapture, callbackfunc, 33, "mouseenter", targetThread);
  9031. }
  9032. function _emscripten_set_mouseleave_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  9033. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(58, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  9034. return registerMouseEventCallback(target, userData, useCapture, callbackfunc, 34, "mouseleave", targetThread);
  9035. }
  9036. function _emscripten_set_mousemove_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  9037. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(59, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  9038. return registerMouseEventCallback(target, userData, useCapture, callbackfunc, 8, "mousemove", targetThread);
  9039. }
  9040. function _emscripten_set_mouseup_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  9041. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(60, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  9042. return registerMouseEventCallback(target, userData, useCapture, callbackfunc, 6, "mouseup", targetThread);
  9043. }
  9044. var fillPointerlockChangeEventData = eventStruct => {
  9045. var pointerLockElement = document.pointerLockElement;
  9046. var isPointerlocked = !!pointerLockElement;
  9047. // Assigning a boolean to HEAP32 with expected type coercion.
  9048. /** @suppress{checkTypes} */ (growMemViews(), HEAP8)[eventStruct] = isPointerlocked;
  9049. var nodeName = JSEvents.getNodeNameForTarget(pointerLockElement);
  9050. var id = pointerLockElement?.id ?? "";
  9051. stringToUTF8(nodeName, eventStruct + 1, 128);
  9052. stringToUTF8(id, eventStruct + 129, 128);
  9053. };
  9054. var registerPointerlockChangeEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  9055. targetThread = JSEvents.getTargetThreadForEventCallback(targetThread);
  9056. var eventSize = 257;
  9057. JSEvents.pointerlockChangeEvent ||= _malloc(eventSize);
  9058. var pointerlockChangeEventHandlerFunc = e => {
  9059. var pointerlockChangeEvent = JSEvents.pointerlockChangeEvent;
  9060. fillPointerlockChangeEventData(pointerlockChangeEvent);
  9061. if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, pointerlockChangeEvent, eventSize, userData); else if (getWasmTableEntry(callbackfunc)(eventTypeId, pointerlockChangeEvent, userData)) e.preventDefault();
  9062. };
  9063. var eventHandler = {
  9064. target,
  9065. eventTypeString,
  9066. eventTypeId,
  9067. userData,
  9068. callbackfunc,
  9069. handlerFunc: pointerlockChangeEventHandlerFunc,
  9070. useCapture
  9071. };
  9072. return JSEvents.registerOrRemoveHandler(eventHandler);
  9073. };
  9074. function _emscripten_set_pointerlockchange_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  9075. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(61, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  9076. if (!document.body?.requestPointerLock) {
  9077. return -1;
  9078. }
  9079. target = findEventTarget(target);
  9080. if (!target) return -4;
  9081. return registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "pointerlockchange", targetThread);
  9082. }
  9083. var registerUiEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  9084. targetThread = JSEvents.getTargetThreadForEventCallback(targetThread);
  9085. var eventSize = 36;
  9086. JSEvents.uiEvent ||= _malloc(eventSize);
  9087. target = findEventTarget(target);
  9088. var uiEventHandlerFunc = e => {
  9089. if (e.target != target) {
  9090. // Never take ui events such as scroll via a 'bubbled' route, but always from the direct element that
  9091. // was targeted. Otherwise e.g. if app logs a message in response to a page scroll, the Emscripten log
  9092. // message box could cause to scroll, generating a new (bubbled) scroll message, causing a new log print,
  9093. // causing a new scroll, etc..
  9094. return;
  9095. }
  9096. var b = document.body;
  9097. // Take document.body to a variable, Closure compiler does not outline access to it on its own.
  9098. if (!b) {
  9099. // During a page unload 'body' can be null, with "Cannot read property 'clientWidth' of null" being thrown
  9100. return;
  9101. }
  9102. var uiEvent = JSEvents.uiEvent;
  9103. (growMemViews(), HEAP32)[((uiEvent) >> 2)] = 0;
  9104. // always zero for resize and scroll
  9105. (growMemViews(), HEAP32)[(((uiEvent) + (4)) >> 2)] = b.clientWidth;
  9106. (growMemViews(), HEAP32)[(((uiEvent) + (8)) >> 2)] = b.clientHeight;
  9107. (growMemViews(), HEAP32)[(((uiEvent) + (12)) >> 2)] = innerWidth;
  9108. (growMemViews(), HEAP32)[(((uiEvent) + (16)) >> 2)] = innerHeight;
  9109. (growMemViews(), HEAP32)[(((uiEvent) + (20)) >> 2)] = outerWidth;
  9110. (growMemViews(), HEAP32)[(((uiEvent) + (24)) >> 2)] = outerHeight;
  9111. (growMemViews(), HEAP32)[(((uiEvent) + (28)) >> 2)] = pageXOffset | 0;
  9112. // scroll offsets are float
  9113. (growMemViews(), HEAP32)[(((uiEvent) + (32)) >> 2)] = pageYOffset | 0;
  9114. if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, uiEvent, eventSize, userData); else if (getWasmTableEntry(callbackfunc)(eventTypeId, uiEvent, userData)) e.preventDefault();
  9115. };
  9116. var eventHandler = {
  9117. target,
  9118. eventTypeString,
  9119. eventTypeId,
  9120. userData,
  9121. callbackfunc,
  9122. handlerFunc: uiEventHandlerFunc,
  9123. useCapture
  9124. };
  9125. return JSEvents.registerOrRemoveHandler(eventHandler);
  9126. };
  9127. function _emscripten_set_resize_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  9128. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(62, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  9129. return registerUiEventCallback(target, userData, useCapture, callbackfunc, 10, "resize", targetThread);
  9130. }
  9131. var registerTouchEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  9132. targetThread = JSEvents.getTargetThreadForEventCallback(targetThread);
  9133. var eventSize = 1552;
  9134. JSEvents.touchEvent ||= _malloc(eventSize);
  9135. target = findEventTarget(target);
  9136. var touchEventHandlerFunc = e => {
  9137. assert(e);
  9138. var t, touches = {}, et = e.touches;
  9139. // To ease marshalling different kinds of touches that browser reports (all touches are listed in e.touches,
  9140. // only changed touches in e.changedTouches, and touches on target at a.targetTouches), mark a boolean in
  9141. // each Touch object so that we can later loop only once over all touches we see to marshall over to Wasm.
  9142. for (let t of et) {
  9143. // Browser might recycle the generated Touch objects between each frame (Firefox on Android), so reset any
  9144. // changed/target states we may have set from previous frame.
  9145. t.isChanged = t.onTarget = 0;
  9146. touches[t.identifier] = t;
  9147. }
  9148. // Mark which touches are part of the changedTouches list.
  9149. for (let t of e.changedTouches) {
  9150. t.isChanged = 1;
  9151. touches[t.identifier] = t;
  9152. }
  9153. // Mark which touches are part of the targetTouches list.
  9154. for (let t of e.targetTouches) {
  9155. touches[t.identifier].onTarget = 1;
  9156. }
  9157. var touchEvent = JSEvents.touchEvent;
  9158. (growMemViews(), HEAPF64)[((touchEvent) >> 3)] = e.timeStamp;
  9159. (growMemViews(), HEAP8)[touchEvent + 12] = e.ctrlKey;
  9160. (growMemViews(), HEAP8)[touchEvent + 13] = e.shiftKey;
  9161. (growMemViews(), HEAP8)[touchEvent + 14] = e.altKey;
  9162. (growMemViews(), HEAP8)[touchEvent + 15] = e.metaKey;
  9163. var idx = touchEvent + 16;
  9164. var targetRect = getBoundingClientRect(target);
  9165. var numTouches = 0;
  9166. for (let t of Object.values(touches)) {
  9167. var idx32 = ((idx) >> 2);
  9168. // Pre-shift the ptr to index to HEAP32 to save code size
  9169. (growMemViews(), HEAP32)[idx32 + 0] = t.identifier;
  9170. (growMemViews(), HEAP32)[idx32 + 1] = t.screenX;
  9171. (growMemViews(), HEAP32)[idx32 + 2] = t.screenY;
  9172. (growMemViews(), HEAP32)[idx32 + 3] = t.clientX;
  9173. (growMemViews(), HEAP32)[idx32 + 4] = t.clientY;
  9174. (growMemViews(), HEAP32)[idx32 + 5] = t.pageX;
  9175. (growMemViews(), HEAP32)[idx32 + 6] = t.pageY;
  9176. (growMemViews(), HEAP8)[idx + 28] = t.isChanged;
  9177. (growMemViews(), HEAP8)[idx + 29] = t.onTarget;
  9178. (growMemViews(), HEAP32)[idx32 + 8] = t.clientX - (targetRect.left | 0);
  9179. (growMemViews(), HEAP32)[idx32 + 9] = t.clientY - (targetRect.top | 0);
  9180. idx += 48;
  9181. if (++numTouches > 31) {
  9182. break;
  9183. }
  9184. }
  9185. (growMemViews(), HEAP32)[(((touchEvent) + (8)) >> 2)] = numTouches;
  9186. if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, touchEvent, eventSize, userData); else if (getWasmTableEntry(callbackfunc)(eventTypeId, touchEvent, userData)) e.preventDefault();
  9187. };
  9188. var eventHandler = {
  9189. target,
  9190. allowsDeferredCalls: eventTypeString == "touchstart" || eventTypeString == "touchend",
  9191. eventTypeString,
  9192. eventTypeId,
  9193. userData,
  9194. callbackfunc,
  9195. handlerFunc: touchEventHandlerFunc,
  9196. useCapture
  9197. };
  9198. return JSEvents.registerOrRemoveHandler(eventHandler);
  9199. };
  9200. function _emscripten_set_touchcancel_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  9201. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(63, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  9202. return registerTouchEventCallback(target, userData, useCapture, callbackfunc, 25, "touchcancel", targetThread);
  9203. }
  9204. function _emscripten_set_touchend_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  9205. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(64, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  9206. return registerTouchEventCallback(target, userData, useCapture, callbackfunc, 23, "touchend", targetThread);
  9207. }
  9208. function _emscripten_set_touchmove_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  9209. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(65, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  9210. return registerTouchEventCallback(target, userData, useCapture, callbackfunc, 24, "touchmove", targetThread);
  9211. }
  9212. function _emscripten_set_touchstart_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  9213. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(66, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  9214. return registerTouchEventCallback(target, userData, useCapture, callbackfunc, 22, "touchstart", targetThread);
  9215. }
  9216. var fillVisibilityChangeEventData = eventStruct => {
  9217. var visibilityStates = [ "hidden", "visible", "prerender", "unloaded" ];
  9218. var visibilityState = visibilityStates.indexOf(document.visibilityState);
  9219. // Assigning a boolean to HEAP32 with expected type coercion.
  9220. /** @suppress{checkTypes} */ (growMemViews(), HEAP8)[eventStruct] = document.hidden;
  9221. (growMemViews(), HEAP32)[(((eventStruct) + (4)) >> 2)] = visibilityState;
  9222. };
  9223. var registerVisibilityChangeEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  9224. targetThread = JSEvents.getTargetThreadForEventCallback(targetThread);
  9225. var eventSize = 8;
  9226. JSEvents.visibilityChangeEvent ||= _malloc(eventSize);
  9227. var visibilityChangeEventHandlerFunc = e => {
  9228. var visibilityChangeEvent = JSEvents.visibilityChangeEvent;
  9229. fillVisibilityChangeEventData(visibilityChangeEvent);
  9230. if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, visibilityChangeEvent, eventSize, userData); else if (getWasmTableEntry(callbackfunc)(eventTypeId, visibilityChangeEvent, userData)) e.preventDefault();
  9231. };
  9232. var eventHandler = {
  9233. target,
  9234. eventTypeString,
  9235. eventTypeId,
  9236. userData,
  9237. callbackfunc,
  9238. handlerFunc: visibilityChangeEventHandlerFunc,
  9239. useCapture
  9240. };
  9241. return JSEvents.registerOrRemoveHandler(eventHandler);
  9242. };
  9243. function _emscripten_set_visibilitychange_callback_on_thread(userData, useCapture, callbackfunc, targetThread) {
  9244. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(67, 0, 1, userData, useCapture, callbackfunc, targetThread);
  9245. if (!specialHTMLTargets[1]) {
  9246. return -4;
  9247. }
  9248. return registerVisibilityChangeEventCallback(specialHTMLTargets[1], userData, useCapture, callbackfunc, 21, "visibilitychange", targetThread);
  9249. }
  9250. var registerWheelEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  9251. targetThread = JSEvents.getTargetThreadForEventCallback(targetThread);
  9252. var eventSize = 96;
  9253. JSEvents.wheelEvent ||= _malloc(eventSize);
  9254. // The DOM Level 3 events spec event 'wheel'
  9255. var wheelHandlerFunc = e => {
  9256. var wheelEvent = JSEvents.wheelEvent;
  9257. fillMouseEventData(wheelEvent, e, target);
  9258. (growMemViews(), HEAPF64)[(((wheelEvent) + (64)) >> 3)] = e["deltaX"];
  9259. (growMemViews(), HEAPF64)[(((wheelEvent) + (72)) >> 3)] = e["deltaY"];
  9260. (growMemViews(), HEAPF64)[(((wheelEvent) + (80)) >> 3)] = e["deltaZ"];
  9261. (growMemViews(), HEAP32)[(((wheelEvent) + (88)) >> 2)] = e["deltaMode"];
  9262. if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, wheelEvent, eventSize, userData); else if (getWasmTableEntry(callbackfunc)(eventTypeId, wheelEvent, userData)) e.preventDefault();
  9263. };
  9264. var eventHandler = {
  9265. target,
  9266. allowsDeferredCalls: true,
  9267. eventTypeString,
  9268. eventTypeId,
  9269. userData,
  9270. callbackfunc,
  9271. handlerFunc: wheelHandlerFunc,
  9272. useCapture
  9273. };
  9274. return JSEvents.registerOrRemoveHandler(eventHandler);
  9275. };
  9276. function _emscripten_set_wheel_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  9277. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(68, 0, 1, target, userData, useCapture, callbackfunc, targetThread);
  9278. target = findEventTarget(target);
  9279. if (!target) return -4;
  9280. if (typeof target.onwheel != "undefined") {
  9281. return registerWheelEventCallback(target, userData, useCapture, callbackfunc, 9, "wheel", targetThread);
  9282. } else {
  9283. return -1;
  9284. }
  9285. }
  9286. function _emscripten_set_window_title(title) {
  9287. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(69, 0, 1, title);
  9288. return document.title = UTF8ToString(title);
  9289. }
  9290. var _emscripten_sleep = () => {
  9291. abort("Please compile your program with async support in order to use asynchronous operations like emscripten_sleep");
  9292. };
  9293. var ENV = {};
  9294. var getExecutableName = () => thisProgram;
  9295. var getEnvStrings = () => {
  9296. if (!getEnvStrings.strings) {
  9297. // Default values.
  9298. var lang = (globalThis.navigator?.language ?? "C").replace("-", "_") + ".UTF-8";
  9299. var env = {
  9300. "USER": "web_user",
  9301. "LOGNAME": "web_user",
  9302. "PATH": "/",
  9303. "PWD": "/",
  9304. "HOME": "/home/web_user",
  9305. "LANG": lang,
  9306. "_": getExecutableName()
  9307. };
  9308. // Apply the user-provided values, if any.
  9309. for (var x in ENV) {
  9310. // x is a key in ENV; if ENV[x] is undefined, that means it was
  9311. // explicitly set to be so. We allow user code to do that to
  9312. // force variables with default values to remain unset.
  9313. if (ENV[x] === undefined) delete env[x]; else env[x] = ENV[x];
  9314. }
  9315. var strings = [];
  9316. for (var x in env) {
  9317. strings.push(`${x}=${env[x]}`);
  9318. }
  9319. getEnvStrings.strings = strings;
  9320. }
  9321. return getEnvStrings.strings;
  9322. };
  9323. function _environ_get(__environ, environ_buf) {
  9324. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(70, 0, 1, __environ, environ_buf);
  9325. var bufSize = 0;
  9326. var envp = 0;
  9327. for (var string of getEnvStrings()) {
  9328. var ptr = environ_buf + bufSize;
  9329. (growMemViews(), HEAPU32)[(((__environ) + (envp)) >> 2)] = ptr;
  9330. bufSize += stringToUTF8(string, ptr, Infinity) + 1;
  9331. envp += 4;
  9332. }
  9333. return 0;
  9334. }
  9335. function _environ_sizes_get(penviron_count, penviron_buf_size) {
  9336. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(71, 0, 1, penviron_count, penviron_buf_size);
  9337. var strings = getEnvStrings();
  9338. (growMemViews(), HEAPU32)[((penviron_count) >> 2)] = strings.length;
  9339. var bufSize = 0;
  9340. for (var string of strings) {
  9341. bufSize += lengthBytesUTF8(string) + 1;
  9342. }
  9343. (growMemViews(), HEAPU32)[((penviron_buf_size) >> 2)] = bufSize;
  9344. return 0;
  9345. }
  9346. function _fd_close(fd) {
  9347. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(72, 0, 1, fd);
  9348. try {
  9349. var stream = SYSCALLS.getStreamFromFD(fd);
  9350. FS.close(stream);
  9351. return 0;
  9352. } catch (e) {
  9353. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  9354. return e.errno;
  9355. }
  9356. }
  9357. /** @param {number=} offset */ var doReadv = (stream, iov, iovcnt, offset) => {
  9358. var ret = 0;
  9359. for (var i = 0; i < iovcnt; i++) {
  9360. var ptr = (growMemViews(), HEAPU32)[((iov) >> 2)];
  9361. var len = (growMemViews(), HEAPU32)[(((iov) + (4)) >> 2)];
  9362. iov += 8;
  9363. var curr = FS.read(stream, (growMemViews(), HEAP8), ptr, len, offset);
  9364. if (curr < 0) return -1;
  9365. ret += curr;
  9366. if (curr < len) break;
  9367. // nothing more to read
  9368. if (typeof offset != "undefined") {
  9369. offset += curr;
  9370. }
  9371. }
  9372. return ret;
  9373. };
  9374. function _fd_read(fd, iov, iovcnt, pnum) {
  9375. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(73, 0, 1, fd, iov, iovcnt, pnum);
  9376. try {
  9377. var stream = SYSCALLS.getStreamFromFD(fd);
  9378. var num = doReadv(stream, iov, iovcnt);
  9379. (growMemViews(), HEAPU32)[((pnum) >> 2)] = num;
  9380. return 0;
  9381. } catch (e) {
  9382. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  9383. return e.errno;
  9384. }
  9385. }
  9386. function _fd_seek(fd, offset, whence, newOffset) {
  9387. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(74, 0, 1, fd, offset, whence, newOffset);
  9388. offset = bigintToI53Checked(offset);
  9389. try {
  9390. if (isNaN(offset)) return 22;
  9391. var stream = SYSCALLS.getStreamFromFD(fd);
  9392. FS.llseek(stream, offset, whence);
  9393. (growMemViews(), HEAP64)[((newOffset) >> 3)] = BigInt(stream.position);
  9394. if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null;
  9395. // reset readdir state
  9396. return 0;
  9397. } catch (e) {
  9398. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  9399. return e.errno;
  9400. }
  9401. }
  9402. /** @param {number=} offset */ var doWritev = (stream, iov, iovcnt, offset) => {
  9403. var ret = 0;
  9404. for (var i = 0; i < iovcnt; i++) {
  9405. var ptr = (growMemViews(), HEAPU32)[((iov) >> 2)];
  9406. var len = (growMemViews(), HEAPU32)[(((iov) + (4)) >> 2)];
  9407. iov += 8;
  9408. var curr = FS.write(stream, (growMemViews(), HEAP8), ptr, len, offset);
  9409. if (curr < 0) return -1;
  9410. ret += curr;
  9411. if (curr < len) {
  9412. // No more space to write.
  9413. break;
  9414. }
  9415. if (typeof offset != "undefined") {
  9416. offset += curr;
  9417. }
  9418. }
  9419. return ret;
  9420. };
  9421. function _fd_write(fd, iov, iovcnt, pnum) {
  9422. if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(75, 0, 1, fd, iov, iovcnt, pnum);
  9423. try {
  9424. var stream = SYSCALLS.getStreamFromFD(fd);
  9425. var num = doWritev(stream, iov, iovcnt);
  9426. (growMemViews(), HEAPU32)[((pnum) >> 2)] = num;
  9427. return 0;
  9428. } catch (e) {
  9429. if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
  9430. return e.errno;
  9431. }
  9432. }
  9433. function _posix_spawnp(...args) {
  9434. abort("missing function: posix_spawnp");
  9435. }
  9436. _posix_spawnp.stub = true;
  9437. var autoResumeAudioContext = ctx => {
  9438. for (var event of [ "keydown", "mousedown", "touchstart" ]) {
  9439. for (var element of [ document, document.getElementById("canvas") ]) {
  9440. element?.addEventListener(event, () => {
  9441. if (ctx.state === "suspended") ctx.resume();
  9442. }, {
  9443. "once": true
  9444. });
  9445. }
  9446. }
  9447. };
  9448. var dynCall = (sig, ptr, args = [], promising = false) => {
  9449. assert(ptr, `null function pointer in dynCall`);
  9450. assert(!promising, "async dynCall is not supported in this mode");
  9451. assert(getWasmTableEntry(ptr), `missing table entry in dynCall: ${ptr}`);
  9452. var func = getWasmTableEntry(ptr);
  9453. var rtn = func(...args);
  9454. function convert(rtn) {
  9455. return rtn;
  9456. }
  9457. return convert(rtn);
  9458. };
  9459. var getCFunc = ident => {
  9460. var func = Module["_" + ident];
  9461. // closure exported function
  9462. assert(func, `Cannot call unknown function ${ident}, make sure it is exported`);
  9463. return func;
  9464. };
  9465. var writeArrayToMemory = (array, buffer) => {
  9466. assert(array.length >= 0, "writeArrayToMemory array must have a length (should be an array or typed array)");
  9467. (growMemViews(), HEAP8).set(array, buffer);
  9468. };
  9469. /**
  9470. * @param {string|null=} returnType
  9471. * @param {Array=} argTypes
  9472. * @param {Array=} args
  9473. * @param {Object=} opts
  9474. */ var ccall = (ident, returnType, argTypes, args, opts) => {
  9475. // For fast lookup of conversion functions
  9476. var toC = {
  9477. "string": str => {
  9478. var ret = 0;
  9479. if (str !== null && str !== undefined && str !== 0) {
  9480. // null string
  9481. ret = stringToUTF8OnStack(str);
  9482. }
  9483. return ret;
  9484. },
  9485. "array": arr => {
  9486. var ret = stackAlloc(arr.length);
  9487. writeArrayToMemory(arr, ret);
  9488. return ret;
  9489. }
  9490. };
  9491. function convertReturnValue(ret) {
  9492. if (returnType === "string") {
  9493. return UTF8ToString(ret);
  9494. }
  9495. if (returnType === "boolean") return Boolean(ret);
  9496. return ret;
  9497. }
  9498. var func = getCFunc(ident);
  9499. var cArgs = [];
  9500. var stack = 0;
  9501. assert(returnType !== "array", 'return type should not be "array"');
  9502. if (args) {
  9503. for (var i = 0; i < args.length; i++) {
  9504. var converter = toC[argTypes[i]];
  9505. if (converter) {
  9506. if (stack === 0) stack = stackSave();
  9507. cArgs[i] = converter(args[i]);
  9508. } else {
  9509. cArgs[i] = args[i];
  9510. }
  9511. }
  9512. }
  9513. var ret = func(...cArgs);
  9514. function onDone(ret) {
  9515. if (stack !== 0) stackRestore(stack);
  9516. return convertReturnValue(ret);
  9517. }
  9518. ret = onDone(ret);
  9519. return ret;
  9520. };
  9521. /**
  9522. * @param {string=} returnType
  9523. * @param {Array=} argTypes
  9524. * @param {Object=} opts
  9525. */ var cwrap = (ident, returnType, argTypes, opts) => (...args) => ccall(ident, returnType, argTypes, args, opts);
  9526. var print = out;
  9527. var FS_createPath = (...args) => FS.createPath(...args);
  9528. var FS_unlink = (...args) => FS.unlink(...args);
  9529. var FS_createLazyFile = (...args) => FS.createLazyFile(...args);
  9530. var FS_createDevice = (...args) => FS.createDevice(...args);
  9531. var createContext = Browser.createContext;
  9532. PThread.init();
  9533. FS.createPreloadedFile = FS_createPreloadedFile;
  9534. FS.preloadFile = FS_preloadFile;
  9535. FS.staticInit();
  9536. Module["requestAnimationFrame"] = MainLoop.requestAnimationFrame;
  9537. Module["pauseMainLoop"] = MainLoop.pause;
  9538. Module["resumeMainLoop"] = MainLoop.resume;
  9539. MainLoop.init();
  9540. for (let i = 0; i < 32; ++i) tempFixedLengthArray.push(new Array(i));
  9541. var miniTempWebGLFloatBuffersStorage = new Float32Array(288);
  9542. // Create GL_POOL_TEMP_BUFFERS_SIZE+1 temporary buffers, for uploads of size 0 through GL_POOL_TEMP_BUFFERS_SIZE inclusive
  9543. for (/**@suppress{duplicate}*/ var i = 0; i <= 288; ++i) {
  9544. miniTempWebGLFloatBuffers[i] = miniTempWebGLFloatBuffersStorage.subarray(0, i);
  9545. }
  9546. var miniTempWebGLIntBuffersStorage = new Int32Array(288);
  9547. // Create GL_POOL_TEMP_BUFFERS_SIZE+1 temporary buffers, for uploads of size 0 through GL_POOL_TEMP_BUFFERS_SIZE inclusive
  9548. for (/**@suppress{duplicate}*/ var i = 0; i <= 288; ++i) {
  9549. miniTempWebGLIntBuffers[i] = miniTempWebGLIntBuffersStorage.subarray(0, i);
  9550. }
  9551. // End JS library code
  9552. // include: postlibrary.js
  9553. // This file is included after the automatically-generated JS library code
  9554. // but before the wasm module is created.
  9555. {
  9556. // With WASM_ESM_INTEGRATION this has to happen at the top level and not
  9557. // delayed until processModuleArgs.
  9558. initMemory();
  9559. // Begin ATMODULES hooks
  9560. if (Module["noExitRuntime"]) noExitRuntime = Module["noExitRuntime"];
  9561. if (Module["print"]) out = Module["print"];
  9562. if (Module["printErr"]) err = Module["printErr"];
  9563. // End ATMODULES hooks
  9564. checkIncomingModuleAPI();
  9565. if (Module["arguments"]) programArgs = Module["arguments"];
  9566. if (Module["thisProgram"]) thisProgram = Module["thisProgram"];
  9567. // Assertions on removed incoming Module JS APIs.
  9568. assert(typeof Module["memoryInitializerPrefixURL"] == "undefined", "Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead");
  9569. assert(typeof Module["pthreadMainPrefixURL"] == "undefined", "Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead");
  9570. assert(typeof Module["cdInitializerPrefixURL"] == "undefined", "Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead");
  9571. assert(typeof Module["filePackagePrefixURL"] == "undefined", "Module.filePackagePrefixURL option was removed, use Module.locateFile instead");
  9572. assert(typeof Module["read"] == "undefined", "Module.read option was removed");
  9573. assert(typeof Module["readAsync"] == "undefined", "Module.readAsync option was removed (modify readAsync in JS)");
  9574. assert(typeof Module["readBinary"] == "undefined", "Module.readBinary option was removed (modify readBinary in JS)");
  9575. assert(typeof Module["setWindowTitle"] == "undefined", "Module.setWindowTitle option was removed (modify emscripten_set_window_title in JS)");
  9576. assert(typeof Module["TOTAL_MEMORY"] == "undefined", "Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY");
  9577. assert(typeof Module["ENVIRONMENT"] == "undefined", "Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)");
  9578. assert(typeof Module["STACK_SIZE"] == "undefined", "STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time");
  9579. var preInit = Module["preInit"];
  9580. if (preInit) {
  9581. if (typeof preInit == "function") Module["preInit"] = preInit = [ preInit ];
  9582. // Written as a loop so that preInit functions that themselves add more
  9583. // preInit functions. Is this actually needed?
  9584. while (preInit.length > 0) {
  9585. preInit.shift()();
  9586. }
  9587. }
  9588. consumedModuleProp("preInit");
  9589. }
  9590. // Begin runtime exports
  9591. Module["addRunDependency"] = addRunDependency;
  9592. Module["removeRunDependency"] = removeRunDependency;
  9593. Module["ccall"] = ccall;
  9594. Module["cwrap"] = cwrap;
  9595. Module["createContext"] = createContext;
  9596. Module["FS_preloadFile"] = FS_preloadFile;
  9597. Module["FS_unlink"] = FS_unlink;
  9598. Module["FS_createPath"] = FS_createPath;
  9599. Module["FS_createDevice"] = FS_createDevice;
  9600. Module["FS_createDataFile"] = FS_createDataFile;
  9601. Module["FS_createLazyFile"] = FS_createLazyFile;
  9602. Module["print"] = print;
  9603. var missingLibrarySymbols = [ "writeI53ToI64Clamped", "writeI53ToI64Signaling", "writeI53ToU64Clamped", "writeI53ToU64Signaling", "convertI32PairToI53", "convertI32PairToI53Checked", "convertU32PairToI53", "getTempRet0", "setTempRet0", "createNamedFunction", "withStackSave", "inetPton4", "inetNtop4", "inetPton6", "inetNtop6", "readSockaddr", "writeSockaddr", "getDynCaller", "asmjsMangle", "HandleAllocator", "addOnInit", "addOnPostCtor", "addOnPreMain", "STACK_SIZE", "STACK_ALIGN", "POINTER_SIZE", "ASSERTIONS", "convertJsFunctionToWasm", "getEmptyTableSlot", "updateTableMap", "getFunctionAddress", "addFunction", "removeFunction", "intArrayToString", "AsciiToString", "stringToAscii", "UTF16ToString", "stringToUTF16", "lengthBytesUTF16", "UTF32ToString", "stringToUTF32", "lengthBytesUTF32", "fillDeviceOrientationEventData", "registerDeviceOrientationEventCallback", "fillDeviceMotionEventData", "registerDeviceMotionEventCallback", "screenOrientation", "fillOrientationChangeEventData", "registerOrientationChangeEventCallback", "hideEverythingExceptGivenElement", "restoreHiddenElements", "softFullscreenResizeWebGLRenderTarget", "registerPointerlockErrorEventCallback", "fillBatteryEventData", "registerBatteryEventCallback", "jsStackTrace", "getCallstack", "convertPCtoSourceLocation", "wasiRightsToMuslOFlags", "wasiOFlagsToMuslOFlags", "setImmediateWrapped", "safeRequestAnimationFrame", "clearImmediateWrapped", "registerPostMainLoop", "registerPreMainLoop", "getPromise", "makePromise", "addPromise", "idsToPromises", "makePromiseCallback", "ExceptionInfo", "findMatchingCatch", "incrementUncaughtExceptionCount", "decrementUncaughtExceptionCount", "Browser_asyncPrepareDataCounter", "arraySum", "addDays", "getSocketFromFD", "getSocketAddress", "FS_mkdirTree", "_setNetworkCallback", "writeGLArray", "emscripten_webgl_destroy_context_before_on_calling_thread", "registerWebGlEventCallback", "runAndAbortIfError", "ALLOC_NORMAL", "ALLOC_STACK", "allocate", "writeStringToMemory", "writeAsciiToMemory", "allocateUTF8", "allocateUTF8OnStack", "demangle", "stackTrace", "getNativeTypeSize" ];
  9604. missingLibrarySymbols.forEach(missingLibrarySymbol);
  9605. var unexportedSymbols = [ "run", "out", "err", "callMain", "abort", "wasmExports", "writeStackCookie", "checkStackCookie", "writeI53ToI64", "readI53FromI64", "readI53FromU64", "INT53_MAX", "INT53_MIN", "bigintToI53Checked", "HEAP8", "HEAPU8", "HEAP16", "HEAPU16", "HEAP32", "HEAPU32", "HEAPF32", "HEAPF64", "HEAP64", "HEAPU64", "stackSave", "stackRestore", "stackAlloc", "ptrToString", "zeroMemory", "exitJS", "getHeapMax", "growMemory", "ENV", "ERRNO_CODES", "strError", "DNS", "Protocols", "Sockets", "timers", "warnOnce", "readEmAsmArgsArray", "readEmAsmArgs", "runEmAsmFunction", "runMainThreadEmAsm", "jstoi_q", "getExecutableName", "autoResumeAudioContext", "dynCall", "handleException", "keepRuntimeAlive", "runtimeKeepalivePush", "runtimeKeepalivePop", "callUserCallback", "maybeExit", "asyncLoad", "alignMemory", "mmapAlloc", "wasmTable", "wasmMemory", "getUniqueRunDependency", "noExitRuntime", "addOnPreRun", "addOnExit", "addOnPostRun", "freeTableIndexes", "functionsInTableMap", "setValue", "getValue", "PATH", "PATH_FS", "UTF8Decoder", "UTF8ArrayToString", "UTF8ToString", "stringToUTF8Array", "stringToUTF8", "lengthBytesUTF8", "intArrayFromString", "UTF16Decoder", "stringToNewUTF8", "stringToUTF8OnStack", "writeArrayToMemory", "JSEvents", "registerKeyEventCallback", "specialHTMLTargets", "maybeCStringToJsString", "findEventTarget", "findCanvasEventTarget", "getBoundingClientRect", "fillMouseEventData", "registerMouseEventCallback", "registerWheelEventCallback", "registerUiEventCallback", "registerFocusEventCallback", "fillFullscreenChangeEventData", "registerFullscreenChangeEventCallback", "JSEvents_requestFullscreen", "JSEvents_resizeCanvasForFullscreen", "registerRestoreOldStyle", "setLetterbox", "currentFullscreenStrategy", "restoreOldWindowedStyle", "doRequestFullscreen", "fillPointerlockChangeEventData", "registerPointerlockChangeEventCallback", "requestPointerLock", "fillVisibilityChangeEventData", "registerVisibilityChangeEventCallback", "registerTouchEventCallback", "fillGamepadEventData", "registerGamepadEventCallback", "registerBeforeUnloadEventCallback", "setCanvasElementSizeCallingThread", "setCanvasElementSizeMainThread", "setCanvasElementSize", "getCanvasSizeCallingThread", "getCanvasSizeMainThread", "getCanvasElementSize", "UNWIND_CACHE", "ExitStatus", "getEnvStrings", "checkWasiClock", "doReadv", "doWritev", "initRandomFill", "randomFill", "safeSetTimeout", "emSetImmediate", "emClearImmediate_deps", "emClearImmediate", "promiseMap", "uncaughtExceptionCount", "exceptionCaught", "Browser", "requestFullscreen", "requestFullScreen", "setCanvasSize", "getUserMedia", "getPreloadedImageData__data", "wget", "MONTH_DAYS_REGULAR", "MONTH_DAYS_LEAP", "MONTH_DAYS_REGULAR_CUMULATIVE", "MONTH_DAYS_LEAP_CUMULATIVE", "isLeapYear", "ydayFromDate", "SYSCALLS", "preloadPlugins", "FS_createPreloadedFile", "FS_modeStringToFlags", "FS_getMode", "FS_fileDataToTypedArray", "FS_stdin_getChar_buffer", "FS_stdin_getChar", "FS_readFile", "FS", "FS_root", "FS_mounts", "FS_devices", "FS_streams", "FS_nextInode", "FS_nameTable", "FS_currentPath", "FS_initialized", "FS_ignorePermissions", "FS_filesystems", "FS_syncFSRequests", "FS_lookupPath", "FS_getPath", "FS_hashName", "FS_hashAddNode", "FS_hashRemoveNode", "FS_lookupNode", "FS_createNode", "FS_destroyNode", "FS_isRoot", "FS_isMountpoint", "FS_isFile", "FS_isDir", "FS_isLink", "FS_isChrdev", "FS_isBlkdev", "FS_isFIFO", "FS_isSocket", "FS_flagsToPermissionString", "FS_nodePermissions", "FS_mayLookup", "FS_mayCreate", "FS_mayDelete", "FS_mayOpen", "FS_checkOpExists", "FS_nextfd", "FS_getStreamChecked", "FS_getStream", "FS_createStream", "FS_closeStream", "FS_dupStream", "FS_doSetAttr", "FS_chrdev_stream_ops", "FS_major", "FS_minor", "FS_makedev", "FS_registerDevice", "FS_getDevice", "FS_getMounts", "FS_syncfs", "FS_mount", "FS_unmount", "FS_lookup", "FS_mknod", "FS_statfs", "FS_statfsStream", "FS_statfsNode", "FS_create", "FS_mkdir", "FS_mkdev", "FS_symlink", "FS_rename", "FS_rmdir", "FS_readdir", "FS_readlink", "FS_stat", "FS_fstat", "FS_lstat", "FS_doChmod", "FS_chmod", "FS_lchmod", "FS_fchmod", "FS_doChown", "FS_chown", "FS_lchown", "FS_fchown", "FS_doTruncate", "FS_truncate", "FS_ftruncate", "FS_utime", "FS_open", "FS_close", "FS_isClosed", "FS_llseek", "FS_read", "FS_write", "FS_mmap", "FS_msync", "FS_ioctl", "FS_writeFile", "FS_cwd", "FS_chdir", "FS_createDefaultDirectories", "FS_createDefaultDevices", "FS_createSpecialDirectories", "FS_createStandardStreams", "FS_staticInit", "FS_init", "FS_quit", "FS_findObject", "FS_analyzePath", "FS_createFile", "FS_forceLoadFile", "MEMFS", "TTY", "PIPEFS", "SOCKFS", "tempFixedLengthArray", "miniTempWebGLFloatBuffers", "miniTempWebGLIntBuffers", "heapObjectForWebGLType", "toTypedArrayIndex", "webgl_enable_ANGLE_instanced_arrays", "webgl_enable_OES_vertex_array_object", "webgl_enable_WEBGL_draw_buffers", "webgl_enable_WEBGL_multi_draw", "webgl_enable_EXT_polygon_offset_clamp", "webgl_enable_EXT_clip_control", "webgl_enable_WEBGL_polygon_mode", "GL", "emscriptenWebGLGet", "computeUnpackAlignedImageSize", "colorChannelsInGlTextureFormat", "emscriptenWebGLGetTexPixelData", "emscriptenWebGLGetUniform", "webglGetProgramUniformLocation", "webglGetUniformLocation", "webglPrepareUniformLocationsBeforeFirstUse", "webglGetLeftBracePos", "emscriptenWebGLGetVertexAttrib", "__glGetActiveAttribOrUniform", "AL", "GLUT", "EGL", "GLEW", "IDBStore", "waitAsyncPolyfilled", "printErr", "jstoi_s", "PThread", "terminateWorker", "cleanupThread", "registerTLSInit", "spawnThread", "exitOnMainThread", "proxyToMainThread", "proxiedJSCallArgs", "invokeEntryPoint", "checkMailbox", "IDBFS" ];
  9606. unexportedSymbols.forEach(unexportedRuntimeSymbol);
  9607. // End runtime exports
  9608. // Begin JS library exports
  9609. // End JS library exports
  9610. // end include: postlibrary.js
  9611. // proxiedFunctionTable specifies the list of functions that can be called
  9612. // either synchronously or asynchronously from other threads in postMessage()d
  9613. // or internally queued events. This way a pthread in a Worker can synchronously
  9614. // access e.g. the DOM on the main thread.
  9615. var proxiedFunctionTable = [ _proc_exit, exitOnMainThread, pthreadCreateProxied, ___syscall_chdir, ___syscall_fcntl64, ___syscall_fstat64, ___syscall_getcwd, ___syscall_ioctl, ___syscall_lstat64, ___syscall_mkdirat, ___syscall_newfstatat, ___syscall_openat, ___syscall_pipe2, ___syscall_stat64, __mmap_js, __munmap_js, _eglBindAPI, _eglChooseConfig, _eglCreateContext, _eglCreateWindowSurface, _eglDestroyContext, _eglDestroySurface, _eglGetConfigAttrib, _eglGetDisplay, _eglGetError, _eglInitialize, _eglMakeCurrent, _eglQueryString, _eglSwapBuffers, _eglSwapInterval, _eglTerminate, _eglWaitClient, _eglWaitNative, _emscripten_exit_fullscreen, getCanvasSizeMainThread, setCanvasElementSizeMainThread, _emscripten_exit_pointerlock, _emscripten_force_exit, _emscripten_get_device_pixel_ratio, _emscripten_get_element_css_size, _emscripten_get_gamepad_status, _emscripten_get_num_gamepads, _emscripten_get_screen_size, _emscripten_request_fullscreen_strategy, _emscripten_request_pointerlock, _emscripten_sample_gamepad_data, _emscripten_set_beforeunload_callback_on_thread, _emscripten_set_blur_callback_on_thread, _emscripten_set_element_css_size, _emscripten_set_focus_callback_on_thread, _emscripten_set_fullscreenchange_callback_on_thread, _emscripten_set_gamepadconnected_callback_on_thread, _emscripten_set_gamepaddisconnected_callback_on_thread, _emscripten_set_keydown_callback_on_thread, _emscripten_set_keypress_callback_on_thread, _emscripten_set_keyup_callback_on_thread, _emscripten_set_mousedown_callback_on_thread, _emscripten_set_mouseenter_callback_on_thread, _emscripten_set_mouseleave_callback_on_thread, _emscripten_set_mousemove_callback_on_thread, _emscripten_set_mouseup_callback_on_thread, _emscripten_set_pointerlockchange_callback_on_thread, _emscripten_set_resize_callback_on_thread, _emscripten_set_touchcancel_callback_on_thread, _emscripten_set_touchend_callback_on_thread, _emscripten_set_touchmove_callback_on_thread, _emscripten_set_touchstart_callback_on_thread, _emscripten_set_visibilitychange_callback_on_thread, _emscripten_set_wheel_callback_on_thread, _emscripten_set_window_title, _environ_get, _environ_sizes_get, _fd_close, _fd_read, _fd_seek, _fd_write ];
  9616. function checkIncomingModuleAPI() {
  9617. ignoredModuleProp("fetchSettings");
  9618. ignoredModuleProp("logReadFiles");
  9619. ignoredModuleProp("loadSplitModule");
  9620. ignoredModuleProp("onMalloc");
  9621. ignoredModuleProp("onRealloc");
  9622. ignoredModuleProp("onFree");
  9623. ignoredModuleProp("onSbrkGrow");
  9624. ignoredModuleProp("onCOSCacheHit");
  9625. ignoredModuleProp("onCOSCacheMiss");
  9626. ignoredModuleProp("onCOSStore");
  9627. ignoredModuleProp("GL_MAX_TEXTURE_IMAGE_UNITS");
  9628. ignoredModuleProp("SDL_canPlayWithWebAudio");
  9629. ignoredModuleProp("SDL_numSimultaneouslyQueuedBuffers");
  9630. ignoredModuleProp("freePreloadedMediaOnUse");
  9631. ignoredModuleProp("preinitializedWebGLContext");
  9632. ignoredModuleProp("keyboardListeningElement");
  9633. ignoredModuleProp("doNotCaptureKeyboard");
  9634. ignoredModuleProp("extraStackTrace");
  9635. ignoredModuleProp("preloadPlugins");
  9636. ignoredModuleProp("preMainLoop");
  9637. ignoredModuleProp("postMainLoop");
  9638. ignoredModuleProp("forcedAspectRatio");
  9639. ignoredModuleProp("mainScriptUrlOrBlob");
  9640. ignoredModuleProp("onFullScreen");
  9641. ignoredModuleProp("INITIAL_MEMORY");
  9642. ignoredModuleProp("wasmMemory");
  9643. ignoredModuleProp("wasmBinary");
  9644. }
  9645. var ASM_CONSTS = {
  9646. 206960: () => {
  9647. FS.mkdir("/IDBFS");
  9648. FS.mount(IDBFS, {}, "/IDBFS");
  9649. Module.print("start file sync..");
  9650. Module.syncdone = 0;
  9651. FS.syncfs(true, function(err) {
  9652. Module.print("syncfs done");
  9653. Module.print(err);
  9654. assert(!err);
  9655. ccall("initConfigDone", "v");
  9656. Module.print("end file sync..");
  9657. Module.syncdone = 1;
  9658. });
  9659. },
  9660. 207247: $0 => {
  9661. var str = UTF8ToString($0) + "\n\n" + "Abort/Retry/Ignore/AlwaysIgnore? [ariA] :";
  9662. var reply = window.prompt(str, "i");
  9663. if (reply === null) {
  9664. reply = "i";
  9665. }
  9666. return reply.length === 1 ? reply.charCodeAt(0) : -1;
  9667. },
  9668. 207462: () => {
  9669. if (typeof (AudioContext) !== "undefined") {
  9670. return true;
  9671. } else if (typeof (webkitAudioContext) !== "undefined") {
  9672. return true;
  9673. }
  9674. return false;
  9675. },
  9676. 207609: () => {
  9677. if ((typeof (navigator.mediaDevices) !== "undefined") && (typeof (navigator.mediaDevices.getUserMedia) !== "undefined")) {
  9678. return true;
  9679. } else if (typeof (navigator.webkitGetUserMedia) !== "undefined") {
  9680. return true;
  9681. }
  9682. return false;
  9683. },
  9684. 207843: $0 => {
  9685. if (typeof (Module["SDL2"]) === "undefined") {
  9686. Module["SDL2"] = {};
  9687. }
  9688. var SDL2 = Module["SDL2"];
  9689. if (!$0) {
  9690. SDL2.audio = {};
  9691. } else {
  9692. SDL2.capture = {};
  9693. }
  9694. if (!SDL2.audioContext) {
  9695. if (typeof (AudioContext) !== "undefined") {
  9696. SDL2.audioContext = new AudioContext;
  9697. } else if (typeof (webkitAudioContext) !== "undefined") {
  9698. SDL2.audioContext = new webkitAudioContext;
  9699. }
  9700. if (SDL2.audioContext) {
  9701. if ((typeof navigator.userActivation) === "undefined") {
  9702. autoResumeAudioContext(SDL2.audioContext);
  9703. }
  9704. }
  9705. }
  9706. return SDL2.audioContext === undefined ? -1 : 0;
  9707. },
  9708. 208395: () => {
  9709. var SDL2 = Module["SDL2"];
  9710. return SDL2.audioContext.sampleRate;
  9711. },
  9712. 208463: ($0, $1, $2, $3) => {
  9713. var SDL2 = Module["SDL2"];
  9714. var have_microphone = function(stream) {
  9715. if (SDL2.capture.silenceTimer !== undefined) {
  9716. clearInterval(SDL2.capture.silenceTimer);
  9717. SDL2.capture.silenceTimer = undefined;
  9718. SDL2.capture.silenceBuffer = undefined;
  9719. }
  9720. SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream);
  9721. SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1);
  9722. SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {
  9723. if ((SDL2 === undefined) || (SDL2.capture === undefined)) {
  9724. return;
  9725. }
  9726. audioProcessingEvent.outputBuffer.getChannelData(0).fill(0);
  9727. SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer;
  9728. dynCall("vp", $2, [ $3 ]);
  9729. };
  9730. SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode);
  9731. SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination);
  9732. SDL2.capture.stream = stream;
  9733. };
  9734. var no_microphone = function(error) {};
  9735. SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate);
  9736. SDL2.capture.silenceBuffer.getChannelData(0).fill(0);
  9737. var silence_callback = function() {
  9738. SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer;
  9739. dynCall("vp", $2, [ $3 ]);
  9740. };
  9741. SDL2.capture.silenceTimer = setInterval(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1e3);
  9742. if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) {
  9743. navigator.mediaDevices.getUserMedia({
  9744. audio: true,
  9745. video: false
  9746. }).then(have_microphone).catch(no_microphone);
  9747. } else if (navigator.webkitGetUserMedia !== undefined) {
  9748. navigator.webkitGetUserMedia({
  9749. audio: true,
  9750. video: false
  9751. }, have_microphone, no_microphone);
  9752. }
  9753. },
  9754. 210156: ($0, $1, $2, $3) => {
  9755. var SDL2 = Module["SDL2"];
  9756. SDL2.audio.scriptProcessorNode = SDL2.audioContext["createScriptProcessor"]($1, 0, $0);
  9757. SDL2.audio.scriptProcessorNode["onaudioprocess"] = function(e) {
  9758. if ((SDL2 === undefined) || (SDL2.audio === undefined)) {
  9759. return;
  9760. }
  9761. if (SDL2.audio.silenceTimer !== undefined) {
  9762. clearInterval(SDL2.audio.silenceTimer);
  9763. SDL2.audio.silenceTimer = undefined;
  9764. SDL2.audio.silenceBuffer = undefined;
  9765. }
  9766. SDL2.audio.currentOutputBuffer = e["outputBuffer"];
  9767. dynCall("vp", $2, [ $3 ]);
  9768. };
  9769. SDL2.audio.scriptProcessorNode["connect"](SDL2.audioContext["destination"]);
  9770. if (SDL2.audioContext.state === "suspended") {
  9771. SDL2.audio.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate);
  9772. SDL2.audio.silenceBuffer.getChannelData(0).fill(0);
  9773. var silence_callback = function() {
  9774. if ((typeof navigator.userActivation) !== "undefined") {
  9775. if (navigator.userActivation.hasBeenActive) {
  9776. SDL2.audioContext.resume();
  9777. }
  9778. }
  9779. SDL2.audio.currentOutputBuffer = SDL2.audio.silenceBuffer;
  9780. dynCall("vp", $2, [ $3 ]);
  9781. SDL2.audio.currentOutputBuffer = undefined;
  9782. };
  9783. SDL2.audio.silenceTimer = setInterval(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1e3);
  9784. }
  9785. },
  9786. 211331: ($0, $1) => {
  9787. var SDL2 = Module["SDL2"];
  9788. var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels;
  9789. for (var c = 0; c < numChannels; ++c) {
  9790. var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(c);
  9791. if (channelData.length != $1) {
  9792. throw "Web Audio capture buffer length mismatch! Destination size: " + channelData.length + " samples vs expected " + $1 + " samples!";
  9793. }
  9794. if (numChannels == 1) {
  9795. for (var j = 0; j < $1; ++j) {
  9796. setValue($0 + (j * 4), channelData[j], "float");
  9797. }
  9798. } else {
  9799. for (var j = 0; j < $1; ++j) {
  9800. setValue($0 + (((j * numChannels) + c) * 4), channelData[j], "float");
  9801. }
  9802. }
  9803. }
  9804. },
  9805. 211936: ($0, $1) => {
  9806. var SDL2 = Module["SDL2"];
  9807. var buf = $0 >>> 2;
  9808. var numChannels = SDL2.audio.currentOutputBuffer["numberOfChannels"];
  9809. for (var c = 0; c < numChannels; ++c) {
  9810. var channelData = SDL2.audio.currentOutputBuffer["getChannelData"](c);
  9811. if (channelData.length != $1) {
  9812. throw "Web Audio output buffer length mismatch! Destination size: " + channelData.length + " samples vs expected " + $1 + " samples!";
  9813. }
  9814. for (var j = 0; j < $1; ++j) {
  9815. channelData[j] = (growMemViews(), HEAPF32)[buf + (j * numChannels + c)];
  9816. }
  9817. }
  9818. },
  9819. 212425: $0 => {
  9820. var SDL2 = Module["SDL2"];
  9821. if ($0) {
  9822. if (SDL2.capture.silenceTimer !== undefined) {
  9823. clearInterval(SDL2.capture.silenceTimer);
  9824. }
  9825. if (SDL2.capture.stream !== undefined) {
  9826. var tracks = SDL2.capture.stream.getAudioTracks();
  9827. for (var i = 0; i < tracks.length; i++) {
  9828. SDL2.capture.stream.removeTrack(tracks[i]);
  9829. }
  9830. }
  9831. if (SDL2.capture.scriptProcessorNode !== undefined) {
  9832. SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {};
  9833. SDL2.capture.scriptProcessorNode.disconnect();
  9834. }
  9835. if (SDL2.capture.mediaStreamNode !== undefined) {
  9836. SDL2.capture.mediaStreamNode.disconnect();
  9837. }
  9838. SDL2.capture = undefined;
  9839. } else {
  9840. if (SDL2.audio.scriptProcessorNode != undefined) {
  9841. SDL2.audio.scriptProcessorNode.disconnect();
  9842. }
  9843. if (SDL2.audio.silenceTimer !== undefined) {
  9844. clearInterval(SDL2.audio.silenceTimer);
  9845. }
  9846. SDL2.audio = undefined;
  9847. }
  9848. if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) {
  9849. SDL2.audioContext.close();
  9850. SDL2.audioContext = undefined;
  9851. }
  9852. },
  9853. 213431: ($0, $1, $2) => {
  9854. var w = $0;
  9855. var h = $1;
  9856. var pixels = $2;
  9857. if (!Module["SDL2"]) Module["SDL2"] = {};
  9858. var SDL2 = Module["SDL2"];
  9859. if (SDL2.ctxCanvas !== Module["canvas"]) {
  9860. SDL2.ctx = Browser.createContext(Module["canvas"], false, true);
  9861. SDL2.ctxCanvas = Module["canvas"];
  9862. }
  9863. if (SDL2.w !== w || SDL2.h !== h || SDL2.imageCtx !== SDL2.ctx) {
  9864. SDL2.image = SDL2.ctx.createImageData(w, h);
  9865. SDL2.w = w;
  9866. SDL2.h = h;
  9867. SDL2.imageCtx = SDL2.ctx;
  9868. }
  9869. var data = SDL2.image.data;
  9870. var src = pixels / 4;
  9871. var dst = 0;
  9872. var num;
  9873. if (typeof CanvasPixelArray !== "undefined" && data instanceof CanvasPixelArray) {
  9874. num = data.length;
  9875. while (dst < num) {
  9876. var val = (growMemViews(), HEAP32)[src];
  9877. data[dst] = val & 255;
  9878. data[dst + 1] = (val >> 8) & 255;
  9879. data[dst + 2] = (val >> 16) & 255;
  9880. data[dst + 3] = 255;
  9881. src++;
  9882. dst += 4;
  9883. }
  9884. } else {
  9885. if (SDL2.data32Data !== data) {
  9886. SDL2.data32 = new Int32Array(data.buffer);
  9887. SDL2.data8 = new Uint8Array(data.buffer);
  9888. SDL2.data32Data = data;
  9889. }
  9890. var data32 = SDL2.data32;
  9891. num = data32.length;
  9892. data32.set((growMemViews(), HEAP32).subarray(src, src + num));
  9893. var data8 = SDL2.data8;
  9894. var i = 3;
  9895. var j = i + 4 * num;
  9896. if (num % 8 == 0) {
  9897. while (i < j) {
  9898. data8[i] = 255;
  9899. i = i + 4 | 0;
  9900. data8[i] = 255;
  9901. i = i + 4 | 0;
  9902. data8[i] = 255;
  9903. i = i + 4 | 0;
  9904. data8[i] = 255;
  9905. i = i + 4 | 0;
  9906. data8[i] = 255;
  9907. i = i + 4 | 0;
  9908. data8[i] = 255;
  9909. i = i + 4 | 0;
  9910. data8[i] = 255;
  9911. i = i + 4 | 0;
  9912. data8[i] = 255;
  9913. i = i + 4 | 0;
  9914. }
  9915. } else {
  9916. while (i < j) {
  9917. data8[i] = 255;
  9918. i = i + 4 | 0;
  9919. }
  9920. }
  9921. }
  9922. SDL2.ctx.putImageData(SDL2.image, 0, 0);
  9923. },
  9924. 214897: ($0, $1, $2, $3, $4) => {
  9925. var w = $0;
  9926. var h = $1;
  9927. var hot_x = $2;
  9928. var hot_y = $3;
  9929. var pixels = $4;
  9930. var canvas = document.createElement("canvas");
  9931. canvas.width = w;
  9932. canvas.height = h;
  9933. var ctx = canvas.getContext("2d");
  9934. var image = ctx.createImageData(w, h);
  9935. var data = image.data;
  9936. var src = pixels / 4;
  9937. var dst = 0;
  9938. var num;
  9939. if (typeof CanvasPixelArray !== "undefined" && data instanceof CanvasPixelArray) {
  9940. num = data.length;
  9941. while (dst < num) {
  9942. var val = (growMemViews(), HEAP32)[src];
  9943. data[dst] = val & 255;
  9944. data[dst + 1] = (val >> 8) & 255;
  9945. data[dst + 2] = (val >> 16) & 255;
  9946. data[dst + 3] = (val >> 24) & 255;
  9947. src++;
  9948. dst += 4;
  9949. }
  9950. } else {
  9951. var data32 = new Int32Array(data.buffer);
  9952. num = data32.length;
  9953. data32.set((growMemViews(), HEAP32).subarray(src, src + num));
  9954. }
  9955. ctx.putImageData(image, 0, 0);
  9956. var url = hot_x === 0 && hot_y === 0 ? "url(" + canvas.toDataURL() + "), auto" : "url(" + canvas.toDataURL() + ") " + hot_x + " " + hot_y + ", auto";
  9957. var urlBuf = _malloc(url.length + 1);
  9958. stringToUTF8(url, urlBuf, url.length + 1);
  9959. return urlBuf;
  9960. },
  9961. 215885: $0 => {
  9962. if (Module["canvas"]) {
  9963. Module["canvas"].style["cursor"] = UTF8ToString($0);
  9964. }
  9965. },
  9966. 215968: () => {
  9967. if (Module["canvas"]) {
  9968. Module["canvas"].style["cursor"] = "none";
  9969. }
  9970. },
  9971. 216037: () => window.innerWidth,
  9972. 216067: () => window.innerHeight
  9973. };
  9974. // Imports from the Wasm binary.
  9975. var _strerror = makeInvalidEarlyAccess("_strerror");
  9976. var _fflush = makeInvalidEarlyAccess("_fflush");
  9977. var _free = makeInvalidEarlyAccess("_free");
  9978. var _malloc = makeInvalidEarlyAccess("_malloc");
  9979. var _initConfigDone = Module["_initConfigDone"] = makeInvalidEarlyAccess("_initConfigDone");
  9980. var _main = Module["_main"] = makeInvalidEarlyAccess("_main");
  9981. var _pthread_self = makeInvalidEarlyAccess("_pthread_self");
  9982. var __emscripten_tls_init = makeInvalidEarlyAccess("__emscripten_tls_init");
  9983. var _emscripten_builtin_memalign = makeInvalidEarlyAccess("_emscripten_builtin_memalign");
  9984. var __emscripten_run_callback_on_thread = makeInvalidEarlyAccess("__emscripten_run_callback_on_thread");
  9985. var __emscripten_thread_init = makeInvalidEarlyAccess("__emscripten_thread_init");
  9986. var ___set_thread_state = makeInvalidEarlyAccess("___set_thread_state");
  9987. var __emscripten_thread_crashed = makeInvalidEarlyAccess("__emscripten_thread_crashed");
  9988. var _emscripten_stack_get_end = makeInvalidEarlyAccess("_emscripten_stack_get_end");
  9989. var _emscripten_stack_get_base = makeInvalidEarlyAccess("_emscripten_stack_get_base");
  9990. var __emscripten_run_js_on_main_thread_done = makeInvalidEarlyAccess("__emscripten_run_js_on_main_thread_done");
  9991. var __emscripten_run_js_on_main_thread = makeInvalidEarlyAccess("__emscripten_run_js_on_main_thread");
  9992. var __emscripten_thread_free_data = makeInvalidEarlyAccess("__emscripten_thread_free_data");
  9993. var __emscripten_thread_exit = makeInvalidEarlyAccess("__emscripten_thread_exit");
  9994. var __emscripten_check_mailbox = makeInvalidEarlyAccess("__emscripten_check_mailbox");
  9995. var _emscripten_stack_init = makeInvalidEarlyAccess("_emscripten_stack_init");
  9996. var _emscripten_stack_set_limits = makeInvalidEarlyAccess("_emscripten_stack_set_limits");
  9997. var _emscripten_stack_get_free = makeInvalidEarlyAccess("_emscripten_stack_get_free");
  9998. var __emscripten_stack_restore = makeInvalidEarlyAccess("__emscripten_stack_restore");
  9999. var __emscripten_stack_alloc = makeInvalidEarlyAccess("__emscripten_stack_alloc");
  10000. var _emscripten_stack_get_current = makeInvalidEarlyAccess("_emscripten_stack_get_current");
  10001. var __indirect_function_table = makeInvalidEarlyAccess("__indirect_function_table");
  10002. var wasmTable = makeInvalidEarlyAccess("wasmTable");
  10003. function assignWasmExports(wasmExports) {
  10004. assert(typeof wasmExports["strerror"] != "undefined", "missing Wasm export: strerror");
  10005. assert(typeof wasmExports["fflush"] != "undefined", "missing Wasm export: fflush");
  10006. assert(typeof wasmExports["free"] != "undefined", "missing Wasm export: free");
  10007. assert(typeof wasmExports["malloc"] != "undefined", "missing Wasm export: malloc");
  10008. assert(typeof wasmExports["initConfigDone"] != "undefined", "missing Wasm export: initConfigDone");
  10009. assert(typeof wasmExports["main"] != "undefined", "missing Wasm export: main");
  10010. assert(typeof wasmExports["pthread_self"] != "undefined", "missing Wasm export: pthread_self");
  10011. assert(typeof wasmExports["_emscripten_tls_init"] != "undefined", "missing Wasm export: _emscripten_tls_init");
  10012. assert(typeof wasmExports["emscripten_builtin_memalign"] != "undefined", "missing Wasm export: emscripten_builtin_memalign");
  10013. assert(typeof wasmExports["_emscripten_run_callback_on_thread"] != "undefined", "missing Wasm export: _emscripten_run_callback_on_thread");
  10014. assert(typeof wasmExports["_emscripten_thread_init"] != "undefined", "missing Wasm export: _emscripten_thread_init");
  10015. assert(typeof wasmExports["__set_thread_state"] != "undefined", "missing Wasm export: __set_thread_state");
  10016. assert(typeof wasmExports["_emscripten_thread_crashed"] != "undefined", "missing Wasm export: _emscripten_thread_crashed");
  10017. assert(typeof wasmExports["emscripten_stack_get_end"] != "undefined", "missing Wasm export: emscripten_stack_get_end");
  10018. assert(typeof wasmExports["emscripten_stack_get_base"] != "undefined", "missing Wasm export: emscripten_stack_get_base");
  10019. assert(typeof wasmExports["_emscripten_run_js_on_main_thread_done"] != "undefined", "missing Wasm export: _emscripten_run_js_on_main_thread_done");
  10020. assert(typeof wasmExports["_emscripten_run_js_on_main_thread"] != "undefined", "missing Wasm export: _emscripten_run_js_on_main_thread");
  10021. assert(typeof wasmExports["_emscripten_thread_free_data"] != "undefined", "missing Wasm export: _emscripten_thread_free_data");
  10022. assert(typeof wasmExports["_emscripten_thread_exit"] != "undefined", "missing Wasm export: _emscripten_thread_exit");
  10023. assert(typeof wasmExports["_emscripten_check_mailbox"] != "undefined", "missing Wasm export: _emscripten_check_mailbox");
  10024. assert(typeof wasmExports["emscripten_stack_init"] != "undefined", "missing Wasm export: emscripten_stack_init");
  10025. assert(typeof wasmExports["emscripten_stack_set_limits"] != "undefined", "missing Wasm export: emscripten_stack_set_limits");
  10026. assert(typeof wasmExports["emscripten_stack_get_free"] != "undefined", "missing Wasm export: emscripten_stack_get_free");
  10027. assert(typeof wasmExports["_emscripten_stack_restore"] != "undefined", "missing Wasm export: _emscripten_stack_restore");
  10028. assert(typeof wasmExports["_emscripten_stack_alloc"] != "undefined", "missing Wasm export: _emscripten_stack_alloc");
  10029. assert(typeof wasmExports["emscripten_stack_get_current"] != "undefined", "missing Wasm export: emscripten_stack_get_current");
  10030. assert(typeof wasmExports["__indirect_function_table"] != "undefined", "missing Wasm export: __indirect_function_table");
  10031. _strerror = createExportWrapper("strerror", wasmExports["strerror"], 1);
  10032. _fflush = createExportWrapper("fflush", wasmExports["fflush"], 1);
  10033. _free = createExportWrapper("free", wasmExports["free"], 1);
  10034. _malloc = createExportWrapper("malloc", wasmExports["malloc"], 1);
  10035. _initConfigDone = Module["_initConfigDone"] = createExportWrapper("initConfigDone", wasmExports["initConfigDone"], 0);
  10036. _main = Module["_main"] = createExportWrapper("main", wasmExports["main"], 3);
  10037. _pthread_self = wasmExports["pthread_self"];
  10038. __emscripten_tls_init = createExportWrapper("_emscripten_tls_init", wasmExports["_emscripten_tls_init"], 0);
  10039. _emscripten_builtin_memalign = createExportWrapper("emscripten_builtin_memalign", wasmExports["emscripten_builtin_memalign"], 2);
  10040. __emscripten_run_callback_on_thread = createExportWrapper("_emscripten_run_callback_on_thread", wasmExports["_emscripten_run_callback_on_thread"], 6);
  10041. __emscripten_thread_init = createExportWrapper("_emscripten_thread_init", wasmExports["_emscripten_thread_init"], 6);
  10042. ___set_thread_state = createExportWrapper("__set_thread_state", wasmExports["__set_thread_state"], 4);
  10043. __emscripten_thread_crashed = createExportWrapper("_emscripten_thread_crashed", wasmExports["_emscripten_thread_crashed"], 0);
  10044. _emscripten_stack_get_end = wasmExports["emscripten_stack_get_end"];
  10045. _emscripten_stack_get_base = wasmExports["emscripten_stack_get_base"];
  10046. __emscripten_run_js_on_main_thread_done = createExportWrapper("_emscripten_run_js_on_main_thread_done", wasmExports["_emscripten_run_js_on_main_thread_done"], 3);
  10047. __emscripten_run_js_on_main_thread = createExportWrapper("_emscripten_run_js_on_main_thread", wasmExports["_emscripten_run_js_on_main_thread"], 5);
  10048. __emscripten_thread_free_data = createExportWrapper("_emscripten_thread_free_data", wasmExports["_emscripten_thread_free_data"], 1);
  10049. __emscripten_thread_exit = createExportWrapper("_emscripten_thread_exit", wasmExports["_emscripten_thread_exit"], 1);
  10050. __emscripten_check_mailbox = createExportWrapper("_emscripten_check_mailbox", wasmExports["_emscripten_check_mailbox"], 0);
  10051. _emscripten_stack_init = wasmExports["emscripten_stack_init"];
  10052. _emscripten_stack_set_limits = wasmExports["emscripten_stack_set_limits"];
  10053. _emscripten_stack_get_free = wasmExports["emscripten_stack_get_free"];
  10054. __emscripten_stack_restore = wasmExports["_emscripten_stack_restore"];
  10055. __emscripten_stack_alloc = wasmExports["_emscripten_stack_alloc"];
  10056. _emscripten_stack_get_current = wasmExports["emscripten_stack_get_current"];
  10057. __indirect_function_table = wasmTable = wasmExports["__indirect_function_table"];
  10058. }
  10059. var wasmImports;
  10060. function assignWasmImports() {
  10061. wasmImports = {
  10062. /** @export */ __assert_fail: ___assert_fail,
  10063. /** @export */ __call_sighandler: ___call_sighandler,
  10064. /** @export */ __pthread_create_js: ___pthread_create_js,
  10065. /** @export */ __syscall_chdir: ___syscall_chdir,
  10066. /** @export */ __syscall_fcntl64: ___syscall_fcntl64,
  10067. /** @export */ __syscall_fstat64: ___syscall_fstat64,
  10068. /** @export */ __syscall_getcwd: ___syscall_getcwd,
  10069. /** @export */ __syscall_ioctl: ___syscall_ioctl,
  10070. /** @export */ __syscall_lstat64: ___syscall_lstat64,
  10071. /** @export */ __syscall_mkdirat: ___syscall_mkdirat,
  10072. /** @export */ __syscall_newfstatat: ___syscall_newfstatat,
  10073. /** @export */ __syscall_openat: ___syscall_openat,
  10074. /** @export */ __syscall_pipe2: ___syscall_pipe2,
  10075. /** @export */ __syscall_stat64: ___syscall_stat64,
  10076. /** @export */ _abort_js: __abort_js,
  10077. /** @export */ _emscripten_init_main_thread_js: __emscripten_init_main_thread_js,
  10078. /** @export */ _emscripten_notify_mailbox_postmessage: __emscripten_notify_mailbox_postmessage,
  10079. /** @export */ _emscripten_receive_on_main_thread_js: __emscripten_receive_on_main_thread_js,
  10080. /** @export */ _emscripten_runtime_keepalive_clear: __emscripten_runtime_keepalive_clear,
  10081. /** @export */ _emscripten_thread_cleanup: __emscripten_thread_cleanup,
  10082. /** @export */ _emscripten_thread_mailbox_await: __emscripten_thread_mailbox_await,
  10083. /** @export */ _emscripten_thread_set_strongref: __emscripten_thread_set_strongref,
  10084. /** @export */ _localtime_js: __localtime_js,
  10085. /** @export */ _mmap_js: __mmap_js,
  10086. /** @export */ _munmap_js: __munmap_js,
  10087. /** @export */ _tzset_js: __tzset_js,
  10088. /** @export */ clock_time_get: _clock_time_get,
  10089. /** @export */ eglBindAPI: _eglBindAPI,
  10090. /** @export */ eglChooseConfig: _eglChooseConfig,
  10091. /** @export */ eglCreateContext: _eglCreateContext,
  10092. /** @export */ eglCreateWindowSurface: _eglCreateWindowSurface,
  10093. /** @export */ eglDestroyContext: _eglDestroyContext,
  10094. /** @export */ eglDestroySurface: _eglDestroySurface,
  10095. /** @export */ eglGetConfigAttrib: _eglGetConfigAttrib,
  10096. /** @export */ eglGetDisplay: _eglGetDisplay,
  10097. /** @export */ eglGetError: _eglGetError,
  10098. /** @export */ eglInitialize: _eglInitialize,
  10099. /** @export */ eglMakeCurrent: _eglMakeCurrent,
  10100. /** @export */ eglQueryString: _eglQueryString,
  10101. /** @export */ eglSwapBuffers: _eglSwapBuffers,
  10102. /** @export */ eglSwapInterval: _eglSwapInterval,
  10103. /** @export */ eglTerminate: _eglTerminate,
  10104. /** @export */ eglWaitGL: _eglWaitGL,
  10105. /** @export */ eglWaitNative: _eglWaitNative,
  10106. /** @export */ emscripten_asm_const_int: _emscripten_asm_const_int,
  10107. /** @export */ emscripten_asm_const_int_sync_on_main_thread: _emscripten_asm_const_int_sync_on_main_thread,
  10108. /** @export */ emscripten_asm_const_ptr_sync_on_main_thread: _emscripten_asm_const_ptr_sync_on_main_thread,
  10109. /** @export */ emscripten_cancel_main_loop: _emscripten_cancel_main_loop,
  10110. /** @export */ emscripten_check_blocking_allowed: _emscripten_check_blocking_allowed,
  10111. /** @export */ emscripten_date_now: _emscripten_date_now,
  10112. /** @export */ emscripten_exit_fullscreen: _emscripten_exit_fullscreen,
  10113. /** @export */ emscripten_exit_pointerlock: _emscripten_exit_pointerlock,
  10114. /** @export */ emscripten_exit_with_live_runtime: _emscripten_exit_with_live_runtime,
  10115. /** @export */ emscripten_force_exit: _emscripten_force_exit,
  10116. /** @export */ emscripten_get_device_pixel_ratio: _emscripten_get_device_pixel_ratio,
  10117. /** @export */ emscripten_get_element_css_size: _emscripten_get_element_css_size,
  10118. /** @export */ emscripten_get_gamepad_status: _emscripten_get_gamepad_status,
  10119. /** @export */ emscripten_get_now: _emscripten_get_now,
  10120. /** @export */ emscripten_get_num_gamepads: _emscripten_get_num_gamepads,
  10121. /** @export */ emscripten_get_screen_size: _emscripten_get_screen_size,
  10122. /** @export */ emscripten_glActiveTexture: _emscripten_glActiveTexture,
  10123. /** @export */ emscripten_glAttachShader: _emscripten_glAttachShader,
  10124. /** @export */ emscripten_glBeginQueryEXT: _emscripten_glBeginQueryEXT,
  10125. /** @export */ emscripten_glBindAttribLocation: _emscripten_glBindAttribLocation,
  10126. /** @export */ emscripten_glBindBuffer: _emscripten_glBindBuffer,
  10127. /** @export */ emscripten_glBindFramebuffer: _emscripten_glBindFramebuffer,
  10128. /** @export */ emscripten_glBindRenderbuffer: _emscripten_glBindRenderbuffer,
  10129. /** @export */ emscripten_glBindTexture: _emscripten_glBindTexture,
  10130. /** @export */ emscripten_glBindVertexArrayOES: _emscripten_glBindVertexArrayOES,
  10131. /** @export */ emscripten_glBlendColor: _emscripten_glBlendColor,
  10132. /** @export */ emscripten_glBlendEquation: _emscripten_glBlendEquation,
  10133. /** @export */ emscripten_glBlendEquationSeparate: _emscripten_glBlendEquationSeparate,
  10134. /** @export */ emscripten_glBlendFunc: _emscripten_glBlendFunc,
  10135. /** @export */ emscripten_glBlendFuncSeparate: _emscripten_glBlendFuncSeparate,
  10136. /** @export */ emscripten_glBufferData: _emscripten_glBufferData,
  10137. /** @export */ emscripten_glBufferSubData: _emscripten_glBufferSubData,
  10138. /** @export */ emscripten_glCheckFramebufferStatus: _emscripten_glCheckFramebufferStatus,
  10139. /** @export */ emscripten_glClear: _emscripten_glClear,
  10140. /** @export */ emscripten_glClearColor: _emscripten_glClearColor,
  10141. /** @export */ emscripten_glClearDepthf: _emscripten_glClearDepthf,
  10142. /** @export */ emscripten_glClearStencil: _emscripten_glClearStencil,
  10143. /** @export */ emscripten_glClipControlEXT: _emscripten_glClipControlEXT,
  10144. /** @export */ emscripten_glColorMask: _emscripten_glColorMask,
  10145. /** @export */ emscripten_glCompileShader: _emscripten_glCompileShader,
  10146. /** @export */ emscripten_glCompressedTexImage2D: _emscripten_glCompressedTexImage2D,
  10147. /** @export */ emscripten_glCompressedTexSubImage2D: _emscripten_glCompressedTexSubImage2D,
  10148. /** @export */ emscripten_glCopyTexImage2D: _emscripten_glCopyTexImage2D,
  10149. /** @export */ emscripten_glCopyTexSubImage2D: _emscripten_glCopyTexSubImage2D,
  10150. /** @export */ emscripten_glCreateProgram: _emscripten_glCreateProgram,
  10151. /** @export */ emscripten_glCreateShader: _emscripten_glCreateShader,
  10152. /** @export */ emscripten_glCullFace: _emscripten_glCullFace,
  10153. /** @export */ emscripten_glDeleteBuffers: _emscripten_glDeleteBuffers,
  10154. /** @export */ emscripten_glDeleteFramebuffers: _emscripten_glDeleteFramebuffers,
  10155. /** @export */ emscripten_glDeleteProgram: _emscripten_glDeleteProgram,
  10156. /** @export */ emscripten_glDeleteQueriesEXT: _emscripten_glDeleteQueriesEXT,
  10157. /** @export */ emscripten_glDeleteRenderbuffers: _emscripten_glDeleteRenderbuffers,
  10158. /** @export */ emscripten_glDeleteShader: _emscripten_glDeleteShader,
  10159. /** @export */ emscripten_glDeleteTextures: _emscripten_glDeleteTextures,
  10160. /** @export */ emscripten_glDeleteVertexArraysOES: _emscripten_glDeleteVertexArraysOES,
  10161. /** @export */ emscripten_glDepthFunc: _emscripten_glDepthFunc,
  10162. /** @export */ emscripten_glDepthMask: _emscripten_glDepthMask,
  10163. /** @export */ emscripten_glDepthRangef: _emscripten_glDepthRangef,
  10164. /** @export */ emscripten_glDetachShader: _emscripten_glDetachShader,
  10165. /** @export */ emscripten_glDisable: _emscripten_glDisable,
  10166. /** @export */ emscripten_glDisableVertexAttribArray: _emscripten_glDisableVertexAttribArray,
  10167. /** @export */ emscripten_glDrawArrays: _emscripten_glDrawArrays,
  10168. /** @export */ emscripten_glDrawArraysInstancedANGLE: _emscripten_glDrawArraysInstancedANGLE,
  10169. /** @export */ emscripten_glDrawBuffersWEBGL: _emscripten_glDrawBuffersWEBGL,
  10170. /** @export */ emscripten_glDrawElements: _emscripten_glDrawElements,
  10171. /** @export */ emscripten_glDrawElementsInstancedANGLE: _emscripten_glDrawElementsInstancedANGLE,
  10172. /** @export */ emscripten_glEnable: _emscripten_glEnable,
  10173. /** @export */ emscripten_glEnableVertexAttribArray: _emscripten_glEnableVertexAttribArray,
  10174. /** @export */ emscripten_glEndQueryEXT: _emscripten_glEndQueryEXT,
  10175. /** @export */ emscripten_glFinish: _emscripten_glFinish,
  10176. /** @export */ emscripten_glFlush: _emscripten_glFlush,
  10177. /** @export */ emscripten_glFramebufferRenderbuffer: _emscripten_glFramebufferRenderbuffer,
  10178. /** @export */ emscripten_glFramebufferTexture2D: _emscripten_glFramebufferTexture2D,
  10179. /** @export */ emscripten_glFrontFace: _emscripten_glFrontFace,
  10180. /** @export */ emscripten_glGenBuffers: _emscripten_glGenBuffers,
  10181. /** @export */ emscripten_glGenFramebuffers: _emscripten_glGenFramebuffers,
  10182. /** @export */ emscripten_glGenQueriesEXT: _emscripten_glGenQueriesEXT,
  10183. /** @export */ emscripten_glGenRenderbuffers: _emscripten_glGenRenderbuffers,
  10184. /** @export */ emscripten_glGenTextures: _emscripten_glGenTextures,
  10185. /** @export */ emscripten_glGenVertexArraysOES: _emscripten_glGenVertexArraysOES,
  10186. /** @export */ emscripten_glGenerateMipmap: _emscripten_glGenerateMipmap,
  10187. /** @export */ emscripten_glGetActiveAttrib: _emscripten_glGetActiveAttrib,
  10188. /** @export */ emscripten_glGetActiveUniform: _emscripten_glGetActiveUniform,
  10189. /** @export */ emscripten_glGetAttachedShaders: _emscripten_glGetAttachedShaders,
  10190. /** @export */ emscripten_glGetAttribLocation: _emscripten_glGetAttribLocation,
  10191. /** @export */ emscripten_glGetBooleanv: _emscripten_glGetBooleanv,
  10192. /** @export */ emscripten_glGetBufferParameteriv: _emscripten_glGetBufferParameteriv,
  10193. /** @export */ emscripten_glGetError: _emscripten_glGetError,
  10194. /** @export */ emscripten_glGetFloatv: _emscripten_glGetFloatv,
  10195. /** @export */ emscripten_glGetFramebufferAttachmentParameteriv: _emscripten_glGetFramebufferAttachmentParameteriv,
  10196. /** @export */ emscripten_glGetIntegerv: _emscripten_glGetIntegerv,
  10197. /** @export */ emscripten_glGetProgramInfoLog: _emscripten_glGetProgramInfoLog,
  10198. /** @export */ emscripten_glGetProgramiv: _emscripten_glGetProgramiv,
  10199. /** @export */ emscripten_glGetQueryObjecti64vEXT: _emscripten_glGetQueryObjecti64vEXT,
  10200. /** @export */ emscripten_glGetQueryObjectivEXT: _emscripten_glGetQueryObjectivEXT,
  10201. /** @export */ emscripten_glGetQueryObjectui64vEXT: _emscripten_glGetQueryObjectui64vEXT,
  10202. /** @export */ emscripten_glGetQueryObjectuivEXT: _emscripten_glGetQueryObjectuivEXT,
  10203. /** @export */ emscripten_glGetQueryivEXT: _emscripten_glGetQueryivEXT,
  10204. /** @export */ emscripten_glGetRenderbufferParameteriv: _emscripten_glGetRenderbufferParameteriv,
  10205. /** @export */ emscripten_glGetShaderInfoLog: _emscripten_glGetShaderInfoLog,
  10206. /** @export */ emscripten_glGetShaderPrecisionFormat: _emscripten_glGetShaderPrecisionFormat,
  10207. /** @export */ emscripten_glGetShaderSource: _emscripten_glGetShaderSource,
  10208. /** @export */ emscripten_glGetShaderiv: _emscripten_glGetShaderiv,
  10209. /** @export */ emscripten_glGetString: _emscripten_glGetString,
  10210. /** @export */ emscripten_glGetTexParameterfv: _emscripten_glGetTexParameterfv,
  10211. /** @export */ emscripten_glGetTexParameteriv: _emscripten_glGetTexParameteriv,
  10212. /** @export */ emscripten_glGetUniformLocation: _emscripten_glGetUniformLocation,
  10213. /** @export */ emscripten_glGetUniformfv: _emscripten_glGetUniformfv,
  10214. /** @export */ emscripten_glGetUniformiv: _emscripten_glGetUniformiv,
  10215. /** @export */ emscripten_glGetVertexAttribPointerv: _emscripten_glGetVertexAttribPointerv,
  10216. /** @export */ emscripten_glGetVertexAttribfv: _emscripten_glGetVertexAttribfv,
  10217. /** @export */ emscripten_glGetVertexAttribiv: _emscripten_glGetVertexAttribiv,
  10218. /** @export */ emscripten_glHint: _emscripten_glHint,
  10219. /** @export */ emscripten_glIsBuffer: _emscripten_glIsBuffer,
  10220. /** @export */ emscripten_glIsEnabled: _emscripten_glIsEnabled,
  10221. /** @export */ emscripten_glIsFramebuffer: _emscripten_glIsFramebuffer,
  10222. /** @export */ emscripten_glIsProgram: _emscripten_glIsProgram,
  10223. /** @export */ emscripten_glIsQueryEXT: _emscripten_glIsQueryEXT,
  10224. /** @export */ emscripten_glIsRenderbuffer: _emscripten_glIsRenderbuffer,
  10225. /** @export */ emscripten_glIsShader: _emscripten_glIsShader,
  10226. /** @export */ emscripten_glIsTexture: _emscripten_glIsTexture,
  10227. /** @export */ emscripten_glIsVertexArrayOES: _emscripten_glIsVertexArrayOES,
  10228. /** @export */ emscripten_glLineWidth: _emscripten_glLineWidth,
  10229. /** @export */ emscripten_glLinkProgram: _emscripten_glLinkProgram,
  10230. /** @export */ emscripten_glPixelStorei: _emscripten_glPixelStorei,
  10231. /** @export */ emscripten_glPolygonModeWEBGL: _emscripten_glPolygonModeWEBGL,
  10232. /** @export */ emscripten_glPolygonOffset: _emscripten_glPolygonOffset,
  10233. /** @export */ emscripten_glPolygonOffsetClampEXT: _emscripten_glPolygonOffsetClampEXT,
  10234. /** @export */ emscripten_glQueryCounterEXT: _emscripten_glQueryCounterEXT,
  10235. /** @export */ emscripten_glReadPixels: _emscripten_glReadPixels,
  10236. /** @export */ emscripten_glReleaseShaderCompiler: _emscripten_glReleaseShaderCompiler,
  10237. /** @export */ emscripten_glRenderbufferStorage: _emscripten_glRenderbufferStorage,
  10238. /** @export */ emscripten_glSampleCoverage: _emscripten_glSampleCoverage,
  10239. /** @export */ emscripten_glScissor: _emscripten_glScissor,
  10240. /** @export */ emscripten_glShaderBinary: _emscripten_glShaderBinary,
  10241. /** @export */ emscripten_glShaderSource: _emscripten_glShaderSource,
  10242. /** @export */ emscripten_glStencilFunc: _emscripten_glStencilFunc,
  10243. /** @export */ emscripten_glStencilFuncSeparate: _emscripten_glStencilFuncSeparate,
  10244. /** @export */ emscripten_glStencilMask: _emscripten_glStencilMask,
  10245. /** @export */ emscripten_glStencilMaskSeparate: _emscripten_glStencilMaskSeparate,
  10246. /** @export */ emscripten_glStencilOp: _emscripten_glStencilOp,
  10247. /** @export */ emscripten_glStencilOpSeparate: _emscripten_glStencilOpSeparate,
  10248. /** @export */ emscripten_glTexImage2D: _emscripten_glTexImage2D,
  10249. /** @export */ emscripten_glTexParameterf: _emscripten_glTexParameterf,
  10250. /** @export */ emscripten_glTexParameterfv: _emscripten_glTexParameterfv,
  10251. /** @export */ emscripten_glTexParameteri: _emscripten_glTexParameteri,
  10252. /** @export */ emscripten_glTexParameteriv: _emscripten_glTexParameteriv,
  10253. /** @export */ emscripten_glTexSubImage2D: _emscripten_glTexSubImage2D,
  10254. /** @export */ emscripten_glUniform1f: _emscripten_glUniform1f,
  10255. /** @export */ emscripten_glUniform1fv: _emscripten_glUniform1fv,
  10256. /** @export */ emscripten_glUniform1i: _emscripten_glUniform1i,
  10257. /** @export */ emscripten_glUniform1iv: _emscripten_glUniform1iv,
  10258. /** @export */ emscripten_glUniform2f: _emscripten_glUniform2f,
  10259. /** @export */ emscripten_glUniform2fv: _emscripten_glUniform2fv,
  10260. /** @export */ emscripten_glUniform2i: _emscripten_glUniform2i,
  10261. /** @export */ emscripten_glUniform2iv: _emscripten_glUniform2iv,
  10262. /** @export */ emscripten_glUniform3f: _emscripten_glUniform3f,
  10263. /** @export */ emscripten_glUniform3fv: _emscripten_glUniform3fv,
  10264. /** @export */ emscripten_glUniform3i: _emscripten_glUniform3i,
  10265. /** @export */ emscripten_glUniform3iv: _emscripten_glUniform3iv,
  10266. /** @export */ emscripten_glUniform4f: _emscripten_glUniform4f,
  10267. /** @export */ emscripten_glUniform4fv: _emscripten_glUniform4fv,
  10268. /** @export */ emscripten_glUniform4i: _emscripten_glUniform4i,
  10269. /** @export */ emscripten_glUniform4iv: _emscripten_glUniform4iv,
  10270. /** @export */ emscripten_glUniformMatrix2fv: _emscripten_glUniformMatrix2fv,
  10271. /** @export */ emscripten_glUniformMatrix3fv: _emscripten_glUniformMatrix3fv,
  10272. /** @export */ emscripten_glUniformMatrix4fv: _emscripten_glUniformMatrix4fv,
  10273. /** @export */ emscripten_glUseProgram: _emscripten_glUseProgram,
  10274. /** @export */ emscripten_glValidateProgram: _emscripten_glValidateProgram,
  10275. /** @export */ emscripten_glVertexAttrib1f: _emscripten_glVertexAttrib1f,
  10276. /** @export */ emscripten_glVertexAttrib1fv: _emscripten_glVertexAttrib1fv,
  10277. /** @export */ emscripten_glVertexAttrib2f: _emscripten_glVertexAttrib2f,
  10278. /** @export */ emscripten_glVertexAttrib2fv: _emscripten_glVertexAttrib2fv,
  10279. /** @export */ emscripten_glVertexAttrib3f: _emscripten_glVertexAttrib3f,
  10280. /** @export */ emscripten_glVertexAttrib3fv: _emscripten_glVertexAttrib3fv,
  10281. /** @export */ emscripten_glVertexAttrib4f: _emscripten_glVertexAttrib4f,
  10282. /** @export */ emscripten_glVertexAttrib4fv: _emscripten_glVertexAttrib4fv,
  10283. /** @export */ emscripten_glVertexAttribDivisorANGLE: _emscripten_glVertexAttribDivisorANGLE,
  10284. /** @export */ emscripten_glVertexAttribPointer: _emscripten_glVertexAttribPointer,
  10285. /** @export */ emscripten_glViewport: _emscripten_glViewport,
  10286. /** @export */ emscripten_has_asyncify: _emscripten_has_asyncify,
  10287. /** @export */ emscripten_request_fullscreen_strategy: _emscripten_request_fullscreen_strategy,
  10288. /** @export */ emscripten_request_pointerlock: _emscripten_request_pointerlock,
  10289. /** @export */ emscripten_resize_heap: _emscripten_resize_heap,
  10290. /** @export */ emscripten_sample_gamepad_data: _emscripten_sample_gamepad_data,
  10291. /** @export */ emscripten_set_beforeunload_callback_on_thread: _emscripten_set_beforeunload_callback_on_thread,
  10292. /** @export */ emscripten_set_blur_callback_on_thread: _emscripten_set_blur_callback_on_thread,
  10293. /** @export */ emscripten_set_canvas_element_size: _emscripten_set_canvas_element_size,
  10294. /** @export */ emscripten_set_element_css_size: _emscripten_set_element_css_size,
  10295. /** @export */ emscripten_set_focus_callback_on_thread: _emscripten_set_focus_callback_on_thread,
  10296. /** @export */ emscripten_set_fullscreenchange_callback_on_thread: _emscripten_set_fullscreenchange_callback_on_thread,
  10297. /** @export */ emscripten_set_gamepadconnected_callback_on_thread: _emscripten_set_gamepadconnected_callback_on_thread,
  10298. /** @export */ emscripten_set_gamepaddisconnected_callback_on_thread: _emscripten_set_gamepaddisconnected_callback_on_thread,
  10299. /** @export */ emscripten_set_keydown_callback_on_thread: _emscripten_set_keydown_callback_on_thread,
  10300. /** @export */ emscripten_set_keypress_callback_on_thread: _emscripten_set_keypress_callback_on_thread,
  10301. /** @export */ emscripten_set_keyup_callback_on_thread: _emscripten_set_keyup_callback_on_thread,
  10302. /** @export */ emscripten_set_main_loop: _emscripten_set_main_loop,
  10303. /** @export */ emscripten_set_mousedown_callback_on_thread: _emscripten_set_mousedown_callback_on_thread,
  10304. /** @export */ emscripten_set_mouseenter_callback_on_thread: _emscripten_set_mouseenter_callback_on_thread,
  10305. /** @export */ emscripten_set_mouseleave_callback_on_thread: _emscripten_set_mouseleave_callback_on_thread,
  10306. /** @export */ emscripten_set_mousemove_callback_on_thread: _emscripten_set_mousemove_callback_on_thread,
  10307. /** @export */ emscripten_set_mouseup_callback_on_thread: _emscripten_set_mouseup_callback_on_thread,
  10308. /** @export */ emscripten_set_pointerlockchange_callback_on_thread: _emscripten_set_pointerlockchange_callback_on_thread,
  10309. /** @export */ emscripten_set_resize_callback_on_thread: _emscripten_set_resize_callback_on_thread,
  10310. /** @export */ emscripten_set_touchcancel_callback_on_thread: _emscripten_set_touchcancel_callback_on_thread,
  10311. /** @export */ emscripten_set_touchend_callback_on_thread: _emscripten_set_touchend_callback_on_thread,
  10312. /** @export */ emscripten_set_touchmove_callback_on_thread: _emscripten_set_touchmove_callback_on_thread,
  10313. /** @export */ emscripten_set_touchstart_callback_on_thread: _emscripten_set_touchstart_callback_on_thread,
  10314. /** @export */ emscripten_set_visibilitychange_callback_on_thread: _emscripten_set_visibilitychange_callback_on_thread,
  10315. /** @export */ emscripten_set_wheel_callback_on_thread: _emscripten_set_wheel_callback_on_thread,
  10316. /** @export */ emscripten_set_window_title: _emscripten_set_window_title,
  10317. /** @export */ emscripten_sleep: _emscripten_sleep,
  10318. /** @export */ environ_get: _environ_get,
  10319. /** @export */ environ_sizes_get: _environ_sizes_get,
  10320. /** @export */ exit: _exit,
  10321. /** @export */ fd_close: _fd_close,
  10322. /** @export */ fd_read: _fd_read,
  10323. /** @export */ fd_seek: _fd_seek,
  10324. /** @export */ fd_write: _fd_write,
  10325. /** @export */ memory: wasmMemory,
  10326. /** @export */ posix_spawnp: _posix_spawnp,
  10327. /** @export */ proc_exit: _proc_exit
  10328. };
  10329. }
  10330. // include: postamble.js
  10331. // === Auto-generated postamble setup entry stuff ===
  10332. var calledRun;
  10333. function callMain(args = []) {
  10334. assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])');
  10335. assert(typeof onPreRuns === "undefined" || onPreRuns.length == 0, "cannot call main when preRun functions remain to be called");
  10336. var entryFunction = _main;
  10337. args.unshift(thisProgram);
  10338. var argc = args.length;
  10339. var argv = stackAlloc((argc + 1) * 4);
  10340. var argv_ptr = argv;
  10341. for (var arg of args) {
  10342. (growMemViews(), HEAPU32)[((argv_ptr) >> 2)] = stringToUTF8OnStack(arg);
  10343. argv_ptr += 4;
  10344. }
  10345. (growMemViews(), HEAPU32)[((argv_ptr) >> 2)] = 0;
  10346. try {
  10347. var ret = entryFunction(argc, argv);
  10348. // if we're not running an evented main loop, it's time to exit
  10349. exitJS(ret, /* implicit = */ true);
  10350. return ret;
  10351. } catch (e) {
  10352. return handleException(e);
  10353. }
  10354. }
  10355. function stackCheckInit() {
  10356. // This is normally called automatically during __wasm_call_ctors but need to
  10357. // get these values before even running any of the ctors so we call it redundantly
  10358. // here.
  10359. // See $establishStackSpace for the equivalent code that runs on a thread
  10360. assert(!ENVIRONMENT_IS_PTHREAD);
  10361. _emscripten_stack_init();
  10362. // TODO(sbc): Move writeStackCookie to native to to avoid this.
  10363. writeStackCookie();
  10364. }
  10365. async function run(args = programArgs) {
  10366. assert(!calledRun);
  10367. calledRun = true;
  10368. if ((ENVIRONMENT_IS_PTHREAD)) {
  10369. initRuntime();
  10370. return;
  10371. }
  10372. stackCheckInit();
  10373. preRun();
  10374. if (runDependencies) {
  10375. await resolveRunDependencies();
  10376. }
  10377. var setStatus = Module["setStatus"];
  10378. if (setStatus) {
  10379. setStatus("Running...");
  10380. // Yield to the event loop to allow the browser to paint "Running..."
  10381. await new Promise(resolve => setTimeout(resolve, 1));
  10382. // Then we want to clear the status text, but only after the rest of this function runs.
  10383. setTimeout(setStatus, 1, "");
  10384. }
  10385. if (ABORT) return;
  10386. initRuntime();
  10387. // No ATMAINS hooks
  10388. Module["onRuntimeInitialized"]?.();
  10389. consumedModuleProp("onRuntimeInitialized");
  10390. var noInitialRun = Module["noInitialRun"] || false;
  10391. if (!noInitialRun) callMain(args);
  10392. postRun();
  10393. }
  10394. function checkUnflushedContent() {
  10395. // Compiler settings do not allow exiting the runtime, so flushing
  10396. // the streams is not possible. but in ASSERTIONS mode we check
  10397. // if there was something to flush, and if so tell the user they
  10398. // should request that the runtime be exitable.
  10399. // Normally we would not even include flush() at all, but in ASSERTIONS
  10400. // builds we do so just for this check, and here we see if there is any
  10401. // content to flush, that is, we check if there would have been
  10402. // something a non-ASSERTIONS build would have not seen.
  10403. // How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0
  10404. // mode (which has its own special function for this; otherwise, all
  10405. // the code is inside libc)
  10406. var oldOut = out;
  10407. var oldErr = err;
  10408. var has = false;
  10409. out = err = x => {
  10410. has = true;
  10411. };
  10412. try {
  10413. // it doesn't matter if it fails
  10414. _fflush(0);
  10415. // also flush in the JS FS layer
  10416. for (var name of [ "stdout", "stderr" ]) {
  10417. var info = FS.analyzePath("/dev/" + name);
  10418. if (!info) return;
  10419. var stream = info.object;
  10420. var rdev = stream.rdev;
  10421. var tty = TTY.ttys[rdev];
  10422. if (tty?.output?.length) {
  10423. has = true;
  10424. }
  10425. }
  10426. } catch (e) {}
  10427. out = oldOut;
  10428. err = oldErr;
  10429. if (has) {
  10430. warnOnce("stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the Emscripten FAQ), or make sure to emit a newline when you printf etc.");
  10431. }
  10432. }
  10433. var wasmExports;
  10434. if ((!(ENVIRONMENT_IS_PTHREAD))) {
  10435. // Call createWasm on startup if we are the main thread.
  10436. // Worker threads call this once they receive the module via postMessage
  10437. // With async instantation wasmExports is assigned asynchronously when the
  10438. // instance is received.
  10439. createWasm().then(() => run());
  10440. }