meg4.js 376 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229
  1. // include: shell.js
  2. // The Module object: Our interface to the outside world. We import
  3. // and export values on it. There are various ways Module can be used:
  4. // 1. Not defined. We create it here
  5. // 2. A function parameter, function(moduleArg) => Promise<Module>
  6. // 3. pre-run appended it, var Module = {}; ..generated code..
  7. // 4. External script tag defines var Module.
  8. // We need to check if Module already exists (e.g. case 3 above).
  9. // Substitution will be replaced with actual code on later stage of the build,
  10. // this way Closure Compiler will not mangle it (e.g. case 4. above).
  11. // Note that if you want to run closure, and also to use Module
  12. // after the generated code, you will need to define var Module = {};
  13. // before the code. Then that object will be used in the code, and you
  14. // can continue to use Module afterwards as well.
  15. var Module = typeof Module != 'undefined' ? Module : {};
  16. // Determine the runtime environment we are in. You can customize this by
  17. // setting the ENVIRONMENT setting at compile time (see settings.js).
  18. // Attempt to auto-detect the environment
  19. var ENVIRONMENT_IS_WEB = typeof window == 'object';
  20. var ENVIRONMENT_IS_WORKER = typeof importScripts == 'function';
  21. // N.b. Electron.js environment is simultaneously a NODE-environment, but
  22. // also a web environment.
  23. var ENVIRONMENT_IS_NODE = typeof process == 'object' && typeof process.versions == 'object' && typeof process.versions.node == 'string';
  24. var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
  25. if (Module['ENVIRONMENT']) {
  26. throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)');
  27. }
  28. if (ENVIRONMENT_IS_NODE) {
  29. // `require()` is no-op in an ESM module, use `createRequire()` to construct
  30. // the require()` function. This is only necessary for multi-environment
  31. // builds, `-sENVIRONMENT=node` emits a static import declaration instead.
  32. // TODO: Swap all `require()`'s with `import()`'s?
  33. }
  34. // --pre-jses are emitted after the Module integration code, so that they can
  35. // refer to Module (if they choose; they can also define Module)
  36. // include: /home/bzt/Documents/meg4/platform/emscripten/pre.js
  37. Module.canvas = document.getElementById("canvas");
  38. if(Module.canvas == undefined) Module.canvas = document.getElementByTagName("canvas");
  39. if(Module.canvas == undefined) alert("No canvas?");
  40. Module.canvas.addEventListener("contextmenu", function() {event.preventDefault()});
  41. Module.canvas.addEventListener("dragover", function() {event.preventDefault()});
  42. Module.canvas.addEventListener("drop", function() {meg4_openfile(event)});
  43. var tag = document.createElement("INPUT");
  44. tag.setAttribute("id", "meg4_upload");
  45. tag.setAttribute("type", "file");
  46. tag.setAttribute("style", "display:none");
  47. tag.addEventListener("change", function() {
  48. inp = document.getElementById("meg4_upload");
  49. if(inp.files.length>0) {
  50. var reader = new FileReader();
  51. reader.onloadend = function() { meg4_execute(inp.files[0].toString(), new Uint8Array(reader.result)); };
  52. reader.readAsArrayBuffer(inp.files[0]);
  53. }
  54. });
  55. document.body.appendChild(tag);
  56. tag = document.createElement("A");
  57. tag.setAttribute("id", "meg4_download");
  58. tag.setAttribute("style", "display:none");
  59. tag.setAttribute("download", "");
  60. document.body.appendChild(tag);
  61. function meg4_execute(name, data) {
  62. var base = name.split('/').pop();
  63. var file = new TextEncoder("utf-8").encode(base == undefined ? name : base);
  64. if(data != undefined && data.length > 0) {
  65. var meg4 = Module.cwrap("meg4_insert", "number", [ "number", "number", "number" ]);
  66. const fn = Module._malloc(file.length);
  67. const buf = Module._malloc(data.length);
  68. Module.HEAPU8.set(file, fn);
  69. Module.HEAPU8.set(data, buf);
  70. if(meg4 != undefined) meg4(fn, buf, data.length);
  71. Module._free(buf);
  72. Module._free(fn);
  73. }
  74. }
  75. function meg4_openfile(e) {
  76. e.stopPropagation();
  77. e.preventDefault();
  78. var floppy = e.dataTransfer.getData("url");
  79. if(floppy == undefined || floppy == "")
  80. floppy = e.dataTransfer.getData("src");
  81. if(floppy == undefined || floppy == "")
  82. floppy = new DOMParser().parseFromString(e.dataTransfer.getData('text/html'), "text/html").querySelector('img').src;
  83. if(floppy != undefined && floppy != "") {
  84. fetch(floppy).then((response) => {
  85. if(response.ok) response.arrayBuffer().then((buf) => { meg4_execute(floppy, new Uint8Array(buf)); });
  86. })
  87. .catch((error) => {
  88. var reader = new FileReader();
  89. reader.onloadend = function() { meg4_execute(floppy, new Uint8Array(reader.result)); };
  90. reader.readAsArrayBuffer(floppy);
  91. });
  92. }
  93. }
  94. function meg4_savefile(fn, fnlen, buf, len) {
  95. const fview = new Uint8Array(Module.HEAPU8.buffer,fn,fnlen);
  96. const bview = new Uint8Array(Module.HEAPU8.buffer,buf,len);
  97. var name = new TextDecoder("utf-8").decode(fview);
  98. var blob = new Blob([bview], { type: "application/octet-stream" });
  99. var url = window.URL.createObjectURL(blob);
  100. var a = document.getElementById('meg4_download');
  101. a.setAttribute('href',url);
  102. a.setAttribute('download', name != undefined ? name : "noname.png");
  103. a.click();
  104. window.URL.revokeObjectURL(url);
  105. }
  106. // end include: /home/bzt/Documents/meg4/platform/emscripten/pre.js
  107. // Sometimes an existing Module object exists with properties
  108. // meant to overwrite the default module functionality. Here
  109. // we collect those properties and reapply _after_ we configure
  110. // the current environment's defaults to avoid having to be so
  111. // defensive during initialization.
  112. var moduleOverrides = Object.assign({}, Module);
  113. var arguments_ = [];
  114. var thisProgram = './this.program';
  115. var quit_ = (status, toThrow) => {
  116. throw toThrow;
  117. };
  118. // `/` should be present at the end if `scriptDirectory` is not empty
  119. var scriptDirectory = '';
  120. function locateFile(path) {
  121. if (Module['locateFile']) {
  122. return Module['locateFile'](path, scriptDirectory);
  123. }
  124. return scriptDirectory + path;
  125. }
  126. // Hooks that are implemented differently in different runtime environments.
  127. var read_,
  128. readAsync,
  129. readBinary;
  130. if (ENVIRONMENT_IS_NODE) {
  131. if (typeof process == 'undefined' || !process.release || process.release.name !== 'node') 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?)');
  132. var nodeVersion = process.versions.node;
  133. var numericVersion = nodeVersion.split('.').slice(0, 3);
  134. numericVersion = (numericVersion[0] * 10000) + (numericVersion[1] * 100) + (numericVersion[2].split('-')[0] * 1);
  135. var minVersion = 160000;
  136. if (numericVersion < 160000) {
  137. throw new Error('This emscripten-generated code requires node v16.0.0 (detected v' + nodeVersion + ')');
  138. }
  139. // These modules will usually be used on Node.js. Load them eagerly to avoid
  140. // the complexity of lazy-loading.
  141. var fs = require('fs');
  142. var nodePath = require('path');
  143. scriptDirectory = __dirname + '/';
  144. // include: node_shell_read.js
  145. read_ = (filename, binary) => {
  146. // We need to re-wrap `file://` strings to URLs. Normalizing isn't
  147. // necessary in that case, the path should already be absolute.
  148. filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
  149. return fs.readFileSync(filename, binary ? undefined : 'utf8');
  150. };
  151. readBinary = (filename) => {
  152. var ret = read_(filename, true);
  153. if (!ret.buffer) {
  154. ret = new Uint8Array(ret);
  155. }
  156. assert(ret.buffer);
  157. return ret;
  158. };
  159. readAsync = (filename, onload, onerror, binary = true) => {
  160. // See the comment in the `read_` function.
  161. filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
  162. fs.readFile(filename, binary ? undefined : 'utf8', (err, data) => {
  163. if (err) onerror(err);
  164. else onload(binary ? data.buffer : data);
  165. });
  166. };
  167. // end include: node_shell_read.js
  168. if (!Module['thisProgram'] && process.argv.length > 1) {
  169. thisProgram = process.argv[1].replace(/\\/g, '/');
  170. }
  171. arguments_ = process.argv.slice(2);
  172. if (typeof module != 'undefined') {
  173. module['exports'] = Module;
  174. }
  175. process.on('uncaughtException', (ex) => {
  176. // suppress ExitStatus exceptions from showing an error
  177. if (ex !== 'unwind' && !(ex instanceof ExitStatus) && !(ex.context instanceof ExitStatus)) {
  178. throw ex;
  179. }
  180. });
  181. quit_ = (status, toThrow) => {
  182. process.exitCode = status;
  183. throw toThrow;
  184. };
  185. } else
  186. if (ENVIRONMENT_IS_SHELL) {
  187. if ((typeof process == 'object' && typeof require === 'function') || typeof window == 'object' || typeof importScripts == 'function') 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?)');
  188. } else
  189. // Note that this includes Node.js workers when relevant (pthreads is enabled).
  190. // Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
  191. // ENVIRONMENT_IS_NODE.
  192. if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
  193. if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled
  194. scriptDirectory = self.location.href;
  195. } else if (typeof document != 'undefined' && document.currentScript) { // web
  196. scriptDirectory = document.currentScript.src;
  197. }
  198. // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
  199. // otherwise, slice off the final part of the url to find the script directory.
  200. // if scriptDirectory does not contain a slash, lastIndexOf will return -1,
  201. // and scriptDirectory will correctly be replaced with an empty string.
  202. // If scriptDirectory contains a query (starting with ?) or a fragment (starting with #),
  203. // they are removed because they could contain a slash.
  204. if (scriptDirectory.startsWith('blob:')) {
  205. scriptDirectory = '';
  206. } else {
  207. scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, '').lastIndexOf('/')+1);
  208. }
  209. if (!(typeof window == 'object' || typeof importScripts == 'function')) 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?)');
  210. {
  211. // include: web_or_worker_shell_read.js
  212. read_ = (url) => {
  213. var xhr = new XMLHttpRequest();
  214. xhr.open('GET', url, false);
  215. xhr.send(null);
  216. return xhr.responseText;
  217. }
  218. if (ENVIRONMENT_IS_WORKER) {
  219. readBinary = (url) => {
  220. var xhr = new XMLHttpRequest();
  221. xhr.open('GET', url, false);
  222. xhr.responseType = 'arraybuffer';
  223. xhr.send(null);
  224. return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));
  225. };
  226. }
  227. readAsync = (url, onload, onerror) => {
  228. // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url.
  229. // See https://github.com/github/fetch/pull/92#issuecomment-140665932
  230. // Cordova or Electron apps are typically loaded from a file:// url.
  231. // So use XHR on webview if URL is a file URL.
  232. if (isFileURI(url)) {
  233. var xhr = new XMLHttpRequest();
  234. xhr.open('GET', url, true);
  235. xhr.responseType = 'arraybuffer';
  236. xhr.onload = () => {
  237. if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
  238. onload(xhr.response);
  239. return;
  240. }
  241. onerror();
  242. };
  243. xhr.onerror = onerror;
  244. xhr.send(null);
  245. return;
  246. }
  247. fetch(url, { credentials: 'same-origin' })
  248. .then((response) => {
  249. if (response.ok) {
  250. return response.arrayBuffer();
  251. }
  252. return Promise.reject(new Error(response.status + ' : ' + response.url));
  253. })
  254. .then(onload, onerror)
  255. };
  256. // end include: web_or_worker_shell_read.js
  257. }
  258. } else
  259. {
  260. throw new Error('environment detection error');
  261. }
  262. var out = Module['print'] || console.log.bind(console);
  263. var err = Module['printErr'] || console.error.bind(console);
  264. // Merge back in the overrides
  265. Object.assign(Module, moduleOverrides);
  266. // Free the object hierarchy contained in the overrides, this lets the GC
  267. // reclaim data used.
  268. moduleOverrides = null;
  269. checkIncomingModuleAPI();
  270. // Emit code to handle expected values on the Module object. This applies Module.x
  271. // to the proper local x. This has two benefits: first, we only emit it if it is
  272. // expected to arrive, and second, by using a local everywhere else that can be
  273. // minified.
  274. if (Module['arguments']) arguments_ = Module['arguments'];legacyModuleProp('arguments', 'arguments_');
  275. if (Module['thisProgram']) thisProgram = Module['thisProgram'];legacyModuleProp('thisProgram', 'thisProgram');
  276. if (Module['quit']) quit_ = Module['quit'];legacyModuleProp('quit', 'quit_');
  277. // perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
  278. // Assertions on removed incoming Module JS APIs.
  279. assert(typeof Module['memoryInitializerPrefixURL'] == 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead');
  280. assert(typeof Module['pthreadMainPrefixURL'] == 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead');
  281. assert(typeof Module['cdInitializerPrefixURL'] == 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead');
  282. assert(typeof Module['filePackagePrefixURL'] == 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead');
  283. assert(typeof Module['read'] == 'undefined', 'Module.read option was removed (modify read_ in JS)');
  284. assert(typeof Module['readAsync'] == 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)');
  285. assert(typeof Module['readBinary'] == 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)');
  286. assert(typeof Module['setWindowTitle'] == 'undefined', 'Module.setWindowTitle option was removed (modify emscripten_set_window_title in JS)');
  287. assert(typeof Module['TOTAL_MEMORY'] == 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY');
  288. legacyModuleProp('asm', 'wasmExports');
  289. legacyModuleProp('read', 'read_');
  290. legacyModuleProp('readAsync', 'readAsync');
  291. legacyModuleProp('readBinary', 'readBinary');
  292. legacyModuleProp('setWindowTitle', 'setWindowTitle');
  293. var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js';
  294. var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js';
  295. var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js';
  296. var FETCHFS = 'FETCHFS is no longer included by default; build with -lfetchfs.js';
  297. var ICASEFS = 'ICASEFS is no longer included by default; build with -licasefs.js';
  298. var JSFILEFS = 'JSFILEFS is no longer included by default; build with -ljsfilefs.js';
  299. var OPFS = 'OPFS is no longer included by default; build with -lopfs.js';
  300. var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js';
  301. assert(!ENVIRONMENT_IS_SHELL, 'shell environment detected but not enabled at build time. Add `shell` to `-sENVIRONMENT` to enable.');
  302. // end include: shell.js
  303. // include: preamble.js
  304. // === Preamble library stuff ===
  305. // Documentation for the public APIs defined in this file must be updated in:
  306. // site/source/docs/api_reference/preamble.js.rst
  307. // A prebuilt local version of the documentation is available at:
  308. // site/build/text/docs/api_reference/preamble.js.txt
  309. // You can also build docs locally as HTML or other formats in site/
  310. // An online HTML version (which may be of a different version of Emscripten)
  311. // is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
  312. var wasmBinary;
  313. if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];legacyModuleProp('wasmBinary', 'wasmBinary');
  314. if (typeof WebAssembly != 'object') {
  315. err('no native wasm support detected');
  316. }
  317. // Wasm globals
  318. var wasmMemory;
  319. //========================================
  320. // Runtime essentials
  321. //========================================
  322. // whether we are quitting the application. no code should run after this.
  323. // set in exit() and abort()
  324. var ABORT = false;
  325. // set by exit() and abort(). Passed to 'onExit' handler.
  326. // NOTE: This is also used as the process return code code in shell environments
  327. // but only when noExitRuntime is false.
  328. var EXITSTATUS;
  329. // In STRICT mode, we only define assert() when ASSERTIONS is set. i.e. we
  330. // don't define it at all in release modes. This matches the behaviour of
  331. // MINIMAL_RUNTIME.
  332. // TODO(sbc): Make this the default even without STRICT enabled.
  333. /** @type {function(*, string=)} */
  334. function assert(condition, text) {
  335. if (!condition) {
  336. abort('Assertion failed' + (text ? ': ' + text : ''));
  337. }
  338. }
  339. // We used to include malloc/free by default in the past. Show a helpful error in
  340. // builds with assertions.
  341. // Memory management
  342. var HEAP,
  343. /** @type {!Int8Array} */
  344. HEAP8,
  345. /** @type {!Uint8Array} */
  346. HEAPU8,
  347. /** @type {!Int16Array} */
  348. HEAP16,
  349. /** @type {!Uint16Array} */
  350. HEAPU16,
  351. /** @type {!Int32Array} */
  352. HEAP32,
  353. /** @type {!Uint32Array} */
  354. HEAPU32,
  355. /** @type {!Float32Array} */
  356. HEAPF32,
  357. /* BigInt64Array type is not correctly defined in closure
  358. /** not-@type {!BigInt64Array} */
  359. HEAP64,
  360. /* BigUInt64Array type is not correctly defined in closure
  361. /** not-t@type {!BigUint64Array} */
  362. HEAPU64,
  363. /** @type {!Float64Array} */
  364. HEAPF64;
  365. // include: runtime_shared.js
  366. function updateMemoryViews() {
  367. var b = wasmMemory.buffer;
  368. Module['HEAP8'] = HEAP8 = new Int8Array(b);
  369. Module['HEAP16'] = HEAP16 = new Int16Array(b);
  370. Module['HEAPU8'] = HEAPU8 = new Uint8Array(b);
  371. Module['HEAPU16'] = HEAPU16 = new Uint16Array(b);
  372. Module['HEAP32'] = HEAP32 = new Int32Array(b);
  373. Module['HEAPU32'] = HEAPU32 = new Uint32Array(b);
  374. Module['HEAPF32'] = HEAPF32 = new Float32Array(b);
  375. Module['HEAPF64'] = HEAPF64 = new Float64Array(b);
  376. Module['HEAP64'] = HEAP64 = new BigInt64Array(b);
  377. Module['HEAPU64'] = HEAPU64 = new BigUint64Array(b);
  378. }
  379. // end include: runtime_shared.js
  380. assert(!Module['STACK_SIZE'], 'STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time')
  381. assert(typeof Int32Array != 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray != undefined && Int32Array.prototype.set != undefined,
  382. 'JS engine does not provide full typed array support');
  383. // If memory is defined in wasm, the user can't provide it, or set INITIAL_MEMORY
  384. assert(!Module['wasmMemory'], 'Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally');
  385. assert(!Module['INITIAL_MEMORY'], 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically');
  386. // include: runtime_stack_check.js
  387. // Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
  388. function writeStackCookie() {
  389. var max = _emscripten_stack_get_end();
  390. assert((max & 3) == 0);
  391. // If the stack ends at address zero we write our cookies 4 bytes into the
  392. // stack. This prevents interference with SAFE_HEAP and ASAN which also
  393. // monitor writes to address zero.
  394. if (max == 0) {
  395. max += 4;
  396. }
  397. // The stack grow downwards towards _emscripten_stack_get_end.
  398. // We write cookies to the final two words in the stack and detect if they are
  399. // ever overwritten.
  400. HEAPU32[((max)>>2)] = 0x02135467;
  401. HEAPU32[(((max)+(4))>>2)] = 0x89BACDFE;
  402. // Also test the global address 0 for integrity.
  403. HEAPU32[((0)>>2)] = 1668509029;
  404. }
  405. function checkStackCookie() {
  406. if (ABORT) return;
  407. var max = _emscripten_stack_get_end();
  408. // See writeStackCookie().
  409. if (max == 0) {
  410. max += 4;
  411. }
  412. var cookie1 = HEAPU32[((max)>>2)];
  413. var cookie2 = HEAPU32[(((max)+(4))>>2)];
  414. if (cookie1 != 0x02135467 || cookie2 != 0x89BACDFE) {
  415. abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString(cookie2)} ${ptrToString(cookie1)}`);
  416. }
  417. // Also test the global address 0 for integrity.
  418. if (HEAPU32[((0)>>2)] != 0x63736d65 /* 'emsc' */) {
  419. abort('Runtime error: The application has corrupted its heap memory area (address zero)!');
  420. }
  421. }
  422. // end include: runtime_stack_check.js
  423. // include: runtime_assertions.js
  424. // Endianness check
  425. (function() {
  426. var h16 = new Int16Array(1);
  427. var h8 = new Int8Array(h16.buffer);
  428. h16[0] = 0x6373;
  429. if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)';
  430. })();
  431. // end include: runtime_assertions.js
  432. var __ATPRERUN__ = []; // functions called before the runtime is initialized
  433. var __ATINIT__ = []; // functions called during startup
  434. var __ATMAIN__ = []; // functions called when main() is to be run
  435. var __ATEXIT__ = []; // functions called during shutdown
  436. var __ATPOSTRUN__ = []; // functions called after the main() is called
  437. var runtimeInitialized = false;
  438. var runtimeExited = false;
  439. function preRun() {
  440. if (Module['preRun']) {
  441. if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
  442. while (Module['preRun'].length) {
  443. addOnPreRun(Module['preRun'].shift());
  444. }
  445. }
  446. callRuntimeCallbacks(__ATPRERUN__);
  447. }
  448. function initRuntime() {
  449. assert(!runtimeInitialized);
  450. runtimeInitialized = true;
  451. checkStackCookie();
  452. if (!Module['noFSInit'] && !FS.init.initialized)
  453. FS.init();
  454. FS.ignorePermissions = false;
  455. TTY.init();
  456. callRuntimeCallbacks(__ATINIT__);
  457. }
  458. function preMain() {
  459. checkStackCookie();
  460. callRuntimeCallbacks(__ATMAIN__);
  461. }
  462. function exitRuntime() {
  463. assert(!runtimeExited);
  464. checkStackCookie();
  465. ___funcs_on_exit(); // Native atexit() functions
  466. callRuntimeCallbacks(__ATEXIT__);
  467. FS.quit();
  468. TTY.shutdown();
  469. runtimeExited = true;
  470. }
  471. function postRun() {
  472. checkStackCookie();
  473. if (Module['postRun']) {
  474. if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
  475. while (Module['postRun'].length) {
  476. addOnPostRun(Module['postRun'].shift());
  477. }
  478. }
  479. callRuntimeCallbacks(__ATPOSTRUN__);
  480. }
  481. function addOnPreRun(cb) {
  482. __ATPRERUN__.unshift(cb);
  483. }
  484. function addOnInit(cb) {
  485. __ATINIT__.unshift(cb);
  486. }
  487. function addOnPreMain(cb) {
  488. __ATMAIN__.unshift(cb);
  489. }
  490. function addOnExit(cb) {
  491. __ATEXIT__.unshift(cb);
  492. }
  493. function addOnPostRun(cb) {
  494. __ATPOSTRUN__.unshift(cb);
  495. }
  496. // include: runtime_math.js
  497. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
  498. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
  499. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
  500. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
  501. assert(Math.imul, 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  502. assert(Math.fround, 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  503. assert(Math.clz32, 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  504. assert(Math.trunc, 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  505. // end include: runtime_math.js
  506. // A counter of dependencies for calling run(). If we need to
  507. // do asynchronous work before running, increment this and
  508. // decrement it. Incrementing must happen in a place like
  509. // Module.preRun (used by emcc to add file preloading).
  510. // Note that you can add dependencies in preRun, even though
  511. // it happens right before run - run will be postponed until
  512. // the dependencies are met.
  513. var runDependencies = 0;
  514. var runDependencyWatcher = null;
  515. var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
  516. var runDependencyTracking = {};
  517. function getUniqueRunDependency(id) {
  518. var orig = id;
  519. while (1) {
  520. if (!runDependencyTracking[id]) return id;
  521. id = orig + Math.random();
  522. }
  523. }
  524. function addRunDependency(id) {
  525. runDependencies++;
  526. Module['monitorRunDependencies']?.(runDependencies);
  527. if (id) {
  528. assert(!runDependencyTracking[id]);
  529. runDependencyTracking[id] = 1;
  530. if (runDependencyWatcher === null && typeof setInterval != 'undefined') {
  531. // Check for missing dependencies every few seconds
  532. runDependencyWatcher = setInterval(() => {
  533. if (ABORT) {
  534. clearInterval(runDependencyWatcher);
  535. runDependencyWatcher = null;
  536. return;
  537. }
  538. var shown = false;
  539. for (var dep in runDependencyTracking) {
  540. if (!shown) {
  541. shown = true;
  542. err('still waiting on run dependencies:');
  543. }
  544. err(`dependency: ${dep}`);
  545. }
  546. if (shown) {
  547. err('(end of list)');
  548. }
  549. }, 10000);
  550. }
  551. } else {
  552. err('warning: run dependency added without ID');
  553. }
  554. }
  555. function removeRunDependency(id) {
  556. runDependencies--;
  557. Module['monitorRunDependencies']?.(runDependencies);
  558. if (id) {
  559. assert(runDependencyTracking[id]);
  560. delete runDependencyTracking[id];
  561. } else {
  562. err('warning: run dependency removed without ID');
  563. }
  564. if (runDependencies == 0) {
  565. if (runDependencyWatcher !== null) {
  566. clearInterval(runDependencyWatcher);
  567. runDependencyWatcher = null;
  568. }
  569. if (dependenciesFulfilled) {
  570. var callback = dependenciesFulfilled;
  571. dependenciesFulfilled = null;
  572. callback(); // can add another dependenciesFulfilled
  573. }
  574. }
  575. }
  576. /** @param {string|number=} what */
  577. function abort(what) {
  578. Module['onAbort']?.(what);
  579. what = 'Aborted(' + what + ')';
  580. // TODO(sbc): Should we remove printing and leave it up to whoever
  581. // catches the exception?
  582. err(what);
  583. ABORT = true;
  584. EXITSTATUS = 1;
  585. // Use a wasm runtime error, because a JS error might be seen as a foreign
  586. // exception, which means we'd run destructors on it. We need the error to
  587. // simply make the program stop.
  588. // FIXME This approach does not work in Wasm EH because it currently does not assume
  589. // all RuntimeErrors are from traps; it decides whether a RuntimeError is from
  590. // a trap or not based on a hidden field within the object. So at the moment
  591. // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that
  592. // allows this in the wasm spec.
  593. // Suppress closure compiler warning here. Closure compiler's builtin extern
  594. // definition for WebAssembly.RuntimeError claims it takes no arguments even
  595. // though it can.
  596. // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.
  597. /** @suppress {checkTypes} */
  598. var e = new WebAssembly.RuntimeError(what);
  599. // Throw the error whether or not MODULARIZE is set because abort is used
  600. // in code paths apart from instantiation where an exception is expected
  601. // to be thrown when abort is called.
  602. throw e;
  603. }
  604. // include: memoryprofiler.js
  605. // end include: memoryprofiler.js
  606. // include: URIUtils.js
  607. // Prefix of data URIs emitted by SINGLE_FILE and related options.
  608. var dataURIPrefix = 'data:application/octet-stream;base64,';
  609. /**
  610. * Indicates whether filename is a base64 data URI.
  611. * @noinline
  612. */
  613. var isDataURI = (filename) => filename.startsWith(dataURIPrefix);
  614. /**
  615. * Indicates whether filename is delivered via file protocol (as opposed to http/https)
  616. * @noinline
  617. */
  618. var isFileURI = (filename) => filename.startsWith('file://');
  619. // end include: URIUtils.js
  620. function createExportWrapper(name, nargs) {
  621. return (...args) => {
  622. assert(runtimeInitialized, `native function \`${name}\` called before runtime initialization`);
  623. assert(!runtimeExited, `native function \`${name}\` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)`);
  624. var f = wasmExports[name];
  625. assert(f, `exported native function \`${name}\` not found`);
  626. // Only assert for too many arguments. Too few can be valid since the missing arguments will be zero filled.
  627. assert(args.length <= nargs, `native function \`${name}\` called with ${args.length} args but expects ${nargs}`);
  628. return f(...args);
  629. };
  630. }
  631. // include: runtime_exceptions.js
  632. // end include: runtime_exceptions.js
  633. function findWasmBinary() {
  634. var f = 'meg4.wasm';
  635. if (!isDataURI(f)) {
  636. return locateFile(f);
  637. }
  638. return f;
  639. }
  640. var wasmBinaryFile;
  641. function getBinarySync(file) {
  642. if (file == wasmBinaryFile && wasmBinary) {
  643. return new Uint8Array(wasmBinary);
  644. }
  645. if (readBinary) {
  646. return readBinary(file);
  647. }
  648. throw 'both async and sync fetching of the wasm failed';
  649. }
  650. function getBinaryPromise(binaryFile) {
  651. // If we don't have the binary yet, load it asynchronously using readAsync.
  652. if (!wasmBinary
  653. ) {
  654. // Fetch the binary use readAsync
  655. return new Promise((resolve, reject) => {
  656. readAsync(binaryFile,
  657. (response) => resolve(new Uint8Array(/** @type{!ArrayBuffer} */(response))),
  658. (error) => {
  659. try { resolve(getBinarySync(binaryFile)); }
  660. catch (e) { reject(e); }
  661. });
  662. });
  663. }
  664. // Otherwise, getBinarySync should be able to get it synchronously
  665. return Promise.resolve().then(() => getBinarySync(binaryFile));
  666. }
  667. function instantiateArrayBuffer(binaryFile, imports, receiver) {
  668. return getBinaryPromise(binaryFile).then((binary) => {
  669. return WebAssembly.instantiate(binary, imports);
  670. }).then(receiver, (reason) => {
  671. err(`failed to asynchronously prepare wasm: ${reason}`);
  672. // Warn on some common problems.
  673. if (isFileURI(wasmBinaryFile)) {
  674. err(`warning: Loading from a file URI (${wasmBinaryFile}) 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`);
  675. }
  676. abort(reason);
  677. });
  678. }
  679. function instantiateAsync(binary, binaryFile, imports, callback) {
  680. if (!binary &&
  681. typeof WebAssembly.instantiateStreaming == 'function' &&
  682. !isDataURI(binaryFile) &&
  683. // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously.
  684. !isFileURI(binaryFile) &&
  685. // Avoid instantiateStreaming() on Node.js environment for now, as while
  686. // Node.js v18.1.0 implements it, it does not have a full fetch()
  687. // implementation yet.
  688. //
  689. // Reference:
  690. // https://github.com/emscripten-core/emscripten/pull/16917
  691. !ENVIRONMENT_IS_NODE &&
  692. typeof fetch == 'function') {
  693. return fetch(binaryFile, { credentials: 'same-origin' }).then((response) => {
  694. // Suppress closure warning here since the upstream definition for
  695. // instantiateStreaming only allows Promise<Repsponse> rather than
  696. // an actual Response.
  697. // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed.
  698. /** @suppress {checkTypes} */
  699. var result = WebAssembly.instantiateStreaming(response, imports);
  700. return result.then(
  701. callback,
  702. function(reason) {
  703. // We expect the most common failure cause to be a bad MIME type for the binary,
  704. // in which case falling back to ArrayBuffer instantiation should work.
  705. err(`wasm streaming compile failed: ${reason}`);
  706. err('falling back to ArrayBuffer instantiation');
  707. return instantiateArrayBuffer(binaryFile, imports, callback);
  708. });
  709. });
  710. }
  711. return instantiateArrayBuffer(binaryFile, imports, callback);
  712. }
  713. function getWasmImports() {
  714. // prepare imports
  715. return {
  716. 'env': wasmImports,
  717. 'wasi_snapshot_preview1': wasmImports,
  718. }
  719. }
  720. // Create the wasm instance.
  721. // Receives the wasm imports, returns the exports.
  722. function createWasm() {
  723. var info = getWasmImports();
  724. // Load the wasm module and create an instance of using native support in the JS engine.
  725. // handle a generated wasm instance, receiving its exports and
  726. // performing other necessary setup
  727. /** @param {WebAssembly.Module=} module*/
  728. function receiveInstance(instance, module) {
  729. wasmExports = instance.exports;
  730. wasmMemory = wasmExports['memory'];
  731. assert(wasmMemory, 'memory not found in wasm exports');
  732. updateMemoryViews();
  733. wasmTable = wasmExports['__indirect_function_table'];
  734. assert(wasmTable, 'table not found in wasm exports');
  735. addOnInit(wasmExports['__wasm_call_ctors']);
  736. removeRunDependency('wasm-instantiate');
  737. return wasmExports;
  738. }
  739. // wait for the pthread pool (if any)
  740. addRunDependency('wasm-instantiate');
  741. // Prefer streaming instantiation if available.
  742. // Async compilation can be confusing when an error on the page overwrites Module
  743. // (for example, if the order of elements is wrong, and the one defining Module is
  744. // later), so we save Module and check it later.
  745. var trueModule = Module;
  746. function receiveInstantiationResult(result) {
  747. // 'result' is a ResultObject object which has both the module and instance.
  748. // receiveInstance() will swap in the exports (to Module.asm) so they can be called
  749. assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?');
  750. trueModule = null;
  751. // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.
  752. // When the regression is fixed, can restore the above PTHREADS-enabled path.
  753. receiveInstance(result['instance']);
  754. }
  755. // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
  756. // to manually instantiate the Wasm module themselves. This allows pages to
  757. // run the instantiation parallel to any other async startup actions they are
  758. // performing.
  759. // Also pthreads and wasm workers initialize the wasm instance through this
  760. // path.
  761. if (Module['instantiateWasm']) {
  762. try {
  763. return Module['instantiateWasm'](info, receiveInstance);
  764. } catch(e) {
  765. err(`Module.instantiateWasm callback failed with error: ${e}`);
  766. return false;
  767. }
  768. }
  769. if (!wasmBinaryFile) wasmBinaryFile = findWasmBinary();
  770. instantiateAsync(wasmBinary, wasmBinaryFile, info, receiveInstantiationResult);
  771. return {}; // no exports yet; we'll fill them in later
  772. }
  773. // include: runtime_debug.js
  774. function legacyModuleProp(prop, newName, incoming=true) {
  775. if (!Object.getOwnPropertyDescriptor(Module, prop)) {
  776. Object.defineProperty(Module, prop, {
  777. configurable: true,
  778. get() {
  779. let extra = incoming ? ' (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)' : '';
  780. abort(`\`Module.${prop}\` has been replaced by \`${newName}\`` + extra);
  781. }
  782. });
  783. }
  784. }
  785. function ignoredModuleProp(prop) {
  786. if (Object.getOwnPropertyDescriptor(Module, prop)) {
  787. abort(`\`Module.${prop}\` was supplied but \`${prop}\` not included in INCOMING_MODULE_JS_API`);
  788. }
  789. }
  790. // forcing the filesystem exports a few things by default
  791. function isExportedByForceFilesystem(name) {
  792. return name === 'FS_createPath' ||
  793. name === 'FS_createDataFile' ||
  794. name === 'FS_createPreloadedFile' ||
  795. name === 'FS_unlink' ||
  796. name === 'addRunDependency' ||
  797. // The old FS has some functionality that WasmFS lacks.
  798. name === 'FS_createLazyFile' ||
  799. name === 'FS_createDevice' ||
  800. name === 'removeRunDependency';
  801. }
  802. function missingGlobal(sym, msg) {
  803. if (typeof globalThis != 'undefined') {
  804. Object.defineProperty(globalThis, sym, {
  805. configurable: true,
  806. get() {
  807. warnOnce(`\`${sym}\` is not longer defined by emscripten. ${msg}`);
  808. return undefined;
  809. }
  810. });
  811. }
  812. }
  813. missingGlobal('buffer', 'Please use HEAP8.buffer or wasmMemory.buffer');
  814. missingGlobal('asm', 'Please use wasmExports instead');
  815. function missingLibrarySymbol(sym) {
  816. if (typeof globalThis != 'undefined' && !Object.getOwnPropertyDescriptor(globalThis, sym)) {
  817. Object.defineProperty(globalThis, sym, {
  818. configurable: true,
  819. get() {
  820. // Can't `abort()` here because it would break code that does runtime
  821. // checks. e.g. `if (typeof SDL === 'undefined')`.
  822. 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`;
  823. // DEFAULT_LIBRARY_FUNCS_TO_INCLUDE requires the name as it appears in
  824. // library.js, which means $name for a JS name with no prefix, or name
  825. // for a JS name like _name.
  826. var librarySymbol = sym;
  827. if (!librarySymbol.startsWith('_')) {
  828. librarySymbol = '$' + sym;
  829. }
  830. msg += ` (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='${librarySymbol}')`;
  831. if (isExportedByForceFilesystem(sym)) {
  832. msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
  833. }
  834. warnOnce(msg);
  835. return undefined;
  836. }
  837. });
  838. }
  839. // Any symbol that is not included from the JS library is also (by definition)
  840. // not exported on the Module object.
  841. unexportedRuntimeSymbol(sym);
  842. }
  843. function unexportedRuntimeSymbol(sym) {
  844. if (!Object.getOwnPropertyDescriptor(Module, sym)) {
  845. Object.defineProperty(Module, sym, {
  846. configurable: true,
  847. get() {
  848. var msg = `'${sym}' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)`;
  849. if (isExportedByForceFilesystem(sym)) {
  850. msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
  851. }
  852. abort(msg);
  853. }
  854. });
  855. }
  856. }
  857. // Used by XXXXX_DEBUG settings to output debug messages.
  858. function dbg(...args) {
  859. // TODO(sbc): Make this configurable somehow. Its not always convenient for
  860. // logging to show up as warnings.
  861. console.warn(...args);
  862. }
  863. // end include: runtime_debug.js
  864. // === Body ===
  865. var ASM_CONSTS = {
  866. 3950064: () => { document.getElementById('meg4_upload').click(); },
  867. 3950116: ($0, $1, $2, $3) => { meg4_savefile($0, $1, $2, $3); },
  868. 3950151: ($0, $1, $2, $3) => { var name = new TextDecoder("utf-8").decode(new Uint8Array(Module.HEAPU8.buffer,$0,$1)); var data = new TextDecoder("utf-8").decode(new Uint8Array(Module.HEAPU8.buffer,$2,$3)); localStorage.setItem("MEG-4/"+name, data); },
  869. 3950374: ($0, $1) => { var name = new TextDecoder("utf-8").decode(new Uint8Array(Module.HEAPU8.buffer,$0,$1)); var data = localStorage.getItem("MEG-4/"+name); if(data != undefined) { const buf = Module._malloc(data.length + 1); Module.HEAPU8.set(new TextEncoder("utf-8").encode(data + String.fromCharCode(0)), buf); return buf; } return 0; },
  870. 3950695: () => { var ln=document.location.href.split('?')[1];if(ln==undefined)ln=navigator.language.substr(0,2); return ln.charCodeAt(1) * 256 + ln.charCodeAt(0); },
  871. 3950845: () => { return Module.canvas.width; },
  872. 3950877: () => { return Module.canvas.height; },
  873. 3950910: ($0) => { var str = UTF8ToString($0) + '\n\n' + 'Abort/Retry/Ignore/AlwaysIgnore? [ariA] :'; var reply = window.prompt(str, "i"); if (reply === null) { reply = "i"; } return allocate(intArrayFromString(reply), 'i8', ALLOC_NORMAL); },
  874. 3951135: () => { if (typeof(AudioContext) !== 'undefined') { return true; } else if (typeof(webkitAudioContext) !== 'undefined') { return true; } return false; },
  875. 3951282: () => { if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) { return true; } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') { return true; } return false; },
  876. 3951516: ($0) => { if(typeof(Module['SDL2']) === 'undefined') { Module['SDL2'] = {}; } var SDL2 = Module['SDL2']; if (!$0) { SDL2.audio = {}; } else { SDL2.capture = {}; } if (!SDL2.audioContext) { if (typeof(AudioContext) !== 'undefined') { SDL2.audioContext = new AudioContext(); } else if (typeof(webkitAudioContext) !== 'undefined') { SDL2.audioContext = new webkitAudioContext(); } if (SDL2.audioContext) { autoResumeAudioContext(SDL2.audioContext); } } return SDL2.audioContext === undefined ? -1 : 0; },
  877. 3952009: () => { var SDL2 = Module['SDL2']; return SDL2.audioContext.sampleRate; },
  878. 3952077: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; var have_microphone = function(stream) { if (SDL2.capture.silenceTimer !== undefined) { clearTimeout(SDL2.capture.silenceTimer); SDL2.capture.silenceTimer = undefined; } SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream); SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1); SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) { if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; } audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0); SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode); SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination); SDL2.capture.stream = stream; }; var no_microphone = function(error) { }; SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0); var silence_callback = function() { SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.silenceTimer = setTimeout(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) { navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone); } else if (navigator.webkitGetUserMedia !== undefined) { navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone); } },
  879. 3953729: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0); SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) { if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; } SDL2.audio.currentOutputBuffer = e['outputBuffer']; dynCall('vi', $2, [$3]); }; SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']); },
  880. 3954139: ($0, $1) => { var SDL2 = Module['SDL2']; var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(c); if (channelData.length != $1) { throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } if (numChannels == 1) { for (var j = 0; j < $1; ++j) { setValue($0 + (j * 4), channelData[j], 'float'); } } else { for (var j = 0; j < $1; ++j) { setValue($0 + (((j * numChannels) + c) * 4), channelData[j], 'float'); } } } },
  881. 3954744: ($0, $1) => { var SDL2 = Module['SDL2']; var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels']; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c); if (channelData.length != $1) { throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } for (var j = 0; j < $1; ++j) { channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2]; } } },
  882. 3955224: ($0) => { var SDL2 = Module['SDL2']; if ($0) { if (SDL2.capture.silenceTimer !== undefined) { clearTimeout(SDL2.capture.silenceTimer); } if (SDL2.capture.stream !== undefined) { var tracks = SDL2.capture.stream.getAudioTracks(); for (var i = 0; i < tracks.length; i++) { SDL2.capture.stream.removeTrack(tracks[i]); } SDL2.capture.stream = undefined; } if (SDL2.capture.scriptProcessorNode !== undefined) { SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {}; SDL2.capture.scriptProcessorNode.disconnect(); SDL2.capture.scriptProcessorNode = undefined; } if (SDL2.capture.mediaStreamNode !== undefined) { SDL2.capture.mediaStreamNode.disconnect(); SDL2.capture.mediaStreamNode = undefined; } if (SDL2.capture.silenceBuffer !== undefined) { SDL2.capture.silenceBuffer = undefined } SDL2.capture = undefined; } else { if (SDL2.audio.scriptProcessorNode != undefined) { SDL2.audio.scriptProcessorNode.disconnect(); SDL2.audio.scriptProcessorNode = undefined; } SDL2.audio = undefined; } if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) { SDL2.audioContext.close(); SDL2.audioContext = undefined; } },
  883. 3956396: ($0, $1, $2) => { var w = $0; var h = $1; var pixels = $2; if (!Module['SDL2']) Module['SDL2'] = {}; var SDL2 = Module['SDL2']; if (SDL2.ctxCanvas !== Module['canvas']) { SDL2.ctx = Module['createContext'](Module['canvas'], false, true); SDL2.ctxCanvas = Module['canvas']; } if (SDL2.w !== w || SDL2.h !== h || SDL2.imageCtx !== SDL2.ctx) { SDL2.image = SDL2.ctx.createImageData(w, h); SDL2.w = w; SDL2.h = h; SDL2.imageCtx = SDL2.ctx; } var data = SDL2.image.data; var src = pixels >> 2; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = 0xff; src++; dst += 4; } } else { if (SDL2.data32Data !== data) { SDL2.data32 = new Int32Array(data.buffer); SDL2.data8 = new Uint8Array(data.buffer); SDL2.data32Data = data; } var data32 = SDL2.data32; num = data32.length; data32.set(HEAP32.subarray(src, src + num)); var data8 = SDL2.data8; var i = 3; var j = i + 4*num; if (num % 8 == 0) { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; } } else { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; } } } SDL2.ctx.putImageData(SDL2.image, 0, 0); },
  884. 3957865: ($0, $1, $2, $3, $4) => { var w = $0; var h = $1; var hot_x = $2; var hot_y = $3; var pixels = $4; var canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; var ctx = canvas.getContext("2d"); var image = ctx.createImageData(w, h); var data = image.data; var src = pixels >> 2; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = (val >> 24) & 0xff; src++; dst += 4; } } else { var data32 = new Int32Array(data.buffer); num = data32.length; data32.set(HEAP32.subarray(src, src + num)); } ctx.putImageData(image, 0, 0); var url = hot_x === 0 && hot_y === 0 ? "url(" + canvas.toDataURL() + "), auto" : "url(" + canvas.toDataURL() + ") " + hot_x + " " + hot_y + ", auto"; var urlBuf = _malloc(url.length + 1); stringToUTF8(url, urlBuf, url.length + 1); return urlBuf; },
  885. 3958854: ($0) => { if (Module['canvas']) { Module['canvas'].style['cursor'] = UTF8ToString($0); } },
  886. 3958937: () => { if (Module['canvas']) { Module['canvas'].style['cursor'] = 'none'; } },
  887. 3959006: () => { return window.innerWidth; },
  888. 3959036: () => { return window.innerHeight; }
  889. };
  890. // end include: preamble.js
  891. /** @constructor */
  892. function ExitStatus(status) {
  893. this.name = 'ExitStatus';
  894. this.message = `Program terminated with exit(${status})`;
  895. this.status = status;
  896. }
  897. var callRuntimeCallbacks = (callbacks) => {
  898. while (callbacks.length > 0) {
  899. // Pass the module as the first argument.
  900. callbacks.shift()(Module);
  901. }
  902. };
  903. /**
  904. * @param {number} ptr
  905. * @param {string} type
  906. */
  907. function getValue(ptr, type = 'i8') {
  908. if (type.endsWith('*')) type = '*';
  909. switch (type) {
  910. case 'i1': return HEAP8[ptr];
  911. case 'i8': return HEAP8[ptr];
  912. case 'i16': return HEAP16[((ptr)>>1)];
  913. case 'i32': return HEAP32[((ptr)>>2)];
  914. case 'i64': return HEAP64[((ptr)>>3)];
  915. case 'float': return HEAPF32[((ptr)>>2)];
  916. case 'double': return HEAPF64[((ptr)>>3)];
  917. case '*': return HEAPU32[((ptr)>>2)];
  918. default: abort(`invalid type for getValue: ${type}`);
  919. }
  920. }
  921. var noExitRuntime = Module['noExitRuntime'] || false;
  922. var ptrToString = (ptr) => {
  923. assert(typeof ptr === 'number');
  924. // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
  925. ptr >>>= 0;
  926. return '0x' + ptr.toString(16).padStart(8, '0');
  927. };
  928. /**
  929. * @param {number} ptr
  930. * @param {number} value
  931. * @param {string} type
  932. */
  933. function setValue(ptr, value, type = 'i8') {
  934. if (type.endsWith('*')) type = '*';
  935. switch (type) {
  936. case 'i1': HEAP8[ptr] = value; break;
  937. case 'i8': HEAP8[ptr] = value; break;
  938. case 'i16': HEAP16[((ptr)>>1)] = value; break;
  939. case 'i32': HEAP32[((ptr)>>2)] = value; break;
  940. case 'i64': HEAP64[((ptr)>>3)] = BigInt(value); break;
  941. case 'float': HEAPF32[((ptr)>>2)] = value; break;
  942. case 'double': HEAPF64[((ptr)>>3)] = value; break;
  943. case '*': HEAPU32[((ptr)>>2)] = value; break;
  944. default: abort(`invalid type for setValue: ${type}`);
  945. }
  946. }
  947. var stackRestore = (val) => __emscripten_stack_restore(val);
  948. var stackSave = () => _emscripten_stack_get_current();
  949. var warnOnce = (text) => {
  950. warnOnce.shown ||= {};
  951. if (!warnOnce.shown[text]) {
  952. warnOnce.shown[text] = 1;
  953. if (ENVIRONMENT_IS_NODE) text = 'warning: ' + text;
  954. err(text);
  955. }
  956. };
  957. /** @suppress {duplicate } */
  958. function syscallGetVarargI() {
  959. assert(SYSCALLS.varargs != undefined);
  960. // the `+` prepended here is necessary to convince the JSCompiler that varargs is indeed a number.
  961. var ret = HEAP32[((+SYSCALLS.varargs)>>2)];
  962. SYSCALLS.varargs += 4;
  963. return ret;
  964. }
  965. var syscallGetVarargP = syscallGetVarargI;
  966. var PATH = {
  967. isAbs:(path) => path.charAt(0) === '/',
  968. splitPath:(filename) => {
  969. var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
  970. return splitPathRe.exec(filename).slice(1);
  971. },
  972. normalizeArray:(parts, allowAboveRoot) => {
  973. // if the path tries to go above the root, `up` ends up > 0
  974. var up = 0;
  975. for (var i = parts.length - 1; i >= 0; i--) {
  976. var last = parts[i];
  977. if (last === '.') {
  978. parts.splice(i, 1);
  979. } else if (last === '..') {
  980. parts.splice(i, 1);
  981. up++;
  982. } else if (up) {
  983. parts.splice(i, 1);
  984. up--;
  985. }
  986. }
  987. // if the path is allowed to go above the root, restore leading ..s
  988. if (allowAboveRoot) {
  989. for (; up; up--) {
  990. parts.unshift('..');
  991. }
  992. }
  993. return parts;
  994. },
  995. normalize:(path) => {
  996. var isAbsolute = PATH.isAbs(path),
  997. trailingSlash = path.substr(-1) === '/';
  998. // Normalize the path
  999. path = PATH.normalizeArray(path.split('/').filter((p) => !!p), !isAbsolute).join('/');
  1000. if (!path && !isAbsolute) {
  1001. path = '.';
  1002. }
  1003. if (path && trailingSlash) {
  1004. path += '/';
  1005. }
  1006. return (isAbsolute ? '/' : '') + path;
  1007. },
  1008. dirname:(path) => {
  1009. var result = PATH.splitPath(path),
  1010. root = result[0],
  1011. dir = result[1];
  1012. if (!root && !dir) {
  1013. // No dirname whatsoever
  1014. return '.';
  1015. }
  1016. if (dir) {
  1017. // It has a dirname, strip trailing slash
  1018. dir = dir.substr(0, dir.length - 1);
  1019. }
  1020. return root + dir;
  1021. },
  1022. basename:(path) => {
  1023. // EMSCRIPTEN return '/'' for '/', not an empty string
  1024. if (path === '/') return '/';
  1025. path = PATH.normalize(path);
  1026. path = path.replace(/\/$/, "");
  1027. var lastSlash = path.lastIndexOf('/');
  1028. if (lastSlash === -1) return path;
  1029. return path.substr(lastSlash+1);
  1030. },
  1031. join:(...paths) => PATH.normalize(paths.join('/')),
  1032. join2:(l, r) => PATH.normalize(l + '/' + r),
  1033. };
  1034. var initRandomFill = () => {
  1035. if (typeof crypto == 'object' && typeof crypto['getRandomValues'] == 'function') {
  1036. // for modern web browsers
  1037. return (view) => crypto.getRandomValues(view);
  1038. } else
  1039. if (ENVIRONMENT_IS_NODE) {
  1040. // for nodejs with or without crypto support included
  1041. try {
  1042. var crypto_module = require('crypto');
  1043. var randomFillSync = crypto_module['randomFillSync'];
  1044. if (randomFillSync) {
  1045. // nodejs with LTS crypto support
  1046. return (view) => crypto_module['randomFillSync'](view);
  1047. }
  1048. // very old nodejs with the original crypto API
  1049. var randomBytes = crypto_module['randomBytes'];
  1050. return (view) => (
  1051. view.set(randomBytes(view.byteLength)),
  1052. // Return the original view to match modern native implementations.
  1053. view
  1054. );
  1055. } catch (e) {
  1056. // nodejs doesn't have crypto support
  1057. }
  1058. }
  1059. // we couldn't find a proper implementation, as Math.random() is not suitable for /dev/random, see emscripten-core/emscripten/pull/7096
  1060. abort('no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: (array) => { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };');
  1061. };
  1062. var randomFill = (view) => {
  1063. // Lazily init on the first invocation.
  1064. return (randomFill = initRandomFill())(view);
  1065. };
  1066. var PATH_FS = {
  1067. resolve:(...args) => {
  1068. var resolvedPath = '',
  1069. resolvedAbsolute = false;
  1070. for (var i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
  1071. var path = (i >= 0) ? args[i] : FS.cwd();
  1072. // Skip empty and invalid entries
  1073. if (typeof path != 'string') {
  1074. throw new TypeError('Arguments to path.resolve must be strings');
  1075. } else if (!path) {
  1076. return ''; // an invalid portion invalidates the whole thing
  1077. }
  1078. resolvedPath = path + '/' + resolvedPath;
  1079. resolvedAbsolute = PATH.isAbs(path);
  1080. }
  1081. // At this point the path should be resolved to a full absolute path, but
  1082. // handle relative paths to be safe (might happen when process.cwd() fails)
  1083. resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter((p) => !!p), !resolvedAbsolute).join('/');
  1084. return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
  1085. },
  1086. relative:(from, to) => {
  1087. from = PATH_FS.resolve(from).substr(1);
  1088. to = PATH_FS.resolve(to).substr(1);
  1089. function trim(arr) {
  1090. var start = 0;
  1091. for (; start < arr.length; start++) {
  1092. if (arr[start] !== '') break;
  1093. }
  1094. var end = arr.length - 1;
  1095. for (; end >= 0; end--) {
  1096. if (arr[end] !== '') break;
  1097. }
  1098. if (start > end) return [];
  1099. return arr.slice(start, end - start + 1);
  1100. }
  1101. var fromParts = trim(from.split('/'));
  1102. var toParts = trim(to.split('/'));
  1103. var length = Math.min(fromParts.length, toParts.length);
  1104. var samePartsLength = length;
  1105. for (var i = 0; i < length; i++) {
  1106. if (fromParts[i] !== toParts[i]) {
  1107. samePartsLength = i;
  1108. break;
  1109. }
  1110. }
  1111. var outputParts = [];
  1112. for (var i = samePartsLength; i < fromParts.length; i++) {
  1113. outputParts.push('..');
  1114. }
  1115. outputParts = outputParts.concat(toParts.slice(samePartsLength));
  1116. return outputParts.join('/');
  1117. },
  1118. };
  1119. var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined;
  1120. /**
  1121. * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given
  1122. * array that contains uint8 values, returns a copy of that string as a
  1123. * Javascript String object.
  1124. * heapOrArray is either a regular array, or a JavaScript typed array view.
  1125. * @param {number} idx
  1126. * @param {number=} maxBytesToRead
  1127. * @return {string}
  1128. */
  1129. var UTF8ArrayToString = (heapOrArray, idx, maxBytesToRead) => {
  1130. var endIdx = idx + maxBytesToRead;
  1131. var endPtr = idx;
  1132. // TextDecoder needs to know the byte length in advance, it doesn't stop on
  1133. // null terminator by itself. Also, use the length info to avoid running tiny
  1134. // strings through TextDecoder, since .subarray() allocates garbage.
  1135. // (As a tiny code save trick, compare endPtr against endIdx using a negation,
  1136. // so that undefined means Infinity)
  1137. while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;
  1138. if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
  1139. return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
  1140. }
  1141. var str = '';
  1142. // If building with TextDecoder, we have already computed the string length
  1143. // above, so test loop end condition against that
  1144. while (idx < endPtr) {
  1145. // For UTF8 byte structure, see:
  1146. // http://en.wikipedia.org/wiki/UTF-8#Description
  1147. // https://www.ietf.org/rfc/rfc2279.txt
  1148. // https://tools.ietf.org/html/rfc3629
  1149. var u0 = heapOrArray[idx++];
  1150. if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
  1151. var u1 = heapOrArray[idx++] & 63;
  1152. if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
  1153. var u2 = heapOrArray[idx++] & 63;
  1154. if ((u0 & 0xF0) == 0xE0) {
  1155. u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
  1156. } else {
  1157. if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte ' + ptrToString(u0) + ' encountered when deserializing a UTF-8 string in wasm memory to a JS string!');
  1158. u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);
  1159. }
  1160. if (u0 < 0x10000) {
  1161. str += String.fromCharCode(u0);
  1162. } else {
  1163. var ch = u0 - 0x10000;
  1164. str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
  1165. }
  1166. }
  1167. return str;
  1168. };
  1169. var FS_stdin_getChar_buffer = [];
  1170. var lengthBytesUTF8 = (str) => {
  1171. var len = 0;
  1172. for (var i = 0; i < str.length; ++i) {
  1173. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
  1174. // unit, not a Unicode code point of the character! So decode
  1175. // UTF16->UTF32->UTF8.
  1176. // See http://unicode.org/faq/utf_bom.html#utf16-3
  1177. var c = str.charCodeAt(i); // possibly a lead surrogate
  1178. if (c <= 0x7F) {
  1179. len++;
  1180. } else if (c <= 0x7FF) {
  1181. len += 2;
  1182. } else if (c >= 0xD800 && c <= 0xDFFF) {
  1183. len += 4; ++i;
  1184. } else {
  1185. len += 3;
  1186. }
  1187. }
  1188. return len;
  1189. };
  1190. var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
  1191. assert(typeof str === 'string', `stringToUTF8Array expects a string (got ${typeof str})`);
  1192. // Parameter maxBytesToWrite is not optional. Negative values, 0, null,
  1193. // undefined and false each don't write out any bytes.
  1194. if (!(maxBytesToWrite > 0))
  1195. return 0;
  1196. var startIdx = outIdx;
  1197. var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
  1198. for (var i = 0; i < str.length; ++i) {
  1199. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
  1200. // unit, not a Unicode code point of the character! So decode
  1201. // UTF16->UTF32->UTF8.
  1202. // See http://unicode.org/faq/utf_bom.html#utf16-3
  1203. // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description
  1204. // and https://www.ietf.org/rfc/rfc2279.txt
  1205. // and https://tools.ietf.org/html/rfc3629
  1206. var u = str.charCodeAt(i); // possibly a lead surrogate
  1207. if (u >= 0xD800 && u <= 0xDFFF) {
  1208. var u1 = str.charCodeAt(++i);
  1209. u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF);
  1210. }
  1211. if (u <= 0x7F) {
  1212. if (outIdx >= endIdx) break;
  1213. heap[outIdx++] = u;
  1214. } else if (u <= 0x7FF) {
  1215. if (outIdx + 1 >= endIdx) break;
  1216. heap[outIdx++] = 0xC0 | (u >> 6);
  1217. heap[outIdx++] = 0x80 | (u & 63);
  1218. } else if (u <= 0xFFFF) {
  1219. if (outIdx + 2 >= endIdx) break;
  1220. heap[outIdx++] = 0xE0 | (u >> 12);
  1221. heap[outIdx++] = 0x80 | ((u >> 6) & 63);
  1222. heap[outIdx++] = 0x80 | (u & 63);
  1223. } else {
  1224. if (outIdx + 3 >= endIdx) break;
  1225. if (u > 0x10FFFF) 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).');
  1226. heap[outIdx++] = 0xF0 | (u >> 18);
  1227. heap[outIdx++] = 0x80 | ((u >> 12) & 63);
  1228. heap[outIdx++] = 0x80 | ((u >> 6) & 63);
  1229. heap[outIdx++] = 0x80 | (u & 63);
  1230. }
  1231. }
  1232. // Null-terminate the pointer to the buffer.
  1233. heap[outIdx] = 0;
  1234. return outIdx - startIdx;
  1235. };
  1236. /** @type {function(string, boolean=, number=)} */
  1237. function intArrayFromString(stringy, dontAddNull, length) {
  1238. var len = length > 0 ? length : lengthBytesUTF8(stringy)+1;
  1239. var u8array = new Array(len);
  1240. var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
  1241. if (dontAddNull) u8array.length = numBytesWritten;
  1242. return u8array;
  1243. }
  1244. var FS_stdin_getChar = () => {
  1245. if (!FS_stdin_getChar_buffer.length) {
  1246. var result = null;
  1247. if (ENVIRONMENT_IS_NODE) {
  1248. // we will read data by chunks of BUFSIZE
  1249. var BUFSIZE = 256;
  1250. var buf = Buffer.alloc(BUFSIZE);
  1251. var bytesRead = 0;
  1252. // For some reason we must suppress a closure warning here, even though
  1253. // fd definitely exists on process.stdin, and is even the proper way to
  1254. // get the fd of stdin,
  1255. // https://github.com/nodejs/help/issues/2136#issuecomment-523649904
  1256. // This started to happen after moving this logic out of library_tty.js,
  1257. // so it is related to the surrounding code in some unclear manner.
  1258. /** @suppress {missingProperties} */
  1259. var fd = process.stdin.fd;
  1260. try {
  1261. bytesRead = fs.readSync(fd, buf, 0, BUFSIZE);
  1262. } catch(e) {
  1263. // Cross-platform differences: on Windows, reading EOF throws an
  1264. // exception, but on other OSes, reading EOF returns 0. Uniformize
  1265. // behavior by treating the EOF exception to return 0.
  1266. if (e.toString().includes('EOF')) bytesRead = 0;
  1267. else throw e;
  1268. }
  1269. if (bytesRead > 0) {
  1270. result = buf.slice(0, bytesRead).toString('utf-8');
  1271. }
  1272. } else
  1273. if (typeof window != 'undefined' &&
  1274. typeof window.prompt == 'function') {
  1275. // Browser.
  1276. result = window.prompt('Input: '); // returns null on cancel
  1277. if (result !== null) {
  1278. result += '\n';
  1279. }
  1280. } else
  1281. {}
  1282. if (!result) {
  1283. return null;
  1284. }
  1285. FS_stdin_getChar_buffer = intArrayFromString(result, true);
  1286. }
  1287. return FS_stdin_getChar_buffer.shift();
  1288. };
  1289. var TTY = {
  1290. ttys:[],
  1291. init() {
  1292. // https://github.com/emscripten-core/emscripten/pull/1555
  1293. // if (ENVIRONMENT_IS_NODE) {
  1294. // // currently, FS.init does not distinguish if process.stdin is a file or TTY
  1295. // // device, it always assumes it's a TTY device. because of this, we're forcing
  1296. // // process.stdin to UTF8 encoding to at least make stdin reading compatible
  1297. // // with text files until FS.init can be refactored.
  1298. // process.stdin.setEncoding('utf8');
  1299. // }
  1300. },
  1301. shutdown() {
  1302. // https://github.com/emscripten-core/emscripten/pull/1555
  1303. // if (ENVIRONMENT_IS_NODE) {
  1304. // // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
  1305. // // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
  1306. // // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
  1307. // // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
  1308. // // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
  1309. // process.stdin.pause();
  1310. // }
  1311. },
  1312. register(dev, ops) {
  1313. TTY.ttys[dev] = { input: [], output: [], ops: ops };
  1314. FS.registerDevice(dev, TTY.stream_ops);
  1315. },
  1316. stream_ops:{
  1317. open(stream) {
  1318. var tty = TTY.ttys[stream.node.rdev];
  1319. if (!tty) {
  1320. throw new FS.ErrnoError(43);
  1321. }
  1322. stream.tty = tty;
  1323. stream.seekable = false;
  1324. },
  1325. close(stream) {
  1326. // flush any pending line data
  1327. stream.tty.ops.fsync(stream.tty);
  1328. },
  1329. fsync(stream) {
  1330. stream.tty.ops.fsync(stream.tty);
  1331. },
  1332. read(stream, buffer, offset, length, pos /* ignored */) {
  1333. if (!stream.tty || !stream.tty.ops.get_char) {
  1334. throw new FS.ErrnoError(60);
  1335. }
  1336. var bytesRead = 0;
  1337. for (var i = 0; i < length; i++) {
  1338. var result;
  1339. try {
  1340. result = stream.tty.ops.get_char(stream.tty);
  1341. } catch (e) {
  1342. throw new FS.ErrnoError(29);
  1343. }
  1344. if (result === undefined && bytesRead === 0) {
  1345. throw new FS.ErrnoError(6);
  1346. }
  1347. if (result === null || result === undefined) break;
  1348. bytesRead++;
  1349. buffer[offset+i] = result;
  1350. }
  1351. if (bytesRead) {
  1352. stream.node.timestamp = Date.now();
  1353. }
  1354. return bytesRead;
  1355. },
  1356. write(stream, buffer, offset, length, pos) {
  1357. if (!stream.tty || !stream.tty.ops.put_char) {
  1358. throw new FS.ErrnoError(60);
  1359. }
  1360. try {
  1361. for (var i = 0; i < length; i++) {
  1362. stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
  1363. }
  1364. } catch (e) {
  1365. throw new FS.ErrnoError(29);
  1366. }
  1367. if (length) {
  1368. stream.node.timestamp = Date.now();
  1369. }
  1370. return i;
  1371. },
  1372. },
  1373. default_tty_ops:{
  1374. get_char(tty) {
  1375. return FS_stdin_getChar();
  1376. },
  1377. put_char(tty, val) {
  1378. if (val === null || val === 10) {
  1379. out(UTF8ArrayToString(tty.output, 0));
  1380. tty.output = [];
  1381. } else {
  1382. if (val != 0) tty.output.push(val); // val == 0 would cut text output off in the middle.
  1383. }
  1384. },
  1385. fsync(tty) {
  1386. if (tty.output && tty.output.length > 0) {
  1387. out(UTF8ArrayToString(tty.output, 0));
  1388. tty.output = [];
  1389. }
  1390. },
  1391. ioctl_tcgets(tty) {
  1392. // typical setting
  1393. return {
  1394. c_iflag: 25856,
  1395. c_oflag: 5,
  1396. c_cflag: 191,
  1397. c_lflag: 35387,
  1398. c_cc: [
  1399. 0x03, 0x1c, 0x7f, 0x15, 0x04, 0x00, 0x01, 0x00, 0x11, 0x13, 0x1a, 0x00,
  1400. 0x12, 0x0f, 0x17, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1401. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1402. ]
  1403. };
  1404. },
  1405. ioctl_tcsets(tty, optional_actions, data) {
  1406. // currently just ignore
  1407. return 0;
  1408. },
  1409. ioctl_tiocgwinsz(tty) {
  1410. return [24, 80];
  1411. },
  1412. },
  1413. default_tty1_ops:{
  1414. put_char(tty, val) {
  1415. if (val === null || val === 10) {
  1416. err(UTF8ArrayToString(tty.output, 0));
  1417. tty.output = [];
  1418. } else {
  1419. if (val != 0) tty.output.push(val);
  1420. }
  1421. },
  1422. fsync(tty) {
  1423. if (tty.output && tty.output.length > 0) {
  1424. err(UTF8ArrayToString(tty.output, 0));
  1425. tty.output = [];
  1426. }
  1427. },
  1428. },
  1429. };
  1430. var zeroMemory = (address, size) => {
  1431. HEAPU8.fill(0, address, address + size);
  1432. return address;
  1433. };
  1434. var alignMemory = (size, alignment) => {
  1435. assert(alignment, "alignment argument is required");
  1436. return Math.ceil(size / alignment) * alignment;
  1437. };
  1438. var mmapAlloc = (size) => {
  1439. abort('internal error: mmapAlloc called but `emscripten_builtin_memalign` native symbol not exported');
  1440. };
  1441. var MEMFS = {
  1442. ops_table:null,
  1443. mount(mount) {
  1444. return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
  1445. },
  1446. createNode(parent, name, mode, dev) {
  1447. if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
  1448. // no supported
  1449. throw new FS.ErrnoError(63);
  1450. }
  1451. MEMFS.ops_table ||= {
  1452. dir: {
  1453. node: {
  1454. getattr: MEMFS.node_ops.getattr,
  1455. setattr: MEMFS.node_ops.setattr,
  1456. lookup: MEMFS.node_ops.lookup,
  1457. mknod: MEMFS.node_ops.mknod,
  1458. rename: MEMFS.node_ops.rename,
  1459. unlink: MEMFS.node_ops.unlink,
  1460. rmdir: MEMFS.node_ops.rmdir,
  1461. readdir: MEMFS.node_ops.readdir,
  1462. symlink: MEMFS.node_ops.symlink
  1463. },
  1464. stream: {
  1465. llseek: MEMFS.stream_ops.llseek
  1466. }
  1467. },
  1468. file: {
  1469. node: {
  1470. getattr: MEMFS.node_ops.getattr,
  1471. setattr: MEMFS.node_ops.setattr
  1472. },
  1473. stream: {
  1474. llseek: MEMFS.stream_ops.llseek,
  1475. read: MEMFS.stream_ops.read,
  1476. write: MEMFS.stream_ops.write,
  1477. allocate: MEMFS.stream_ops.allocate,
  1478. mmap: MEMFS.stream_ops.mmap,
  1479. msync: MEMFS.stream_ops.msync
  1480. }
  1481. },
  1482. link: {
  1483. node: {
  1484. getattr: MEMFS.node_ops.getattr,
  1485. setattr: MEMFS.node_ops.setattr,
  1486. readlink: MEMFS.node_ops.readlink
  1487. },
  1488. stream: {}
  1489. },
  1490. chrdev: {
  1491. node: {
  1492. getattr: MEMFS.node_ops.getattr,
  1493. setattr: MEMFS.node_ops.setattr
  1494. },
  1495. stream: FS.chrdev_stream_ops
  1496. }
  1497. };
  1498. var node = FS.createNode(parent, name, mode, dev);
  1499. if (FS.isDir(node.mode)) {
  1500. node.node_ops = MEMFS.ops_table.dir.node;
  1501. node.stream_ops = MEMFS.ops_table.dir.stream;
  1502. node.contents = {};
  1503. } else if (FS.isFile(node.mode)) {
  1504. node.node_ops = MEMFS.ops_table.file.node;
  1505. node.stream_ops = MEMFS.ops_table.file.stream;
  1506. node.usedBytes = 0; // The actual number of bytes used in the typed array, as opposed to contents.length which gives the whole capacity.
  1507. // When the byte data of the file is populated, this will point to either a typed array, or a normal JS array. Typed arrays are preferred
  1508. // for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size
  1509. // penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme.
  1510. node.contents = null;
  1511. } else if (FS.isLink(node.mode)) {
  1512. node.node_ops = MEMFS.ops_table.link.node;
  1513. node.stream_ops = MEMFS.ops_table.link.stream;
  1514. } else if (FS.isChrdev(node.mode)) {
  1515. node.node_ops = MEMFS.ops_table.chrdev.node;
  1516. node.stream_ops = MEMFS.ops_table.chrdev.stream;
  1517. }
  1518. node.timestamp = Date.now();
  1519. // add the new node to the parent
  1520. if (parent) {
  1521. parent.contents[name] = node;
  1522. parent.timestamp = node.timestamp;
  1523. }
  1524. return node;
  1525. },
  1526. getFileDataAsTypedArray(node) {
  1527. if (!node.contents) return new Uint8Array(0);
  1528. if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
  1529. return new Uint8Array(node.contents);
  1530. },
  1531. expandFileStorage(node, newCapacity) {
  1532. var prevCapacity = node.contents ? node.contents.length : 0;
  1533. if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.
  1534. // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.
  1535. // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to
  1536. // avoid overshooting the allocation cap by a very large margin.
  1537. var CAPACITY_DOUBLING_MAX = 1024 * 1024;
  1538. newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>> 0);
  1539. if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
  1540. var oldContents = node.contents;
  1541. node.contents = new Uint8Array(newCapacity); // Allocate new storage.
  1542. if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); // Copy old data over to the new storage.
  1543. },
  1544. resizeFileStorage(node, newSize) {
  1545. if (node.usedBytes == newSize) return;
  1546. if (newSize == 0) {
  1547. node.contents = null; // Fully decommit when requesting a resize to zero.
  1548. node.usedBytes = 0;
  1549. } else {
  1550. var oldContents = node.contents;
  1551. node.contents = new Uint8Array(newSize); // Allocate new storage.
  1552. if (oldContents) {
  1553. node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
  1554. }
  1555. node.usedBytes = newSize;
  1556. }
  1557. },
  1558. node_ops:{
  1559. getattr(node) {
  1560. var attr = {};
  1561. // device numbers reuse inode numbers.
  1562. attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
  1563. attr.ino = node.id;
  1564. attr.mode = node.mode;
  1565. attr.nlink = 1;
  1566. attr.uid = 0;
  1567. attr.gid = 0;
  1568. attr.rdev = node.rdev;
  1569. if (FS.isDir(node.mode)) {
  1570. attr.size = 4096;
  1571. } else if (FS.isFile(node.mode)) {
  1572. attr.size = node.usedBytes;
  1573. } else if (FS.isLink(node.mode)) {
  1574. attr.size = node.link.length;
  1575. } else {
  1576. attr.size = 0;
  1577. }
  1578. attr.atime = new Date(node.timestamp);
  1579. attr.mtime = new Date(node.timestamp);
  1580. attr.ctime = new Date(node.timestamp);
  1581. // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
  1582. // but this is not required by the standard.
  1583. attr.blksize = 4096;
  1584. attr.blocks = Math.ceil(attr.size / attr.blksize);
  1585. return attr;
  1586. },
  1587. setattr(node, attr) {
  1588. if (attr.mode !== undefined) {
  1589. node.mode = attr.mode;
  1590. }
  1591. if (attr.timestamp !== undefined) {
  1592. node.timestamp = attr.timestamp;
  1593. }
  1594. if (attr.size !== undefined) {
  1595. MEMFS.resizeFileStorage(node, attr.size);
  1596. }
  1597. },
  1598. lookup(parent, name) {
  1599. throw FS.genericErrors[44];
  1600. },
  1601. mknod(parent, name, mode, dev) {
  1602. return MEMFS.createNode(parent, name, mode, dev);
  1603. },
  1604. rename(old_node, new_dir, new_name) {
  1605. // if we're overwriting a directory at new_name, make sure it's empty.
  1606. if (FS.isDir(old_node.mode)) {
  1607. var new_node;
  1608. try {
  1609. new_node = FS.lookupNode(new_dir, new_name);
  1610. } catch (e) {
  1611. }
  1612. if (new_node) {
  1613. for (var i in new_node.contents) {
  1614. throw new FS.ErrnoError(55);
  1615. }
  1616. }
  1617. }
  1618. // do the internal rewiring
  1619. delete old_node.parent.contents[old_node.name];
  1620. old_node.parent.timestamp = Date.now()
  1621. old_node.name = new_name;
  1622. new_dir.contents[new_name] = old_node;
  1623. new_dir.timestamp = old_node.parent.timestamp;
  1624. },
  1625. unlink(parent, name) {
  1626. delete parent.contents[name];
  1627. parent.timestamp = Date.now();
  1628. },
  1629. rmdir(parent, name) {
  1630. var node = FS.lookupNode(parent, name);
  1631. for (var i in node.contents) {
  1632. throw new FS.ErrnoError(55);
  1633. }
  1634. delete parent.contents[name];
  1635. parent.timestamp = Date.now();
  1636. },
  1637. readdir(node) {
  1638. var entries = ['.', '..'];
  1639. for (var key of Object.keys(node.contents)) {
  1640. entries.push(key);
  1641. }
  1642. return entries;
  1643. },
  1644. symlink(parent, newname, oldpath) {
  1645. var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
  1646. node.link = oldpath;
  1647. return node;
  1648. },
  1649. readlink(node) {
  1650. if (!FS.isLink(node.mode)) {
  1651. throw new FS.ErrnoError(28);
  1652. }
  1653. return node.link;
  1654. },
  1655. },
  1656. stream_ops:{
  1657. read(stream, buffer, offset, length, position) {
  1658. var contents = stream.node.contents;
  1659. if (position >= stream.node.usedBytes) return 0;
  1660. var size = Math.min(stream.node.usedBytes - position, length);
  1661. assert(size >= 0);
  1662. if (size > 8 && contents.subarray) { // non-trivial, and typed array
  1663. buffer.set(contents.subarray(position, position + size), offset);
  1664. } else {
  1665. for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
  1666. }
  1667. return size;
  1668. },
  1669. write(stream, buffer, offset, length, position, canOwn) {
  1670. // The data buffer should be a typed array view
  1671. assert(!(buffer instanceof ArrayBuffer));
  1672. // If the buffer is located in main memory (HEAP), and if
  1673. // memory can grow, we can't hold on to references of the
  1674. // memory buffer, as they may get invalidated. That means we
  1675. // need to do copy its contents.
  1676. if (buffer.buffer === HEAP8.buffer) {
  1677. canOwn = false;
  1678. }
  1679. if (!length) return 0;
  1680. var node = stream.node;
  1681. node.timestamp = Date.now();
  1682. if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array?
  1683. if (canOwn) {
  1684. assert(position === 0, 'canOwn must imply no weird position inside the file');
  1685. node.contents = buffer.subarray(offset, offset + length);
  1686. node.usedBytes = length;
  1687. return length;
  1688. } else if (node.usedBytes === 0 && position === 0) { // 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.
  1689. node.contents = buffer.slice(offset, offset + length);
  1690. node.usedBytes = length;
  1691. return length;
  1692. } else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file?
  1693. node.contents.set(buffer.subarray(offset, offset + length), position);
  1694. return length;
  1695. }
  1696. }
  1697. // Appending to an existing file and we need to reallocate, or source data did not come as a typed array.
  1698. MEMFS.expandFileStorage(node, position+length);
  1699. if (node.contents.subarray && buffer.subarray) {
  1700. // Use typed array write which is available.
  1701. node.contents.set(buffer.subarray(offset, offset + length), position);
  1702. } else {
  1703. for (var i = 0; i < length; i++) {
  1704. node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not.
  1705. }
  1706. }
  1707. node.usedBytes = Math.max(node.usedBytes, position + length);
  1708. return length;
  1709. },
  1710. llseek(stream, offset, whence) {
  1711. var position = offset;
  1712. if (whence === 1) {
  1713. position += stream.position;
  1714. } else if (whence === 2) {
  1715. if (FS.isFile(stream.node.mode)) {
  1716. position += stream.node.usedBytes;
  1717. }
  1718. }
  1719. if (position < 0) {
  1720. throw new FS.ErrnoError(28);
  1721. }
  1722. return position;
  1723. },
  1724. allocate(stream, offset, length) {
  1725. MEMFS.expandFileStorage(stream.node, offset + length);
  1726. stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length);
  1727. },
  1728. mmap(stream, length, position, prot, flags) {
  1729. if (!FS.isFile(stream.node.mode)) {
  1730. throw new FS.ErrnoError(43);
  1731. }
  1732. var ptr;
  1733. var allocated;
  1734. var contents = stream.node.contents;
  1735. // Only make a new copy when MAP_PRIVATE is specified.
  1736. if (!(flags & 2) && contents.buffer === HEAP8.buffer) {
  1737. // We can't emulate MAP_SHARED when the file is not backed by the
  1738. // buffer we're mapping to (e.g. the HEAP buffer).
  1739. allocated = false;
  1740. ptr = contents.byteOffset;
  1741. } else {
  1742. // Try to avoid unnecessary slices.
  1743. if (position > 0 || position + length < contents.length) {
  1744. if (contents.subarray) {
  1745. contents = contents.subarray(position, position + length);
  1746. } else {
  1747. contents = Array.prototype.slice.call(contents, position, position + length);
  1748. }
  1749. }
  1750. allocated = true;
  1751. ptr = mmapAlloc(length);
  1752. if (!ptr) {
  1753. throw new FS.ErrnoError(48);
  1754. }
  1755. HEAP8.set(contents, ptr);
  1756. }
  1757. return { ptr, allocated };
  1758. },
  1759. msync(stream, buffer, offset, length, mmapFlags) {
  1760. MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
  1761. // should we check if bytesWritten and length are the same?
  1762. return 0;
  1763. },
  1764. },
  1765. };
  1766. /** @param {boolean=} noRunDep */
  1767. var asyncLoad = (url, onload, onerror, noRunDep) => {
  1768. var dep = !noRunDep ? getUniqueRunDependency(`al ${url}`) : '';
  1769. readAsync(url, (arrayBuffer) => {
  1770. assert(arrayBuffer, `Loading data file "${url}" failed (no arrayBuffer).`);
  1771. onload(new Uint8Array(arrayBuffer));
  1772. if (dep) removeRunDependency(dep);
  1773. }, (event) => {
  1774. if (onerror) {
  1775. onerror();
  1776. } else {
  1777. throw `Loading data file "${url}" failed.`;
  1778. }
  1779. });
  1780. if (dep) addRunDependency(dep);
  1781. };
  1782. var FS_createDataFile = (parent, name, fileData, canRead, canWrite, canOwn) => {
  1783. FS.createDataFile(parent, name, fileData, canRead, canWrite, canOwn);
  1784. };
  1785. var preloadPlugins = Module['preloadPlugins'] || [];
  1786. var FS_handledByPreloadPlugin = (byteArray, fullname, finish, onerror) => {
  1787. // Ensure plugins are ready.
  1788. if (typeof Browser != 'undefined') Browser.init();
  1789. var handled = false;
  1790. preloadPlugins.forEach((plugin) => {
  1791. if (handled) return;
  1792. if (plugin['canHandle'](fullname)) {
  1793. plugin['handle'](byteArray, fullname, finish, onerror);
  1794. handled = true;
  1795. }
  1796. });
  1797. return handled;
  1798. };
  1799. var FS_createPreloadedFile = (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => {
  1800. // TODO we should allow people to just pass in a complete filename instead
  1801. // of parent and name being that we just join them anyways
  1802. var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
  1803. var dep = getUniqueRunDependency(`cp ${fullname}`); // might have several active requests for the same fullname
  1804. function processData(byteArray) {
  1805. function finish(byteArray) {
  1806. preFinish?.();
  1807. if (!dontCreateFile) {
  1808. FS_createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
  1809. }
  1810. onload?.();
  1811. removeRunDependency(dep);
  1812. }
  1813. if (FS_handledByPreloadPlugin(byteArray, fullname, finish, () => {
  1814. onerror?.();
  1815. removeRunDependency(dep);
  1816. })) {
  1817. return;
  1818. }
  1819. finish(byteArray);
  1820. }
  1821. addRunDependency(dep);
  1822. if (typeof url == 'string') {
  1823. asyncLoad(url, processData, onerror);
  1824. } else {
  1825. processData(url);
  1826. }
  1827. };
  1828. var FS_modeStringToFlags = (str) => {
  1829. var flagModes = {
  1830. 'r': 0,
  1831. 'r+': 2,
  1832. 'w': 512 | 64 | 1,
  1833. 'w+': 512 | 64 | 2,
  1834. 'a': 1024 | 64 | 1,
  1835. 'a+': 1024 | 64 | 2,
  1836. };
  1837. var flags = flagModes[str];
  1838. if (typeof flags == 'undefined') {
  1839. throw new Error(`Unknown file open mode: ${str}`);
  1840. }
  1841. return flags;
  1842. };
  1843. var FS_getMode = (canRead, canWrite) => {
  1844. var mode = 0;
  1845. if (canRead) mode |= 292 | 73;
  1846. if (canWrite) mode |= 146;
  1847. return mode;
  1848. };
  1849. var ERRNO_MESSAGES = {
  1850. 0:"Success",
  1851. 1:"Arg list too long",
  1852. 2:"Permission denied",
  1853. 3:"Address already in use",
  1854. 4:"Address not available",
  1855. 5:"Address family not supported by protocol family",
  1856. 6:"No more processes",
  1857. 7:"Socket already connected",
  1858. 8:"Bad file number",
  1859. 9:"Trying to read unreadable message",
  1860. 10:"Mount device busy",
  1861. 11:"Operation canceled",
  1862. 12:"No children",
  1863. 13:"Connection aborted",
  1864. 14:"Connection refused",
  1865. 15:"Connection reset by peer",
  1866. 16:"File locking deadlock error",
  1867. 17:"Destination address required",
  1868. 18:"Math arg out of domain of func",
  1869. 19:"Quota exceeded",
  1870. 20:"File exists",
  1871. 21:"Bad address",
  1872. 22:"File too large",
  1873. 23:"Host is unreachable",
  1874. 24:"Identifier removed",
  1875. 25:"Illegal byte sequence",
  1876. 26:"Connection already in progress",
  1877. 27:"Interrupted system call",
  1878. 28:"Invalid argument",
  1879. 29:"I/O error",
  1880. 30:"Socket is already connected",
  1881. 31:"Is a directory",
  1882. 32:"Too many symbolic links",
  1883. 33:"Too many open files",
  1884. 34:"Too many links",
  1885. 35:"Message too long",
  1886. 36:"Multihop attempted",
  1887. 37:"File or path name too long",
  1888. 38:"Network interface is not configured",
  1889. 39:"Connection reset by network",
  1890. 40:"Network is unreachable",
  1891. 41:"Too many open files in system",
  1892. 42:"No buffer space available",
  1893. 43:"No such device",
  1894. 44:"No such file or directory",
  1895. 45:"Exec format error",
  1896. 46:"No record locks available",
  1897. 47:"The link has been severed",
  1898. 48:"Not enough core",
  1899. 49:"No message of desired type",
  1900. 50:"Protocol not available",
  1901. 51:"No space left on device",
  1902. 52:"Function not implemented",
  1903. 53:"Socket is not connected",
  1904. 54:"Not a directory",
  1905. 55:"Directory not empty",
  1906. 56:"State not recoverable",
  1907. 57:"Socket operation on non-socket",
  1908. 59:"Not a typewriter",
  1909. 60:"No such device or address",
  1910. 61:"Value too large for defined data type",
  1911. 62:"Previous owner died",
  1912. 63:"Not super-user",
  1913. 64:"Broken pipe",
  1914. 65:"Protocol error",
  1915. 66:"Unknown protocol",
  1916. 67:"Protocol wrong type for socket",
  1917. 68:"Math result not representable",
  1918. 69:"Read only file system",
  1919. 70:"Illegal seek",
  1920. 71:"No such process",
  1921. 72:"Stale file handle",
  1922. 73:"Connection timed out",
  1923. 74:"Text file busy",
  1924. 75:"Cross-device link",
  1925. 100:"Device not a stream",
  1926. 101:"Bad font file fmt",
  1927. 102:"Invalid slot",
  1928. 103:"Invalid request code",
  1929. 104:"No anode",
  1930. 105:"Block device required",
  1931. 106:"Channel number out of range",
  1932. 107:"Level 3 halted",
  1933. 108:"Level 3 reset",
  1934. 109:"Link number out of range",
  1935. 110:"Protocol driver not attached",
  1936. 111:"No CSI structure available",
  1937. 112:"Level 2 halted",
  1938. 113:"Invalid exchange",
  1939. 114:"Invalid request descriptor",
  1940. 115:"Exchange full",
  1941. 116:"No data (for no delay io)",
  1942. 117:"Timer expired",
  1943. 118:"Out of streams resources",
  1944. 119:"Machine is not on the network",
  1945. 120:"Package not installed",
  1946. 121:"The object is remote",
  1947. 122:"Advertise error",
  1948. 123:"Srmount error",
  1949. 124:"Communication error on send",
  1950. 125:"Cross mount point (not really error)",
  1951. 126:"Given log. name not unique",
  1952. 127:"f.d. invalid for this operation",
  1953. 128:"Remote address changed",
  1954. 129:"Can access a needed shared lib",
  1955. 130:"Accessing a corrupted shared lib",
  1956. 131:".lib section in a.out corrupted",
  1957. 132:"Attempting to link in too many libs",
  1958. 133:"Attempting to exec a shared library",
  1959. 135:"Streams pipe error",
  1960. 136:"Too many users",
  1961. 137:"Socket type not supported",
  1962. 138:"Not supported",
  1963. 139:"Protocol family not supported",
  1964. 140:"Can't send after socket shutdown",
  1965. 141:"Too many references",
  1966. 142:"Host is down",
  1967. 148:"No medium (in tape drive)",
  1968. 156:"Level 2 not synchronized",
  1969. };
  1970. var ERRNO_CODES = {
  1971. 'EPERM': 63,
  1972. 'ENOENT': 44,
  1973. 'ESRCH': 71,
  1974. 'EINTR': 27,
  1975. 'EIO': 29,
  1976. 'ENXIO': 60,
  1977. 'E2BIG': 1,
  1978. 'ENOEXEC': 45,
  1979. 'EBADF': 8,
  1980. 'ECHILD': 12,
  1981. 'EAGAIN': 6,
  1982. 'EWOULDBLOCK': 6,
  1983. 'ENOMEM': 48,
  1984. 'EACCES': 2,
  1985. 'EFAULT': 21,
  1986. 'ENOTBLK': 105,
  1987. 'EBUSY': 10,
  1988. 'EEXIST': 20,
  1989. 'EXDEV': 75,
  1990. 'ENODEV': 43,
  1991. 'ENOTDIR': 54,
  1992. 'EISDIR': 31,
  1993. 'EINVAL': 28,
  1994. 'ENFILE': 41,
  1995. 'EMFILE': 33,
  1996. 'ENOTTY': 59,
  1997. 'ETXTBSY': 74,
  1998. 'EFBIG': 22,
  1999. 'ENOSPC': 51,
  2000. 'ESPIPE': 70,
  2001. 'EROFS': 69,
  2002. 'EMLINK': 34,
  2003. 'EPIPE': 64,
  2004. 'EDOM': 18,
  2005. 'ERANGE': 68,
  2006. 'ENOMSG': 49,
  2007. 'EIDRM': 24,
  2008. 'ECHRNG': 106,
  2009. 'EL2NSYNC': 156,
  2010. 'EL3HLT': 107,
  2011. 'EL3RST': 108,
  2012. 'ELNRNG': 109,
  2013. 'EUNATCH': 110,
  2014. 'ENOCSI': 111,
  2015. 'EL2HLT': 112,
  2016. 'EDEADLK': 16,
  2017. 'ENOLCK': 46,
  2018. 'EBADE': 113,
  2019. 'EBADR': 114,
  2020. 'EXFULL': 115,
  2021. 'ENOANO': 104,
  2022. 'EBADRQC': 103,
  2023. 'EBADSLT': 102,
  2024. 'EDEADLOCK': 16,
  2025. 'EBFONT': 101,
  2026. 'ENOSTR': 100,
  2027. 'ENODATA': 116,
  2028. 'ETIME': 117,
  2029. 'ENOSR': 118,
  2030. 'ENONET': 119,
  2031. 'ENOPKG': 120,
  2032. 'EREMOTE': 121,
  2033. 'ENOLINK': 47,
  2034. 'EADV': 122,
  2035. 'ESRMNT': 123,
  2036. 'ECOMM': 124,
  2037. 'EPROTO': 65,
  2038. 'EMULTIHOP': 36,
  2039. 'EDOTDOT': 125,
  2040. 'EBADMSG': 9,
  2041. 'ENOTUNIQ': 126,
  2042. 'EBADFD': 127,
  2043. 'EREMCHG': 128,
  2044. 'ELIBACC': 129,
  2045. 'ELIBBAD': 130,
  2046. 'ELIBSCN': 131,
  2047. 'ELIBMAX': 132,
  2048. 'ELIBEXEC': 133,
  2049. 'ENOSYS': 52,
  2050. 'ENOTEMPTY': 55,
  2051. 'ENAMETOOLONG': 37,
  2052. 'ELOOP': 32,
  2053. 'EOPNOTSUPP': 138,
  2054. 'EPFNOSUPPORT': 139,
  2055. 'ECONNRESET': 15,
  2056. 'ENOBUFS': 42,
  2057. 'EAFNOSUPPORT': 5,
  2058. 'EPROTOTYPE': 67,
  2059. 'ENOTSOCK': 57,
  2060. 'ENOPROTOOPT': 50,
  2061. 'ESHUTDOWN': 140,
  2062. 'ECONNREFUSED': 14,
  2063. 'EADDRINUSE': 3,
  2064. 'ECONNABORTED': 13,
  2065. 'ENETUNREACH': 40,
  2066. 'ENETDOWN': 38,
  2067. 'ETIMEDOUT': 73,
  2068. 'EHOSTDOWN': 142,
  2069. 'EHOSTUNREACH': 23,
  2070. 'EINPROGRESS': 26,
  2071. 'EALREADY': 7,
  2072. 'EDESTADDRREQ': 17,
  2073. 'EMSGSIZE': 35,
  2074. 'EPROTONOSUPPORT': 66,
  2075. 'ESOCKTNOSUPPORT': 137,
  2076. 'EADDRNOTAVAIL': 4,
  2077. 'ENETRESET': 39,
  2078. 'EISCONN': 30,
  2079. 'ENOTCONN': 53,
  2080. 'ETOOMANYREFS': 141,
  2081. 'EUSERS': 136,
  2082. 'EDQUOT': 19,
  2083. 'ESTALE': 72,
  2084. 'ENOTSUP': 138,
  2085. 'ENOMEDIUM': 148,
  2086. 'EILSEQ': 25,
  2087. 'EOVERFLOW': 61,
  2088. 'ECANCELED': 11,
  2089. 'ENOTRECOVERABLE': 56,
  2090. 'EOWNERDEAD': 62,
  2091. 'ESTRPIPE': 135,
  2092. };
  2093. var FS = {
  2094. root:null,
  2095. mounts:[],
  2096. devices:{
  2097. },
  2098. streams:[],
  2099. nextInode:1,
  2100. nameTable:null,
  2101. currentPath:"/",
  2102. initialized:false,
  2103. ignorePermissions:true,
  2104. ErrnoError:class extends Error {
  2105. // We set the `name` property to be able to identify `FS.ErrnoError`
  2106. // - the `name` is a standard ECMA-262 property of error objects. Kind of good to have it anyway.
  2107. // - when using PROXYFS, an error can come from an underlying FS
  2108. // as different FS objects have their own FS.ErrnoError each,
  2109. // the test `err instanceof FS.ErrnoError` won't detect an error coming from another filesystem, causing bugs.
  2110. // we'll use the reliable test `err.name == "ErrnoError"` instead
  2111. constructor(errno) {
  2112. super(ERRNO_MESSAGES[errno]);
  2113. // TODO(sbc): Use the inline member declaration syntax once we
  2114. // support it in acorn and closure.
  2115. this.name = 'ErrnoError';
  2116. this.errno = errno;
  2117. for (var key in ERRNO_CODES) {
  2118. if (ERRNO_CODES[key] === errno) {
  2119. this.code = key;
  2120. break;
  2121. }
  2122. }
  2123. }
  2124. },
  2125. genericErrors:{
  2126. },
  2127. filesystems:null,
  2128. syncFSRequests:0,
  2129. FSStream:class {
  2130. constructor() {
  2131. // TODO(https://github.com/emscripten-core/emscripten/issues/21414):
  2132. // Use inline field declarations.
  2133. this.shared = {};
  2134. }
  2135. get object() {
  2136. return this.node;
  2137. }
  2138. set object(val) {
  2139. this.node = val;
  2140. }
  2141. get isRead() {
  2142. return (this.flags & 2097155) !== 1;
  2143. }
  2144. get isWrite() {
  2145. return (this.flags & 2097155) !== 0;
  2146. }
  2147. get isAppend() {
  2148. return (this.flags & 1024);
  2149. }
  2150. get flags() {
  2151. return this.shared.flags;
  2152. }
  2153. set flags(val) {
  2154. this.shared.flags = val;
  2155. }
  2156. get position() {
  2157. return this.shared.position;
  2158. }
  2159. set position(val) {
  2160. this.shared.position = val;
  2161. }
  2162. },
  2163. FSNode:class {
  2164. constructor(parent, name, mode, rdev) {
  2165. if (!parent) {
  2166. parent = this; // root node sets parent to itself
  2167. }
  2168. this.parent = parent;
  2169. this.mount = parent.mount;
  2170. this.mounted = null;
  2171. this.id = FS.nextInode++;
  2172. this.name = name;
  2173. this.mode = mode;
  2174. this.node_ops = {};
  2175. this.stream_ops = {};
  2176. this.rdev = rdev;
  2177. this.readMode = 292/*292*/ | 73/*73*/;
  2178. this.writeMode = 146/*146*/;
  2179. }
  2180. get read() {
  2181. return (this.mode & this.readMode) === this.readMode;
  2182. }
  2183. set read(val) {
  2184. val ? this.mode |= this.readMode : this.mode &= ~this.readMode;
  2185. }
  2186. get write() {
  2187. return (this.mode & this.writeMode) === this.writeMode;
  2188. }
  2189. set write(val) {
  2190. val ? this.mode |= this.writeMode : this.mode &= ~this.writeMode;
  2191. }
  2192. get isFolder() {
  2193. return FS.isDir(this.mode);
  2194. }
  2195. get isDevice() {
  2196. return FS.isChrdev(this.mode);
  2197. }
  2198. },
  2199. lookupPath(path, opts = {}) {
  2200. path = PATH_FS.resolve(path);
  2201. if (!path) return { path: '', node: null };
  2202. var defaults = {
  2203. follow_mount: true,
  2204. recurse_count: 0
  2205. };
  2206. opts = Object.assign(defaults, opts)
  2207. if (opts.recurse_count > 8) { // max recursive lookup of 8
  2208. throw new FS.ErrnoError(32);
  2209. }
  2210. // split the absolute path
  2211. var parts = path.split('/').filter((p) => !!p);
  2212. // start at the root
  2213. var current = FS.root;
  2214. var current_path = '/';
  2215. for (var i = 0; i < parts.length; i++) {
  2216. var islast = (i === parts.length-1);
  2217. if (islast && opts.parent) {
  2218. // stop resolving
  2219. break;
  2220. }
  2221. current = FS.lookupNode(current, parts[i]);
  2222. current_path = PATH.join2(current_path, parts[i]);
  2223. // jump to the mount's root node if this is a mountpoint
  2224. if (FS.isMountpoint(current)) {
  2225. if (!islast || (islast && opts.follow_mount)) {
  2226. current = current.mounted.root;
  2227. }
  2228. }
  2229. // by default, lookupPath will not follow a symlink if it is the final path component.
  2230. // setting opts.follow = true will override this behavior.
  2231. if (!islast || opts.follow) {
  2232. var count = 0;
  2233. while (FS.isLink(current.mode)) {
  2234. var link = FS.readlink(current_path);
  2235. current_path = PATH_FS.resolve(PATH.dirname(current_path), link);
  2236. var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count + 1 });
  2237. current = lookup.node;
  2238. if (count++ > 40) { // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
  2239. throw new FS.ErrnoError(32);
  2240. }
  2241. }
  2242. }
  2243. }
  2244. return { path: current_path, node: current };
  2245. },
  2246. getPath(node) {
  2247. var path;
  2248. while (true) {
  2249. if (FS.isRoot(node)) {
  2250. var mount = node.mount.mountpoint;
  2251. if (!path) return mount;
  2252. return mount[mount.length-1] !== '/' ? `${mount}/${path}` : mount + path;
  2253. }
  2254. path = path ? `${node.name}/${path}` : node.name;
  2255. node = node.parent;
  2256. }
  2257. },
  2258. hashName(parentid, name) {
  2259. var hash = 0;
  2260. for (var i = 0; i < name.length; i++) {
  2261. hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
  2262. }
  2263. return ((parentid + hash) >>> 0) % FS.nameTable.length;
  2264. },
  2265. hashAddNode(node) {
  2266. var hash = FS.hashName(node.parent.id, node.name);
  2267. node.name_next = FS.nameTable[hash];
  2268. FS.nameTable[hash] = node;
  2269. },
  2270. hashRemoveNode(node) {
  2271. var hash = FS.hashName(node.parent.id, node.name);
  2272. if (FS.nameTable[hash] === node) {
  2273. FS.nameTable[hash] = node.name_next;
  2274. } else {
  2275. var current = FS.nameTable[hash];
  2276. while (current) {
  2277. if (current.name_next === node) {
  2278. current.name_next = node.name_next;
  2279. break;
  2280. }
  2281. current = current.name_next;
  2282. }
  2283. }
  2284. },
  2285. lookupNode(parent, name) {
  2286. var errCode = FS.mayLookup(parent);
  2287. if (errCode) {
  2288. throw new FS.ErrnoError(errCode);
  2289. }
  2290. var hash = FS.hashName(parent.id, name);
  2291. for (var node = FS.nameTable[hash]; node; node = node.name_next) {
  2292. var nodeName = node.name;
  2293. if (node.parent.id === parent.id && nodeName === name) {
  2294. return node;
  2295. }
  2296. }
  2297. // if we failed to find it in the cache, call into the VFS
  2298. return FS.lookup(parent, name);
  2299. },
  2300. createNode(parent, name, mode, rdev) {
  2301. assert(typeof parent == 'object')
  2302. var node = new FS.FSNode(parent, name, mode, rdev);
  2303. FS.hashAddNode(node);
  2304. return node;
  2305. },
  2306. destroyNode(node) {
  2307. FS.hashRemoveNode(node);
  2308. },
  2309. isRoot(node) {
  2310. return node === node.parent;
  2311. },
  2312. isMountpoint(node) {
  2313. return !!node.mounted;
  2314. },
  2315. isFile(mode) {
  2316. return (mode & 61440) === 32768;
  2317. },
  2318. isDir(mode) {
  2319. return (mode & 61440) === 16384;
  2320. },
  2321. isLink(mode) {
  2322. return (mode & 61440) === 40960;
  2323. },
  2324. isChrdev(mode) {
  2325. return (mode & 61440) === 8192;
  2326. },
  2327. isBlkdev(mode) {
  2328. return (mode & 61440) === 24576;
  2329. },
  2330. isFIFO(mode) {
  2331. return (mode & 61440) === 4096;
  2332. },
  2333. isSocket(mode) {
  2334. return (mode & 49152) === 49152;
  2335. },
  2336. flagsToPermissionString(flag) {
  2337. var perms = ['r', 'w', 'rw'][flag & 3];
  2338. if ((flag & 512)) {
  2339. perms += 'w';
  2340. }
  2341. return perms;
  2342. },
  2343. nodePermissions(node, perms) {
  2344. if (FS.ignorePermissions) {
  2345. return 0;
  2346. }
  2347. // return 0 if any user, group or owner bits are set.
  2348. if (perms.includes('r') && !(node.mode & 292)) {
  2349. return 2;
  2350. } else if (perms.includes('w') && !(node.mode & 146)) {
  2351. return 2;
  2352. } else if (perms.includes('x') && !(node.mode & 73)) {
  2353. return 2;
  2354. }
  2355. return 0;
  2356. },
  2357. mayLookup(dir) {
  2358. if (!FS.isDir(dir.mode)) return 54;
  2359. var errCode = FS.nodePermissions(dir, 'x');
  2360. if (errCode) return errCode;
  2361. if (!dir.node_ops.lookup) return 2;
  2362. return 0;
  2363. },
  2364. mayCreate(dir, name) {
  2365. try {
  2366. var node = FS.lookupNode(dir, name);
  2367. return 20;
  2368. } catch (e) {
  2369. }
  2370. return FS.nodePermissions(dir, 'wx');
  2371. },
  2372. mayDelete(dir, name, isdir) {
  2373. var node;
  2374. try {
  2375. node = FS.lookupNode(dir, name);
  2376. } catch (e) {
  2377. return e.errno;
  2378. }
  2379. var errCode = FS.nodePermissions(dir, 'wx');
  2380. if (errCode) {
  2381. return errCode;
  2382. }
  2383. if (isdir) {
  2384. if (!FS.isDir(node.mode)) {
  2385. return 54;
  2386. }
  2387. if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
  2388. return 10;
  2389. }
  2390. } else {
  2391. if (FS.isDir(node.mode)) {
  2392. return 31;
  2393. }
  2394. }
  2395. return 0;
  2396. },
  2397. mayOpen(node, flags) {
  2398. if (!node) {
  2399. return 44;
  2400. }
  2401. if (FS.isLink(node.mode)) {
  2402. return 32;
  2403. } else if (FS.isDir(node.mode)) {
  2404. if (FS.flagsToPermissionString(flags) !== 'r' || // opening for write
  2405. (flags & 512)) { // TODO: check for O_SEARCH? (== search for dir only)
  2406. return 31;
  2407. }
  2408. }
  2409. return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
  2410. },
  2411. MAX_OPEN_FDS:4096,
  2412. nextfd() {
  2413. for (var fd = 0; fd <= FS.MAX_OPEN_FDS; fd++) {
  2414. if (!FS.streams[fd]) {
  2415. return fd;
  2416. }
  2417. }
  2418. throw new FS.ErrnoError(33);
  2419. },
  2420. getStreamChecked(fd) {
  2421. var stream = FS.getStream(fd);
  2422. if (!stream) {
  2423. throw new FS.ErrnoError(8);
  2424. }
  2425. return stream;
  2426. },
  2427. getStream:(fd) => FS.streams[fd],
  2428. createStream(stream, fd = -1) {
  2429. // clone it, so we can return an instance of FSStream
  2430. stream = Object.assign(new FS.FSStream(), stream);
  2431. if (fd == -1) {
  2432. fd = FS.nextfd();
  2433. }
  2434. stream.fd = fd;
  2435. FS.streams[fd] = stream;
  2436. return stream;
  2437. },
  2438. closeStream(fd) {
  2439. FS.streams[fd] = null;
  2440. },
  2441. dupStream(origStream, fd = -1) {
  2442. var stream = FS.createStream(origStream, fd);
  2443. stream.stream_ops?.dup?.(stream);
  2444. return stream;
  2445. },
  2446. chrdev_stream_ops:{
  2447. open(stream) {
  2448. var device = FS.getDevice(stream.node.rdev);
  2449. // override node's stream ops with the device's
  2450. stream.stream_ops = device.stream_ops;
  2451. // forward the open call
  2452. stream.stream_ops.open?.(stream);
  2453. },
  2454. llseek() {
  2455. throw new FS.ErrnoError(70);
  2456. },
  2457. },
  2458. major:(dev) => ((dev) >> 8),
  2459. minor:(dev) => ((dev) & 0xff),
  2460. makedev:(ma, mi) => ((ma) << 8 | (mi)),
  2461. registerDevice(dev, ops) {
  2462. FS.devices[dev] = { stream_ops: ops };
  2463. },
  2464. getDevice:(dev) => FS.devices[dev],
  2465. getMounts(mount) {
  2466. var mounts = [];
  2467. var check = [mount];
  2468. while (check.length) {
  2469. var m = check.pop();
  2470. mounts.push(m);
  2471. check.push(...m.mounts);
  2472. }
  2473. return mounts;
  2474. },
  2475. syncfs(populate, callback) {
  2476. if (typeof populate == 'function') {
  2477. callback = populate;
  2478. populate = false;
  2479. }
  2480. FS.syncFSRequests++;
  2481. if (FS.syncFSRequests > 1) {
  2482. err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`);
  2483. }
  2484. var mounts = FS.getMounts(FS.root.mount);
  2485. var completed = 0;
  2486. function doCallback(errCode) {
  2487. assert(FS.syncFSRequests > 0);
  2488. FS.syncFSRequests--;
  2489. return callback(errCode);
  2490. }
  2491. function done(errCode) {
  2492. if (errCode) {
  2493. if (!done.errored) {
  2494. done.errored = true;
  2495. return doCallback(errCode);
  2496. }
  2497. return;
  2498. }
  2499. if (++completed >= mounts.length) {
  2500. doCallback(null);
  2501. }
  2502. };
  2503. // sync all mounts
  2504. mounts.forEach((mount) => {
  2505. if (!mount.type.syncfs) {
  2506. return done(null);
  2507. }
  2508. mount.type.syncfs(mount, populate, done);
  2509. });
  2510. },
  2511. mount(type, opts, mountpoint) {
  2512. if (typeof type == 'string') {
  2513. // The filesystem was not included, and instead we have an error
  2514. // message stored in the variable.
  2515. throw type;
  2516. }
  2517. var root = mountpoint === '/';
  2518. var pseudo = !mountpoint;
  2519. var node;
  2520. if (root && FS.root) {
  2521. throw new FS.ErrnoError(10);
  2522. } else if (!root && !pseudo) {
  2523. var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
  2524. mountpoint = lookup.path; // use the absolute path
  2525. node = lookup.node;
  2526. if (FS.isMountpoint(node)) {
  2527. throw new FS.ErrnoError(10);
  2528. }
  2529. if (!FS.isDir(node.mode)) {
  2530. throw new FS.ErrnoError(54);
  2531. }
  2532. }
  2533. var mount = {
  2534. type,
  2535. opts,
  2536. mountpoint,
  2537. mounts: []
  2538. };
  2539. // create a root node for the fs
  2540. var mountRoot = type.mount(mount);
  2541. mountRoot.mount = mount;
  2542. mount.root = mountRoot;
  2543. if (root) {
  2544. FS.root = mountRoot;
  2545. } else if (node) {
  2546. // set as a mountpoint
  2547. node.mounted = mount;
  2548. // add the new mount to the current mount's children
  2549. if (node.mount) {
  2550. node.mount.mounts.push(mount);
  2551. }
  2552. }
  2553. return mountRoot;
  2554. },
  2555. unmount(mountpoint) {
  2556. var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
  2557. if (!FS.isMountpoint(lookup.node)) {
  2558. throw new FS.ErrnoError(28);
  2559. }
  2560. // destroy the nodes for this mount, and all its child mounts
  2561. var node = lookup.node;
  2562. var mount = node.mounted;
  2563. var mounts = FS.getMounts(mount);
  2564. Object.keys(FS.nameTable).forEach((hash) => {
  2565. var current = FS.nameTable[hash];
  2566. while (current) {
  2567. var next = current.name_next;
  2568. if (mounts.includes(current.mount)) {
  2569. FS.destroyNode(current);
  2570. }
  2571. current = next;
  2572. }
  2573. });
  2574. // no longer a mountpoint
  2575. node.mounted = null;
  2576. // remove this mount from the child mounts
  2577. var idx = node.mount.mounts.indexOf(mount);
  2578. assert(idx !== -1);
  2579. node.mount.mounts.splice(idx, 1);
  2580. },
  2581. lookup(parent, name) {
  2582. return parent.node_ops.lookup(parent, name);
  2583. },
  2584. mknod(path, mode, dev) {
  2585. var lookup = FS.lookupPath(path, { parent: true });
  2586. var parent = lookup.node;
  2587. var name = PATH.basename(path);
  2588. if (!name || name === '.' || name === '..') {
  2589. throw new FS.ErrnoError(28);
  2590. }
  2591. var errCode = FS.mayCreate(parent, name);
  2592. if (errCode) {
  2593. throw new FS.ErrnoError(errCode);
  2594. }
  2595. if (!parent.node_ops.mknod) {
  2596. throw new FS.ErrnoError(63);
  2597. }
  2598. return parent.node_ops.mknod(parent, name, mode, dev);
  2599. },
  2600. create(path, mode) {
  2601. mode = mode !== undefined ? mode : 438 /* 0666 */;
  2602. mode &= 4095;
  2603. mode |= 32768;
  2604. return FS.mknod(path, mode, 0);
  2605. },
  2606. mkdir(path, mode) {
  2607. mode = mode !== undefined ? mode : 511 /* 0777 */;
  2608. mode &= 511 | 512;
  2609. mode |= 16384;
  2610. return FS.mknod(path, mode, 0);
  2611. },
  2612. mkdirTree(path, mode) {
  2613. var dirs = path.split('/');
  2614. var d = '';
  2615. for (var i = 0; i < dirs.length; ++i) {
  2616. if (!dirs[i]) continue;
  2617. d += '/' + dirs[i];
  2618. try {
  2619. FS.mkdir(d, mode);
  2620. } catch(e) {
  2621. if (e.errno != 20) throw e;
  2622. }
  2623. }
  2624. },
  2625. mkdev(path, mode, dev) {
  2626. if (typeof dev == 'undefined') {
  2627. dev = mode;
  2628. mode = 438 /* 0666 */;
  2629. }
  2630. mode |= 8192;
  2631. return FS.mknod(path, mode, dev);
  2632. },
  2633. symlink(oldpath, newpath) {
  2634. if (!PATH_FS.resolve(oldpath)) {
  2635. throw new FS.ErrnoError(44);
  2636. }
  2637. var lookup = FS.lookupPath(newpath, { parent: true });
  2638. var parent = lookup.node;
  2639. if (!parent) {
  2640. throw new FS.ErrnoError(44);
  2641. }
  2642. var newname = PATH.basename(newpath);
  2643. var errCode = FS.mayCreate(parent, newname);
  2644. if (errCode) {
  2645. throw new FS.ErrnoError(errCode);
  2646. }
  2647. if (!parent.node_ops.symlink) {
  2648. throw new FS.ErrnoError(63);
  2649. }
  2650. return parent.node_ops.symlink(parent, newname, oldpath);
  2651. },
  2652. rename(old_path, new_path) {
  2653. var old_dirname = PATH.dirname(old_path);
  2654. var new_dirname = PATH.dirname(new_path);
  2655. var old_name = PATH.basename(old_path);
  2656. var new_name = PATH.basename(new_path);
  2657. // parents must exist
  2658. var lookup, old_dir, new_dir;
  2659. // let the errors from non existent directories percolate up
  2660. lookup = FS.lookupPath(old_path, { parent: true });
  2661. old_dir = lookup.node;
  2662. lookup = FS.lookupPath(new_path, { parent: true });
  2663. new_dir = lookup.node;
  2664. if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
  2665. // need to be part of the same mount
  2666. if (old_dir.mount !== new_dir.mount) {
  2667. throw new FS.ErrnoError(75);
  2668. }
  2669. // source must exist
  2670. var old_node = FS.lookupNode(old_dir, old_name);
  2671. // old path should not be an ancestor of the new path
  2672. var relative = PATH_FS.relative(old_path, new_dirname);
  2673. if (relative.charAt(0) !== '.') {
  2674. throw new FS.ErrnoError(28);
  2675. }
  2676. // new path should not be an ancestor of the old path
  2677. relative = PATH_FS.relative(new_path, old_dirname);
  2678. if (relative.charAt(0) !== '.') {
  2679. throw new FS.ErrnoError(55);
  2680. }
  2681. // see if the new path already exists
  2682. var new_node;
  2683. try {
  2684. new_node = FS.lookupNode(new_dir, new_name);
  2685. } catch (e) {
  2686. // not fatal
  2687. }
  2688. // early out if nothing needs to change
  2689. if (old_node === new_node) {
  2690. return;
  2691. }
  2692. // we'll need to delete the old entry
  2693. var isdir = FS.isDir(old_node.mode);
  2694. var errCode = FS.mayDelete(old_dir, old_name, isdir);
  2695. if (errCode) {
  2696. throw new FS.ErrnoError(errCode);
  2697. }
  2698. // need delete permissions if we'll be overwriting.
  2699. // need create permissions if new doesn't already exist.
  2700. errCode = new_node ?
  2701. FS.mayDelete(new_dir, new_name, isdir) :
  2702. FS.mayCreate(new_dir, new_name);
  2703. if (errCode) {
  2704. throw new FS.ErrnoError(errCode);
  2705. }
  2706. if (!old_dir.node_ops.rename) {
  2707. throw new FS.ErrnoError(63);
  2708. }
  2709. if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
  2710. throw new FS.ErrnoError(10);
  2711. }
  2712. // if we are going to change the parent, check write permissions
  2713. if (new_dir !== old_dir) {
  2714. errCode = FS.nodePermissions(old_dir, 'w');
  2715. if (errCode) {
  2716. throw new FS.ErrnoError(errCode);
  2717. }
  2718. }
  2719. // remove the node from the lookup hash
  2720. FS.hashRemoveNode(old_node);
  2721. // do the underlying fs rename
  2722. try {
  2723. old_dir.node_ops.rename(old_node, new_dir, new_name);
  2724. // update old node (we do this here to avoid each backend
  2725. // needing to)
  2726. old_node.parent = new_dir;
  2727. } catch (e) {
  2728. throw e;
  2729. } finally {
  2730. // add the node back to the hash (in case node_ops.rename
  2731. // changed its name)
  2732. FS.hashAddNode(old_node);
  2733. }
  2734. },
  2735. rmdir(path) {
  2736. var lookup = FS.lookupPath(path, { parent: true });
  2737. var parent = lookup.node;
  2738. var name = PATH.basename(path);
  2739. var node = FS.lookupNode(parent, name);
  2740. var errCode = FS.mayDelete(parent, name, true);
  2741. if (errCode) {
  2742. throw new FS.ErrnoError(errCode);
  2743. }
  2744. if (!parent.node_ops.rmdir) {
  2745. throw new FS.ErrnoError(63);
  2746. }
  2747. if (FS.isMountpoint(node)) {
  2748. throw new FS.ErrnoError(10);
  2749. }
  2750. parent.node_ops.rmdir(parent, name);
  2751. FS.destroyNode(node);
  2752. },
  2753. readdir(path) {
  2754. var lookup = FS.lookupPath(path, { follow: true });
  2755. var node = lookup.node;
  2756. if (!node.node_ops.readdir) {
  2757. throw new FS.ErrnoError(54);
  2758. }
  2759. return node.node_ops.readdir(node);
  2760. },
  2761. unlink(path) {
  2762. var lookup = FS.lookupPath(path, { parent: true });
  2763. var parent = lookup.node;
  2764. if (!parent) {
  2765. throw new FS.ErrnoError(44);
  2766. }
  2767. var name = PATH.basename(path);
  2768. var node = FS.lookupNode(parent, name);
  2769. var errCode = FS.mayDelete(parent, name, false);
  2770. if (errCode) {
  2771. // According to POSIX, we should map EISDIR to EPERM, but
  2772. // we instead do what Linux does (and we must, as we use
  2773. // the musl linux libc).
  2774. throw new FS.ErrnoError(errCode);
  2775. }
  2776. if (!parent.node_ops.unlink) {
  2777. throw new FS.ErrnoError(63);
  2778. }
  2779. if (FS.isMountpoint(node)) {
  2780. throw new FS.ErrnoError(10);
  2781. }
  2782. parent.node_ops.unlink(parent, name);
  2783. FS.destroyNode(node);
  2784. },
  2785. readlink(path) {
  2786. var lookup = FS.lookupPath(path);
  2787. var link = lookup.node;
  2788. if (!link) {
  2789. throw new FS.ErrnoError(44);
  2790. }
  2791. if (!link.node_ops.readlink) {
  2792. throw new FS.ErrnoError(28);
  2793. }
  2794. return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link));
  2795. },
  2796. stat(path, dontFollow) {
  2797. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  2798. var node = lookup.node;
  2799. if (!node) {
  2800. throw new FS.ErrnoError(44);
  2801. }
  2802. if (!node.node_ops.getattr) {
  2803. throw new FS.ErrnoError(63);
  2804. }
  2805. return node.node_ops.getattr(node);
  2806. },
  2807. lstat(path) {
  2808. return FS.stat(path, true);
  2809. },
  2810. chmod(path, mode, dontFollow) {
  2811. var node;
  2812. if (typeof path == 'string') {
  2813. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  2814. node = lookup.node;
  2815. } else {
  2816. node = path;
  2817. }
  2818. if (!node.node_ops.setattr) {
  2819. throw new FS.ErrnoError(63);
  2820. }
  2821. node.node_ops.setattr(node, {
  2822. mode: (mode & 4095) | (node.mode & ~4095),
  2823. timestamp: Date.now()
  2824. });
  2825. },
  2826. lchmod(path, mode) {
  2827. FS.chmod(path, mode, true);
  2828. },
  2829. fchmod(fd, mode) {
  2830. var stream = FS.getStreamChecked(fd);
  2831. FS.chmod(stream.node, mode);
  2832. },
  2833. chown(path, uid, gid, dontFollow) {
  2834. var node;
  2835. if (typeof path == 'string') {
  2836. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  2837. node = lookup.node;
  2838. } else {
  2839. node = path;
  2840. }
  2841. if (!node.node_ops.setattr) {
  2842. throw new FS.ErrnoError(63);
  2843. }
  2844. node.node_ops.setattr(node, {
  2845. timestamp: Date.now()
  2846. // we ignore the uid / gid for now
  2847. });
  2848. },
  2849. lchown(path, uid, gid) {
  2850. FS.chown(path, uid, gid, true);
  2851. },
  2852. fchown(fd, uid, gid) {
  2853. var stream = FS.getStreamChecked(fd);
  2854. FS.chown(stream.node, uid, gid);
  2855. },
  2856. truncate(path, len) {
  2857. if (len < 0) {
  2858. throw new FS.ErrnoError(28);
  2859. }
  2860. var node;
  2861. if (typeof path == 'string') {
  2862. var lookup = FS.lookupPath(path, { follow: true });
  2863. node = lookup.node;
  2864. } else {
  2865. node = path;
  2866. }
  2867. if (!node.node_ops.setattr) {
  2868. throw new FS.ErrnoError(63);
  2869. }
  2870. if (FS.isDir(node.mode)) {
  2871. throw new FS.ErrnoError(31);
  2872. }
  2873. if (!FS.isFile(node.mode)) {
  2874. throw new FS.ErrnoError(28);
  2875. }
  2876. var errCode = FS.nodePermissions(node, 'w');
  2877. if (errCode) {
  2878. throw new FS.ErrnoError(errCode);
  2879. }
  2880. node.node_ops.setattr(node, {
  2881. size: len,
  2882. timestamp: Date.now()
  2883. });
  2884. },
  2885. ftruncate(fd, len) {
  2886. var stream = FS.getStreamChecked(fd);
  2887. if ((stream.flags & 2097155) === 0) {
  2888. throw new FS.ErrnoError(28);
  2889. }
  2890. FS.truncate(stream.node, len);
  2891. },
  2892. utime(path, atime, mtime) {
  2893. var lookup = FS.lookupPath(path, { follow: true });
  2894. var node = lookup.node;
  2895. node.node_ops.setattr(node, {
  2896. timestamp: Math.max(atime, mtime)
  2897. });
  2898. },
  2899. open(path, flags, mode) {
  2900. if (path === "") {
  2901. throw new FS.ErrnoError(44);
  2902. }
  2903. flags = typeof flags == 'string' ? FS_modeStringToFlags(flags) : flags;
  2904. if ((flags & 64)) {
  2905. mode = typeof mode == 'undefined' ? 438 /* 0666 */ : mode;
  2906. mode = (mode & 4095) | 32768;
  2907. } else {
  2908. mode = 0;
  2909. }
  2910. var node;
  2911. if (typeof path == 'object') {
  2912. node = path;
  2913. } else {
  2914. path = PATH.normalize(path);
  2915. try {
  2916. var lookup = FS.lookupPath(path, {
  2917. follow: !(flags & 131072)
  2918. });
  2919. node = lookup.node;
  2920. } catch (e) {
  2921. // ignore
  2922. }
  2923. }
  2924. // perhaps we need to create the node
  2925. var created = false;
  2926. if ((flags & 64)) {
  2927. if (node) {
  2928. // if O_CREAT and O_EXCL are set, error out if the node already exists
  2929. if ((flags & 128)) {
  2930. throw new FS.ErrnoError(20);
  2931. }
  2932. } else {
  2933. // node doesn't exist, try to create it
  2934. node = FS.mknod(path, mode, 0);
  2935. created = true;
  2936. }
  2937. }
  2938. if (!node) {
  2939. throw new FS.ErrnoError(44);
  2940. }
  2941. // can't truncate a device
  2942. if (FS.isChrdev(node.mode)) {
  2943. flags &= ~512;
  2944. }
  2945. // if asked only for a directory, then this must be one
  2946. if ((flags & 65536) && !FS.isDir(node.mode)) {
  2947. throw new FS.ErrnoError(54);
  2948. }
  2949. // check permissions, if this is not a file we just created now (it is ok to
  2950. // create and write to a file with read-only permissions; it is read-only
  2951. // for later use)
  2952. if (!created) {
  2953. var errCode = FS.mayOpen(node, flags);
  2954. if (errCode) {
  2955. throw new FS.ErrnoError(errCode);
  2956. }
  2957. }
  2958. // do truncation if necessary
  2959. if ((flags & 512) && !created) {
  2960. FS.truncate(node, 0);
  2961. }
  2962. // we've already handled these, don't pass down to the underlying vfs
  2963. flags &= ~(128 | 512 | 131072);
  2964. // register the stream with the filesystem
  2965. var stream = FS.createStream({
  2966. node,
  2967. path: FS.getPath(node), // we want the absolute path to the node
  2968. flags,
  2969. seekable: true,
  2970. position: 0,
  2971. stream_ops: node.stream_ops,
  2972. // used by the file family libc calls (fopen, fwrite, ferror, etc.)
  2973. ungotten: [],
  2974. error: false
  2975. });
  2976. // call the new stream's open function
  2977. if (stream.stream_ops.open) {
  2978. stream.stream_ops.open(stream);
  2979. }
  2980. if (Module['logReadFiles'] && !(flags & 1)) {
  2981. if (!FS.readFiles) FS.readFiles = {};
  2982. if (!(path in FS.readFiles)) {
  2983. FS.readFiles[path] = 1;
  2984. }
  2985. }
  2986. return stream;
  2987. },
  2988. close(stream) {
  2989. if (FS.isClosed(stream)) {
  2990. throw new FS.ErrnoError(8);
  2991. }
  2992. if (stream.getdents) stream.getdents = null; // free readdir state
  2993. try {
  2994. if (stream.stream_ops.close) {
  2995. stream.stream_ops.close(stream);
  2996. }
  2997. } catch (e) {
  2998. throw e;
  2999. } finally {
  3000. FS.closeStream(stream.fd);
  3001. }
  3002. stream.fd = null;
  3003. },
  3004. isClosed(stream) {
  3005. return stream.fd === null;
  3006. },
  3007. llseek(stream, offset, whence) {
  3008. if (FS.isClosed(stream)) {
  3009. throw new FS.ErrnoError(8);
  3010. }
  3011. if (!stream.seekable || !stream.stream_ops.llseek) {
  3012. throw new FS.ErrnoError(70);
  3013. }
  3014. if (whence != 0 && whence != 1 && whence != 2) {
  3015. throw new FS.ErrnoError(28);
  3016. }
  3017. stream.position = stream.stream_ops.llseek(stream, offset, whence);
  3018. stream.ungotten = [];
  3019. return stream.position;
  3020. },
  3021. read(stream, buffer, offset, length, position) {
  3022. assert(offset >= 0);
  3023. if (length < 0 || position < 0) {
  3024. throw new FS.ErrnoError(28);
  3025. }
  3026. if (FS.isClosed(stream)) {
  3027. throw new FS.ErrnoError(8);
  3028. }
  3029. if ((stream.flags & 2097155) === 1) {
  3030. throw new FS.ErrnoError(8);
  3031. }
  3032. if (FS.isDir(stream.node.mode)) {
  3033. throw new FS.ErrnoError(31);
  3034. }
  3035. if (!stream.stream_ops.read) {
  3036. throw new FS.ErrnoError(28);
  3037. }
  3038. var seeking = typeof position != 'undefined';
  3039. if (!seeking) {
  3040. position = stream.position;
  3041. } else if (!stream.seekable) {
  3042. throw new FS.ErrnoError(70);
  3043. }
  3044. var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
  3045. if (!seeking) stream.position += bytesRead;
  3046. return bytesRead;
  3047. },
  3048. write(stream, buffer, offset, length, position, canOwn) {
  3049. assert(offset >= 0);
  3050. if (length < 0 || position < 0) {
  3051. throw new FS.ErrnoError(28);
  3052. }
  3053. if (FS.isClosed(stream)) {
  3054. throw new FS.ErrnoError(8);
  3055. }
  3056. if ((stream.flags & 2097155) === 0) {
  3057. throw new FS.ErrnoError(8);
  3058. }
  3059. if (FS.isDir(stream.node.mode)) {
  3060. throw new FS.ErrnoError(31);
  3061. }
  3062. if (!stream.stream_ops.write) {
  3063. throw new FS.ErrnoError(28);
  3064. }
  3065. if (stream.seekable && stream.flags & 1024) {
  3066. // seek to the end before writing in append mode
  3067. FS.llseek(stream, 0, 2);
  3068. }
  3069. var seeking = typeof position != 'undefined';
  3070. if (!seeking) {
  3071. position = stream.position;
  3072. } else if (!stream.seekable) {
  3073. throw new FS.ErrnoError(70);
  3074. }
  3075. var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
  3076. if (!seeking) stream.position += bytesWritten;
  3077. return bytesWritten;
  3078. },
  3079. allocate(stream, offset, length) {
  3080. if (FS.isClosed(stream)) {
  3081. throw new FS.ErrnoError(8);
  3082. }
  3083. if (offset < 0 || length <= 0) {
  3084. throw new FS.ErrnoError(28);
  3085. }
  3086. if ((stream.flags & 2097155) === 0) {
  3087. throw new FS.ErrnoError(8);
  3088. }
  3089. if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) {
  3090. throw new FS.ErrnoError(43);
  3091. }
  3092. if (!stream.stream_ops.allocate) {
  3093. throw new FS.ErrnoError(138);
  3094. }
  3095. stream.stream_ops.allocate(stream, offset, length);
  3096. },
  3097. mmap(stream, length, position, prot, flags) {
  3098. // User requests writing to file (prot & PROT_WRITE != 0).
  3099. // Checking if we have permissions to write to the file unless
  3100. // MAP_PRIVATE flag is set. According to POSIX spec it is possible
  3101. // to write to file opened in read-only mode with MAP_PRIVATE flag,
  3102. // as all modifications will be visible only in the memory of
  3103. // the current process.
  3104. if ((prot & 2) !== 0
  3105. && (flags & 2) === 0
  3106. && (stream.flags & 2097155) !== 2) {
  3107. throw new FS.ErrnoError(2);
  3108. }
  3109. if ((stream.flags & 2097155) === 1) {
  3110. throw new FS.ErrnoError(2);
  3111. }
  3112. if (!stream.stream_ops.mmap) {
  3113. throw new FS.ErrnoError(43);
  3114. }
  3115. return stream.stream_ops.mmap(stream, length, position, prot, flags);
  3116. },
  3117. msync(stream, buffer, offset, length, mmapFlags) {
  3118. assert(offset >= 0);
  3119. if (!stream.stream_ops.msync) {
  3120. return 0;
  3121. }
  3122. return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags);
  3123. },
  3124. ioctl(stream, cmd, arg) {
  3125. if (!stream.stream_ops.ioctl) {
  3126. throw new FS.ErrnoError(59);
  3127. }
  3128. return stream.stream_ops.ioctl(stream, cmd, arg);
  3129. },
  3130. readFile(path, opts = {}) {
  3131. opts.flags = opts.flags || 0;
  3132. opts.encoding = opts.encoding || 'binary';
  3133. if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
  3134. throw new Error(`Invalid encoding type "${opts.encoding}"`);
  3135. }
  3136. var ret;
  3137. var stream = FS.open(path, opts.flags);
  3138. var stat = FS.stat(path);
  3139. var length = stat.size;
  3140. var buf = new Uint8Array(length);
  3141. FS.read(stream, buf, 0, length, 0);
  3142. if (opts.encoding === 'utf8') {
  3143. ret = UTF8ArrayToString(buf, 0);
  3144. } else if (opts.encoding === 'binary') {
  3145. ret = buf;
  3146. }
  3147. FS.close(stream);
  3148. return ret;
  3149. },
  3150. writeFile(path, data, opts = {}) {
  3151. opts.flags = opts.flags || 577;
  3152. var stream = FS.open(path, opts.flags, opts.mode);
  3153. if (typeof data == 'string') {
  3154. var buf = new Uint8Array(lengthBytesUTF8(data)+1);
  3155. var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length);
  3156. FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn);
  3157. } else if (ArrayBuffer.isView(data)) {
  3158. FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
  3159. } else {
  3160. throw new Error('Unsupported data type');
  3161. }
  3162. FS.close(stream);
  3163. },
  3164. cwd:() => FS.currentPath,
  3165. chdir(path) {
  3166. var lookup = FS.lookupPath(path, { follow: true });
  3167. if (lookup.node === null) {
  3168. throw new FS.ErrnoError(44);
  3169. }
  3170. if (!FS.isDir(lookup.node.mode)) {
  3171. throw new FS.ErrnoError(54);
  3172. }
  3173. var errCode = FS.nodePermissions(lookup.node, 'x');
  3174. if (errCode) {
  3175. throw new FS.ErrnoError(errCode);
  3176. }
  3177. FS.currentPath = lookup.path;
  3178. },
  3179. createDefaultDirectories() {
  3180. FS.mkdir('/tmp');
  3181. FS.mkdir('/home');
  3182. FS.mkdir('/home/web_user');
  3183. },
  3184. createDefaultDevices() {
  3185. // create /dev
  3186. FS.mkdir('/dev');
  3187. // setup /dev/null
  3188. FS.registerDevice(FS.makedev(1, 3), {
  3189. read: () => 0,
  3190. write: (stream, buffer, offset, length, pos) => length,
  3191. });
  3192. FS.mkdev('/dev/null', FS.makedev(1, 3));
  3193. // setup /dev/tty and /dev/tty1
  3194. // stderr needs to print output using err() rather than out()
  3195. // so we register a second tty just for it.
  3196. TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
  3197. TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
  3198. FS.mkdev('/dev/tty', FS.makedev(5, 0));
  3199. FS.mkdev('/dev/tty1', FS.makedev(6, 0));
  3200. // setup /dev/[u]random
  3201. // use a buffer to avoid overhead of individual crypto calls per byte
  3202. var randomBuffer = new Uint8Array(1024), randomLeft = 0;
  3203. var randomByte = () => {
  3204. if (randomLeft === 0) {
  3205. randomLeft = randomFill(randomBuffer).byteLength;
  3206. }
  3207. return randomBuffer[--randomLeft];
  3208. };
  3209. FS.createDevice('/dev', 'random', randomByte);
  3210. FS.createDevice('/dev', 'urandom', randomByte);
  3211. // we're not going to emulate the actual shm device,
  3212. // just create the tmp dirs that reside in it commonly
  3213. FS.mkdir('/dev/shm');
  3214. FS.mkdir('/dev/shm/tmp');
  3215. },
  3216. createSpecialDirectories() {
  3217. // create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the
  3218. // name of the stream for fd 6 (see test_unistd_ttyname)
  3219. FS.mkdir('/proc');
  3220. var proc_self = FS.mkdir('/proc/self');
  3221. FS.mkdir('/proc/self/fd');
  3222. FS.mount({
  3223. mount() {
  3224. var node = FS.createNode(proc_self, 'fd', 16384 | 511 /* 0777 */, 73);
  3225. node.node_ops = {
  3226. lookup(parent, name) {
  3227. var fd = +name;
  3228. var stream = FS.getStreamChecked(fd);
  3229. var ret = {
  3230. parent: null,
  3231. mount: { mountpoint: 'fake' },
  3232. node_ops: { readlink: () => stream.path },
  3233. };
  3234. ret.parent = ret; // make it look like a simple root node
  3235. return ret;
  3236. }
  3237. };
  3238. return node;
  3239. }
  3240. }, {}, '/proc/self/fd');
  3241. },
  3242. createStandardStreams() {
  3243. // TODO deprecate the old functionality of a single
  3244. // input / output callback and that utilizes FS.createDevice
  3245. // and instead require a unique set of stream ops
  3246. // by default, we symlink the standard streams to the
  3247. // default tty devices. however, if the standard streams
  3248. // have been overwritten we create a unique device for
  3249. // them instead.
  3250. if (Module['stdin']) {
  3251. FS.createDevice('/dev', 'stdin', Module['stdin']);
  3252. } else {
  3253. FS.symlink('/dev/tty', '/dev/stdin');
  3254. }
  3255. if (Module['stdout']) {
  3256. FS.createDevice('/dev', 'stdout', null, Module['stdout']);
  3257. } else {
  3258. FS.symlink('/dev/tty', '/dev/stdout');
  3259. }
  3260. if (Module['stderr']) {
  3261. FS.createDevice('/dev', 'stderr', null, Module['stderr']);
  3262. } else {
  3263. FS.symlink('/dev/tty1', '/dev/stderr');
  3264. }
  3265. // open default streams for the stdin, stdout and stderr devices
  3266. var stdin = FS.open('/dev/stdin', 0);
  3267. var stdout = FS.open('/dev/stdout', 1);
  3268. var stderr = FS.open('/dev/stderr', 1);
  3269. assert(stdin.fd === 0, `invalid handle for stdin (${stdin.fd})`);
  3270. assert(stdout.fd === 1, `invalid handle for stdout (${stdout.fd})`);
  3271. assert(stderr.fd === 2, `invalid handle for stderr (${stderr.fd})`);
  3272. },
  3273. staticInit() {
  3274. // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
  3275. [44].forEach((code) => {
  3276. FS.genericErrors[code] = new FS.ErrnoError(code);
  3277. FS.genericErrors[code].stack = '<generic error, no stack>';
  3278. });
  3279. FS.nameTable = new Array(4096);
  3280. FS.mount(MEMFS, {}, '/');
  3281. FS.createDefaultDirectories();
  3282. FS.createDefaultDevices();
  3283. FS.createSpecialDirectories();
  3284. FS.filesystems = {
  3285. 'MEMFS': MEMFS,
  3286. };
  3287. },
  3288. init(input, output, error) {
  3289. assert(!FS.init.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)');
  3290. FS.init.initialized = true;
  3291. // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
  3292. Module['stdin'] = input || Module['stdin'];
  3293. Module['stdout'] = output || Module['stdout'];
  3294. Module['stderr'] = error || Module['stderr'];
  3295. FS.createStandardStreams();
  3296. },
  3297. quit() {
  3298. FS.init.initialized = false;
  3299. // force-flush all streams, so we get musl std streams printed out
  3300. _fflush(0);
  3301. // close all of our streams
  3302. for (var i = 0; i < FS.streams.length; i++) {
  3303. var stream = FS.streams[i];
  3304. if (!stream) {
  3305. continue;
  3306. }
  3307. FS.close(stream);
  3308. }
  3309. },
  3310. findObject(path, dontResolveLastLink) {
  3311. var ret = FS.analyzePath(path, dontResolveLastLink);
  3312. if (!ret.exists) {
  3313. return null;
  3314. }
  3315. return ret.object;
  3316. },
  3317. analyzePath(path, dontResolveLastLink) {
  3318. // operate from within the context of the symlink's target
  3319. try {
  3320. var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
  3321. path = lookup.path;
  3322. } catch (e) {
  3323. }
  3324. var ret = {
  3325. isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
  3326. parentExists: false, parentPath: null, parentObject: null
  3327. };
  3328. try {
  3329. var lookup = FS.lookupPath(path, { parent: true });
  3330. ret.parentExists = true;
  3331. ret.parentPath = lookup.path;
  3332. ret.parentObject = lookup.node;
  3333. ret.name = PATH.basename(path);
  3334. lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
  3335. ret.exists = true;
  3336. ret.path = lookup.path;
  3337. ret.object = lookup.node;
  3338. ret.name = lookup.node.name;
  3339. ret.isRoot = lookup.path === '/';
  3340. } catch (e) {
  3341. ret.error = e.errno;
  3342. };
  3343. return ret;
  3344. },
  3345. createPath(parent, path, canRead, canWrite) {
  3346. parent = typeof parent == 'string' ? parent : FS.getPath(parent);
  3347. var parts = path.split('/').reverse();
  3348. while (parts.length) {
  3349. var part = parts.pop();
  3350. if (!part) continue;
  3351. var current = PATH.join2(parent, part);
  3352. try {
  3353. FS.mkdir(current);
  3354. } catch (e) {
  3355. // ignore EEXIST
  3356. }
  3357. parent = current;
  3358. }
  3359. return current;
  3360. },
  3361. createFile(parent, name, properties, canRead, canWrite) {
  3362. var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name);
  3363. var mode = FS_getMode(canRead, canWrite);
  3364. return FS.create(path, mode);
  3365. },
  3366. createDataFile(parent, name, data, canRead, canWrite, canOwn) {
  3367. var path = name;
  3368. if (parent) {
  3369. parent = typeof parent == 'string' ? parent : FS.getPath(parent);
  3370. path = name ? PATH.join2(parent, name) : parent;
  3371. }
  3372. var mode = FS_getMode(canRead, canWrite);
  3373. var node = FS.create(path, mode);
  3374. if (data) {
  3375. if (typeof data == 'string') {
  3376. var arr = new Array(data.length);
  3377. for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
  3378. data = arr;
  3379. }
  3380. // make sure we can write to the file
  3381. FS.chmod(node, mode | 146);
  3382. var stream = FS.open(node, 577);
  3383. FS.write(stream, data, 0, data.length, 0, canOwn);
  3384. FS.close(stream);
  3385. FS.chmod(node, mode);
  3386. }
  3387. },
  3388. createDevice(parent, name, input, output) {
  3389. var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name);
  3390. var mode = FS_getMode(!!input, !!output);
  3391. if (!FS.createDevice.major) FS.createDevice.major = 64;
  3392. var dev = FS.makedev(FS.createDevice.major++, 0);
  3393. // Create a fake device that a set of stream ops to emulate
  3394. // the old behavior.
  3395. FS.registerDevice(dev, {
  3396. open(stream) {
  3397. stream.seekable = false;
  3398. },
  3399. close(stream) {
  3400. // flush any pending line data
  3401. if (output?.buffer?.length) {
  3402. output(10);
  3403. }
  3404. },
  3405. read(stream, buffer, offset, length, pos /* ignored */) {
  3406. var bytesRead = 0;
  3407. for (var i = 0; i < length; i++) {
  3408. var result;
  3409. try {
  3410. result = input();
  3411. } catch (e) {
  3412. throw new FS.ErrnoError(29);
  3413. }
  3414. if (result === undefined && bytesRead === 0) {
  3415. throw new FS.ErrnoError(6);
  3416. }
  3417. if (result === null || result === undefined) break;
  3418. bytesRead++;
  3419. buffer[offset+i] = result;
  3420. }
  3421. if (bytesRead) {
  3422. stream.node.timestamp = Date.now();
  3423. }
  3424. return bytesRead;
  3425. },
  3426. write(stream, buffer, offset, length, pos) {
  3427. for (var i = 0; i < length; i++) {
  3428. try {
  3429. output(buffer[offset+i]);
  3430. } catch (e) {
  3431. throw new FS.ErrnoError(29);
  3432. }
  3433. }
  3434. if (length) {
  3435. stream.node.timestamp = Date.now();
  3436. }
  3437. return i;
  3438. }
  3439. });
  3440. return FS.mkdev(path, mode, dev);
  3441. },
  3442. forceLoadFile(obj) {
  3443. if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
  3444. if (typeof XMLHttpRequest != 'undefined') {
  3445. throw new Error("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.");
  3446. } else if (read_) {
  3447. // Command-line.
  3448. try {
  3449. // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
  3450. // read() will try to parse UTF8.
  3451. obj.contents = intArrayFromString(read_(obj.url), true);
  3452. obj.usedBytes = obj.contents.length;
  3453. } catch (e) {
  3454. throw new FS.ErrnoError(29);
  3455. }
  3456. } else {
  3457. throw new Error('Cannot load without read() or XMLHttpRequest.');
  3458. }
  3459. },
  3460. createLazyFile(parent, name, url, canRead, canWrite) {
  3461. // Lazy chunked Uint8Array (implements get and length from Uint8Array).
  3462. // Actual getting is abstracted away for eventual reuse.
  3463. class LazyUint8Array {
  3464. constructor() {
  3465. this.lengthKnown = false;
  3466. this.chunks = []; // Loaded chunks. Index is the chunk number
  3467. }
  3468. get(idx) {
  3469. if (idx > this.length-1 || idx < 0) {
  3470. return undefined;
  3471. }
  3472. var chunkOffset = idx % this.chunkSize;
  3473. var chunkNum = (idx / this.chunkSize)|0;
  3474. return this.getter(chunkNum)[chunkOffset];
  3475. }
  3476. setDataGetter(getter) {
  3477. this.getter = getter;
  3478. }
  3479. cacheLength() {
  3480. // Find length
  3481. var xhr = new XMLHttpRequest();
  3482. xhr.open('HEAD', url, false);
  3483. xhr.send(null);
  3484. if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
  3485. var datalength = Number(xhr.getResponseHeader("Content-length"));
  3486. var header;
  3487. var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
  3488. var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";
  3489. var chunkSize = 1024*1024; // Chunk size in bytes
  3490. if (!hasByteServing) chunkSize = datalength;
  3491. // Function to get a range from the remote URL.
  3492. var doXHR = (from, to) => {
  3493. if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
  3494. if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
  3495. // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
  3496. var xhr = new XMLHttpRequest();
  3497. xhr.open('GET', url, false);
  3498. if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
  3499. // Some hints to the browser that we want binary data.
  3500. xhr.responseType = 'arraybuffer';
  3501. if (xhr.overrideMimeType) {
  3502. xhr.overrideMimeType('text/plain; charset=x-user-defined');
  3503. }
  3504. xhr.send(null);
  3505. if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
  3506. if (xhr.response !== undefined) {
  3507. return new Uint8Array(/** @type{Array<number>} */(xhr.response || []));
  3508. }
  3509. return intArrayFromString(xhr.responseText || '', true);
  3510. };
  3511. var lazyArray = this;
  3512. lazyArray.setDataGetter((chunkNum) => {
  3513. var start = chunkNum * chunkSize;
  3514. var end = (chunkNum+1) * chunkSize - 1; // including this byte
  3515. end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
  3516. if (typeof lazyArray.chunks[chunkNum] == 'undefined') {
  3517. lazyArray.chunks[chunkNum] = doXHR(start, end);
  3518. }
  3519. if (typeof lazyArray.chunks[chunkNum] == 'undefined') throw new Error('doXHR failed!');
  3520. return lazyArray.chunks[chunkNum];
  3521. });
  3522. if (usesGzip || !datalength) {
  3523. // if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length
  3524. chunkSize = datalength = 1; // this will force getter(0)/doXHR do download the whole file
  3525. datalength = this.getter(0).length;
  3526. chunkSize = datalength;
  3527. out("LazyFiles on gzip forces download of the whole file when length is accessed");
  3528. }
  3529. this._length = datalength;
  3530. this._chunkSize = chunkSize;
  3531. this.lengthKnown = true;
  3532. }
  3533. get length() {
  3534. if (!this.lengthKnown) {
  3535. this.cacheLength();
  3536. }
  3537. return this._length;
  3538. }
  3539. get chunkSize() {
  3540. if (!this.lengthKnown) {
  3541. this.cacheLength();
  3542. }
  3543. return this._chunkSize;
  3544. }
  3545. }
  3546. if (typeof XMLHttpRequest != 'undefined') {
  3547. if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
  3548. var lazyArray = new LazyUint8Array();
  3549. var properties = { isDevice: false, contents: lazyArray };
  3550. } else {
  3551. var properties = { isDevice: false, url: url };
  3552. }
  3553. var node = FS.createFile(parent, name, properties, canRead, canWrite);
  3554. // This is a total hack, but I want to get this lazy file code out of the
  3555. // core of MEMFS. If we want to keep this lazy file concept I feel it should
  3556. // be its own thin LAZYFS proxying calls to MEMFS.
  3557. if (properties.contents) {
  3558. node.contents = properties.contents;
  3559. } else if (properties.url) {
  3560. node.contents = null;
  3561. node.url = properties.url;
  3562. }
  3563. // Add a function that defers querying the file size until it is asked the first time.
  3564. Object.defineProperties(node, {
  3565. usedBytes: {
  3566. get: function() { return this.contents.length; }
  3567. }
  3568. });
  3569. // override each stream op with one that tries to force load the lazy file first
  3570. var stream_ops = {};
  3571. var keys = Object.keys(node.stream_ops);
  3572. keys.forEach((key) => {
  3573. var fn = node.stream_ops[key];
  3574. stream_ops[key] = (...args) => {
  3575. FS.forceLoadFile(node);
  3576. return fn(...args);
  3577. };
  3578. });
  3579. function writeChunks(stream, buffer, offset, length, position) {
  3580. var contents = stream.node.contents;
  3581. if (position >= contents.length)
  3582. return 0;
  3583. var size = Math.min(contents.length - position, length);
  3584. assert(size >= 0);
  3585. if (contents.slice) { // normal array
  3586. for (var i = 0; i < size; i++) {
  3587. buffer[offset + i] = contents[position + i];
  3588. }
  3589. } else {
  3590. for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
  3591. buffer[offset + i] = contents.get(position + i);
  3592. }
  3593. }
  3594. return size;
  3595. }
  3596. // use a custom read function
  3597. stream_ops.read = (stream, buffer, offset, length, position) => {
  3598. FS.forceLoadFile(node);
  3599. return writeChunks(stream, buffer, offset, length, position)
  3600. };
  3601. // use a custom mmap function
  3602. stream_ops.mmap = (stream, length, position, prot, flags) => {
  3603. FS.forceLoadFile(node);
  3604. var ptr = mmapAlloc(length);
  3605. if (!ptr) {
  3606. throw new FS.ErrnoError(48);
  3607. }
  3608. writeChunks(stream, HEAP8, ptr, length, position);
  3609. return { ptr, allocated: true };
  3610. };
  3611. node.stream_ops = stream_ops;
  3612. return node;
  3613. },
  3614. absolutePath() {
  3615. abort('FS.absolutePath has been removed; use PATH_FS.resolve instead');
  3616. },
  3617. createFolder() {
  3618. abort('FS.createFolder has been removed; use FS.mkdir instead');
  3619. },
  3620. createLink() {
  3621. abort('FS.createLink has been removed; use FS.symlink instead');
  3622. },
  3623. joinPath() {
  3624. abort('FS.joinPath has been removed; use PATH.join instead');
  3625. },
  3626. mmapAlloc() {
  3627. abort('FS.mmapAlloc has been replaced by the top level function mmapAlloc');
  3628. },
  3629. standardizePath() {
  3630. abort('FS.standardizePath has been removed; use PATH.normalize instead');
  3631. },
  3632. };
  3633. /**
  3634. * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
  3635. * emscripten HEAP, returns a copy of that string as a Javascript String object.
  3636. *
  3637. * @param {number} ptr
  3638. * @param {number=} maxBytesToRead - An optional length that specifies the
  3639. * maximum number of bytes to read. You can omit this parameter to scan the
  3640. * string until the first 0 byte. If maxBytesToRead is passed, and the string
  3641. * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
  3642. * string will cut short at that byte index (i.e. maxBytesToRead will not
  3643. * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing
  3644. * frequent uses of UTF8ToString() with and without maxBytesToRead may throw
  3645. * JS JIT optimizations off, so it is worth to consider consistently using one
  3646. * @return {string}
  3647. */
  3648. var UTF8ToString = (ptr, maxBytesToRead) => {
  3649. assert(typeof ptr == 'number', `UTF8ToString expects a number (got ${typeof ptr})`);
  3650. return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';
  3651. };
  3652. var SYSCALLS = {
  3653. DEFAULT_POLLMASK:5,
  3654. calculateAt(dirfd, path, allowEmpty) {
  3655. if (PATH.isAbs(path)) {
  3656. return path;
  3657. }
  3658. // relative path
  3659. var dir;
  3660. if (dirfd === -100) {
  3661. dir = FS.cwd();
  3662. } else {
  3663. var dirstream = SYSCALLS.getStreamFromFD(dirfd);
  3664. dir = dirstream.path;
  3665. }
  3666. if (path.length == 0) {
  3667. if (!allowEmpty) {
  3668. throw new FS.ErrnoError(44);;
  3669. }
  3670. return dir;
  3671. }
  3672. return PATH.join2(dir, path);
  3673. },
  3674. doStat(func, path, buf) {
  3675. var stat = func(path);
  3676. HEAP32[((buf)>>2)] = stat.dev;
  3677. HEAP32[(((buf)+(4))>>2)] = stat.mode;
  3678. HEAPU32[(((buf)+(8))>>2)] = stat.nlink;
  3679. HEAP32[(((buf)+(12))>>2)] = stat.uid;
  3680. HEAP32[(((buf)+(16))>>2)] = stat.gid;
  3681. HEAP32[(((buf)+(20))>>2)] = stat.rdev;
  3682. HEAP64[(((buf)+(24))>>3)] = BigInt(stat.size);
  3683. HEAP32[(((buf)+(32))>>2)] = 4096;
  3684. HEAP32[(((buf)+(36))>>2)] = stat.blocks;
  3685. var atime = stat.atime.getTime();
  3686. var mtime = stat.mtime.getTime();
  3687. var ctime = stat.ctime.getTime();
  3688. HEAP64[(((buf)+(40))>>3)] = BigInt(Math.floor(atime / 1000));
  3689. HEAPU32[(((buf)+(48))>>2)] = (atime % 1000) * 1000;
  3690. HEAP64[(((buf)+(56))>>3)] = BigInt(Math.floor(mtime / 1000));
  3691. HEAPU32[(((buf)+(64))>>2)] = (mtime % 1000) * 1000;
  3692. HEAP64[(((buf)+(72))>>3)] = BigInt(Math.floor(ctime / 1000));
  3693. HEAPU32[(((buf)+(80))>>2)] = (ctime % 1000) * 1000;
  3694. HEAP64[(((buf)+(88))>>3)] = BigInt(stat.ino);
  3695. return 0;
  3696. },
  3697. doMsync(addr, stream, len, flags, offset) {
  3698. if (!FS.isFile(stream.node.mode)) {
  3699. throw new FS.ErrnoError(43);
  3700. }
  3701. if (flags & 2) {
  3702. // MAP_PRIVATE calls need not to be synced back to underlying fs
  3703. return 0;
  3704. }
  3705. var buffer = HEAPU8.slice(addr, addr + len);
  3706. FS.msync(stream, buffer, offset, len, flags);
  3707. },
  3708. getStreamFromFD(fd) {
  3709. var stream = FS.getStreamChecked(fd);
  3710. return stream;
  3711. },
  3712. varargs:undefined,
  3713. getStr(ptr) {
  3714. var ret = UTF8ToString(ptr);
  3715. return ret;
  3716. },
  3717. };
  3718. function ___syscall_fcntl64(fd, cmd, varargs) {
  3719. SYSCALLS.varargs = varargs;
  3720. try {
  3721. var stream = SYSCALLS.getStreamFromFD(fd);
  3722. switch (cmd) {
  3723. case 0: {
  3724. var arg = syscallGetVarargI();
  3725. if (arg < 0) {
  3726. return -28;
  3727. }
  3728. while (FS.streams[arg]) {
  3729. arg++;
  3730. }
  3731. var newStream;
  3732. newStream = FS.dupStream(stream, arg);
  3733. return newStream.fd;
  3734. }
  3735. case 1:
  3736. case 2:
  3737. return 0; // FD_CLOEXEC makes no sense for a single process.
  3738. case 3:
  3739. return stream.flags;
  3740. case 4: {
  3741. var arg = syscallGetVarargI();
  3742. stream.flags |= arg;
  3743. return 0;
  3744. }
  3745. case 12: {
  3746. var arg = syscallGetVarargP();
  3747. var offset = 0;
  3748. // We're always unlocked.
  3749. HEAP16[(((arg)+(offset))>>1)] = 2;
  3750. return 0;
  3751. }
  3752. case 13:
  3753. case 14:
  3754. return 0; // Pretend that the locking is successful.
  3755. }
  3756. return -28;
  3757. } catch (e) {
  3758. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  3759. return -e.errno;
  3760. }
  3761. }
  3762. function ___syscall_ioctl(fd, op, varargs) {
  3763. SYSCALLS.varargs = varargs;
  3764. try {
  3765. var stream = SYSCALLS.getStreamFromFD(fd);
  3766. switch (op) {
  3767. case 21509: {
  3768. if (!stream.tty) return -59;
  3769. return 0;
  3770. }
  3771. case 21505: {
  3772. if (!stream.tty) return -59;
  3773. if (stream.tty.ops.ioctl_tcgets) {
  3774. var termios = stream.tty.ops.ioctl_tcgets(stream);
  3775. var argp = syscallGetVarargP();
  3776. HEAP32[((argp)>>2)] = termios.c_iflag || 0;
  3777. HEAP32[(((argp)+(4))>>2)] = termios.c_oflag || 0;
  3778. HEAP32[(((argp)+(8))>>2)] = termios.c_cflag || 0;
  3779. HEAP32[(((argp)+(12))>>2)] = termios.c_lflag || 0;
  3780. for (var i = 0; i < 32; i++) {
  3781. HEAP8[(argp + i)+(17)] = termios.c_cc[i] || 0;
  3782. }
  3783. return 0;
  3784. }
  3785. return 0;
  3786. }
  3787. case 21510:
  3788. case 21511:
  3789. case 21512: {
  3790. if (!stream.tty) return -59;
  3791. return 0; // no-op, not actually adjusting terminal settings
  3792. }
  3793. case 21506:
  3794. case 21507:
  3795. case 21508: {
  3796. if (!stream.tty) return -59;
  3797. if (stream.tty.ops.ioctl_tcsets) {
  3798. var argp = syscallGetVarargP();
  3799. var c_iflag = HEAP32[((argp)>>2)];
  3800. var c_oflag = HEAP32[(((argp)+(4))>>2)];
  3801. var c_cflag = HEAP32[(((argp)+(8))>>2)];
  3802. var c_lflag = HEAP32[(((argp)+(12))>>2)];
  3803. var c_cc = []
  3804. for (var i = 0; i < 32; i++) {
  3805. c_cc.push(HEAP8[(argp + i)+(17)]);
  3806. }
  3807. return stream.tty.ops.ioctl_tcsets(stream.tty, op, { c_iflag, c_oflag, c_cflag, c_lflag, c_cc });
  3808. }
  3809. return 0; // no-op, not actually adjusting terminal settings
  3810. }
  3811. case 21519: {
  3812. if (!stream.tty) return -59;
  3813. var argp = syscallGetVarargP();
  3814. HEAP32[((argp)>>2)] = 0;
  3815. return 0;
  3816. }
  3817. case 21520: {
  3818. if (!stream.tty) return -59;
  3819. return -28; // not supported
  3820. }
  3821. case 21531: {
  3822. var argp = syscallGetVarargP();
  3823. return FS.ioctl(stream, op, argp);
  3824. }
  3825. case 21523: {
  3826. // TODO: in theory we should write to the winsize struct that gets
  3827. // passed in, but for now musl doesn't read anything on it
  3828. if (!stream.tty) return -59;
  3829. if (stream.tty.ops.ioctl_tiocgwinsz) {
  3830. var winsize = stream.tty.ops.ioctl_tiocgwinsz(stream.tty);
  3831. var argp = syscallGetVarargP();
  3832. HEAP16[((argp)>>1)] = winsize[0];
  3833. HEAP16[(((argp)+(2))>>1)] = winsize[1];
  3834. }
  3835. return 0;
  3836. }
  3837. case 21524: {
  3838. // TODO: technically, this ioctl call should change the window size.
  3839. // but, since emscripten doesn't have any concept of a terminal window
  3840. // yet, we'll just silently throw it away as we do TIOCGWINSZ
  3841. if (!stream.tty) return -59;
  3842. return 0;
  3843. }
  3844. case 21515: {
  3845. if (!stream.tty) return -59;
  3846. return 0;
  3847. }
  3848. default: return -28; // not supported
  3849. }
  3850. } catch (e) {
  3851. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  3852. return -e.errno;
  3853. }
  3854. }
  3855. function ___syscall_openat(dirfd, path, flags, varargs) {
  3856. SYSCALLS.varargs = varargs;
  3857. try {
  3858. path = SYSCALLS.getStr(path);
  3859. path = SYSCALLS.calculateAt(dirfd, path);
  3860. var mode = varargs ? syscallGetVarargI() : 0;
  3861. return FS.open(path, flags, mode).fd;
  3862. } catch (e) {
  3863. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  3864. return -e.errno;
  3865. }
  3866. }
  3867. var __abort_js = () => {
  3868. abort('native code called abort()');
  3869. };
  3870. var nowIsMonotonic = 1;
  3871. var __emscripten_get_now_is_monotonic = () => nowIsMonotonic;
  3872. var __emscripten_throw_longjmp = () => {
  3873. throw Infinity;
  3874. };
  3875. var MAX_INT53 = 9007199254740992;
  3876. var MIN_INT53 = -9007199254740992;
  3877. var bigintToI53Checked = (num) => (num < MIN_INT53 || num > MAX_INT53) ? NaN : Number(num);
  3878. function __gmtime_js(time, tmPtr) {
  3879. time = bigintToI53Checked(time);
  3880. var date = new Date(time * 1000);
  3881. HEAP32[((tmPtr)>>2)] = date.getUTCSeconds();
  3882. HEAP32[(((tmPtr)+(4))>>2)] = date.getUTCMinutes();
  3883. HEAP32[(((tmPtr)+(8))>>2)] = date.getUTCHours();
  3884. HEAP32[(((tmPtr)+(12))>>2)] = date.getUTCDate();
  3885. HEAP32[(((tmPtr)+(16))>>2)] = date.getUTCMonth();
  3886. HEAP32[(((tmPtr)+(20))>>2)] = date.getUTCFullYear()-1900;
  3887. HEAP32[(((tmPtr)+(24))>>2)] = date.getUTCDay();
  3888. var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0);
  3889. var yday = ((date.getTime() - start) / (1000 * 60 * 60 * 24))|0;
  3890. HEAP32[(((tmPtr)+(28))>>2)] = yday;
  3891. ;
  3892. }
  3893. var stringToUTF8 = (str, outPtr, maxBytesToWrite) => {
  3894. assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
  3895. return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
  3896. };
  3897. var __tzset_js = (timezone, daylight, std_name, dst_name) => {
  3898. // TODO: Use (malleable) environment variables instead of system settings.
  3899. var currentYear = new Date().getFullYear();
  3900. var winter = new Date(currentYear, 0, 1);
  3901. var summer = new Date(currentYear, 6, 1);
  3902. var winterOffset = winter.getTimezoneOffset();
  3903. var summerOffset = summer.getTimezoneOffset();
  3904. // Local standard timezone offset. Local standard time is not adjusted for
  3905. // daylight savings. This code uses the fact that getTimezoneOffset returns
  3906. // a greater value during Standard Time versus Daylight Saving Time (DST).
  3907. // Thus it determines the expected output during Standard Time, and it
  3908. // compares whether the output of the given date the same (Standard) or less
  3909. // (DST).
  3910. var stdTimezoneOffset = Math.max(winterOffset, summerOffset);
  3911. // timezone is specified as seconds west of UTC ("The external variable
  3912. // `timezone` shall be set to the difference, in seconds, between
  3913. // Coordinated Universal Time (UTC) and local standard time."), the same
  3914. // as returned by stdTimezoneOffset.
  3915. // See http://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html
  3916. HEAPU32[((timezone)>>2)] = stdTimezoneOffset * 60;
  3917. HEAP32[((daylight)>>2)] = Number(winterOffset != summerOffset);
  3918. var extractZone = (date) => date.toLocaleTimeString(undefined, {hour12:false, timeZoneName:'short'}).split(' ')[1];
  3919. var winterName = extractZone(winter);
  3920. var summerName = extractZone(summer);
  3921. assert(winterName);
  3922. assert(summerName);
  3923. assert(lengthBytesUTF8(winterName) <= 16, `timezone name truncated to fit in TZNAME_MAX (${winterName})`);
  3924. assert(lengthBytesUTF8(summerName) <= 16, `timezone name truncated to fit in TZNAME_MAX (${summerName})`);
  3925. if (summerOffset < winterOffset) {
  3926. // Northern hemisphere
  3927. stringToUTF8(winterName, std_name, 17);
  3928. stringToUTF8(summerName, dst_name, 17);
  3929. } else {
  3930. stringToUTF8(winterName, dst_name, 17);
  3931. stringToUTF8(summerName, std_name, 17);
  3932. }
  3933. };
  3934. var runtimeKeepaliveCounter = 0;
  3935. var runtimeKeepalivePush = () => {
  3936. runtimeKeepaliveCounter += 1;
  3937. };
  3938. var _emscripten_set_main_loop_timing = (mode, value) => {
  3939. Browser.mainLoop.timingMode = mode;
  3940. Browser.mainLoop.timingValue = value;
  3941. if (!Browser.mainLoop.func) {
  3942. 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.');
  3943. return 1; // Return non-zero on failure, can't set timing mode when there is no main loop.
  3944. }
  3945. if (!Browser.mainLoop.running) {
  3946. runtimeKeepalivePush();
  3947. Browser.mainLoop.running = true;
  3948. }
  3949. if (mode == 0) {
  3950. Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_setTimeout() {
  3951. var timeUntilNextTick = Math.max(0, Browser.mainLoop.tickStartTime + value - _emscripten_get_now())|0;
  3952. setTimeout(Browser.mainLoop.runner, timeUntilNextTick); // doing this each time means that on exception, we stop
  3953. };
  3954. Browser.mainLoop.method = 'timeout';
  3955. } else if (mode == 1) {
  3956. Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_rAF() {
  3957. Browser.requestAnimationFrame(Browser.mainLoop.runner);
  3958. };
  3959. Browser.mainLoop.method = 'rAF';
  3960. } else if (mode == 2) {
  3961. if (typeof Browser.setImmediate == 'undefined') {
  3962. if (typeof setImmediate == 'undefined') {
  3963. // Emulate setImmediate. (note: not a complete polyfill, we don't emulate clearImmediate() to keep code size to minimum, since not needed)
  3964. var setImmediates = [];
  3965. var emscriptenMainLoopMessageId = 'setimmediate';
  3966. /** @param {Event} event */
  3967. var Browser_setImmediate_messageHandler = (event) => {
  3968. // When called in current thread or Worker, the main loop ID is structured slightly different to accommodate for --proxy-to-worker runtime listening to Worker events,
  3969. // so check for both cases.
  3970. if (event.data === emscriptenMainLoopMessageId || event.data.target === emscriptenMainLoopMessageId) {
  3971. event.stopPropagation();
  3972. setImmediates.shift()();
  3973. }
  3974. };
  3975. addEventListener("message", Browser_setImmediate_messageHandler, true);
  3976. Browser.setImmediate = /** @type{function(function(): ?, ...?): number} */(function Browser_emulated_setImmediate(func) {
  3977. setImmediates.push(func);
  3978. if (ENVIRONMENT_IS_WORKER) {
  3979. if (Module['setImmediates'] === undefined) Module['setImmediates'] = [];
  3980. Module['setImmediates'].push(func);
  3981. postMessage({target: emscriptenMainLoopMessageId}); // In --proxy-to-worker, route the message via proxyClient.js
  3982. } else postMessage(emscriptenMainLoopMessageId, "*"); // On the main thread, can just send the message to itself.
  3983. });
  3984. } else {
  3985. Browser.setImmediate = setImmediate;
  3986. }
  3987. }
  3988. Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_setImmediate() {
  3989. Browser.setImmediate(Browser.mainLoop.runner);
  3990. };
  3991. Browser.mainLoop.method = 'immediate';
  3992. }
  3993. return 0;
  3994. };
  3995. var _emscripten_get_now;
  3996. // Modern environment where performance.now() is supported:
  3997. // N.B. a shorter form "_emscripten_get_now = performance.now;" is
  3998. // unfortunately not allowed even in current browsers (e.g. FF Nightly 75).
  3999. _emscripten_get_now = () => performance.now();
  4000. ;
  4001. var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0;
  4002. var _proc_exit = (code) => {
  4003. EXITSTATUS = code;
  4004. if (!keepRuntimeAlive()) {
  4005. Module['onExit']?.(code);
  4006. ABORT = true;
  4007. }
  4008. quit_(code, new ExitStatus(code));
  4009. };
  4010. /** @suppress {duplicate } */
  4011. /** @param {boolean|number=} implicit */
  4012. var exitJS = (status, implicit) => {
  4013. EXITSTATUS = status;
  4014. if (!keepRuntimeAlive()) {
  4015. exitRuntime();
  4016. }
  4017. // if exit() was called explicitly, warn the user if the runtime isn't actually being shut down
  4018. if (keepRuntimeAlive() && !implicit) {
  4019. 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)`;
  4020. err(msg);
  4021. }
  4022. _proc_exit(status);
  4023. };
  4024. var _exit = exitJS;
  4025. var handleException = (e) => {
  4026. // Certain exception types we do not treat as errors since they are used for
  4027. // internal control flow.
  4028. // 1. ExitStatus, which is thrown by exit()
  4029. // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others
  4030. // that wish to return to JS event loop.
  4031. if (e instanceof ExitStatus || e == 'unwind') {
  4032. return EXITSTATUS;
  4033. }
  4034. checkStackCookie();
  4035. if (e instanceof WebAssembly.RuntimeError) {
  4036. if (_emscripten_stack_get_current() <= 0) {
  4037. err('Stack overflow detected. You can try increasing -sSTACK_SIZE (currently set to 65536)');
  4038. }
  4039. }
  4040. quit_(1, e);
  4041. };
  4042. var maybeExit = () => {
  4043. if (runtimeExited) {
  4044. return;
  4045. }
  4046. if (!keepRuntimeAlive()) {
  4047. try {
  4048. _exit(EXITSTATUS);
  4049. } catch (e) {
  4050. handleException(e);
  4051. }
  4052. }
  4053. };
  4054. var runtimeKeepalivePop = () => {
  4055. assert(runtimeKeepaliveCounter > 0);
  4056. runtimeKeepaliveCounter -= 1;
  4057. };
  4058. /**
  4059. * @param {number=} arg
  4060. * @param {boolean=} noSetTiming
  4061. */
  4062. var setMainLoop = (browserIterationFunc, fps, simulateInfiniteLoop, arg, noSetTiming) => {
  4063. assert(!Browser.mainLoop.func, 'emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.');
  4064. Browser.mainLoop.func = browserIterationFunc;
  4065. Browser.mainLoop.arg = arg;
  4066. // Closure compiler bug(?): Closure does not see that the assignment
  4067. // var thisMainLoopId = Browser.mainLoop.currentlyRunningMainloop
  4068. // is a value copy of a number (even with the JSDoc @type annotation)
  4069. // but optimizeis the code as if the assignment was a reference assignment,
  4070. // which results in Browser.mainLoop.pause() not working. Hence use a
  4071. // workaround to make Closure believe this is a value copy that should occur:
  4072. // (TODO: Minimize this down to a small test case and report - was unable
  4073. // to reproduce in a small written test case)
  4074. /** @type{number} */
  4075. var thisMainLoopId = (() => Browser.mainLoop.currentlyRunningMainloop)();
  4076. function checkIsRunning() {
  4077. if (thisMainLoopId < Browser.mainLoop.currentlyRunningMainloop) {
  4078. runtimeKeepalivePop();
  4079. maybeExit();
  4080. return false;
  4081. }
  4082. return true;
  4083. }
  4084. // We create the loop runner here but it is not actually running until
  4085. // _emscripten_set_main_loop_timing is called (which might happen a
  4086. // later time). This member signifies that the current runner has not
  4087. // yet been started so that we can call runtimeKeepalivePush when it
  4088. // gets it timing set for the first time.
  4089. Browser.mainLoop.running = false;
  4090. Browser.mainLoop.runner = function Browser_mainLoop_runner() {
  4091. if (ABORT) return;
  4092. if (Browser.mainLoop.queue.length > 0) {
  4093. var start = Date.now();
  4094. var blocker = Browser.mainLoop.queue.shift();
  4095. blocker.func(blocker.arg);
  4096. if (Browser.mainLoop.remainingBlockers) {
  4097. var remaining = Browser.mainLoop.remainingBlockers;
  4098. var next = remaining%1 == 0 ? remaining-1 : Math.floor(remaining);
  4099. if (blocker.counted) {
  4100. Browser.mainLoop.remainingBlockers = next;
  4101. } else {
  4102. // not counted, but move the progress along a tiny bit
  4103. next = next + 0.5; // do not steal all the next one's progress
  4104. Browser.mainLoop.remainingBlockers = (8*remaining + next)/9;
  4105. }
  4106. }
  4107. Browser.mainLoop.updateStatus();
  4108. // catches pause/resume main loop from blocker execution
  4109. if (!checkIsRunning()) return;
  4110. setTimeout(Browser.mainLoop.runner, 0);
  4111. return;
  4112. }
  4113. // catch pauses from non-main loop sources
  4114. if (!checkIsRunning()) return;
  4115. // Implement very basic swap interval control
  4116. Browser.mainLoop.currentFrameNumber = Browser.mainLoop.currentFrameNumber + 1 | 0;
  4117. if (Browser.mainLoop.timingMode == 1 && Browser.mainLoop.timingValue > 1 && Browser.mainLoop.currentFrameNumber % Browser.mainLoop.timingValue != 0) {
  4118. // Not the scheduled time to render this frame - skip.
  4119. Browser.mainLoop.scheduler();
  4120. return;
  4121. } else if (Browser.mainLoop.timingMode == 0) {
  4122. Browser.mainLoop.tickStartTime = _emscripten_get_now();
  4123. }
  4124. // Signal GL rendering layer that processing of a new frame is about to start. This helps it optimize
  4125. // VBO double-buffering and reduce GPU stalls.
  4126. if (Browser.mainLoop.method === 'timeout' && Module.ctx) {
  4127. 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!');
  4128. Browser.mainLoop.method = ''; // just warn once per call to set main loop
  4129. }
  4130. Browser.mainLoop.runIter(browserIterationFunc);
  4131. checkStackCookie();
  4132. // catch pauses from the main loop itself
  4133. if (!checkIsRunning()) return;
  4134. // Queue new audio data. This is important to be right after the main loop invocation, so that we will immediately be able
  4135. // to queue the newest produced audio samples.
  4136. // TODO: Consider adding pre- and post- rAF callbacks so that GL.newRenderingFrameStarted() and SDL.audio.queueNewAudioData()
  4137. // do not need to be hardcoded into this function, but can be more generic.
  4138. if (typeof SDL == 'object') SDL.audio?.queueNewAudioData?.();
  4139. Browser.mainLoop.scheduler();
  4140. }
  4141. if (!noSetTiming) {
  4142. if (fps && fps > 0) {
  4143. _emscripten_set_main_loop_timing(0, 1000.0 / fps);
  4144. } else {
  4145. // Do rAF by rendering each frame (no decimating)
  4146. _emscripten_set_main_loop_timing(1, 1);
  4147. }
  4148. Browser.mainLoop.scheduler();
  4149. }
  4150. if (simulateInfiniteLoop) {
  4151. throw 'unwind';
  4152. }
  4153. };
  4154. var callUserCallback = (func) => {
  4155. if (runtimeExited || ABORT) {
  4156. err('user callback triggered after runtime exited or application aborted. Ignoring.');
  4157. return;
  4158. }
  4159. try {
  4160. func();
  4161. maybeExit();
  4162. } catch (e) {
  4163. handleException(e);
  4164. }
  4165. };
  4166. /** @param {number=} timeout */
  4167. var safeSetTimeout = (func, timeout) => {
  4168. runtimeKeepalivePush();
  4169. return setTimeout(() => {
  4170. runtimeKeepalivePop();
  4171. callUserCallback(func);
  4172. }, timeout);
  4173. };
  4174. var Browser = {
  4175. mainLoop:{
  4176. running:false,
  4177. scheduler:null,
  4178. method:"",
  4179. currentlyRunningMainloop:0,
  4180. func:null,
  4181. arg:0,
  4182. timingMode:0,
  4183. timingValue:0,
  4184. currentFrameNumber:0,
  4185. queue:[],
  4186. pause() {
  4187. Browser.mainLoop.scheduler = null;
  4188. // Incrementing this signals the previous main loop that it's now become old, and it must return.
  4189. Browser.mainLoop.currentlyRunningMainloop++;
  4190. },
  4191. resume() {
  4192. Browser.mainLoop.currentlyRunningMainloop++;
  4193. var timingMode = Browser.mainLoop.timingMode;
  4194. var timingValue = Browser.mainLoop.timingValue;
  4195. var func = Browser.mainLoop.func;
  4196. Browser.mainLoop.func = null;
  4197. // do not set timing and call scheduler, we will do it on the next lines
  4198. setMainLoop(func, 0, false, Browser.mainLoop.arg, true);
  4199. _emscripten_set_main_loop_timing(timingMode, timingValue);
  4200. Browser.mainLoop.scheduler();
  4201. },
  4202. updateStatus() {
  4203. if (Module['setStatus']) {
  4204. var message = Module['statusMessage'] || 'Please wait...';
  4205. var remaining = Browser.mainLoop.remainingBlockers;
  4206. var expected = Browser.mainLoop.expectedBlockers;
  4207. if (remaining) {
  4208. if (remaining < expected) {
  4209. Module['setStatus'](`{message} ({expected - remaining}/{expected})`);
  4210. } else {
  4211. Module['setStatus'](message);
  4212. }
  4213. } else {
  4214. Module['setStatus']('');
  4215. }
  4216. }
  4217. },
  4218. runIter(func) {
  4219. if (ABORT) return;
  4220. if (Module['preMainLoop']) {
  4221. var preRet = Module['preMainLoop']();
  4222. if (preRet === false) {
  4223. return; // |return false| skips a frame
  4224. }
  4225. }
  4226. callUserCallback(func);
  4227. Module['postMainLoop']?.();
  4228. },
  4229. },
  4230. isFullscreen:false,
  4231. pointerLock:false,
  4232. moduleContextCreatedCallbacks:[],
  4233. workers:[],
  4234. init() {
  4235. if (Browser.initted) return;
  4236. Browser.initted = true;
  4237. // Support for plugins that can process preloaded files. You can add more of these to
  4238. // your app by creating and appending to preloadPlugins.
  4239. //
  4240. // Each plugin is asked if it can handle a file based on the file's name. If it can,
  4241. // it is given the file's raw data. When it is done, it calls a callback with the file's
  4242. // (possibly modified) data. For example, a plugin might decompress a file, or it
  4243. // might create some side data structure for use later (like an Image element, etc.).
  4244. var imagePlugin = {};
  4245. imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
  4246. return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name);
  4247. };
  4248. imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
  4249. var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
  4250. if (b.size !== byteArray.length) { // Safari bug #118630
  4251. // Safari's Blob can only take an ArrayBuffer
  4252. b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
  4253. }
  4254. var url = URL.createObjectURL(b);
  4255. assert(typeof url == 'string', 'createObjectURL must return a url as a string');
  4256. var img = new Image();
  4257. img.onload = () => {
  4258. assert(img.complete, `Image ${name} could not be decoded`);
  4259. var canvas = /** @type {!HTMLCanvasElement} */ (document.createElement('canvas'));
  4260. canvas.width = img.width;
  4261. canvas.height = img.height;
  4262. var ctx = canvas.getContext('2d');
  4263. ctx.drawImage(img, 0, 0);
  4264. preloadedImages[name] = canvas;
  4265. URL.revokeObjectURL(url);
  4266. onload?.(byteArray);
  4267. };
  4268. img.onerror = (event) => {
  4269. err(`Image ${url} could not be decoded`);
  4270. onerror?.();
  4271. };
  4272. img.src = url;
  4273. };
  4274. preloadPlugins.push(imagePlugin);
  4275. var audioPlugin = {};
  4276. audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
  4277. return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
  4278. };
  4279. audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
  4280. var done = false;
  4281. function finish(audio) {
  4282. if (done) return;
  4283. done = true;
  4284. preloadedAudios[name] = audio;
  4285. onload?.(byteArray);
  4286. }
  4287. function fail() {
  4288. if (done) return;
  4289. done = true;
  4290. preloadedAudios[name] = new Audio(); // empty shim
  4291. onerror?.();
  4292. }
  4293. var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
  4294. var url = URL.createObjectURL(b); // XXX we never revoke this!
  4295. assert(typeof url == 'string', 'createObjectURL must return a url as a string');
  4296. var audio = new Audio();
  4297. audio.addEventListener('canplaythrough', () => finish(audio), false); // use addEventListener due to chromium bug 124926
  4298. audio.onerror = function audio_onerror(event) {
  4299. if (done) return;
  4300. err(`warning: browser could not fully decode audio ${name}, trying slower base64 approach`);
  4301. function encode64(data) {
  4302. var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  4303. var PAD = '=';
  4304. var ret = '';
  4305. var leftchar = 0;
  4306. var leftbits = 0;
  4307. for (var i = 0; i < data.length; i++) {
  4308. leftchar = (leftchar << 8) | data[i];
  4309. leftbits += 8;
  4310. while (leftbits >= 6) {
  4311. var curr = (leftchar >> (leftbits-6)) & 0x3f;
  4312. leftbits -= 6;
  4313. ret += BASE[curr];
  4314. }
  4315. }
  4316. if (leftbits == 2) {
  4317. ret += BASE[(leftchar&3) << 4];
  4318. ret += PAD + PAD;
  4319. } else if (leftbits == 4) {
  4320. ret += BASE[(leftchar&0xf) << 2];
  4321. ret += PAD;
  4322. }
  4323. return ret;
  4324. }
  4325. audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);
  4326. finish(audio); // we don't wait for confirmation this worked - but it's worth trying
  4327. };
  4328. audio.src = url;
  4329. // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
  4330. safeSetTimeout(() => {
  4331. finish(audio); // try to use it even though it is not necessarily ready to play
  4332. }, 10000);
  4333. };
  4334. preloadPlugins.push(audioPlugin);
  4335. // Canvas event setup
  4336. function pointerLockChange() {
  4337. Browser.pointerLock = document['pointerLockElement'] === Module['canvas'] ||
  4338. document['mozPointerLockElement'] === Module['canvas'] ||
  4339. document['webkitPointerLockElement'] === Module['canvas'] ||
  4340. document['msPointerLockElement'] === Module['canvas'];
  4341. }
  4342. var canvas = Module['canvas'];
  4343. if (canvas) {
  4344. // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
  4345. // Module['forcedAspectRatio'] = 4 / 3;
  4346. canvas.requestPointerLock = canvas['requestPointerLock'] ||
  4347. canvas['mozRequestPointerLock'] ||
  4348. canvas['webkitRequestPointerLock'] ||
  4349. canvas['msRequestPointerLock'] ||
  4350. (() => {});
  4351. canvas.exitPointerLock = document['exitPointerLock'] ||
  4352. document['mozExitPointerLock'] ||
  4353. document['webkitExitPointerLock'] ||
  4354. document['msExitPointerLock'] ||
  4355. (() => {}); // no-op if function does not exist
  4356. canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
  4357. document.addEventListener('pointerlockchange', pointerLockChange, false);
  4358. document.addEventListener('mozpointerlockchange', pointerLockChange, false);
  4359. document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
  4360. document.addEventListener('mspointerlockchange', pointerLockChange, false);
  4361. if (Module['elementPointerLock']) {
  4362. canvas.addEventListener("click", (ev) => {
  4363. if (!Browser.pointerLock && Module['canvas'].requestPointerLock) {
  4364. Module['canvas'].requestPointerLock();
  4365. ev.preventDefault();
  4366. }
  4367. }, false);
  4368. }
  4369. }
  4370. },
  4371. createContext(/** @type {HTMLCanvasElement} */ canvas, useWebGL, setInModule, webGLContextAttributes) {
  4372. if (useWebGL && Module.ctx && canvas == Module.canvas) return Module.ctx; // no need to recreate GL context if it's already been created for this canvas.
  4373. var ctx;
  4374. var contextHandle;
  4375. if (useWebGL) {
  4376. // For GLES2/desktop GL compatibility, adjust a few defaults to be different to WebGL defaults, so that they align better with the desktop defaults.
  4377. var contextAttributes = {
  4378. antialias: false,
  4379. alpha: false,
  4380. majorVersion: 1,
  4381. };
  4382. if (webGLContextAttributes) {
  4383. for (var attribute in webGLContextAttributes) {
  4384. contextAttributes[attribute] = webGLContextAttributes[attribute];
  4385. }
  4386. }
  4387. // 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
  4388. // actually compiled in because application is not doing any GL operations. TODO: Ideally if GL is not being used, this function
  4389. // Browser.createContext() should not even be emitted.
  4390. if (typeof GL != 'undefined') {
  4391. contextHandle = GL.createContext(canvas, contextAttributes);
  4392. if (contextHandle) {
  4393. ctx = GL.getContext(contextHandle).GLctx;
  4394. }
  4395. }
  4396. } else {
  4397. ctx = canvas.getContext('2d');
  4398. }
  4399. if (!ctx) return null;
  4400. if (setInModule) {
  4401. 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');
  4402. Module.ctx = ctx;
  4403. if (useWebGL) GL.makeContextCurrent(contextHandle);
  4404. Module.useWebGL = useWebGL;
  4405. Browser.moduleContextCreatedCallbacks.forEach((callback) => callback());
  4406. Browser.init();
  4407. }
  4408. return ctx;
  4409. },
  4410. destroyContext(canvas, useWebGL, setInModule) {},
  4411. fullscreenHandlersInstalled:false,
  4412. lockPointer:undefined,
  4413. resizeCanvas:undefined,
  4414. requestFullscreen(lockPointer, resizeCanvas) {
  4415. Browser.lockPointer = lockPointer;
  4416. Browser.resizeCanvas = resizeCanvas;
  4417. if (typeof Browser.lockPointer == 'undefined') Browser.lockPointer = true;
  4418. if (typeof Browser.resizeCanvas == 'undefined') Browser.resizeCanvas = false;
  4419. var canvas = Module['canvas'];
  4420. function fullscreenChange() {
  4421. Browser.isFullscreen = false;
  4422. var canvasContainer = canvas.parentNode;
  4423. if ((document['fullscreenElement'] || document['mozFullScreenElement'] ||
  4424. document['msFullscreenElement'] || document['webkitFullscreenElement'] ||
  4425. document['webkitCurrentFullScreenElement']) === canvasContainer) {
  4426. canvas.exitFullscreen = Browser.exitFullscreen;
  4427. if (Browser.lockPointer) canvas.requestPointerLock();
  4428. Browser.isFullscreen = true;
  4429. if (Browser.resizeCanvas) {
  4430. Browser.setFullscreenCanvasSize();
  4431. } else {
  4432. Browser.updateCanvasDimensions(canvas);
  4433. }
  4434. } else {
  4435. // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
  4436. canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
  4437. canvasContainer.parentNode.removeChild(canvasContainer);
  4438. if (Browser.resizeCanvas) {
  4439. Browser.setWindowedCanvasSize();
  4440. } else {
  4441. Browser.updateCanvasDimensions(canvas);
  4442. }
  4443. }
  4444. Module['onFullScreen']?.(Browser.isFullscreen);
  4445. Module['onFullscreen']?.(Browser.isFullscreen);
  4446. }
  4447. if (!Browser.fullscreenHandlersInstalled) {
  4448. Browser.fullscreenHandlersInstalled = true;
  4449. document.addEventListener('fullscreenchange', fullscreenChange, false);
  4450. document.addEventListener('mozfullscreenchange', fullscreenChange, false);
  4451. document.addEventListener('webkitfullscreenchange', fullscreenChange, false);
  4452. document.addEventListener('MSFullscreenChange', fullscreenChange, false);
  4453. }
  4454. // 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
  4455. var canvasContainer = document.createElement("div");
  4456. canvas.parentNode.insertBefore(canvasContainer, canvas);
  4457. canvasContainer.appendChild(canvas);
  4458. // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
  4459. canvasContainer.requestFullscreen = canvasContainer['requestFullscreen'] ||
  4460. canvasContainer['mozRequestFullScreen'] ||
  4461. canvasContainer['msRequestFullscreen'] ||
  4462. (canvasContainer['webkitRequestFullscreen'] ? () => canvasContainer['webkitRequestFullscreen'](Element['ALLOW_KEYBOARD_INPUT']) : null) ||
  4463. (canvasContainer['webkitRequestFullScreen'] ? () => canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) : null);
  4464. canvasContainer.requestFullscreen();
  4465. },
  4466. requestFullScreen() {
  4467. abort('Module.requestFullScreen has been replaced by Module.requestFullscreen (without a capital S)');
  4468. },
  4469. exitFullscreen() {
  4470. // This is workaround for chrome. Trying to exit from fullscreen
  4471. // not in fullscreen state will cause "TypeError: Document not active"
  4472. // in chrome. See https://github.com/emscripten-core/emscripten/pull/8236
  4473. if (!Browser.isFullscreen) {
  4474. return false;
  4475. }
  4476. var CFS = document['exitFullscreen'] ||
  4477. document['cancelFullScreen'] ||
  4478. document['mozCancelFullScreen'] ||
  4479. document['msExitFullscreen'] ||
  4480. document['webkitCancelFullScreen'] ||
  4481. (() => {});
  4482. CFS.apply(document, []);
  4483. return true;
  4484. },
  4485. nextRAF:0,
  4486. fakeRequestAnimationFrame(func) {
  4487. // try to keep 60fps between calls to here
  4488. var now = Date.now();
  4489. if (Browser.nextRAF === 0) {
  4490. Browser.nextRAF = now + 1000/60;
  4491. } else {
  4492. while (now + 2 >= Browser.nextRAF) { // fudge a little, to avoid timer jitter causing us to do lots of delay:0
  4493. Browser.nextRAF += 1000/60;
  4494. }
  4495. }
  4496. var delay = Math.max(Browser.nextRAF - now, 0);
  4497. setTimeout(func, delay);
  4498. },
  4499. requestAnimationFrame(func) {
  4500. if (typeof requestAnimationFrame == 'function') {
  4501. requestAnimationFrame(func);
  4502. return;
  4503. }
  4504. var RAF = Browser.fakeRequestAnimationFrame;
  4505. RAF(func);
  4506. },
  4507. safeSetTimeout(func, timeout) {
  4508. // Legacy function, this is used by the SDL2 port so we need to keep it
  4509. // around at least until that is updated.
  4510. // See https://github.com/libsdl-org/SDL/pull/6304
  4511. return safeSetTimeout(func, timeout);
  4512. },
  4513. safeRequestAnimationFrame(func) {
  4514. runtimeKeepalivePush();
  4515. return Browser.requestAnimationFrame(() => {
  4516. runtimeKeepalivePop();
  4517. callUserCallback(func);
  4518. });
  4519. },
  4520. getMimetype(name) {
  4521. return {
  4522. 'jpg': 'image/jpeg',
  4523. 'jpeg': 'image/jpeg',
  4524. 'png': 'image/png',
  4525. 'bmp': 'image/bmp',
  4526. 'ogg': 'audio/ogg',
  4527. 'wav': 'audio/wav',
  4528. 'mp3': 'audio/mpeg'
  4529. }[name.substr(name.lastIndexOf('.')+1)];
  4530. },
  4531. getUserMedia(func) {
  4532. window.getUserMedia ||= navigator['getUserMedia'] ||
  4533. navigator['mozGetUserMedia'];
  4534. window.getUserMedia(func);
  4535. },
  4536. getMovementX(event) {
  4537. return event['movementX'] ||
  4538. event['mozMovementX'] ||
  4539. event['webkitMovementX'] ||
  4540. 0;
  4541. },
  4542. getMovementY(event) {
  4543. return event['movementY'] ||
  4544. event['mozMovementY'] ||
  4545. event['webkitMovementY'] ||
  4546. 0;
  4547. },
  4548. getMouseWheelDelta(event) {
  4549. var delta = 0;
  4550. switch (event.type) {
  4551. case 'DOMMouseScroll':
  4552. // 3 lines make up a step
  4553. delta = event.detail / 3;
  4554. break;
  4555. case 'mousewheel':
  4556. // 120 units make up a step
  4557. delta = event.wheelDelta / 120;
  4558. break;
  4559. case 'wheel':
  4560. delta = event.deltaY
  4561. switch (event.deltaMode) {
  4562. case 0:
  4563. // DOM_DELTA_PIXEL: 100 pixels make up a step
  4564. delta /= 100;
  4565. break;
  4566. case 1:
  4567. // DOM_DELTA_LINE: 3 lines make up a step
  4568. delta /= 3;
  4569. break;
  4570. case 2:
  4571. // DOM_DELTA_PAGE: A page makes up 80 steps
  4572. delta *= 80;
  4573. break;
  4574. default:
  4575. throw 'unrecognized mouse wheel delta mode: ' + event.deltaMode;
  4576. }
  4577. break;
  4578. default:
  4579. throw 'unrecognized mouse wheel event: ' + event.type;
  4580. }
  4581. return delta;
  4582. },
  4583. mouseX:0,
  4584. mouseY:0,
  4585. mouseMovementX:0,
  4586. mouseMovementY:0,
  4587. touches:{
  4588. },
  4589. lastTouches:{
  4590. },
  4591. calculateMouseCoords(pageX, pageY) {
  4592. // Calculate the movement based on the changes
  4593. // in the coordinates.
  4594. var rect = Module["canvas"].getBoundingClientRect();
  4595. var cw = Module["canvas"].width;
  4596. var ch = Module["canvas"].height;
  4597. // Neither .scrollX or .pageXOffset are defined in a spec, but
  4598. // we prefer .scrollX because it is currently in a spec draft.
  4599. // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
  4600. var scrollX = ((typeof window.scrollX != 'undefined') ? window.scrollX : window.pageXOffset);
  4601. var scrollY = ((typeof window.scrollY != 'undefined') ? window.scrollY : window.pageYOffset);
  4602. // If this assert lands, it's likely because the browser doesn't support scrollX or pageXOffset
  4603. // and we have no viable fallback.
  4604. assert((typeof scrollX != 'undefined') && (typeof scrollY != 'undefined'), 'Unable to retrieve scroll position, mouse positions likely broken.');
  4605. var adjustedX = pageX - (scrollX + rect.left);
  4606. var adjustedY = pageY - (scrollY + rect.top);
  4607. // the canvas might be CSS-scaled compared to its backbuffer;
  4608. // SDL-using content will want mouse coordinates in terms
  4609. // of backbuffer units.
  4610. adjustedX = adjustedX * (cw / rect.width);
  4611. adjustedY = adjustedY * (ch / rect.height);
  4612. return { x: adjustedX, y: adjustedY };
  4613. },
  4614. setMouseCoords(pageX, pageY) {
  4615. const {x, y} = Browser.calculateMouseCoords(pageX, pageY);
  4616. Browser.mouseMovementX = x - Browser.mouseX;
  4617. Browser.mouseMovementY = y - Browser.mouseY;
  4618. Browser.mouseX = x;
  4619. Browser.mouseY = y;
  4620. },
  4621. calculateMouseEvent(event) { // event should be mousemove, mousedown or mouseup
  4622. if (Browser.pointerLock) {
  4623. // When the pointer is locked, calculate the coordinates
  4624. // based on the movement of the mouse.
  4625. // Workaround for Firefox bug 764498
  4626. if (event.type != 'mousemove' &&
  4627. ('mozMovementX' in event)) {
  4628. Browser.mouseMovementX = Browser.mouseMovementY = 0;
  4629. } else {
  4630. Browser.mouseMovementX = Browser.getMovementX(event);
  4631. Browser.mouseMovementY = Browser.getMovementY(event);
  4632. }
  4633. // add the mouse delta to the current absolute mouse position
  4634. Browser.mouseX += Browser.mouseMovementX;
  4635. Browser.mouseY += Browser.mouseMovementY;
  4636. } else {
  4637. if (event.type === 'touchstart' || event.type === 'touchend' || event.type === 'touchmove') {
  4638. var touch = event.touch;
  4639. if (touch === undefined) {
  4640. return; // the "touch" property is only defined in SDL
  4641. }
  4642. var coords = Browser.calculateMouseCoords(touch.pageX, touch.pageY);
  4643. if (event.type === 'touchstart') {
  4644. Browser.lastTouches[touch.identifier] = coords;
  4645. Browser.touches[touch.identifier] = coords;
  4646. } else if (event.type === 'touchend' || event.type === 'touchmove') {
  4647. var last = Browser.touches[touch.identifier];
  4648. last ||= coords;
  4649. Browser.lastTouches[touch.identifier] = last;
  4650. Browser.touches[touch.identifier] = coords;
  4651. }
  4652. return;
  4653. }
  4654. Browser.setMouseCoords(event.pageX, event.pageY);
  4655. }
  4656. },
  4657. resizeListeners:[],
  4658. updateResizeListeners() {
  4659. var canvas = Module['canvas'];
  4660. Browser.resizeListeners.forEach((listener) => listener(canvas.width, canvas.height));
  4661. },
  4662. setCanvasSize(width, height, noUpdates) {
  4663. var canvas = Module['canvas'];
  4664. Browser.updateCanvasDimensions(canvas, width, height);
  4665. if (!noUpdates) Browser.updateResizeListeners();
  4666. },
  4667. windowedWidth:0,
  4668. windowedHeight:0,
  4669. setFullscreenCanvasSize() {
  4670. // check if SDL is available
  4671. if (typeof SDL != "undefined") {
  4672. var flags = HEAPU32[((SDL.screen)>>2)];
  4673. flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
  4674. HEAP32[((SDL.screen)>>2)] = flags;
  4675. }
  4676. Browser.updateCanvasDimensions(Module['canvas']);
  4677. Browser.updateResizeListeners();
  4678. },
  4679. setWindowedCanvasSize() {
  4680. // check if SDL is available
  4681. if (typeof SDL != "undefined") {
  4682. var flags = HEAPU32[((SDL.screen)>>2)];
  4683. flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
  4684. HEAP32[((SDL.screen)>>2)] = flags;
  4685. }
  4686. Browser.updateCanvasDimensions(Module['canvas']);
  4687. Browser.updateResizeListeners();
  4688. },
  4689. updateCanvasDimensions(canvas, wNative, hNative) {
  4690. if (wNative && hNative) {
  4691. canvas.widthNative = wNative;
  4692. canvas.heightNative = hNative;
  4693. } else {
  4694. wNative = canvas.widthNative;
  4695. hNative = canvas.heightNative;
  4696. }
  4697. var w = wNative;
  4698. var h = hNative;
  4699. if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
  4700. if (w/h < Module['forcedAspectRatio']) {
  4701. w = Math.round(h * Module['forcedAspectRatio']);
  4702. } else {
  4703. h = Math.round(w / Module['forcedAspectRatio']);
  4704. }
  4705. }
  4706. if (((document['fullscreenElement'] || document['mozFullScreenElement'] ||
  4707. document['msFullscreenElement'] || document['webkitFullscreenElement'] ||
  4708. document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
  4709. var factor = Math.min(screen.width / w, screen.height / h);
  4710. w = Math.round(w * factor);
  4711. h = Math.round(h * factor);
  4712. }
  4713. if (Browser.resizeCanvas) {
  4714. if (canvas.width != w) canvas.width = w;
  4715. if (canvas.height != h) canvas.height = h;
  4716. if (typeof canvas.style != 'undefined') {
  4717. canvas.style.removeProperty( "width");
  4718. canvas.style.removeProperty("height");
  4719. }
  4720. } else {
  4721. if (canvas.width != wNative) canvas.width = wNative;
  4722. if (canvas.height != hNative) canvas.height = hNative;
  4723. if (typeof canvas.style != 'undefined') {
  4724. if (w != wNative || h != hNative) {
  4725. canvas.style.setProperty( "width", w + "px", "important");
  4726. canvas.style.setProperty("height", h + "px", "important");
  4727. } else {
  4728. canvas.style.removeProperty( "width");
  4729. canvas.style.removeProperty("height");
  4730. }
  4731. }
  4732. }
  4733. },
  4734. };
  4735. var EGL = {
  4736. errorCode:12288,
  4737. defaultDisplayInitialized:false,
  4738. currentContext:0,
  4739. currentReadSurface:0,
  4740. currentDrawSurface:0,
  4741. contextAttributes:{
  4742. alpha:false,
  4743. depth:false,
  4744. stencil:false,
  4745. antialias:false,
  4746. },
  4747. stringCache:{
  4748. },
  4749. setErrorCode(code) {
  4750. EGL.errorCode = code;
  4751. },
  4752. chooseConfig(display, attribList, config, config_size, numConfigs) {
  4753. if (display != 62000) {
  4754. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4755. return 0;
  4756. }
  4757. if (attribList) {
  4758. // read attribList if it is non-null
  4759. for (;;) {
  4760. var param = HEAP32[((attribList)>>2)];
  4761. if (param == 0x3021 /*EGL_ALPHA_SIZE*/) {
  4762. var alphaSize = HEAP32[(((attribList)+(4))>>2)];
  4763. EGL.contextAttributes.alpha = (alphaSize > 0);
  4764. } else if (param == 0x3025 /*EGL_DEPTH_SIZE*/) {
  4765. var depthSize = HEAP32[(((attribList)+(4))>>2)];
  4766. EGL.contextAttributes.depth = (depthSize > 0);
  4767. } else if (param == 0x3026 /*EGL_STENCIL_SIZE*/) {
  4768. var stencilSize = HEAP32[(((attribList)+(4))>>2)];
  4769. EGL.contextAttributes.stencil = (stencilSize > 0);
  4770. } else if (param == 0x3031 /*EGL_SAMPLES*/) {
  4771. var samples = HEAP32[(((attribList)+(4))>>2)];
  4772. EGL.contextAttributes.antialias = (samples > 0);
  4773. } else if (param == 0x3032 /*EGL_SAMPLE_BUFFERS*/) {
  4774. var samples = HEAP32[(((attribList)+(4))>>2)];
  4775. EGL.contextAttributes.antialias = (samples == 1);
  4776. } else if (param == 0x3100 /*EGL_CONTEXT_PRIORITY_LEVEL_IMG*/) {
  4777. var requestedPriority = HEAP32[(((attribList)+(4))>>2)];
  4778. EGL.contextAttributes.lowLatency = (requestedPriority != 0x3103 /*EGL_CONTEXT_PRIORITY_LOW_IMG*/);
  4779. } else if (param == 0x3038 /*EGL_NONE*/) {
  4780. break;
  4781. }
  4782. attribList += 8;
  4783. }
  4784. }
  4785. if ((!config || !config_size) && !numConfigs) {
  4786. EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);
  4787. return 0;
  4788. }
  4789. if (numConfigs) {
  4790. HEAP32[((numConfigs)>>2)] = 1; // Total number of supported configs: 1.
  4791. }
  4792. if (config && config_size > 0) {
  4793. HEAPU32[((config)>>2)] = 62002;
  4794. }
  4795. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4796. return 1;
  4797. },
  4798. };
  4799. var _eglBindAPI = (api) => {
  4800. if (api == 0x30A0 /* EGL_OPENGL_ES_API */) {
  4801. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4802. return 1;
  4803. }
  4804. // if (api == 0x30A1 /* EGL_OPENVG_API */ || api == 0x30A2 /* EGL_OPENGL_API */) {
  4805. EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);
  4806. return 0;
  4807. };
  4808. var _eglChooseConfig = (display, attrib_list, configs, config_size, numConfigs) => {
  4809. return EGL.chooseConfig(display, attrib_list, configs, config_size, numConfigs);
  4810. };
  4811. var webgl_enable_ANGLE_instanced_arrays = (ctx) => {
  4812. // Extension available in WebGL 1 from Firefox 26 and Google Chrome 30 onwards. Core feature in WebGL 2.
  4813. var ext = ctx.getExtension('ANGLE_instanced_arrays');
  4814. if (ext) {
  4815. ctx['vertexAttribDivisor'] = (index, divisor) => ext['vertexAttribDivisorANGLE'](index, divisor);
  4816. ctx['drawArraysInstanced'] = (mode, first, count, primcount) => ext['drawArraysInstancedANGLE'](mode, first, count, primcount);
  4817. ctx['drawElementsInstanced'] = (mode, count, type, indices, primcount) => ext['drawElementsInstancedANGLE'](mode, count, type, indices, primcount);
  4818. return 1;
  4819. }
  4820. };
  4821. var webgl_enable_OES_vertex_array_object = (ctx) => {
  4822. // Extension available in WebGL 1 from Firefox 25 and WebKit 536.28/desktop Safari 6.0.3 onwards. Core feature in WebGL 2.
  4823. var ext = ctx.getExtension('OES_vertex_array_object');
  4824. if (ext) {
  4825. ctx['createVertexArray'] = () => ext['createVertexArrayOES']();
  4826. ctx['deleteVertexArray'] = (vao) => ext['deleteVertexArrayOES'](vao);
  4827. ctx['bindVertexArray'] = (vao) => ext['bindVertexArrayOES'](vao);
  4828. ctx['isVertexArray'] = (vao) => ext['isVertexArrayOES'](vao);
  4829. return 1;
  4830. }
  4831. };
  4832. var webgl_enable_WEBGL_draw_buffers = (ctx) => {
  4833. // Extension available in WebGL 1 from Firefox 28 onwards. Core feature in WebGL 2.
  4834. var ext = ctx.getExtension('WEBGL_draw_buffers');
  4835. if (ext) {
  4836. ctx['drawBuffers'] = (n, bufs) => ext['drawBuffersWEBGL'](n, bufs);
  4837. return 1;
  4838. }
  4839. };
  4840. var webgl_enable_WEBGL_multi_draw = (ctx) => {
  4841. // Closure is expected to be allowed to minify the '.multiDrawWebgl' property, so not accessing it quoted.
  4842. return !!(ctx.multiDrawWebgl = ctx.getExtension('WEBGL_multi_draw'));
  4843. };
  4844. var getEmscriptenSupportedExtensions = (ctx) => {
  4845. // Restrict the list of advertised extensions to those that we actually
  4846. // support.
  4847. var supportedExtensions = [
  4848. // WebGL 1 extensions
  4849. 'ANGLE_instanced_arrays',
  4850. 'EXT_blend_minmax',
  4851. 'EXT_disjoint_timer_query',
  4852. 'EXT_frag_depth',
  4853. 'EXT_shader_texture_lod',
  4854. 'EXT_sRGB',
  4855. 'OES_element_index_uint',
  4856. 'OES_fbo_render_mipmap',
  4857. 'OES_standard_derivatives',
  4858. 'OES_texture_float',
  4859. 'OES_texture_half_float',
  4860. 'OES_texture_half_float_linear',
  4861. 'OES_vertex_array_object',
  4862. 'WEBGL_color_buffer_float',
  4863. 'WEBGL_depth_texture',
  4864. 'WEBGL_draw_buffers',
  4865. // WebGL 1 and WebGL 2 extensions
  4866. 'EXT_color_buffer_half_float',
  4867. 'EXT_depth_clamp',
  4868. 'EXT_float_blend',
  4869. 'EXT_texture_compression_bptc',
  4870. 'EXT_texture_compression_rgtc',
  4871. 'EXT_texture_filter_anisotropic',
  4872. 'KHR_parallel_shader_compile',
  4873. 'OES_texture_float_linear',
  4874. 'WEBGL_blend_func_extended',
  4875. 'WEBGL_compressed_texture_astc',
  4876. 'WEBGL_compressed_texture_etc',
  4877. 'WEBGL_compressed_texture_etc1',
  4878. 'WEBGL_compressed_texture_s3tc',
  4879. 'WEBGL_compressed_texture_s3tc_srgb',
  4880. 'WEBGL_debug_renderer_info',
  4881. 'WEBGL_debug_shaders',
  4882. 'WEBGL_lose_context',
  4883. 'WEBGL_multi_draw',
  4884. ];
  4885. // .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
  4886. return (ctx.getSupportedExtensions() || []).filter(ext => supportedExtensions.includes(ext));
  4887. };
  4888. var GL = {
  4889. counter:1,
  4890. buffers:[],
  4891. programs:[],
  4892. framebuffers:[],
  4893. renderbuffers:[],
  4894. textures:[],
  4895. shaders:[],
  4896. vaos:[],
  4897. contexts:[],
  4898. offscreenCanvases:{
  4899. },
  4900. queries:[],
  4901. stringCache:{
  4902. },
  4903. unpackAlignment:4,
  4904. unpackRowLength:0,
  4905. recordError:(errorCode) => {
  4906. if (!GL.lastError) {
  4907. GL.lastError = errorCode;
  4908. }
  4909. },
  4910. getNewId:(table) => {
  4911. var ret = GL.counter++;
  4912. for (var i = table.length; i < ret; i++) {
  4913. table[i] = null;
  4914. }
  4915. return ret;
  4916. },
  4917. genObject:(n, buffers, createFunction, objectTable
  4918. ) => {
  4919. for (var i = 0; i < n; i++) {
  4920. var buffer = GLctx[createFunction]();
  4921. var id = buffer && GL.getNewId(objectTable);
  4922. if (buffer) {
  4923. buffer.name = id;
  4924. objectTable[id] = buffer;
  4925. } else {
  4926. GL.recordError(0x502 /* GL_INVALID_OPERATION */);
  4927. }
  4928. HEAP32[(((buffers)+(i*4))>>2)] = id;
  4929. }
  4930. },
  4931. getSource:(shader, count, string, length) => {
  4932. var source = '';
  4933. for (var i = 0; i < count; ++i) {
  4934. var len = length ? HEAPU32[(((length)+(i*4))>>2)] : undefined;
  4935. source += UTF8ToString(HEAPU32[(((string)+(i*4))>>2)], len);
  4936. }
  4937. return source;
  4938. },
  4939. createContext:(/** @type {HTMLCanvasElement} */ canvas, webGLContextAttributes) => {
  4940. // BUG: Workaround Safari WebGL issue: After successfully acquiring WebGL
  4941. // context on a canvas, calling .getContext() will always return that
  4942. // context independent of which 'webgl' or 'webgl2'
  4943. // context version was passed. See:
  4944. // https://bugs.webkit.org/show_bug.cgi?id=222758
  4945. // and:
  4946. // https://github.com/emscripten-core/emscripten/issues/13295.
  4947. // TODO: Once the bug is fixed and shipped in Safari, adjust the Safari
  4948. // version field in above check.
  4949. if (!canvas.getContextSafariWebGL2Fixed) {
  4950. canvas.getContextSafariWebGL2Fixed = canvas.getContext;
  4951. /** @type {function(this:HTMLCanvasElement, string, (Object|null)=): (Object|null)} */
  4952. function fixedGetContext(ver, attrs) {
  4953. var gl = canvas.getContextSafariWebGL2Fixed(ver, attrs);
  4954. return ((ver == 'webgl') == (gl instanceof WebGLRenderingContext)) ? gl : null;
  4955. }
  4956. canvas.getContext = fixedGetContext;
  4957. }
  4958. var ctx =
  4959. (canvas.getContext("webgl", webGLContextAttributes)
  4960. // https://caniuse.com/#feat=webgl
  4961. );
  4962. if (!ctx) return 0;
  4963. var handle = GL.registerContext(ctx, webGLContextAttributes);
  4964. return handle;
  4965. },
  4966. registerContext:(ctx, webGLContextAttributes) => {
  4967. // without pthreads a context is just an integer ID
  4968. var handle = GL.getNewId(GL.contexts);
  4969. var context = {
  4970. handle,
  4971. attributes: webGLContextAttributes,
  4972. version: webGLContextAttributes.majorVersion,
  4973. GLctx: ctx
  4974. };
  4975. // Store the created context object so that we can access the context
  4976. // given a canvas without having to pass the parameters again.
  4977. if (ctx.canvas) ctx.canvas.GLctxObject = context;
  4978. GL.contexts[handle] = context;
  4979. if (typeof webGLContextAttributes.enableExtensionsByDefault == 'undefined' || webGLContextAttributes.enableExtensionsByDefault) {
  4980. GL.initExtensions(context);
  4981. }
  4982. return handle;
  4983. },
  4984. makeContextCurrent:(contextHandle) => {
  4985. // Active Emscripten GL layer context object.
  4986. GL.currentContext = GL.contexts[contextHandle];
  4987. // Active WebGL context object.
  4988. Module.ctx = GLctx = GL.currentContext?.GLctx;
  4989. return !(contextHandle && !GLctx);
  4990. },
  4991. getContext:(contextHandle) => {
  4992. return GL.contexts[contextHandle];
  4993. },
  4994. deleteContext:(contextHandle) => {
  4995. if (GL.currentContext === GL.contexts[contextHandle]) {
  4996. GL.currentContext = null;
  4997. }
  4998. if (typeof JSEvents == 'object') {
  4999. // Release all JS event handlers on the DOM element that the GL context is
  5000. // associated with since the context is now deleted.
  5001. JSEvents.removeAllHandlersOnTarget(GL.contexts[contextHandle].GLctx.canvas);
  5002. }
  5003. // Make sure the canvas object no longer refers to the context object so
  5004. // there are no GC surprises.
  5005. if (GL.contexts[contextHandle] && GL.contexts[contextHandle].GLctx.canvas) {
  5006. GL.contexts[contextHandle].GLctx.canvas.GLctxObject = undefined;
  5007. }
  5008. GL.contexts[contextHandle] = null;
  5009. },
  5010. initExtensions:(context) => {
  5011. // If this function is called without a specific context object, init the
  5012. // extensions of the currently active context.
  5013. context ||= GL.currentContext;
  5014. if (context.initExtensionsDone) return;
  5015. context.initExtensionsDone = true;
  5016. var GLctx = context.GLctx;
  5017. // Detect the presence of a few extensions manually, ction GL interop
  5018. // layer itself will need to know if they exist.
  5019. // Extensions that are only available in WebGL 1 (the calls will be no-ops
  5020. // if called on a WebGL 2 context active)
  5021. webgl_enable_ANGLE_instanced_arrays(GLctx);
  5022. webgl_enable_OES_vertex_array_object(GLctx);
  5023. webgl_enable_WEBGL_draw_buffers(GLctx);
  5024. {
  5025. GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query");
  5026. }
  5027. webgl_enable_WEBGL_multi_draw(GLctx);
  5028. getEmscriptenSupportedExtensions(GLctx).forEach((ext) => {
  5029. // WEBGL_lose_context, WEBGL_debug_renderer_info and WEBGL_debug_shaders
  5030. // are not enabled by default.
  5031. if (!ext.includes('lose_context') && !ext.includes('debug')) {
  5032. // Call .getExtension() to enable that extension permanently.
  5033. GLctx.getExtension(ext);
  5034. }
  5035. });
  5036. },
  5037. };
  5038. var _eglCreateContext = (display, config, hmm, contextAttribs) => {
  5039. if (display != 62000) {
  5040. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  5041. return 0;
  5042. }
  5043. // EGL 1.4 spec says default EGL_CONTEXT_CLIENT_VERSION is GLES1, but this is not supported by Emscripten.
  5044. // So user must pass EGL_CONTEXT_CLIENT_VERSION == 2 to initialize EGL.
  5045. var glesContextVersion = 1;
  5046. for (;;) {
  5047. var param = HEAP32[((contextAttribs)>>2)];
  5048. if (param == 0x3098 /*EGL_CONTEXT_CLIENT_VERSION*/) {
  5049. glesContextVersion = HEAP32[(((contextAttribs)+(4))>>2)];
  5050. } else if (param == 0x3038 /*EGL_NONE*/) {
  5051. break;
  5052. } else {
  5053. /* EGL1.4 specifies only EGL_CONTEXT_CLIENT_VERSION as supported attribute */
  5054. EGL.setErrorCode(0x3004 /*EGL_BAD_ATTRIBUTE*/);
  5055. return 0;
  5056. }
  5057. contextAttribs += 8;
  5058. }
  5059. if (glesContextVersion != 2) {
  5060. EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */);
  5061. return 0; /* EGL_NO_CONTEXT */
  5062. }
  5063. EGL.contextAttributes.majorVersion = glesContextVersion - 1; // WebGL 1 is GLES 2, WebGL2 is GLES3
  5064. EGL.contextAttributes.minorVersion = 0;
  5065. EGL.context = GL.createContext(Module['canvas'], EGL.contextAttributes);
  5066. if (EGL.context != 0) {
  5067. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5068. // Run callbacks so that GL emulation works
  5069. GL.makeContextCurrent(EGL.context);
  5070. Module.useWebGL = true;
  5071. Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });
  5072. // Note: This function only creates a context, but it shall not make it active.
  5073. GL.makeContextCurrent(null);
  5074. return 62004;
  5075. } else {
  5076. EGL.setErrorCode(0x3009 /* EGL_BAD_MATCH */); // By the EGL 1.4 spec, an implementation that does not support GLES2 (WebGL in this case), this error code is set.
  5077. return 0; /* EGL_NO_CONTEXT */
  5078. }
  5079. };
  5080. var _eglCreateWindowSurface = (display, config, win, attrib_list) => {
  5081. if (display != 62000) {
  5082. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  5083. return 0;
  5084. }
  5085. if (config != 62002) {
  5086. EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */);
  5087. return 0;
  5088. }
  5089. // TODO: Examine attrib_list! Parameters that can be present there are:
  5090. // - EGL_RENDER_BUFFER (must be EGL_BACK_BUFFER)
  5091. // - EGL_VG_COLORSPACE (can't be set)
  5092. // - EGL_VG_ALPHA_FORMAT (can't be set)
  5093. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5094. return 62006; /* Magic ID for Emscripten 'default surface' */
  5095. };
  5096. var _eglDestroyContext = (display, context) => {
  5097. if (display != 62000) {
  5098. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  5099. return 0;
  5100. }
  5101. if (context != 62004) {
  5102. EGL.setErrorCode(0x3006 /* EGL_BAD_CONTEXT */);
  5103. return 0;
  5104. }
  5105. GL.deleteContext(EGL.context);
  5106. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5107. if (EGL.currentContext == context) {
  5108. EGL.currentContext = 0;
  5109. }
  5110. return 1 /* EGL_TRUE */;
  5111. };
  5112. var _eglDestroySurface = (display, surface) => {
  5113. if (display != 62000) {
  5114. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  5115. return 0;
  5116. }
  5117. if (surface != 62006 /* Magic ID for the only EGLSurface supported by Emscripten */) {
  5118. EGL.setErrorCode(0x300D /* EGL_BAD_SURFACE */);
  5119. return 1;
  5120. }
  5121. if (EGL.currentReadSurface == surface) {
  5122. EGL.currentReadSurface = 0;
  5123. }
  5124. if (EGL.currentDrawSurface == surface) {
  5125. EGL.currentDrawSurface = 0;
  5126. }
  5127. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5128. return 1; /* Magic ID for Emscripten 'default surface' */
  5129. };
  5130. var _eglGetConfigAttrib = (display, config, attribute, value) => {
  5131. if (display != 62000) {
  5132. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  5133. return 0;
  5134. }
  5135. if (config != 62002) {
  5136. EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */);
  5137. return 0;
  5138. }
  5139. if (!value) {
  5140. EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);
  5141. return 0;
  5142. }
  5143. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5144. switch (attribute) {
  5145. case 0x3020: // EGL_BUFFER_SIZE
  5146. HEAP32[((value)>>2)] = EGL.contextAttributes.alpha ? 32 : 24;
  5147. return 1;
  5148. case 0x3021: // EGL_ALPHA_SIZE
  5149. HEAP32[((value)>>2)] = EGL.contextAttributes.alpha ? 8 : 0;
  5150. return 1;
  5151. case 0x3022: // EGL_BLUE_SIZE
  5152. HEAP32[((value)>>2)] = 8;
  5153. return 1;
  5154. case 0x3023: // EGL_GREEN_SIZE
  5155. HEAP32[((value)>>2)] = 8;
  5156. return 1;
  5157. case 0x3024: // EGL_RED_SIZE
  5158. HEAP32[((value)>>2)] = 8;
  5159. return 1;
  5160. case 0x3025: // EGL_DEPTH_SIZE
  5161. HEAP32[((value)>>2)] = EGL.contextAttributes.depth ? 24 : 0;
  5162. return 1;
  5163. case 0x3026: // EGL_STENCIL_SIZE
  5164. HEAP32[((value)>>2)] = EGL.contextAttributes.stencil ? 8 : 0;
  5165. return 1;
  5166. case 0x3027: // EGL_CONFIG_CAVEAT
  5167. // We can return here one of EGL_NONE (0x3038), EGL_SLOW_CONFIG (0x3050) or EGL_NON_CONFORMANT_CONFIG (0x3051).
  5168. HEAP32[((value)>>2)] = 0x3038;
  5169. return 1;
  5170. case 0x3028: // EGL_CONFIG_ID
  5171. HEAP32[((value)>>2)] = 62002;
  5172. return 1;
  5173. case 0x3029: // EGL_LEVEL
  5174. HEAP32[((value)>>2)] = 0;
  5175. return 1;
  5176. case 0x302A: // EGL_MAX_PBUFFER_HEIGHT
  5177. HEAP32[((value)>>2)] = 4096;
  5178. return 1;
  5179. case 0x302B: // EGL_MAX_PBUFFER_PIXELS
  5180. HEAP32[((value)>>2)] = 16777216;
  5181. return 1;
  5182. case 0x302C: // EGL_MAX_PBUFFER_WIDTH
  5183. HEAP32[((value)>>2)] = 4096;
  5184. return 1;
  5185. case 0x302D: // EGL_NATIVE_RENDERABLE
  5186. HEAP32[((value)>>2)] = 0;
  5187. return 1;
  5188. case 0x302E: // EGL_NATIVE_VISUAL_ID
  5189. HEAP32[((value)>>2)] = 0;
  5190. return 1;
  5191. case 0x302F: // EGL_NATIVE_VISUAL_TYPE
  5192. HEAP32[((value)>>2)] = 0x3038;
  5193. return 1;
  5194. case 0x3031: // EGL_SAMPLES
  5195. HEAP32[((value)>>2)] = EGL.contextAttributes.antialias ? 4 : 0;
  5196. return 1;
  5197. case 0x3032: // EGL_SAMPLE_BUFFERS
  5198. HEAP32[((value)>>2)] = EGL.contextAttributes.antialias ? 1 : 0;
  5199. return 1;
  5200. case 0x3033: // EGL_SURFACE_TYPE
  5201. HEAP32[((value)>>2)] = 0x4;
  5202. return 1;
  5203. case 0x3034: // EGL_TRANSPARENT_TYPE
  5204. // If this returns EGL_TRANSPARENT_RGB (0x3052), transparency is used through color-keying. No such thing applies to Emscripten canvas.
  5205. HEAP32[((value)>>2)] = 0x3038;
  5206. return 1;
  5207. case 0x3035: // EGL_TRANSPARENT_BLUE_VALUE
  5208. case 0x3036: // EGL_TRANSPARENT_GREEN_VALUE
  5209. case 0x3037: // EGL_TRANSPARENT_RED_VALUE
  5210. // "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."
  5211. HEAP32[((value)>>2)] = -1;
  5212. return 1;
  5213. case 0x3039: // EGL_BIND_TO_TEXTURE_RGB
  5214. case 0x303A: // EGL_BIND_TO_TEXTURE_RGBA
  5215. HEAP32[((value)>>2)] = 0;
  5216. return 1;
  5217. case 0x303B: // EGL_MIN_SWAP_INTERVAL
  5218. HEAP32[((value)>>2)] = 0;
  5219. return 1;
  5220. case 0x303C: // EGL_MAX_SWAP_INTERVAL
  5221. HEAP32[((value)>>2)] = 1;
  5222. return 1;
  5223. case 0x303D: // EGL_LUMINANCE_SIZE
  5224. case 0x303E: // EGL_ALPHA_MASK_SIZE
  5225. HEAP32[((value)>>2)] = 0;
  5226. return 1;
  5227. case 0x303F: // EGL_COLOR_BUFFER_TYPE
  5228. // EGL has two types of buffers: EGL_RGB_BUFFER and EGL_LUMINANCE_BUFFER.
  5229. HEAP32[((value)>>2)] = 0x308E;
  5230. return 1;
  5231. case 0x3040: // EGL_RENDERABLE_TYPE
  5232. // A bit combination of EGL_OPENGL_ES_BIT,EGL_OPENVG_BIT,EGL_OPENGL_ES2_BIT and EGL_OPENGL_BIT.
  5233. HEAP32[((value)>>2)] = 0x4;
  5234. return 1;
  5235. case 0x3042: // EGL_CONFORMANT
  5236. // "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."
  5237. HEAP32[((value)>>2)] = 0;
  5238. return 1;
  5239. default:
  5240. EGL.setErrorCode(0x3004 /* EGL_BAD_ATTRIBUTE */);
  5241. return 0;
  5242. }
  5243. };
  5244. var _eglGetDisplay = (nativeDisplayType) => {
  5245. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5246. // Emscripten EGL implementation "emulates" X11, and eglGetDisplay is
  5247. // expected to accept/receive a pointer to an X11 Display object (or
  5248. // EGL_DEFAULT_DISPLAY).
  5249. if (nativeDisplayType != 0 /* EGL_DEFAULT_DISPLAY */ && nativeDisplayType != 1 /* see library_xlib.js */) {
  5250. return 0; // EGL_NO_DISPLAY
  5251. }
  5252. return 62000;
  5253. };
  5254. var _eglGetError = () => EGL.errorCode;
  5255. var _eglInitialize = (display, majorVersion, minorVersion) => {
  5256. if (display != 62000) {
  5257. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  5258. return 0;
  5259. }
  5260. if (majorVersion) {
  5261. HEAP32[((majorVersion)>>2)] = 1; // Advertise EGL Major version: '1'
  5262. }
  5263. if (minorVersion) {
  5264. HEAP32[((minorVersion)>>2)] = 4; // Advertise EGL Minor version: '4'
  5265. }
  5266. EGL.defaultDisplayInitialized = true;
  5267. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5268. return 1;
  5269. };
  5270. var _eglMakeCurrent = (display, draw, read, context) => {
  5271. if (display != 62000) {
  5272. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  5273. return 0 /* EGL_FALSE */;
  5274. }
  5275. //\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy.
  5276. if (context != 0 && context != 62004) {
  5277. EGL.setErrorCode(0x3006 /* EGL_BAD_CONTEXT */);
  5278. return 0;
  5279. }
  5280. if ((read != 0 && read != 62006) || (draw != 0 && draw != 62006 /* Magic ID for Emscripten 'default surface' */)) {
  5281. EGL.setErrorCode(0x300D /* EGL_BAD_SURFACE */);
  5282. return 0;
  5283. }
  5284. GL.makeContextCurrent(context ? EGL.context : null);
  5285. EGL.currentContext = context;
  5286. EGL.currentDrawSurface = draw;
  5287. EGL.currentReadSurface = read;
  5288. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5289. return 1 /* EGL_TRUE */;
  5290. };
  5291. var stringToNewUTF8 = (str) => {
  5292. var size = lengthBytesUTF8(str) + 1;
  5293. var ret = _malloc(size);
  5294. if (ret) stringToUTF8(str, ret, size);
  5295. return ret;
  5296. };
  5297. var _eglQueryString = (display, name) => {
  5298. if (display != 62000) {
  5299. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  5300. return 0;
  5301. }
  5302. //\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy.
  5303. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5304. if (EGL.stringCache[name]) return EGL.stringCache[name];
  5305. var ret;
  5306. switch (name) {
  5307. case 0x3053 /* EGL_VENDOR */: ret = stringToNewUTF8("Emscripten"); break;
  5308. case 0x3054 /* EGL_VERSION */: ret = stringToNewUTF8("1.4 Emscripten EGL"); break;
  5309. case 0x3055 /* EGL_EXTENSIONS */: ret = stringToNewUTF8(""); break; // Currently not supporting any EGL extensions.
  5310. case 0x308D /* EGL_CLIENT_APIS */: ret = stringToNewUTF8("OpenGL_ES"); break;
  5311. default:
  5312. EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);
  5313. return 0;
  5314. }
  5315. EGL.stringCache[name] = ret;
  5316. return ret;
  5317. };
  5318. var _eglSwapBuffers = (dpy, surface) => {
  5319. if (!EGL.defaultDisplayInitialized) {
  5320. EGL.setErrorCode(0x3001 /* EGL_NOT_INITIALIZED */);
  5321. } else if (!Module.ctx) {
  5322. EGL.setErrorCode(0x3002 /* EGL_BAD_ACCESS */);
  5323. } else if (Module.ctx.isContextLost()) {
  5324. EGL.setErrorCode(0x300E /* EGL_CONTEXT_LOST */);
  5325. } else {
  5326. // According to documentation this does an implicit flush.
  5327. // Due to discussion at https://github.com/emscripten-core/emscripten/pull/1871
  5328. // the flush was removed since this _may_ result in slowing code down.
  5329. //_glFlush();
  5330. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5331. return 1 /* EGL_TRUE */;
  5332. }
  5333. return 0 /* EGL_FALSE */;
  5334. };
  5335. var _eglSwapInterval = (display, interval) => {
  5336. if (display != 62000) {
  5337. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  5338. return 0;
  5339. }
  5340. if (interval == 0) _emscripten_set_main_loop_timing(0, 0);
  5341. else _emscripten_set_main_loop_timing(1, interval);
  5342. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5343. return 1;
  5344. };
  5345. var _eglTerminate = (display) => {
  5346. if (display != 62000) {
  5347. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  5348. return 0;
  5349. }
  5350. EGL.currentContext = 0;
  5351. EGL.currentReadSurface = 0;
  5352. EGL.currentDrawSurface = 0;
  5353. EGL.defaultDisplayInitialized = false;
  5354. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5355. return 1;
  5356. };
  5357. /** @suppress {duplicate } */
  5358. var _eglWaitClient = () => {
  5359. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5360. return 1;
  5361. };
  5362. var _eglWaitGL = _eglWaitClient;
  5363. var _eglWaitNative = (nativeEngineId) => {
  5364. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5365. return 1;
  5366. };
  5367. var readEmAsmArgsArray = [];
  5368. var readEmAsmArgs = (sigPtr, buf) => {
  5369. // Nobody should have mutated _readEmAsmArgsArray underneath us to be something else than an array.
  5370. assert(Array.isArray(readEmAsmArgsArray));
  5371. // The input buffer is allocated on the stack, so it must be stack-aligned.
  5372. assert(buf % 16 == 0);
  5373. readEmAsmArgsArray.length = 0;
  5374. var ch;
  5375. // Most arguments are i32s, so shift the buffer pointer so it is a plain
  5376. // index into HEAP32.
  5377. while (ch = HEAPU8[sigPtr++]) {
  5378. var chr = String.fromCharCode(ch);
  5379. var validChars = ['d', 'f', 'i', 'p'];
  5380. // In WASM_BIGINT mode we support passing i64 values as bigint.
  5381. validChars.push('j');
  5382. assert(validChars.includes(chr), `Invalid character ${ch}("${chr}") in readEmAsmArgs! Use only [${validChars}], and do not specify "v" for void return argument.`);
  5383. // Floats are always passed as doubles, so all types except for 'i'
  5384. // are 8 bytes and require alignment.
  5385. var wide = (ch != 105);
  5386. wide &= (ch != 112);
  5387. buf += wide && (buf % 8) ? 4 : 0;
  5388. readEmAsmArgsArray.push(
  5389. // Special case for pointers under wasm64 or CAN_ADDRESS_2GB mode.
  5390. ch == 112 ? HEAPU32[((buf)>>2)] :
  5391. ch == 106 ? HEAP64[((buf)>>3)] :
  5392. ch == 105 ?
  5393. HEAP32[((buf)>>2)] :
  5394. HEAPF64[((buf)>>3)]
  5395. );
  5396. buf += wide ? 8 : 4;
  5397. }
  5398. return readEmAsmArgsArray;
  5399. };
  5400. var runEmAsmFunction = (code, sigPtr, argbuf) => {
  5401. var args = readEmAsmArgs(sigPtr, argbuf);
  5402. 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.`);
  5403. return ASM_CONSTS[code](...args);
  5404. };
  5405. var _emscripten_asm_const_int = (code, sigPtr, argbuf) => {
  5406. return runEmAsmFunction(code, sigPtr, argbuf);
  5407. };
  5408. var runMainThreadEmAsm = (emAsmAddr, sigPtr, argbuf, sync) => {
  5409. var args = readEmAsmArgs(sigPtr, argbuf);
  5410. 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.`);
  5411. return ASM_CONSTS[emAsmAddr](...args);
  5412. };
  5413. var _emscripten_asm_const_int_sync_on_main_thread = (emAsmAddr, sigPtr, argbuf) => runMainThreadEmAsm(emAsmAddr, sigPtr, argbuf, 1);
  5414. var _emscripten_asm_const_ptr = (code, sigPtr, argbuf) => {
  5415. return runEmAsmFunction(code, sigPtr, argbuf);
  5416. };
  5417. var _emscripten_asm_const_ptr_sync_on_main_thread = (emAsmAddr, sigPtr, argbuf) => runMainThreadEmAsm(emAsmAddr, sigPtr, argbuf, 1);
  5418. var _emscripten_cancel_main_loop = () => {
  5419. Browser.mainLoop.pause();
  5420. Browser.mainLoop.func = null;
  5421. };
  5422. var _emscripten_date_now = () => Date.now();
  5423. var JSEvents = {
  5424. removeAllEventListeners() {
  5425. while (JSEvents.eventHandlers.length) {
  5426. JSEvents._removeHandler(JSEvents.eventHandlers.length - 1);
  5427. }
  5428. JSEvents.deferredCalls = [];
  5429. },
  5430. registerRemoveEventListeners() {
  5431. if (!JSEvents.removeEventListenersRegistered) {
  5432. __ATEXIT__.push(JSEvents.removeAllEventListeners);
  5433. JSEvents.removeEventListenersRegistered = true;
  5434. }
  5435. },
  5436. inEventHandler:0,
  5437. deferredCalls:[],
  5438. deferCall(targetFunction, precedence, argsList) {
  5439. function arraysHaveEqualContent(arrA, arrB) {
  5440. if (arrA.length != arrB.length) return false;
  5441. for (var i in arrA) {
  5442. if (arrA[i] != arrB[i]) return false;
  5443. }
  5444. return true;
  5445. }
  5446. // Test if the given call was already queued, and if so, don't add it again.
  5447. for (var i in JSEvents.deferredCalls) {
  5448. var call = JSEvents.deferredCalls[i];
  5449. if (call.targetFunction == targetFunction && arraysHaveEqualContent(call.argsList, argsList)) {
  5450. return;
  5451. }
  5452. }
  5453. JSEvents.deferredCalls.push({
  5454. targetFunction,
  5455. precedence,
  5456. argsList
  5457. });
  5458. JSEvents.deferredCalls.sort((x,y) => x.precedence < y.precedence);
  5459. },
  5460. removeDeferredCalls(targetFunction) {
  5461. for (var i = 0; i < JSEvents.deferredCalls.length; ++i) {
  5462. if (JSEvents.deferredCalls[i].targetFunction == targetFunction) {
  5463. JSEvents.deferredCalls.splice(i, 1);
  5464. --i;
  5465. }
  5466. }
  5467. },
  5468. canPerformEventHandlerRequests() {
  5469. if (navigator.userActivation) {
  5470. // Verify against transient activation status from UserActivation API
  5471. // whether it is possible to perform a request here without needing to defer. See
  5472. // https://developer.mozilla.org/en-US/docs/Web/Security/User_activation#transient_activation
  5473. // and https://caniuse.com/mdn-api_useractivation
  5474. // At the time of writing, Firefox does not support this API: https://bugzilla.mozilla.org/show_bug.cgi?id=1791079
  5475. return navigator.userActivation.isActive;
  5476. }
  5477. return JSEvents.inEventHandler && JSEvents.currentEventHandler.allowsDeferredCalls;
  5478. },
  5479. runDeferredCalls() {
  5480. if (!JSEvents.canPerformEventHandlerRequests()) {
  5481. return;
  5482. }
  5483. for (var i = 0; i < JSEvents.deferredCalls.length; ++i) {
  5484. var call = JSEvents.deferredCalls[i];
  5485. JSEvents.deferredCalls.splice(i, 1);
  5486. --i;
  5487. call.targetFunction(...call.argsList);
  5488. }
  5489. },
  5490. eventHandlers:[],
  5491. removeAllHandlersOnTarget:(target, eventTypeString) => {
  5492. for (var i = 0; i < JSEvents.eventHandlers.length; ++i) {
  5493. if (JSEvents.eventHandlers[i].target == target &&
  5494. (!eventTypeString || eventTypeString == JSEvents.eventHandlers[i].eventTypeString)) {
  5495. JSEvents._removeHandler(i--);
  5496. }
  5497. }
  5498. },
  5499. _removeHandler(i) {
  5500. var h = JSEvents.eventHandlers[i];
  5501. h.target.removeEventListener(h.eventTypeString, h.eventListenerFunc, h.useCapture);
  5502. JSEvents.eventHandlers.splice(i, 1);
  5503. },
  5504. registerOrRemoveHandler(eventHandler) {
  5505. if (!eventHandler.target) {
  5506. err('registerOrRemoveHandler: the target element for event handler registration does not exist, when processing the following event handler registration:');
  5507. console.dir(eventHandler);
  5508. return -4;
  5509. }
  5510. if (eventHandler.callbackfunc) {
  5511. eventHandler.eventListenerFunc = function(event) {
  5512. // Increment nesting count for the event handler.
  5513. ++JSEvents.inEventHandler;
  5514. JSEvents.currentEventHandler = eventHandler;
  5515. // Process any old deferred calls the user has placed.
  5516. JSEvents.runDeferredCalls();
  5517. // Process the actual event, calls back to user C code handler.
  5518. eventHandler.handlerFunc(event);
  5519. // Process any new deferred calls that were placed right now from this event handler.
  5520. JSEvents.runDeferredCalls();
  5521. // Out of event handler - restore nesting count.
  5522. --JSEvents.inEventHandler;
  5523. };
  5524. eventHandler.target.addEventListener(eventHandler.eventTypeString,
  5525. eventHandler.eventListenerFunc,
  5526. eventHandler.useCapture);
  5527. JSEvents.eventHandlers.push(eventHandler);
  5528. JSEvents.registerRemoveEventListeners();
  5529. } else {
  5530. for (var i = 0; i < JSEvents.eventHandlers.length; ++i) {
  5531. if (JSEvents.eventHandlers[i].target == eventHandler.target
  5532. && JSEvents.eventHandlers[i].eventTypeString == eventHandler.eventTypeString) {
  5533. JSEvents._removeHandler(i--);
  5534. }
  5535. }
  5536. }
  5537. return 0;
  5538. },
  5539. getNodeNameForTarget(target) {
  5540. if (!target) return '';
  5541. if (target == window) return '#window';
  5542. if (target == screen) return '#screen';
  5543. return target?.nodeName || '';
  5544. },
  5545. fullscreenEnabled() {
  5546. return document.fullscreenEnabled
  5547. // Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitFullscreenEnabled.
  5548. // TODO: If Safari at some point ships with unprefixed version, update the version check above.
  5549. || document.webkitFullscreenEnabled
  5550. ;
  5551. },
  5552. };
  5553. var currentFullscreenStrategy = {
  5554. };
  5555. var maybeCStringToJsString = (cString) => {
  5556. // "cString > 2" checks if the input is a number, and isn't of the special
  5557. // values we accept here, EMSCRIPTEN_EVENT_TARGET_* (which map to 0, 1, 2).
  5558. // In other words, if cString > 2 then it's a pointer to a valid place in
  5559. // memory, and points to a C string.
  5560. return cString > 2 ? UTF8ToString(cString) : cString;
  5561. };
  5562. /** @type {Object} */
  5563. var specialHTMLTargets = [0, typeof document != 'undefined' ? document : 0, typeof window != 'undefined' ? window : 0];
  5564. /** @suppress {duplicate } */
  5565. var findEventTarget = (target) => {
  5566. target = maybeCStringToJsString(target);
  5567. var domElement = specialHTMLTargets[target] || (typeof document != 'undefined' ? document.querySelector(target) : undefined);
  5568. return domElement;
  5569. };
  5570. var findCanvasEventTarget = findEventTarget;
  5571. var _emscripten_get_canvas_element_size = (target, width, height) => {
  5572. var canvas = findCanvasEventTarget(target);
  5573. if (!canvas) return -4;
  5574. HEAP32[((width)>>2)] = canvas.width;
  5575. HEAP32[((height)>>2)] = canvas.height;
  5576. };
  5577. var stackAlloc = (sz) => __emscripten_stack_alloc(sz);
  5578. var stringToUTF8OnStack = (str) => {
  5579. var size = lengthBytesUTF8(str) + 1;
  5580. var ret = stackAlloc(size);
  5581. stringToUTF8(str, ret, size);
  5582. return ret;
  5583. };
  5584. var getCanvasElementSize = (target) => {
  5585. var sp = stackSave();
  5586. var w = stackAlloc(8);
  5587. var h = w + 4;
  5588. var targetInt = stringToUTF8OnStack(target.id);
  5589. var ret = _emscripten_get_canvas_element_size(targetInt, w, h);
  5590. var size = [HEAP32[((w)>>2)], HEAP32[((h)>>2)]];
  5591. stackRestore(sp);
  5592. return size;
  5593. };
  5594. var _emscripten_set_canvas_element_size = (target, width, height) => {
  5595. var canvas = findCanvasEventTarget(target);
  5596. if (!canvas) return -4;
  5597. canvas.width = width;
  5598. canvas.height = height;
  5599. return 0;
  5600. };
  5601. var setCanvasElementSize = (target, width, height) => {
  5602. if (!target.controlTransferredOffscreen) {
  5603. target.width = width;
  5604. target.height = height;
  5605. } else {
  5606. // This function is being called from high-level JavaScript code instead of asm.js/Wasm,
  5607. // and it needs to synchronously proxy over to another thread, so marshal the string onto the heap to do the call.
  5608. var sp = stackSave();
  5609. var targetInt = stringToUTF8OnStack(target.id);
  5610. _emscripten_set_canvas_element_size(targetInt, width, height);
  5611. stackRestore(sp);
  5612. }
  5613. };
  5614. var wasmTableMirror = [];
  5615. /** @type {WebAssembly.Table} */
  5616. var wasmTable;
  5617. var getWasmTableEntry = (funcPtr) => {
  5618. var func = wasmTableMirror[funcPtr];
  5619. if (!func) {
  5620. if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1;
  5621. wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
  5622. }
  5623. assert(wasmTable.get(funcPtr) == func, 'JavaScript-side Wasm function table mirror is out of date!');
  5624. return func;
  5625. };
  5626. var registerRestoreOldStyle = (canvas) => {
  5627. var canvasSize = getCanvasElementSize(canvas);
  5628. var oldWidth = canvasSize[0];
  5629. var oldHeight = canvasSize[1];
  5630. var oldCssWidth = canvas.style.width;
  5631. var oldCssHeight = canvas.style.height;
  5632. var oldBackgroundColor = canvas.style.backgroundColor; // Chrome reads color from here.
  5633. var oldDocumentBackgroundColor = document.body.style.backgroundColor; // IE11 reads color from here.
  5634. // Firefox always has black background color.
  5635. var oldPaddingLeft = canvas.style.paddingLeft; // Chrome, FF, Safari
  5636. var oldPaddingRight = canvas.style.paddingRight;
  5637. var oldPaddingTop = canvas.style.paddingTop;
  5638. var oldPaddingBottom = canvas.style.paddingBottom;
  5639. var oldMarginLeft = canvas.style.marginLeft; // IE11
  5640. var oldMarginRight = canvas.style.marginRight;
  5641. var oldMarginTop = canvas.style.marginTop;
  5642. var oldMarginBottom = canvas.style.marginBottom;
  5643. var oldDocumentBodyMargin = document.body.style.margin;
  5644. var oldDocumentOverflow = document.documentElement.style.overflow; // Chrome, Firefox
  5645. var oldDocumentScroll = document.body.scroll; // IE
  5646. var oldImageRendering = canvas.style.imageRendering;
  5647. function restoreOldStyle() {
  5648. var fullscreenElement = document.fullscreenElement
  5649. || document.webkitFullscreenElement
  5650. ;
  5651. if (!fullscreenElement) {
  5652. document.removeEventListener('fullscreenchange', restoreOldStyle);
  5653. // Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
  5654. // 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.
  5655. document.removeEventListener('webkitfullscreenchange', restoreOldStyle);
  5656. setCanvasElementSize(canvas, oldWidth, oldHeight);
  5657. canvas.style.width = oldCssWidth;
  5658. canvas.style.height = oldCssHeight;
  5659. canvas.style.backgroundColor = oldBackgroundColor; // Chrome
  5660. // IE11 hack: assigning 'undefined' or an empty string to document.body.style.backgroundColor has no effect, so first assign back the default color
  5661. // before setting the undefined value. Setting undefined value is also important, or otherwise we would later treat that as something that the user
  5662. // had explicitly set so subsequent fullscreen transitions would not set background color properly.
  5663. if (!oldDocumentBackgroundColor) document.body.style.backgroundColor = 'white';
  5664. document.body.style.backgroundColor = oldDocumentBackgroundColor; // IE11
  5665. canvas.style.paddingLeft = oldPaddingLeft; // Chrome, FF, Safari
  5666. canvas.style.paddingRight = oldPaddingRight;
  5667. canvas.style.paddingTop = oldPaddingTop;
  5668. canvas.style.paddingBottom = oldPaddingBottom;
  5669. canvas.style.marginLeft = oldMarginLeft; // IE11
  5670. canvas.style.marginRight = oldMarginRight;
  5671. canvas.style.marginTop = oldMarginTop;
  5672. canvas.style.marginBottom = oldMarginBottom;
  5673. document.body.style.margin = oldDocumentBodyMargin;
  5674. document.documentElement.style.overflow = oldDocumentOverflow; // Chrome, Firefox
  5675. document.body.scroll = oldDocumentScroll; // IE
  5676. canvas.style.imageRendering = oldImageRendering;
  5677. if (canvas.GLctxObject) canvas.GLctxObject.GLctx.viewport(0, 0, oldWidth, oldHeight);
  5678. if (currentFullscreenStrategy.canvasResizedCallback) {
  5679. getWasmTableEntry(currentFullscreenStrategy.canvasResizedCallback)(37, 0, currentFullscreenStrategy.canvasResizedCallbackUserData);
  5680. }
  5681. }
  5682. }
  5683. document.addEventListener('fullscreenchange', restoreOldStyle);
  5684. // Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
  5685. // 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.
  5686. document.addEventListener('webkitfullscreenchange', restoreOldStyle);
  5687. return restoreOldStyle;
  5688. };
  5689. var setLetterbox = (element, topBottom, leftRight) => {
  5690. // Cannot use margin to specify letterboxes in FF or Chrome, since those ignore margins in fullscreen mode.
  5691. element.style.paddingLeft = element.style.paddingRight = leftRight + 'px';
  5692. element.style.paddingTop = element.style.paddingBottom = topBottom + 'px';
  5693. };
  5694. var getBoundingClientRect = (e) => specialHTMLTargets.indexOf(e) < 0 ? e.getBoundingClientRect() : {'left':0,'top':0};
  5695. var JSEvents_resizeCanvasForFullscreen = (target, strategy) => {
  5696. var restoreOldStyle = registerRestoreOldStyle(target);
  5697. var cssWidth = strategy.softFullscreen ? innerWidth : screen.width;
  5698. var cssHeight = strategy.softFullscreen ? innerHeight : screen.height;
  5699. var rect = getBoundingClientRect(target);
  5700. var windowedCssWidth = rect.width;
  5701. var windowedCssHeight = rect.height;
  5702. var canvasSize = getCanvasElementSize(target);
  5703. var windowedRttWidth = canvasSize[0];
  5704. var windowedRttHeight = canvasSize[1];
  5705. if (strategy.scaleMode == 3) {
  5706. setLetterbox(target, (cssHeight - windowedCssHeight) / 2, (cssWidth - windowedCssWidth) / 2);
  5707. cssWidth = windowedCssWidth;
  5708. cssHeight = windowedCssHeight;
  5709. } else if (strategy.scaleMode == 2) {
  5710. if (cssWidth*windowedRttHeight < windowedRttWidth*cssHeight) {
  5711. var desiredCssHeight = windowedRttHeight * cssWidth / windowedRttWidth;
  5712. setLetterbox(target, (cssHeight - desiredCssHeight) / 2, 0);
  5713. cssHeight = desiredCssHeight;
  5714. } else {
  5715. var desiredCssWidth = windowedRttWidth * cssHeight / windowedRttHeight;
  5716. setLetterbox(target, 0, (cssWidth - desiredCssWidth) / 2);
  5717. cssWidth = desiredCssWidth;
  5718. }
  5719. }
  5720. // If we are adding padding, must choose a background color or otherwise Chrome will give the
  5721. // padding a default white color. Do it only if user has not customized their own background color.
  5722. if (!target.style.backgroundColor) target.style.backgroundColor = 'black';
  5723. // IE11 does the same, but requires the color to be set in the document body.
  5724. if (!document.body.style.backgroundColor) document.body.style.backgroundColor = 'black'; // IE11
  5725. // Firefox always shows black letterboxes independent of style color.
  5726. target.style.width = cssWidth + 'px';
  5727. target.style.height = cssHeight + 'px';
  5728. if (strategy.filteringMode == 1) {
  5729. target.style.imageRendering = 'optimizeSpeed';
  5730. target.style.imageRendering = '-moz-crisp-edges';
  5731. target.style.imageRendering = '-o-crisp-edges';
  5732. target.style.imageRendering = '-webkit-optimize-contrast';
  5733. target.style.imageRendering = 'optimize-contrast';
  5734. target.style.imageRendering = 'crisp-edges';
  5735. target.style.imageRendering = 'pixelated';
  5736. }
  5737. var dpiScale = (strategy.canvasResolutionScaleMode == 2) ? devicePixelRatio : 1;
  5738. if (strategy.canvasResolutionScaleMode != 0) {
  5739. var newWidth = (cssWidth * dpiScale)|0;
  5740. var newHeight = (cssHeight * dpiScale)|0;
  5741. setCanvasElementSize(target, newWidth, newHeight);
  5742. if (target.GLctxObject) target.GLctxObject.GLctx.viewport(0, 0, newWidth, newHeight);
  5743. }
  5744. return restoreOldStyle;
  5745. };
  5746. var JSEvents_requestFullscreen = (target, strategy) => {
  5747. // EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT + EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE is a mode where no extra logic is performed to the DOM elements.
  5748. if (strategy.scaleMode != 0 || strategy.canvasResolutionScaleMode != 0) {
  5749. JSEvents_resizeCanvasForFullscreen(target, strategy);
  5750. }
  5751. if (target.requestFullscreen) {
  5752. target.requestFullscreen();
  5753. } else if (target.webkitRequestFullscreen) {
  5754. target.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
  5755. } else {
  5756. return JSEvents.fullscreenEnabled() ? -3 : -1;
  5757. }
  5758. currentFullscreenStrategy = strategy;
  5759. if (strategy.canvasResizedCallback) {
  5760. getWasmTableEntry(strategy.canvasResizedCallback)(37, 0, strategy.canvasResizedCallbackUserData);
  5761. }
  5762. return 0;
  5763. };
  5764. var _emscripten_exit_fullscreen = () => {
  5765. if (!JSEvents.fullscreenEnabled()) return -1;
  5766. // Make sure no queued up calls will fire after this.
  5767. JSEvents.removeDeferredCalls(JSEvents_requestFullscreen);
  5768. var d = specialHTMLTargets[1];
  5769. if (d.exitFullscreen) {
  5770. d.fullscreenElement && d.exitFullscreen();
  5771. } else if (d.webkitExitFullscreen) {
  5772. d.webkitFullscreenElement && d.webkitExitFullscreen();
  5773. } else {
  5774. return -1;
  5775. }
  5776. return 0;
  5777. };
  5778. var requestPointerLock = (target) => {
  5779. if (target.requestPointerLock) {
  5780. target.requestPointerLock();
  5781. } else {
  5782. // document.body is known to accept pointer lock, so use that to differentiate if the user passed a bad element,
  5783. // or if the whole browser just doesn't support the feature.
  5784. if (document.body.requestPointerLock
  5785. ) {
  5786. return -3;
  5787. }
  5788. return -1;
  5789. }
  5790. return 0;
  5791. };
  5792. var _emscripten_exit_pointerlock = () => {
  5793. // Make sure no queued up calls will fire after this.
  5794. JSEvents.removeDeferredCalls(requestPointerLock);
  5795. if (document.exitPointerLock) {
  5796. document.exitPointerLock();
  5797. } else {
  5798. return -1;
  5799. }
  5800. return 0;
  5801. };
  5802. var __emscripten_runtime_keepalive_clear = () => {
  5803. noExitRuntime = false;
  5804. runtimeKeepaliveCounter = 0;
  5805. };
  5806. var _emscripten_force_exit = (status) => {
  5807. __emscripten_runtime_keepalive_clear();
  5808. _exit(status);
  5809. };
  5810. var _emscripten_get_device_pixel_ratio = () => {
  5811. return (typeof devicePixelRatio == 'number' && devicePixelRatio) || 1.0;
  5812. };
  5813. var _emscripten_get_element_css_size = (target, width, height) => {
  5814. target = findEventTarget(target);
  5815. if (!target) return -4;
  5816. var rect = getBoundingClientRect(target);
  5817. HEAPF64[((width)>>3)] = rect.width;
  5818. HEAPF64[((height)>>3)] = rect.height;
  5819. return 0;
  5820. };
  5821. var fillGamepadEventData = (eventStruct, e) => {
  5822. HEAPF64[((eventStruct)>>3)] = e.timestamp;
  5823. for (var i = 0; i < e.axes.length; ++i) {
  5824. HEAPF64[(((eventStruct+i*8)+(16))>>3)] = e.axes[i];
  5825. }
  5826. for (var i = 0; i < e.buttons.length; ++i) {
  5827. if (typeof e.buttons[i] == 'object') {
  5828. HEAPF64[(((eventStruct+i*8)+(528))>>3)] = e.buttons[i].value;
  5829. } else {
  5830. HEAPF64[(((eventStruct+i*8)+(528))>>3)] = e.buttons[i];
  5831. }
  5832. }
  5833. for (var i = 0; i < e.buttons.length; ++i) {
  5834. if (typeof e.buttons[i] == 'object') {
  5835. HEAP32[(((eventStruct+i*4)+(1040))>>2)] = e.buttons[i].pressed;
  5836. } else {
  5837. // Assigning a boolean to HEAP32, that's ok, but Closure would like to warn about it:
  5838. /** @suppress {checkTypes} */
  5839. HEAP32[(((eventStruct+i*4)+(1040))>>2)] = e.buttons[i] == 1;
  5840. }
  5841. }
  5842. HEAP32[(((eventStruct)+(1296))>>2)] = e.connected;
  5843. HEAP32[(((eventStruct)+(1300))>>2)] = e.index;
  5844. HEAP32[(((eventStruct)+(8))>>2)] = e.axes.length;
  5845. HEAP32[(((eventStruct)+(12))>>2)] = e.buttons.length;
  5846. stringToUTF8(e.id, eventStruct + 1304, 64);
  5847. stringToUTF8(e.mapping, eventStruct + 1368, 64);
  5848. };
  5849. var _emscripten_get_gamepad_status = (index, gamepadState) => {
  5850. if (!JSEvents.lastGamepadState) throw 'emscripten_get_gamepad_status() can only be called after having first called emscripten_sample_gamepad_data() and that function has returned EMSCRIPTEN_RESULT_SUCCESS!';
  5851. // INVALID_PARAM is returned on a Gamepad index that never was there.
  5852. if (index < 0 || index >= JSEvents.lastGamepadState.length) return -5;
  5853. // NO_DATA is returned on a Gamepad index that was removed.
  5854. // For previously disconnected gamepads there should be an empty slot (null/undefined/false) at the index.
  5855. // This is because gamepads must keep their original position in the array.
  5856. // For example, removing the first of two gamepads produces [null/undefined/false, gamepad].
  5857. if (!JSEvents.lastGamepadState[index]) return -7;
  5858. fillGamepadEventData(gamepadState, JSEvents.lastGamepadState[index]);
  5859. return 0;
  5860. };
  5861. var _emscripten_get_num_gamepads = () => {
  5862. if (!JSEvents.lastGamepadState) throw 'emscripten_get_num_gamepads() can only be called after having first called emscripten_sample_gamepad_data() and that function has returned EMSCRIPTEN_RESULT_SUCCESS!';
  5863. // N.B. Do not call emscripten_get_num_gamepads() unless having first called emscripten_sample_gamepad_data(), and that has returned EMSCRIPTEN_RESULT_SUCCESS.
  5864. // Otherwise the following line will throw an exception.
  5865. return JSEvents.lastGamepadState.length;
  5866. };
  5867. var _emscripten_get_screen_size = (width, height) => {
  5868. HEAP32[((width)>>2)] = screen.width;
  5869. HEAP32[((height)>>2)] = screen.height;
  5870. };
  5871. /** @suppress {duplicate } */
  5872. var _glActiveTexture = (x0) => GLctx.activeTexture(x0);
  5873. var _emscripten_glActiveTexture = _glActiveTexture;
  5874. /** @suppress {duplicate } */
  5875. var _glAttachShader = (program, shader) => {
  5876. GLctx.attachShader(GL.programs[program], GL.shaders[shader]);
  5877. };
  5878. var _emscripten_glAttachShader = _glAttachShader;
  5879. /** @suppress {duplicate } */
  5880. var _glBeginQueryEXT = (target, id) => {
  5881. GLctx.disjointTimerQueryExt['beginQueryEXT'](target, GL.queries[id]);
  5882. };
  5883. var _emscripten_glBeginQueryEXT = _glBeginQueryEXT;
  5884. /** @suppress {duplicate } */
  5885. var _glBindAttribLocation = (program, index, name) => {
  5886. GLctx.bindAttribLocation(GL.programs[program], index, UTF8ToString(name));
  5887. };
  5888. var _emscripten_glBindAttribLocation = _glBindAttribLocation;
  5889. /** @suppress {duplicate } */
  5890. var _glBindBuffer = (target, buffer) => {
  5891. GLctx.bindBuffer(target, GL.buffers[buffer]);
  5892. };
  5893. var _emscripten_glBindBuffer = _glBindBuffer;
  5894. /** @suppress {duplicate } */
  5895. var _glBindFramebuffer = (target, framebuffer) => {
  5896. GLctx.bindFramebuffer(target, GL.framebuffers[framebuffer]);
  5897. };
  5898. var _emscripten_glBindFramebuffer = _glBindFramebuffer;
  5899. /** @suppress {duplicate } */
  5900. var _glBindRenderbuffer = (target, renderbuffer) => {
  5901. GLctx.bindRenderbuffer(target, GL.renderbuffers[renderbuffer]);
  5902. };
  5903. var _emscripten_glBindRenderbuffer = _glBindRenderbuffer;
  5904. /** @suppress {duplicate } */
  5905. var _glBindTexture = (target, texture) => {
  5906. GLctx.bindTexture(target, GL.textures[texture]);
  5907. };
  5908. var _emscripten_glBindTexture = _glBindTexture;
  5909. /** @suppress {duplicate } */
  5910. var _glBindVertexArray = (vao) => {
  5911. GLctx.bindVertexArray(GL.vaos[vao]);
  5912. };
  5913. /** @suppress {duplicate } */
  5914. var _glBindVertexArrayOES = _glBindVertexArray;
  5915. var _emscripten_glBindVertexArrayOES = _glBindVertexArrayOES;
  5916. /** @suppress {duplicate } */
  5917. var _glBlendColor = (x0, x1, x2, x3) => GLctx.blendColor(x0, x1, x2, x3);
  5918. var _emscripten_glBlendColor = _glBlendColor;
  5919. /** @suppress {duplicate } */
  5920. var _glBlendEquation = (x0) => GLctx.blendEquation(x0);
  5921. var _emscripten_glBlendEquation = _glBlendEquation;
  5922. /** @suppress {duplicate } */
  5923. var _glBlendEquationSeparate = (x0, x1) => GLctx.blendEquationSeparate(x0, x1);
  5924. var _emscripten_glBlendEquationSeparate = _glBlendEquationSeparate;
  5925. /** @suppress {duplicate } */
  5926. var _glBlendFunc = (x0, x1) => GLctx.blendFunc(x0, x1);
  5927. var _emscripten_glBlendFunc = _glBlendFunc;
  5928. /** @suppress {duplicate } */
  5929. var _glBlendFuncSeparate = (x0, x1, x2, x3) => GLctx.blendFuncSeparate(x0, x1, x2, x3);
  5930. var _emscripten_glBlendFuncSeparate = _glBlendFuncSeparate;
  5931. /** @suppress {duplicate } */
  5932. var _glBufferData = (target, size, data, usage) => {
  5933. // N.b. here first form specifies a heap subarray, second form an integer
  5934. // size, so the ?: code here is polymorphic. It is advised to avoid
  5935. // randomly mixing both uses in calling code, to avoid any potential JS
  5936. // engine JIT issues.
  5937. GLctx.bufferData(target, data ? HEAPU8.subarray(data, data+size) : size, usage);
  5938. };
  5939. var _emscripten_glBufferData = _glBufferData;
  5940. /** @suppress {duplicate } */
  5941. var _glBufferSubData = (target, offset, size, data) => {
  5942. GLctx.bufferSubData(target, offset, HEAPU8.subarray(data, data+size));
  5943. };
  5944. var _emscripten_glBufferSubData = _glBufferSubData;
  5945. /** @suppress {duplicate } */
  5946. var _glCheckFramebufferStatus = (x0) => GLctx.checkFramebufferStatus(x0);
  5947. var _emscripten_glCheckFramebufferStatus = _glCheckFramebufferStatus;
  5948. /** @suppress {duplicate } */
  5949. var _glClear = (x0) => GLctx.clear(x0);
  5950. var _emscripten_glClear = _glClear;
  5951. /** @suppress {duplicate } */
  5952. var _glClearColor = (x0, x1, x2, x3) => GLctx.clearColor(x0, x1, x2, x3);
  5953. var _emscripten_glClearColor = _glClearColor;
  5954. /** @suppress {duplicate } */
  5955. var _glClearDepthf = (x0) => GLctx.clearDepth(x0);
  5956. var _emscripten_glClearDepthf = _glClearDepthf;
  5957. /** @suppress {duplicate } */
  5958. var _glClearStencil = (x0) => GLctx.clearStencil(x0);
  5959. var _emscripten_glClearStencil = _glClearStencil;
  5960. /** @suppress {duplicate } */
  5961. var _glColorMask = (red, green, blue, alpha) => {
  5962. GLctx.colorMask(!!red, !!green, !!blue, !!alpha);
  5963. };
  5964. var _emscripten_glColorMask = _glColorMask;
  5965. /** @suppress {duplicate } */
  5966. var _glCompileShader = (shader) => {
  5967. GLctx.compileShader(GL.shaders[shader]);
  5968. };
  5969. var _emscripten_glCompileShader = _glCompileShader;
  5970. /** @suppress {duplicate } */
  5971. var _glCompressedTexImage2D = (target, level, internalFormat, width, height, border, imageSize, data) => {
  5972. GLctx.compressedTexImage2D(target, level, internalFormat, width, height, border, data ? HEAPU8.subarray((data), data+imageSize) : null);
  5973. };
  5974. var _emscripten_glCompressedTexImage2D = _glCompressedTexImage2D;
  5975. /** @suppress {duplicate } */
  5976. var _glCompressedTexSubImage2D = (target, level, xoffset, yoffset, width, height, format, imageSize, data) => {
  5977. GLctx.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, data ? HEAPU8.subarray((data), data+imageSize) : null);
  5978. };
  5979. var _emscripten_glCompressedTexSubImage2D = _glCompressedTexSubImage2D;
  5980. /** @suppress {duplicate } */
  5981. var _glCopyTexImage2D = (x0, x1, x2, x3, x4, x5, x6, x7) => GLctx.copyTexImage2D(x0, x1, x2, x3, x4, x5, x6, x7);
  5982. var _emscripten_glCopyTexImage2D = _glCopyTexImage2D;
  5983. /** @suppress {duplicate } */
  5984. var _glCopyTexSubImage2D = (x0, x1, x2, x3, x4, x5, x6, x7) => GLctx.copyTexSubImage2D(x0, x1, x2, x3, x4, x5, x6, x7);
  5985. var _emscripten_glCopyTexSubImage2D = _glCopyTexSubImage2D;
  5986. /** @suppress {duplicate } */
  5987. var _glCreateProgram = () => {
  5988. var id = GL.getNewId(GL.programs);
  5989. var program = GLctx.createProgram();
  5990. // Store additional information needed for each shader program:
  5991. program.name = id;
  5992. // Lazy cache results of
  5993. // glGetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH/GL_ACTIVE_ATTRIBUTE_MAX_LENGTH/GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH)
  5994. program.maxUniformLength = program.maxAttributeLength = program.maxUniformBlockNameLength = 0;
  5995. program.uniformIdCounter = 1;
  5996. GL.programs[id] = program;
  5997. return id;
  5998. };
  5999. var _emscripten_glCreateProgram = _glCreateProgram;
  6000. /** @suppress {duplicate } */
  6001. var _glCreateShader = (shaderType) => {
  6002. var id = GL.getNewId(GL.shaders);
  6003. GL.shaders[id] = GLctx.createShader(shaderType);
  6004. return id;
  6005. };
  6006. var _emscripten_glCreateShader = _glCreateShader;
  6007. /** @suppress {duplicate } */
  6008. var _glCullFace = (x0) => GLctx.cullFace(x0);
  6009. var _emscripten_glCullFace = _glCullFace;
  6010. /** @suppress {duplicate } */
  6011. var _glDeleteBuffers = (n, buffers) => {
  6012. for (var i = 0; i < n; i++) {
  6013. var id = HEAP32[(((buffers)+(i*4))>>2)];
  6014. var buffer = GL.buffers[id];
  6015. // From spec: "glDeleteBuffers silently ignores 0's and names that do not
  6016. // correspond to existing buffer objects."
  6017. if (!buffer) continue;
  6018. GLctx.deleteBuffer(buffer);
  6019. buffer.name = 0;
  6020. GL.buffers[id] = null;
  6021. }
  6022. };
  6023. var _emscripten_glDeleteBuffers = _glDeleteBuffers;
  6024. /** @suppress {duplicate } */
  6025. var _glDeleteFramebuffers = (n, framebuffers) => {
  6026. for (var i = 0; i < n; ++i) {
  6027. var id = HEAP32[(((framebuffers)+(i*4))>>2)];
  6028. var framebuffer = GL.framebuffers[id];
  6029. if (!framebuffer) continue; // GL spec: "glDeleteFramebuffers silently ignores 0s and names that do not correspond to existing framebuffer objects".
  6030. GLctx.deleteFramebuffer(framebuffer);
  6031. framebuffer.name = 0;
  6032. GL.framebuffers[id] = null;
  6033. }
  6034. };
  6035. var _emscripten_glDeleteFramebuffers = _glDeleteFramebuffers;
  6036. /** @suppress {duplicate } */
  6037. var _glDeleteProgram = (id) => {
  6038. if (!id) return;
  6039. var program = GL.programs[id];
  6040. if (!program) {
  6041. // glDeleteProgram actually signals an error when deleting a nonexisting
  6042. // object, unlike some other GL delete functions.
  6043. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6044. return;
  6045. }
  6046. GLctx.deleteProgram(program);
  6047. program.name = 0;
  6048. GL.programs[id] = null;
  6049. };
  6050. var _emscripten_glDeleteProgram = _glDeleteProgram;
  6051. /** @suppress {duplicate } */
  6052. var _glDeleteQueriesEXT = (n, ids) => {
  6053. for (var i = 0; i < n; i++) {
  6054. var id = HEAP32[(((ids)+(i*4))>>2)];
  6055. var query = GL.queries[id];
  6056. if (!query) continue; // GL spec: "unused names in ids are ignored, as is the name zero."
  6057. GLctx.disjointTimerQueryExt['deleteQueryEXT'](query);
  6058. GL.queries[id] = null;
  6059. }
  6060. };
  6061. var _emscripten_glDeleteQueriesEXT = _glDeleteQueriesEXT;
  6062. /** @suppress {duplicate } */
  6063. var _glDeleteRenderbuffers = (n, renderbuffers) => {
  6064. for (var i = 0; i < n; i++) {
  6065. var id = HEAP32[(((renderbuffers)+(i*4))>>2)];
  6066. var renderbuffer = GL.renderbuffers[id];
  6067. if (!renderbuffer) continue; // GL spec: "glDeleteRenderbuffers silently ignores 0s and names that do not correspond to existing renderbuffer objects".
  6068. GLctx.deleteRenderbuffer(renderbuffer);
  6069. renderbuffer.name = 0;
  6070. GL.renderbuffers[id] = null;
  6071. }
  6072. };
  6073. var _emscripten_glDeleteRenderbuffers = _glDeleteRenderbuffers;
  6074. /** @suppress {duplicate } */
  6075. var _glDeleteShader = (id) => {
  6076. if (!id) return;
  6077. var shader = GL.shaders[id];
  6078. if (!shader) {
  6079. // glDeleteShader actually signals an error when deleting a nonexisting
  6080. // object, unlike some other GL delete functions.
  6081. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6082. return;
  6083. }
  6084. GLctx.deleteShader(shader);
  6085. GL.shaders[id] = null;
  6086. };
  6087. var _emscripten_glDeleteShader = _glDeleteShader;
  6088. /** @suppress {duplicate } */
  6089. var _glDeleteTextures = (n, textures) => {
  6090. for (var i = 0; i < n; i++) {
  6091. var id = HEAP32[(((textures)+(i*4))>>2)];
  6092. var texture = GL.textures[id];
  6093. // GL spec: "glDeleteTextures silently ignores 0s and names that do not
  6094. // correspond to existing textures".
  6095. if (!texture) continue;
  6096. GLctx.deleteTexture(texture);
  6097. texture.name = 0;
  6098. GL.textures[id] = null;
  6099. }
  6100. };
  6101. var _emscripten_glDeleteTextures = _glDeleteTextures;
  6102. /** @suppress {duplicate } */
  6103. var _glDeleteVertexArrays = (n, vaos) => {
  6104. for (var i = 0; i < n; i++) {
  6105. var id = HEAP32[(((vaos)+(i*4))>>2)];
  6106. GLctx.deleteVertexArray(GL.vaos[id]);
  6107. GL.vaos[id] = null;
  6108. }
  6109. };
  6110. /** @suppress {duplicate } */
  6111. var _glDeleteVertexArraysOES = _glDeleteVertexArrays;
  6112. var _emscripten_glDeleteVertexArraysOES = _glDeleteVertexArraysOES;
  6113. /** @suppress {duplicate } */
  6114. var _glDepthFunc = (x0) => GLctx.depthFunc(x0);
  6115. var _emscripten_glDepthFunc = _glDepthFunc;
  6116. /** @suppress {duplicate } */
  6117. var _glDepthMask = (flag) => {
  6118. GLctx.depthMask(!!flag);
  6119. };
  6120. var _emscripten_glDepthMask = _glDepthMask;
  6121. /** @suppress {duplicate } */
  6122. var _glDepthRangef = (x0, x1) => GLctx.depthRange(x0, x1);
  6123. var _emscripten_glDepthRangef = _glDepthRangef;
  6124. /** @suppress {duplicate } */
  6125. var _glDetachShader = (program, shader) => {
  6126. GLctx.detachShader(GL.programs[program], GL.shaders[shader]);
  6127. };
  6128. var _emscripten_glDetachShader = _glDetachShader;
  6129. /** @suppress {duplicate } */
  6130. var _glDisable = (x0) => GLctx.disable(x0);
  6131. var _emscripten_glDisable = _glDisable;
  6132. /** @suppress {duplicate } */
  6133. var _glDisableVertexAttribArray = (index) => {
  6134. GLctx.disableVertexAttribArray(index);
  6135. };
  6136. var _emscripten_glDisableVertexAttribArray = _glDisableVertexAttribArray;
  6137. /** @suppress {duplicate } */
  6138. var _glDrawArrays = (mode, first, count) => {
  6139. GLctx.drawArrays(mode, first, count);
  6140. };
  6141. var _emscripten_glDrawArrays = _glDrawArrays;
  6142. /** @suppress {duplicate } */
  6143. var _glDrawArraysInstanced = (mode, first, count, primcount) => {
  6144. GLctx.drawArraysInstanced(mode, first, count, primcount);
  6145. };
  6146. /** @suppress {duplicate } */
  6147. var _glDrawArraysInstancedANGLE = _glDrawArraysInstanced;
  6148. var _emscripten_glDrawArraysInstancedANGLE = _glDrawArraysInstancedANGLE;
  6149. var tempFixedLengthArray = [];
  6150. /** @suppress {duplicate } */
  6151. var _glDrawBuffers = (n, bufs) => {
  6152. var bufArray = tempFixedLengthArray[n];
  6153. for (var i = 0; i < n; i++) {
  6154. bufArray[i] = HEAP32[(((bufs)+(i*4))>>2)];
  6155. }
  6156. GLctx.drawBuffers(bufArray);
  6157. };
  6158. /** @suppress {duplicate } */
  6159. var _glDrawBuffersWEBGL = _glDrawBuffers;
  6160. var _emscripten_glDrawBuffersWEBGL = _glDrawBuffersWEBGL;
  6161. /** @suppress {duplicate } */
  6162. var _glDrawElements = (mode, count, type, indices) => {
  6163. GLctx.drawElements(mode, count, type, indices);
  6164. };
  6165. var _emscripten_glDrawElements = _glDrawElements;
  6166. /** @suppress {duplicate } */
  6167. var _glDrawElementsInstanced = (mode, count, type, indices, primcount) => {
  6168. GLctx.drawElementsInstanced(mode, count, type, indices, primcount);
  6169. };
  6170. /** @suppress {duplicate } */
  6171. var _glDrawElementsInstancedANGLE = _glDrawElementsInstanced;
  6172. var _emscripten_glDrawElementsInstancedANGLE = _glDrawElementsInstancedANGLE;
  6173. /** @suppress {duplicate } */
  6174. var _glEnable = (x0) => GLctx.enable(x0);
  6175. var _emscripten_glEnable = _glEnable;
  6176. /** @suppress {duplicate } */
  6177. var _glEnableVertexAttribArray = (index) => {
  6178. GLctx.enableVertexAttribArray(index);
  6179. };
  6180. var _emscripten_glEnableVertexAttribArray = _glEnableVertexAttribArray;
  6181. /** @suppress {duplicate } */
  6182. var _glEndQueryEXT = (target) => {
  6183. GLctx.disjointTimerQueryExt['endQueryEXT'](target);
  6184. };
  6185. var _emscripten_glEndQueryEXT = _glEndQueryEXT;
  6186. /** @suppress {duplicate } */
  6187. var _glFinish = () => GLctx.finish();
  6188. var _emscripten_glFinish = _glFinish;
  6189. /** @suppress {duplicate } */
  6190. var _glFlush = () => GLctx.flush();
  6191. var _emscripten_glFlush = _glFlush;
  6192. /** @suppress {duplicate } */
  6193. var _glFramebufferRenderbuffer = (target, attachment, renderbuffertarget, renderbuffer) => {
  6194. GLctx.framebufferRenderbuffer(target, attachment, renderbuffertarget,
  6195. GL.renderbuffers[renderbuffer]);
  6196. };
  6197. var _emscripten_glFramebufferRenderbuffer = _glFramebufferRenderbuffer;
  6198. /** @suppress {duplicate } */
  6199. var _glFramebufferTexture2D = (target, attachment, textarget, texture, level) => {
  6200. GLctx.framebufferTexture2D(target, attachment, textarget,
  6201. GL.textures[texture], level);
  6202. };
  6203. var _emscripten_glFramebufferTexture2D = _glFramebufferTexture2D;
  6204. /** @suppress {duplicate } */
  6205. var _glFrontFace = (x0) => GLctx.frontFace(x0);
  6206. var _emscripten_glFrontFace = _glFrontFace;
  6207. /** @suppress {duplicate } */
  6208. var _glGenBuffers = (n, buffers) => {
  6209. GL.genObject(n, buffers, 'createBuffer', GL.buffers
  6210. );
  6211. };
  6212. var _emscripten_glGenBuffers = _glGenBuffers;
  6213. /** @suppress {duplicate } */
  6214. var _glGenFramebuffers = (n, ids) => {
  6215. GL.genObject(n, ids, 'createFramebuffer', GL.framebuffers
  6216. );
  6217. };
  6218. var _emscripten_glGenFramebuffers = _glGenFramebuffers;
  6219. /** @suppress {duplicate } */
  6220. var _glGenQueriesEXT = (n, ids) => {
  6221. for (var i = 0; i < n; i++) {
  6222. var query = GLctx.disjointTimerQueryExt['createQueryEXT']();
  6223. if (!query) {
  6224. GL.recordError(0x502 /* GL_INVALID_OPERATION */);
  6225. while (i < n) HEAP32[(((ids)+(i++*4))>>2)] = 0;
  6226. return;
  6227. }
  6228. var id = GL.getNewId(GL.queries);
  6229. query.name = id;
  6230. GL.queries[id] = query;
  6231. HEAP32[(((ids)+(i*4))>>2)] = id;
  6232. }
  6233. };
  6234. var _emscripten_glGenQueriesEXT = _glGenQueriesEXT;
  6235. /** @suppress {duplicate } */
  6236. var _glGenRenderbuffers = (n, renderbuffers) => {
  6237. GL.genObject(n, renderbuffers, 'createRenderbuffer', GL.renderbuffers
  6238. );
  6239. };
  6240. var _emscripten_glGenRenderbuffers = _glGenRenderbuffers;
  6241. /** @suppress {duplicate } */
  6242. var _glGenTextures = (n, textures) => {
  6243. GL.genObject(n, textures, 'createTexture', GL.textures
  6244. );
  6245. };
  6246. var _emscripten_glGenTextures = _glGenTextures;
  6247. /** @suppress {duplicate } */
  6248. var _glGenVertexArrays = (n, arrays) => {
  6249. GL.genObject(n, arrays, 'createVertexArray', GL.vaos
  6250. );
  6251. };
  6252. /** @suppress {duplicate } */
  6253. var _glGenVertexArraysOES = _glGenVertexArrays;
  6254. var _emscripten_glGenVertexArraysOES = _glGenVertexArraysOES;
  6255. /** @suppress {duplicate } */
  6256. var _glGenerateMipmap = (x0) => GLctx.generateMipmap(x0);
  6257. var _emscripten_glGenerateMipmap = _glGenerateMipmap;
  6258. var __glGetActiveAttribOrUniform = (funcName, program, index, bufSize, length, size, type, name) => {
  6259. program = GL.programs[program];
  6260. var info = GLctx[funcName](program, index);
  6261. if (info) {
  6262. // If an error occurs, nothing will be written to length, size and type and name.
  6263. var numBytesWrittenExclNull = name && stringToUTF8(info.name, name, bufSize);
  6264. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  6265. if (size) HEAP32[((size)>>2)] = info.size;
  6266. if (type) HEAP32[((type)>>2)] = info.type;
  6267. }
  6268. };
  6269. /** @suppress {duplicate } */
  6270. var _glGetActiveAttrib = (program, index, bufSize, length, size, type, name) => {
  6271. __glGetActiveAttribOrUniform('getActiveAttrib', program, index, bufSize, length, size, type, name);
  6272. };
  6273. var _emscripten_glGetActiveAttrib = _glGetActiveAttrib;
  6274. /** @suppress {duplicate } */
  6275. var _glGetActiveUniform = (program, index, bufSize, length, size, type, name) => {
  6276. __glGetActiveAttribOrUniform('getActiveUniform', program, index, bufSize, length, size, type, name);
  6277. };
  6278. var _emscripten_glGetActiveUniform = _glGetActiveUniform;
  6279. /** @suppress {duplicate } */
  6280. var _glGetAttachedShaders = (program, maxCount, count, shaders) => {
  6281. var result = GLctx.getAttachedShaders(GL.programs[program]);
  6282. var len = result.length;
  6283. if (len > maxCount) {
  6284. len = maxCount;
  6285. }
  6286. HEAP32[((count)>>2)] = len;
  6287. for (var i = 0; i < len; ++i) {
  6288. var id = GL.shaders.indexOf(result[i]);
  6289. HEAP32[(((shaders)+(i*4))>>2)] = id;
  6290. }
  6291. };
  6292. var _emscripten_glGetAttachedShaders = _glGetAttachedShaders;
  6293. /** @suppress {duplicate } */
  6294. var _glGetAttribLocation = (program, name) => {
  6295. return GLctx.getAttribLocation(GL.programs[program], UTF8ToString(name));
  6296. };
  6297. var _emscripten_glGetAttribLocation = _glGetAttribLocation;
  6298. var readI53FromI64 = (ptr) => {
  6299. return HEAPU32[((ptr)>>2)] + HEAP32[(((ptr)+(4))>>2)] * 4294967296;
  6300. };
  6301. var readI53FromU64 = (ptr) => {
  6302. return HEAPU32[((ptr)>>2)] + HEAPU32[(((ptr)+(4))>>2)] * 4294967296;
  6303. };
  6304. var writeI53ToI64 = (ptr, num) => {
  6305. HEAPU32[((ptr)>>2)] = num;
  6306. var lower = HEAPU32[((ptr)>>2)];
  6307. HEAPU32[(((ptr)+(4))>>2)] = (num - lower)/4294967296;
  6308. var deserialized = (num >= 0) ? readI53FromU64(ptr) : readI53FromI64(ptr);
  6309. var offset = ((ptr)>>2);
  6310. if (deserialized != num) warnOnce(`writeI53ToI64() out of range: serialized JS Number ${num} to Wasm heap as bytes lo=${ptrToString(HEAPU32[offset])}, hi=${ptrToString(HEAPU32[offset+1])}, which deserializes back to ${deserialized} instead!`);
  6311. };
  6312. var emscriptenWebGLGet = (name_, p, type) => {
  6313. // Guard against user passing a null pointer.
  6314. // Note that GLES2 spec does not say anything about how passing a null
  6315. // pointer should be treated. Testing on desktop core GL 3, the application
  6316. // crashes on glGetIntegerv to a null pointer, but better to report an error
  6317. // instead of doing anything random.
  6318. if (!p) {
  6319. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6320. return;
  6321. }
  6322. var ret = undefined;
  6323. switch (name_) { // Handle a few trivial GLES values
  6324. case 0x8DFA: // GL_SHADER_COMPILER
  6325. ret = 1;
  6326. break;
  6327. case 0x8DF8: // GL_SHADER_BINARY_FORMATS
  6328. if (type != 0 && type != 1) {
  6329. GL.recordError(0x500); // GL_INVALID_ENUM
  6330. }
  6331. // Do not write anything to the out pointer, since no binary formats are
  6332. // supported.
  6333. return;
  6334. case 0x8DF9: // GL_NUM_SHADER_BINARY_FORMATS
  6335. ret = 0;
  6336. break;
  6337. case 0x86A2: // GL_NUM_COMPRESSED_TEXTURE_FORMATS
  6338. // WebGL doesn't have GL_NUM_COMPRESSED_TEXTURE_FORMATS (it's obsolete
  6339. // since GL_COMPRESSED_TEXTURE_FORMATS returns a JS array that can be
  6340. // queried for length), so implement it ourselves to allow C++ GLES2
  6341. // code get the length.
  6342. var formats = GLctx.getParameter(0x86A3 /*GL_COMPRESSED_TEXTURE_FORMATS*/);
  6343. ret = formats ? formats.length : 0;
  6344. break;
  6345. }
  6346. if (ret === undefined) {
  6347. var result = GLctx.getParameter(name_);
  6348. switch (typeof result) {
  6349. case "number":
  6350. ret = result;
  6351. break;
  6352. case "boolean":
  6353. ret = result ? 1 : 0;
  6354. break;
  6355. case "string":
  6356. GL.recordError(0x500); // GL_INVALID_ENUM
  6357. return;
  6358. case "object":
  6359. if (result === null) {
  6360. // null is a valid result for some (e.g., which buffer is bound -
  6361. // perhaps nothing is bound), but otherwise can mean an invalid
  6362. // name_, which we need to report as an error
  6363. switch (name_) {
  6364. case 0x8894: // ARRAY_BUFFER_BINDING
  6365. case 0x8B8D: // CURRENT_PROGRAM
  6366. case 0x8895: // ELEMENT_ARRAY_BUFFER_BINDING
  6367. case 0x8CA6: // FRAMEBUFFER_BINDING or DRAW_FRAMEBUFFER_BINDING
  6368. case 0x8CA7: // RENDERBUFFER_BINDING
  6369. case 0x8069: // TEXTURE_BINDING_2D
  6370. case 0x85B5: // WebGL 2 GL_VERTEX_ARRAY_BINDING, or WebGL 1 extension OES_vertex_array_object GL_VERTEX_ARRAY_BINDING_OES
  6371. case 0x8514: { // TEXTURE_BINDING_CUBE_MAP
  6372. ret = 0;
  6373. break;
  6374. }
  6375. default: {
  6376. GL.recordError(0x500); // GL_INVALID_ENUM
  6377. return;
  6378. }
  6379. }
  6380. } else if (result instanceof Float32Array ||
  6381. result instanceof Uint32Array ||
  6382. result instanceof Int32Array ||
  6383. result instanceof Array) {
  6384. for (var i = 0; i < result.length; ++i) {
  6385. switch (type) {
  6386. case 0: HEAP32[(((p)+(i*4))>>2)] = result[i]; break;
  6387. case 2: HEAPF32[(((p)+(i*4))>>2)] = result[i]; break;
  6388. case 4: HEAP8[(p)+(i)] = result[i] ? 1 : 0; break;
  6389. }
  6390. }
  6391. return;
  6392. } else {
  6393. try {
  6394. ret = result.name | 0;
  6395. } catch(e) {
  6396. GL.recordError(0x500); // GL_INVALID_ENUM
  6397. err(`GL_INVALID_ENUM in glGet${type}v: Unknown object returned from WebGL getParameter(${name_})! (error: ${e})`);
  6398. return;
  6399. }
  6400. }
  6401. break;
  6402. default:
  6403. GL.recordError(0x500); // GL_INVALID_ENUM
  6404. err(`GL_INVALID_ENUM in glGet${type}v: Native code calling glGet${type}v(${name_}) and it returns ${result} of type ${typeof(result)}!`);
  6405. return;
  6406. }
  6407. }
  6408. switch (type) {
  6409. case 1: writeI53ToI64(p, ret); break;
  6410. case 0: HEAP32[((p)>>2)] = ret; break;
  6411. case 2: HEAPF32[((p)>>2)] = ret; break;
  6412. case 4: HEAP8[p] = ret ? 1 : 0; break;
  6413. }
  6414. };
  6415. /** @suppress {duplicate } */
  6416. var _glGetBooleanv = (name_, p) => emscriptenWebGLGet(name_, p, 4);
  6417. var _emscripten_glGetBooleanv = _glGetBooleanv;
  6418. /** @suppress {duplicate } */
  6419. var _glGetBufferParameteriv = (target, value, data) => {
  6420. if (!data) {
  6421. // GLES2 specification does not specify how to behave if data is a null
  6422. // pointer. Since calling this function does not make sense if data ==
  6423. // null, issue a GL error to notify user about it.
  6424. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6425. return;
  6426. }
  6427. HEAP32[((data)>>2)] = GLctx.getBufferParameter(target, value);
  6428. };
  6429. var _emscripten_glGetBufferParameteriv = _glGetBufferParameteriv;
  6430. /** @suppress {duplicate } */
  6431. var _glGetError = () => {
  6432. var error = GLctx.getError() || GL.lastError;
  6433. GL.lastError = 0/*GL_NO_ERROR*/;
  6434. return error;
  6435. };
  6436. var _emscripten_glGetError = _glGetError;
  6437. /** @suppress {duplicate } */
  6438. var _glGetFloatv = (name_, p) => emscriptenWebGLGet(name_, p, 2);
  6439. var _emscripten_glGetFloatv = _glGetFloatv;
  6440. /** @suppress {duplicate } */
  6441. var _glGetFramebufferAttachmentParameteriv = (target, attachment, pname, params) => {
  6442. var result = GLctx.getFramebufferAttachmentParameter(target, attachment, pname);
  6443. if (result instanceof WebGLRenderbuffer ||
  6444. result instanceof WebGLTexture) {
  6445. result = result.name | 0;
  6446. }
  6447. HEAP32[((params)>>2)] = result;
  6448. };
  6449. var _emscripten_glGetFramebufferAttachmentParameteriv = _glGetFramebufferAttachmentParameteriv;
  6450. /** @suppress {duplicate } */
  6451. var _glGetIntegerv = (name_, p) => emscriptenWebGLGet(name_, p, 0);
  6452. var _emscripten_glGetIntegerv = _glGetIntegerv;
  6453. /** @suppress {duplicate } */
  6454. var _glGetProgramInfoLog = (program, maxLength, length, infoLog) => {
  6455. var log = GLctx.getProgramInfoLog(GL.programs[program]);
  6456. if (log === null) log = '(unknown error)';
  6457. var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0;
  6458. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  6459. };
  6460. var _emscripten_glGetProgramInfoLog = _glGetProgramInfoLog;
  6461. /** @suppress {duplicate } */
  6462. var _glGetProgramiv = (program, pname, p) => {
  6463. if (!p) {
  6464. // GLES2 specification does not specify how to behave if p is a null
  6465. // pointer. Since calling this function does not make sense if p == null,
  6466. // issue a GL error to notify user about it.
  6467. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6468. return;
  6469. }
  6470. if (program >= GL.counter) {
  6471. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6472. return;
  6473. }
  6474. program = GL.programs[program];
  6475. if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH
  6476. var log = GLctx.getProgramInfoLog(program);
  6477. if (log === null) log = '(unknown error)';
  6478. HEAP32[((p)>>2)] = log.length + 1;
  6479. } else if (pname == 0x8B87 /* GL_ACTIVE_UNIFORM_MAX_LENGTH */) {
  6480. if (!program.maxUniformLength) {
  6481. for (var i = 0; i < GLctx.getProgramParameter(program, 0x8B86/*GL_ACTIVE_UNIFORMS*/); ++i) {
  6482. program.maxUniformLength = Math.max(program.maxUniformLength, GLctx.getActiveUniform(program, i).name.length+1);
  6483. }
  6484. }
  6485. HEAP32[((p)>>2)] = program.maxUniformLength;
  6486. } else if (pname == 0x8B8A /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */) {
  6487. if (!program.maxAttributeLength) {
  6488. for (var i = 0; i < GLctx.getProgramParameter(program, 0x8B89/*GL_ACTIVE_ATTRIBUTES*/); ++i) {
  6489. program.maxAttributeLength = Math.max(program.maxAttributeLength, GLctx.getActiveAttrib(program, i).name.length+1);
  6490. }
  6491. }
  6492. HEAP32[((p)>>2)] = program.maxAttributeLength;
  6493. } else if (pname == 0x8A35 /* GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */) {
  6494. if (!program.maxUniformBlockNameLength) {
  6495. for (var i = 0; i < GLctx.getProgramParameter(program, 0x8A36/*GL_ACTIVE_UNIFORM_BLOCKS*/); ++i) {
  6496. program.maxUniformBlockNameLength = Math.max(program.maxUniformBlockNameLength, GLctx.getActiveUniformBlockName(program, i).length+1);
  6497. }
  6498. }
  6499. HEAP32[((p)>>2)] = program.maxUniformBlockNameLength;
  6500. } else {
  6501. HEAP32[((p)>>2)] = GLctx.getProgramParameter(program, pname);
  6502. }
  6503. };
  6504. var _emscripten_glGetProgramiv = _glGetProgramiv;
  6505. /** @suppress {duplicate } */
  6506. var _glGetQueryObjecti64vEXT = (id, pname, params) => {
  6507. if (!params) {
  6508. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  6509. // if p == null, issue a GL error to notify user about it.
  6510. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6511. return;
  6512. }
  6513. var query = GL.queries[id];
  6514. var param;
  6515. {
  6516. param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname);
  6517. }
  6518. var ret;
  6519. if (typeof param == 'boolean') {
  6520. ret = param ? 1 : 0;
  6521. } else {
  6522. ret = param;
  6523. }
  6524. writeI53ToI64(params, ret);
  6525. };
  6526. var _emscripten_glGetQueryObjecti64vEXT = _glGetQueryObjecti64vEXT;
  6527. /** @suppress {duplicate } */
  6528. var _glGetQueryObjectivEXT = (id, pname, params) => {
  6529. if (!params) {
  6530. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  6531. // if p == null, issue a GL error to notify user about it.
  6532. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6533. return;
  6534. }
  6535. var query = GL.queries[id];
  6536. var param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname);
  6537. var ret;
  6538. if (typeof param == 'boolean') {
  6539. ret = param ? 1 : 0;
  6540. } else {
  6541. ret = param;
  6542. }
  6543. HEAP32[((params)>>2)] = ret;
  6544. };
  6545. var _emscripten_glGetQueryObjectivEXT = _glGetQueryObjectivEXT;
  6546. /** @suppress {duplicate } */
  6547. var _glGetQueryObjectui64vEXT = _glGetQueryObjecti64vEXT;
  6548. var _emscripten_glGetQueryObjectui64vEXT = _glGetQueryObjectui64vEXT;
  6549. /** @suppress {duplicate } */
  6550. var _glGetQueryObjectuivEXT = _glGetQueryObjectivEXT;
  6551. var _emscripten_glGetQueryObjectuivEXT = _glGetQueryObjectuivEXT;
  6552. /** @suppress {duplicate } */
  6553. var _glGetQueryivEXT = (target, pname, params) => {
  6554. if (!params) {
  6555. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  6556. // if p == null, issue a GL error to notify user about it.
  6557. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6558. return;
  6559. }
  6560. HEAP32[((params)>>2)] = GLctx.disjointTimerQueryExt['getQueryEXT'](target, pname);
  6561. };
  6562. var _emscripten_glGetQueryivEXT = _glGetQueryivEXT;
  6563. /** @suppress {duplicate } */
  6564. var _glGetRenderbufferParameteriv = (target, pname, params) => {
  6565. if (!params) {
  6566. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  6567. // if params == null, issue a GL error to notify user about it.
  6568. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6569. return;
  6570. }
  6571. HEAP32[((params)>>2)] = GLctx.getRenderbufferParameter(target, pname);
  6572. };
  6573. var _emscripten_glGetRenderbufferParameteriv = _glGetRenderbufferParameteriv;
  6574. /** @suppress {duplicate } */
  6575. var _glGetShaderInfoLog = (shader, maxLength, length, infoLog) => {
  6576. var log = GLctx.getShaderInfoLog(GL.shaders[shader]);
  6577. if (log === null) log = '(unknown error)';
  6578. var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0;
  6579. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  6580. };
  6581. var _emscripten_glGetShaderInfoLog = _glGetShaderInfoLog;
  6582. /** @suppress {duplicate } */
  6583. var _glGetShaderPrecisionFormat = (shaderType, precisionType, range, precision) => {
  6584. var result = GLctx.getShaderPrecisionFormat(shaderType, precisionType);
  6585. HEAP32[((range)>>2)] = result.rangeMin;
  6586. HEAP32[(((range)+(4))>>2)] = result.rangeMax;
  6587. HEAP32[((precision)>>2)] = result.precision;
  6588. };
  6589. var _emscripten_glGetShaderPrecisionFormat = _glGetShaderPrecisionFormat;
  6590. /** @suppress {duplicate } */
  6591. var _glGetShaderSource = (shader, bufSize, length, source) => {
  6592. var result = GLctx.getShaderSource(GL.shaders[shader]);
  6593. if (!result) return; // If an error occurs, nothing will be written to length or source.
  6594. var numBytesWrittenExclNull = (bufSize > 0 && source) ? stringToUTF8(result, source, bufSize) : 0;
  6595. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  6596. };
  6597. var _emscripten_glGetShaderSource = _glGetShaderSource;
  6598. /** @suppress {duplicate } */
  6599. var _glGetShaderiv = (shader, pname, p) => {
  6600. if (!p) {
  6601. // GLES2 specification does not specify how to behave if p is a null
  6602. // pointer. Since calling this function does not make sense if p == null,
  6603. // issue a GL error to notify user about it.
  6604. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6605. return;
  6606. }
  6607. if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH
  6608. var log = GLctx.getShaderInfoLog(GL.shaders[shader]);
  6609. if (log === null) log = '(unknown error)';
  6610. // The GLES2 specification says that if the shader has an empty info log,
  6611. // a value of 0 is returned. Otherwise the log has a null char appended.
  6612. // (An empty string is falsey, so we can just check that instead of
  6613. // looking at log.length.)
  6614. var logLength = log ? log.length + 1 : 0;
  6615. HEAP32[((p)>>2)] = logLength;
  6616. } else if (pname == 0x8B88) { // GL_SHADER_SOURCE_LENGTH
  6617. var source = GLctx.getShaderSource(GL.shaders[shader]);
  6618. // source may be a null, or the empty string, both of which are falsey
  6619. // values that we report a 0 length for.
  6620. var sourceLength = source ? source.length + 1 : 0;
  6621. HEAP32[((p)>>2)] = sourceLength;
  6622. } else {
  6623. HEAP32[((p)>>2)] = GLctx.getShaderParameter(GL.shaders[shader], pname);
  6624. }
  6625. };
  6626. var _emscripten_glGetShaderiv = _glGetShaderiv;
  6627. var webglGetExtensions = function $webglGetExtensions() {
  6628. var exts = getEmscriptenSupportedExtensions(GLctx);
  6629. exts = exts.concat(exts.map((e) => "GL_" + e));
  6630. return exts;
  6631. };
  6632. /** @suppress {duplicate } */
  6633. var _glGetString = (name_) => {
  6634. var ret = GL.stringCache[name_];
  6635. if (!ret) {
  6636. switch (name_) {
  6637. case 0x1F03 /* GL_EXTENSIONS */:
  6638. ret = stringToNewUTF8(webglGetExtensions().join(' '));
  6639. break;
  6640. case 0x1F00 /* GL_VENDOR */:
  6641. case 0x1F01 /* GL_RENDERER */:
  6642. case 0x9245 /* UNMASKED_VENDOR_WEBGL */:
  6643. case 0x9246 /* UNMASKED_RENDERER_WEBGL */:
  6644. var s = GLctx.getParameter(name_);
  6645. if (!s) {
  6646. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  6647. }
  6648. ret = s ? stringToNewUTF8(s) : 0;
  6649. break;
  6650. case 0x1F02 /* GL_VERSION */:
  6651. var glVersion = GLctx.getParameter(0x1F02 /*GL_VERSION*/);
  6652. // return GLES version string corresponding to the version of the WebGL context
  6653. {
  6654. glVersion = `OpenGL ES 2.0 (${glVersion})`;
  6655. }
  6656. ret = stringToNewUTF8(glVersion);
  6657. break;
  6658. case 0x8B8C /* GL_SHADING_LANGUAGE_VERSION */:
  6659. var glslVersion = GLctx.getParameter(0x8B8C /*GL_SHADING_LANGUAGE_VERSION*/);
  6660. // extract the version number 'N.M' from the string 'WebGL GLSL ES N.M ...'
  6661. var ver_re = /^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;
  6662. var ver_num = glslVersion.match(ver_re);
  6663. if (ver_num !== null) {
  6664. if (ver_num[1].length == 3) ver_num[1] = ver_num[1] + '0'; // ensure minor version has 2 digits
  6665. glslVersion = `OpenGL ES GLSL ES ${ver_num[1]} (${glslVersion})`;
  6666. }
  6667. ret = stringToNewUTF8(glslVersion);
  6668. break;
  6669. default:
  6670. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  6671. // fall through
  6672. }
  6673. GL.stringCache[name_] = ret;
  6674. }
  6675. return ret;
  6676. };
  6677. var _emscripten_glGetString = _glGetString;
  6678. /** @suppress {duplicate } */
  6679. var _glGetTexParameterfv = (target, pname, params) => {
  6680. if (!params) {
  6681. // GLES2 specification does not specify how to behave if params is a null
  6682. // pointer. Since calling this function does not make sense if p == null,
  6683. // issue a GL error to notify user about it.
  6684. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6685. return;
  6686. }
  6687. HEAPF32[((params)>>2)] = GLctx.getTexParameter(target, pname);
  6688. };
  6689. var _emscripten_glGetTexParameterfv = _glGetTexParameterfv;
  6690. /** @suppress {duplicate } */
  6691. var _glGetTexParameteriv = (target, pname, params) => {
  6692. if (!params) {
  6693. // GLES2 specification does not specify how to behave if params is a null
  6694. // pointer. Since calling this function does not make sense if p == null,
  6695. // issue a GL error to notify user about it.
  6696. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6697. return;
  6698. }
  6699. HEAP32[((params)>>2)] = GLctx.getTexParameter(target, pname);
  6700. };
  6701. var _emscripten_glGetTexParameteriv = _glGetTexParameteriv;
  6702. /** @suppress {checkTypes} */
  6703. var jstoi_q = (str) => parseInt(str);
  6704. /** @noinline */
  6705. var webglGetLeftBracePos = (name) => name.slice(-1) == ']' && name.lastIndexOf('[');
  6706. var webglPrepareUniformLocationsBeforeFirstUse = (program) => {
  6707. var uniformLocsById = program.uniformLocsById, // Maps GLuint -> WebGLUniformLocation
  6708. uniformSizeAndIdsByName = program.uniformSizeAndIdsByName, // Maps name -> [uniform array length, GLuint]
  6709. i, j;
  6710. // On the first time invocation of glGetUniformLocation on this shader program:
  6711. // initialize cache data structures and discover which uniforms are arrays.
  6712. if (!uniformLocsById) {
  6713. // maps GLint integer locations to WebGLUniformLocations
  6714. program.uniformLocsById = uniformLocsById = {};
  6715. // maps integer locations back to uniform name strings, so that we can lazily fetch uniform array locations
  6716. program.uniformArrayNamesById = {};
  6717. for (i = 0; i < GLctx.getProgramParameter(program, 0x8B86/*GL_ACTIVE_UNIFORMS*/); ++i) {
  6718. var u = GLctx.getActiveUniform(program, i);
  6719. var nm = u.name;
  6720. var sz = u.size;
  6721. var lb = webglGetLeftBracePos(nm);
  6722. var arrayName = lb > 0 ? nm.slice(0, lb) : nm;
  6723. // Assign a new location.
  6724. var id = program.uniformIdCounter;
  6725. program.uniformIdCounter += sz;
  6726. // Eagerly get the location of the uniformArray[0] base element.
  6727. // The remaining indices >0 will be left for lazy evaluation to
  6728. // improve performance. Those may never be needed to fetch, if the
  6729. // application fills arrays always in full starting from the first
  6730. // element of the array.
  6731. uniformSizeAndIdsByName[arrayName] = [sz, id];
  6732. // Store placeholder integers in place that highlight that these
  6733. // >0 index locations are array indices pending population.
  6734. for (j = 0; j < sz; ++j) {
  6735. uniformLocsById[id] = j;
  6736. program.uniformArrayNamesById[id++] = arrayName;
  6737. }
  6738. }
  6739. }
  6740. };
  6741. /** @suppress {duplicate } */
  6742. var _glGetUniformLocation = (program, name) => {
  6743. name = UTF8ToString(name);
  6744. if (program = GL.programs[program]) {
  6745. webglPrepareUniformLocationsBeforeFirstUse(program);
  6746. var uniformLocsById = program.uniformLocsById; // Maps GLuint -> WebGLUniformLocation
  6747. var arrayIndex = 0;
  6748. var uniformBaseName = name;
  6749. // Invariant: when populating integer IDs for uniform locations, we must
  6750. // maintain the precondition that arrays reside in contiguous addresses,
  6751. // i.e. for a 'vec4 colors[10];', colors[4] must be at location
  6752. // colors[0]+4. However, user might call glGetUniformLocation(program,
  6753. // "colors") for an array, so we cannot discover based on the user input
  6754. // arguments whether the uniform we are dealing with is an array. The only
  6755. // way to discover which uniforms are arrays is to enumerate over all the
  6756. // active uniforms in the program.
  6757. var leftBrace = webglGetLeftBracePos(name);
  6758. // If user passed an array accessor "[index]", parse the array index off the accessor.
  6759. if (leftBrace > 0) {
  6760. arrayIndex = jstoi_q(name.slice(leftBrace + 1)) >>> 0; // "index]", coerce parseInt(']') with >>>0 to treat "foo[]" as "foo[0]" and foo[-1] as unsigned out-of-bounds.
  6761. uniformBaseName = name.slice(0, leftBrace);
  6762. }
  6763. // Have we cached the location of this uniform before?
  6764. // A pair [array length, GLint of the uniform location]
  6765. var sizeAndId = program.uniformSizeAndIdsByName[uniformBaseName];
  6766. // If an uniform with this name exists, and if its index is within the
  6767. // array limits (if it's even an array), query the WebGLlocation, or
  6768. // return an existing cached location.
  6769. if (sizeAndId && arrayIndex < sizeAndId[0]) {
  6770. arrayIndex += sizeAndId[1]; // Add the base location of the uniform to the array index offset.
  6771. if ((uniformLocsById[arrayIndex] = uniformLocsById[arrayIndex] || GLctx.getUniformLocation(program, name))) {
  6772. return arrayIndex;
  6773. }
  6774. }
  6775. }
  6776. else {
  6777. // N.b. we are currently unable to distinguish between GL program IDs that
  6778. // never existed vs GL program IDs that have been deleted, so report
  6779. // GL_INVALID_VALUE in both cases.
  6780. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6781. }
  6782. return -1;
  6783. };
  6784. var _emscripten_glGetUniformLocation = _glGetUniformLocation;
  6785. var webglGetUniformLocation = (location) => {
  6786. var p = GLctx.currentProgram;
  6787. if (p) {
  6788. var webglLoc = p.uniformLocsById[location];
  6789. // p.uniformLocsById[location] stores either an integer, or a
  6790. // WebGLUniformLocation.
  6791. // If an integer, we have not yet bound the location, so do it now. The
  6792. // integer value specifies the array index we should bind to.
  6793. if (typeof webglLoc == 'number') {
  6794. p.uniformLocsById[location] = webglLoc = GLctx.getUniformLocation(p, p.uniformArrayNamesById[location] + (webglLoc > 0 ? `[${webglLoc}]` : ''));
  6795. }
  6796. // Else an already cached WebGLUniformLocation, return it.
  6797. return webglLoc;
  6798. } else {
  6799. GL.recordError(0x502/*GL_INVALID_OPERATION*/);
  6800. }
  6801. };
  6802. /** @suppress{checkTypes} */
  6803. var emscriptenWebGLGetUniform = (program, location, params, type) => {
  6804. if (!params) {
  6805. // GLES2 specification does not specify how to behave if params is a null
  6806. // pointer. Since calling this function does not make sense if params ==
  6807. // null, issue a GL error to notify user about it.
  6808. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6809. return;
  6810. }
  6811. program = GL.programs[program];
  6812. webglPrepareUniformLocationsBeforeFirstUse(program);
  6813. var data = GLctx.getUniform(program, webglGetUniformLocation(location));
  6814. if (typeof data == 'number' || typeof data == 'boolean') {
  6815. switch (type) {
  6816. case 0: HEAP32[((params)>>2)] = data; break;
  6817. case 2: HEAPF32[((params)>>2)] = data; break;
  6818. }
  6819. } else {
  6820. for (var i = 0; i < data.length; i++) {
  6821. switch (type) {
  6822. case 0: HEAP32[(((params)+(i*4))>>2)] = data[i]; break;
  6823. case 2: HEAPF32[(((params)+(i*4))>>2)] = data[i]; break;
  6824. }
  6825. }
  6826. }
  6827. };
  6828. /** @suppress {duplicate } */
  6829. var _glGetUniformfv = (program, location, params) => {
  6830. emscriptenWebGLGetUniform(program, location, params, 2);
  6831. };
  6832. var _emscripten_glGetUniformfv = _glGetUniformfv;
  6833. /** @suppress {duplicate } */
  6834. var _glGetUniformiv = (program, location, params) => {
  6835. emscriptenWebGLGetUniform(program, location, params, 0);
  6836. };
  6837. var _emscripten_glGetUniformiv = _glGetUniformiv;
  6838. /** @suppress {duplicate } */
  6839. var _glGetVertexAttribPointerv = (index, pname, pointer) => {
  6840. if (!pointer) {
  6841. // GLES2 specification does not specify how to behave if pointer is a null
  6842. // pointer. Since calling this function does not make sense if pointer ==
  6843. // null, issue a GL error to notify user about it.
  6844. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6845. return;
  6846. }
  6847. HEAP32[((pointer)>>2)] = GLctx.getVertexAttribOffset(index, pname);
  6848. };
  6849. var _emscripten_glGetVertexAttribPointerv = _glGetVertexAttribPointerv;
  6850. /** @suppress{checkTypes} */
  6851. var emscriptenWebGLGetVertexAttrib = (index, pname, params, type) => {
  6852. if (!params) {
  6853. // GLES2 specification does not specify how to behave if params is a null
  6854. // pointer. Since calling this function does not make sense if params ==
  6855. // null, issue a GL error to notify user about it.
  6856. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6857. return;
  6858. }
  6859. var data = GLctx.getVertexAttrib(index, pname);
  6860. if (pname == 0x889F/*VERTEX_ATTRIB_ARRAY_BUFFER_BINDING*/) {
  6861. HEAP32[((params)>>2)] = data && data["name"];
  6862. } else if (typeof data == 'number' || typeof data == 'boolean') {
  6863. switch (type) {
  6864. case 0: HEAP32[((params)>>2)] = data; break;
  6865. case 2: HEAPF32[((params)>>2)] = data; break;
  6866. case 5: HEAP32[((params)>>2)] = Math.fround(data); break;
  6867. }
  6868. } else {
  6869. for (var i = 0; i < data.length; i++) {
  6870. switch (type) {
  6871. case 0: HEAP32[(((params)+(i*4))>>2)] = data[i]; break;
  6872. case 2: HEAPF32[(((params)+(i*4))>>2)] = data[i]; break;
  6873. case 5: HEAP32[(((params)+(i*4))>>2)] = Math.fround(data[i]); break;
  6874. }
  6875. }
  6876. }
  6877. };
  6878. /** @suppress {duplicate } */
  6879. var _glGetVertexAttribfv = (index, pname, params) => {
  6880. // N.B. This function may only be called if the vertex attribute was
  6881. // specified using the function glVertexAttrib*f(), otherwise the results
  6882. // are undefined. (GLES3 spec 6.1.12)
  6883. emscriptenWebGLGetVertexAttrib(index, pname, params, 2);
  6884. };
  6885. var _emscripten_glGetVertexAttribfv = _glGetVertexAttribfv;
  6886. /** @suppress {duplicate } */
  6887. var _glGetVertexAttribiv = (index, pname, params) => {
  6888. // N.B. This function may only be called if the vertex attribute was
  6889. // specified using the function glVertexAttrib*f(), otherwise the results
  6890. // are undefined. (GLES3 spec 6.1.12)
  6891. emscriptenWebGLGetVertexAttrib(index, pname, params, 5);
  6892. };
  6893. var _emscripten_glGetVertexAttribiv = _glGetVertexAttribiv;
  6894. /** @suppress {duplicate } */
  6895. var _glHint = (x0, x1) => GLctx.hint(x0, x1);
  6896. var _emscripten_glHint = _glHint;
  6897. /** @suppress {duplicate } */
  6898. var _glIsBuffer = (buffer) => {
  6899. var b = GL.buffers[buffer];
  6900. if (!b) return 0;
  6901. return GLctx.isBuffer(b);
  6902. };
  6903. var _emscripten_glIsBuffer = _glIsBuffer;
  6904. /** @suppress {duplicate } */
  6905. var _glIsEnabled = (x0) => GLctx.isEnabled(x0);
  6906. var _emscripten_glIsEnabled = _glIsEnabled;
  6907. /** @suppress {duplicate } */
  6908. var _glIsFramebuffer = (framebuffer) => {
  6909. var fb = GL.framebuffers[framebuffer];
  6910. if (!fb) return 0;
  6911. return GLctx.isFramebuffer(fb);
  6912. };
  6913. var _emscripten_glIsFramebuffer = _glIsFramebuffer;
  6914. /** @suppress {duplicate } */
  6915. var _glIsProgram = (program) => {
  6916. program = GL.programs[program];
  6917. if (!program) return 0;
  6918. return GLctx.isProgram(program);
  6919. };
  6920. var _emscripten_glIsProgram = _glIsProgram;
  6921. /** @suppress {duplicate } */
  6922. var _glIsQueryEXT = (id) => {
  6923. var query = GL.queries[id];
  6924. if (!query) return 0;
  6925. return GLctx.disjointTimerQueryExt['isQueryEXT'](query);
  6926. };
  6927. var _emscripten_glIsQueryEXT = _glIsQueryEXT;
  6928. /** @suppress {duplicate } */
  6929. var _glIsRenderbuffer = (renderbuffer) => {
  6930. var rb = GL.renderbuffers[renderbuffer];
  6931. if (!rb) return 0;
  6932. return GLctx.isRenderbuffer(rb);
  6933. };
  6934. var _emscripten_glIsRenderbuffer = _glIsRenderbuffer;
  6935. /** @suppress {duplicate } */
  6936. var _glIsShader = (shader) => {
  6937. var s = GL.shaders[shader];
  6938. if (!s) return 0;
  6939. return GLctx.isShader(s);
  6940. };
  6941. var _emscripten_glIsShader = _glIsShader;
  6942. /** @suppress {duplicate } */
  6943. var _glIsTexture = (id) => {
  6944. var texture = GL.textures[id];
  6945. if (!texture) return 0;
  6946. return GLctx.isTexture(texture);
  6947. };
  6948. var _emscripten_glIsTexture = _glIsTexture;
  6949. /** @suppress {duplicate } */
  6950. var _glIsVertexArray = (array) => {
  6951. var vao = GL.vaos[array];
  6952. if (!vao) return 0;
  6953. return GLctx.isVertexArray(vao);
  6954. };
  6955. /** @suppress {duplicate } */
  6956. var _glIsVertexArrayOES = _glIsVertexArray;
  6957. var _emscripten_glIsVertexArrayOES = _glIsVertexArrayOES;
  6958. /** @suppress {duplicate } */
  6959. var _glLineWidth = (x0) => GLctx.lineWidth(x0);
  6960. var _emscripten_glLineWidth = _glLineWidth;
  6961. /** @suppress {duplicate } */
  6962. var _glLinkProgram = (program) => {
  6963. program = GL.programs[program];
  6964. GLctx.linkProgram(program);
  6965. // Invalidate earlier computed uniform->ID mappings, those have now become stale
  6966. program.uniformLocsById = 0; // Mark as null-like so that glGetUniformLocation() knows to populate this again.
  6967. program.uniformSizeAndIdsByName = {};
  6968. };
  6969. var _emscripten_glLinkProgram = _glLinkProgram;
  6970. /** @suppress {duplicate } */
  6971. var _glPixelStorei = (pname, param) => {
  6972. if (pname == 3317) {
  6973. GL.unpackAlignment = param;
  6974. } else if (pname == 3314) {
  6975. GL.unpackRowLength = param;
  6976. }
  6977. GLctx.pixelStorei(pname, param);
  6978. };
  6979. var _emscripten_glPixelStorei = _glPixelStorei;
  6980. /** @suppress {duplicate } */
  6981. var _glPolygonOffset = (x0, x1) => GLctx.polygonOffset(x0, x1);
  6982. var _emscripten_glPolygonOffset = _glPolygonOffset;
  6983. /** @suppress {duplicate } */
  6984. var _glQueryCounterEXT = (id, target) => {
  6985. GLctx.disjointTimerQueryExt['queryCounterEXT'](GL.queries[id], target);
  6986. };
  6987. var _emscripten_glQueryCounterEXT = _glQueryCounterEXT;
  6988. var computeUnpackAlignedImageSize = (width, height, sizePerPixel) => {
  6989. function roundedToNextMultipleOf(x, y) {
  6990. return (x + y - 1) & -y;
  6991. }
  6992. var plainRowSize = (GL.unpackRowLength || width) * sizePerPixel;
  6993. var alignedRowSize = roundedToNextMultipleOf(plainRowSize, GL.unpackAlignment);
  6994. return height * alignedRowSize;
  6995. };
  6996. var colorChannelsInGlTextureFormat = (format) => {
  6997. // Micro-optimizations for size: map format to size by subtracting smallest
  6998. // enum value (0x1902) from all values first. Also omit the most common
  6999. // size value (1) from the list, which is assumed by formats not on the
  7000. // list.
  7001. var colorChannels = {
  7002. // 0x1902 /* GL_DEPTH_COMPONENT */ - 0x1902: 1,
  7003. // 0x1906 /* GL_ALPHA */ - 0x1902: 1,
  7004. 5: 3,
  7005. 6: 4,
  7006. // 0x1909 /* GL_LUMINANCE */ - 0x1902: 1,
  7007. 8: 2,
  7008. 29502: 3,
  7009. 29504: 4,
  7010. };
  7011. return colorChannels[format - 0x1902]||1;
  7012. };
  7013. var heapObjectForWebGLType = (type) => {
  7014. // Micro-optimization for size: Subtract lowest GL enum number (0x1400/* GL_BYTE */) from type to compare
  7015. // smaller values for the heap, for shorter generated code size.
  7016. // Also the type HEAPU16 is not tested for explicitly, but any unrecognized type will return out HEAPU16.
  7017. // (since most types are HEAPU16)
  7018. type -= 0x1400;
  7019. if (type == 1) return HEAPU8;
  7020. if (type == 4) return HEAP32;
  7021. if (type == 6) return HEAPF32;
  7022. if (type == 5
  7023. || type == 28922
  7024. )
  7025. return HEAPU32;
  7026. return HEAPU16;
  7027. };
  7028. var toTypedArrayIndex = (pointer, heap) =>
  7029. pointer >>> (31 - Math.clz32(heap.BYTES_PER_ELEMENT));
  7030. var emscriptenWebGLGetTexPixelData = (type, format, width, height, pixels, internalFormat) => {
  7031. var heap = heapObjectForWebGLType(type);
  7032. var sizePerPixel = colorChannelsInGlTextureFormat(format) * heap.BYTES_PER_ELEMENT;
  7033. var bytes = computeUnpackAlignedImageSize(width, height, sizePerPixel);
  7034. return heap.subarray(toTypedArrayIndex(pixels, heap), toTypedArrayIndex(pixels + bytes, heap));
  7035. };
  7036. /** @suppress {duplicate } */
  7037. var _glReadPixels = (x, y, width, height, format, type, pixels) => {
  7038. var pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, format);
  7039. if (!pixelData) {
  7040. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  7041. return;
  7042. }
  7043. GLctx.readPixels(x, y, width, height, format, type, pixelData);
  7044. };
  7045. var _emscripten_glReadPixels = _glReadPixels;
  7046. /** @suppress {duplicate } */
  7047. var _glReleaseShaderCompiler = () => {
  7048. // NOP (as allowed by GLES 2.0 spec)
  7049. };
  7050. var _emscripten_glReleaseShaderCompiler = _glReleaseShaderCompiler;
  7051. /** @suppress {duplicate } */
  7052. var _glRenderbufferStorage = (x0, x1, x2, x3) => GLctx.renderbufferStorage(x0, x1, x2, x3);
  7053. var _emscripten_glRenderbufferStorage = _glRenderbufferStorage;
  7054. /** @suppress {duplicate } */
  7055. var _glSampleCoverage = (value, invert) => {
  7056. GLctx.sampleCoverage(value, !!invert);
  7057. };
  7058. var _emscripten_glSampleCoverage = _glSampleCoverage;
  7059. /** @suppress {duplicate } */
  7060. var _glScissor = (x0, x1, x2, x3) => GLctx.scissor(x0, x1, x2, x3);
  7061. var _emscripten_glScissor = _glScissor;
  7062. /** @suppress {duplicate } */
  7063. var _glShaderBinary = (count, shaders, binaryformat, binary, length) => {
  7064. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  7065. };
  7066. var _emscripten_glShaderBinary = _glShaderBinary;
  7067. /** @suppress {duplicate } */
  7068. var _glShaderSource = (shader, count, string, length) => {
  7069. var source = GL.getSource(shader, count, string, length);
  7070. GLctx.shaderSource(GL.shaders[shader], source);
  7071. };
  7072. var _emscripten_glShaderSource = _glShaderSource;
  7073. /** @suppress {duplicate } */
  7074. var _glStencilFunc = (x0, x1, x2) => GLctx.stencilFunc(x0, x1, x2);
  7075. var _emscripten_glStencilFunc = _glStencilFunc;
  7076. /** @suppress {duplicate } */
  7077. var _glStencilFuncSeparate = (x0, x1, x2, x3) => GLctx.stencilFuncSeparate(x0, x1, x2, x3);
  7078. var _emscripten_glStencilFuncSeparate = _glStencilFuncSeparate;
  7079. /** @suppress {duplicate } */
  7080. var _glStencilMask = (x0) => GLctx.stencilMask(x0);
  7081. var _emscripten_glStencilMask = _glStencilMask;
  7082. /** @suppress {duplicate } */
  7083. var _glStencilMaskSeparate = (x0, x1) => GLctx.stencilMaskSeparate(x0, x1);
  7084. var _emscripten_glStencilMaskSeparate = _glStencilMaskSeparate;
  7085. /** @suppress {duplicate } */
  7086. var _glStencilOp = (x0, x1, x2) => GLctx.stencilOp(x0, x1, x2);
  7087. var _emscripten_glStencilOp = _glStencilOp;
  7088. /** @suppress {duplicate } */
  7089. var _glStencilOpSeparate = (x0, x1, x2, x3) => GLctx.stencilOpSeparate(x0, x1, x2, x3);
  7090. var _emscripten_glStencilOpSeparate = _glStencilOpSeparate;
  7091. /** @suppress {duplicate } */
  7092. var _glTexImage2D = (target, level, internalFormat, width, height, border, format, type, pixels) => {
  7093. var pixelData = pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) : null;
  7094. GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixelData);
  7095. };
  7096. var _emscripten_glTexImage2D = _glTexImage2D;
  7097. /** @suppress {duplicate } */
  7098. var _glTexParameterf = (x0, x1, x2) => GLctx.texParameterf(x0, x1, x2);
  7099. var _emscripten_glTexParameterf = _glTexParameterf;
  7100. /** @suppress {duplicate } */
  7101. var _glTexParameterfv = (target, pname, params) => {
  7102. var param = HEAPF32[((params)>>2)];
  7103. GLctx.texParameterf(target, pname, param);
  7104. };
  7105. var _emscripten_glTexParameterfv = _glTexParameterfv;
  7106. /** @suppress {duplicate } */
  7107. var _glTexParameteri = (x0, x1, x2) => GLctx.texParameteri(x0, x1, x2);
  7108. var _emscripten_glTexParameteri = _glTexParameteri;
  7109. /** @suppress {duplicate } */
  7110. var _glTexParameteriv = (target, pname, params) => {
  7111. var param = HEAP32[((params)>>2)];
  7112. GLctx.texParameteri(target, pname, param);
  7113. };
  7114. var _emscripten_glTexParameteriv = _glTexParameteriv;
  7115. /** @suppress {duplicate } */
  7116. var _glTexSubImage2D = (target, level, xoffset, yoffset, width, height, format, type, pixels) => {
  7117. var pixelData = pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, 0) : null;
  7118. GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixelData);
  7119. };
  7120. var _emscripten_glTexSubImage2D = _glTexSubImage2D;
  7121. /** @suppress {duplicate } */
  7122. var _glUniform1f = (location, v0) => {
  7123. GLctx.uniform1f(webglGetUniformLocation(location), v0);
  7124. };
  7125. var _emscripten_glUniform1f = _glUniform1f;
  7126. var miniTempWebGLFloatBuffers = [];
  7127. /** @suppress {duplicate } */
  7128. var _glUniform1fv = (location, count, value) => {
  7129. if (count <= 288) {
  7130. // avoid allocation when uploading few enough uniforms
  7131. var view = miniTempWebGLFloatBuffers[count];
  7132. for (var i = 0; i < count; ++i) {
  7133. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  7134. }
  7135. } else
  7136. {
  7137. var view = HEAPF32.subarray((((value)>>2)), ((value+count*4)>>2));
  7138. }
  7139. GLctx.uniform1fv(webglGetUniformLocation(location), view);
  7140. };
  7141. var _emscripten_glUniform1fv = _glUniform1fv;
  7142. /** @suppress {duplicate } */
  7143. var _glUniform1i = (location, v0) => {
  7144. GLctx.uniform1i(webglGetUniformLocation(location), v0);
  7145. };
  7146. var _emscripten_glUniform1i = _glUniform1i;
  7147. var miniTempWebGLIntBuffers = [];
  7148. /** @suppress {duplicate } */
  7149. var _glUniform1iv = (location, count, value) => {
  7150. if (count <= 288) {
  7151. // avoid allocation when uploading few enough uniforms
  7152. var view = miniTempWebGLIntBuffers[count];
  7153. for (var i = 0; i < count; ++i) {
  7154. view[i] = HEAP32[(((value)+(4*i))>>2)];
  7155. }
  7156. } else
  7157. {
  7158. var view = HEAP32.subarray((((value)>>2)), ((value+count*4)>>2));
  7159. }
  7160. GLctx.uniform1iv(webglGetUniformLocation(location), view);
  7161. };
  7162. var _emscripten_glUniform1iv = _glUniform1iv;
  7163. /** @suppress {duplicate } */
  7164. var _glUniform2f = (location, v0, v1) => {
  7165. GLctx.uniform2f(webglGetUniformLocation(location), v0, v1);
  7166. };
  7167. var _emscripten_glUniform2f = _glUniform2f;
  7168. /** @suppress {duplicate } */
  7169. var _glUniform2fv = (location, count, value) => {
  7170. if (count <= 144) {
  7171. // avoid allocation when uploading few enough uniforms
  7172. var view = miniTempWebGLFloatBuffers[2*count];
  7173. for (var i = 0; i < 2*count; i += 2) {
  7174. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  7175. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  7176. }
  7177. } else
  7178. {
  7179. var view = HEAPF32.subarray((((value)>>2)), ((value+count*8)>>2));
  7180. }
  7181. GLctx.uniform2fv(webglGetUniformLocation(location), view);
  7182. };
  7183. var _emscripten_glUniform2fv = _glUniform2fv;
  7184. /** @suppress {duplicate } */
  7185. var _glUniform2i = (location, v0, v1) => {
  7186. GLctx.uniform2i(webglGetUniformLocation(location), v0, v1);
  7187. };
  7188. var _emscripten_glUniform2i = _glUniform2i;
  7189. /** @suppress {duplicate } */
  7190. var _glUniform2iv = (location, count, value) => {
  7191. if (count <= 144) {
  7192. // avoid allocation when uploading few enough uniforms
  7193. var view = miniTempWebGLIntBuffers[2*count];
  7194. for (var i = 0; i < 2*count; i += 2) {
  7195. view[i] = HEAP32[(((value)+(4*i))>>2)];
  7196. view[i+1] = HEAP32[(((value)+(4*i+4))>>2)];
  7197. }
  7198. } else
  7199. {
  7200. var view = HEAP32.subarray((((value)>>2)), ((value+count*8)>>2));
  7201. }
  7202. GLctx.uniform2iv(webglGetUniformLocation(location), view);
  7203. };
  7204. var _emscripten_glUniform2iv = _glUniform2iv;
  7205. /** @suppress {duplicate } */
  7206. var _glUniform3f = (location, v0, v1, v2) => {
  7207. GLctx.uniform3f(webglGetUniformLocation(location), v0, v1, v2);
  7208. };
  7209. var _emscripten_glUniform3f = _glUniform3f;
  7210. /** @suppress {duplicate } */
  7211. var _glUniform3fv = (location, count, value) => {
  7212. if (count <= 96) {
  7213. // avoid allocation when uploading few enough uniforms
  7214. var view = miniTempWebGLFloatBuffers[3*count];
  7215. for (var i = 0; i < 3*count; i += 3) {
  7216. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  7217. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  7218. view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];
  7219. }
  7220. } else
  7221. {
  7222. var view = HEAPF32.subarray((((value)>>2)), ((value+count*12)>>2));
  7223. }
  7224. GLctx.uniform3fv(webglGetUniformLocation(location), view);
  7225. };
  7226. var _emscripten_glUniform3fv = _glUniform3fv;
  7227. /** @suppress {duplicate } */
  7228. var _glUniform3i = (location, v0, v1, v2) => {
  7229. GLctx.uniform3i(webglGetUniformLocation(location), v0, v1, v2);
  7230. };
  7231. var _emscripten_glUniform3i = _glUniform3i;
  7232. /** @suppress {duplicate } */
  7233. var _glUniform3iv = (location, count, value) => {
  7234. if (count <= 96) {
  7235. // avoid allocation when uploading few enough uniforms
  7236. var view = miniTempWebGLIntBuffers[3*count];
  7237. for (var i = 0; i < 3*count; i += 3) {
  7238. view[i] = HEAP32[(((value)+(4*i))>>2)];
  7239. view[i+1] = HEAP32[(((value)+(4*i+4))>>2)];
  7240. view[i+2] = HEAP32[(((value)+(4*i+8))>>2)];
  7241. }
  7242. } else
  7243. {
  7244. var view = HEAP32.subarray((((value)>>2)), ((value+count*12)>>2));
  7245. }
  7246. GLctx.uniform3iv(webglGetUniformLocation(location), view);
  7247. };
  7248. var _emscripten_glUniform3iv = _glUniform3iv;
  7249. /** @suppress {duplicate } */
  7250. var _glUniform4f = (location, v0, v1, v2, v3) => {
  7251. GLctx.uniform4f(webglGetUniformLocation(location), v0, v1, v2, v3);
  7252. };
  7253. var _emscripten_glUniform4f = _glUniform4f;
  7254. /** @suppress {duplicate } */
  7255. var _glUniform4fv = (location, count, value) => {
  7256. if (count <= 72) {
  7257. // avoid allocation when uploading few enough uniforms
  7258. var view = miniTempWebGLFloatBuffers[4*count];
  7259. // hoist the heap out of the loop for size and for pthreads+growth.
  7260. var heap = HEAPF32;
  7261. value = ((value)>>2);
  7262. for (var i = 0; i < 4 * count; i += 4) {
  7263. var dst = value + i;
  7264. view[i] = heap[dst];
  7265. view[i + 1] = heap[dst + 1];
  7266. view[i + 2] = heap[dst + 2];
  7267. view[i + 3] = heap[dst + 3];
  7268. }
  7269. } else
  7270. {
  7271. var view = HEAPF32.subarray((((value)>>2)), ((value+count*16)>>2));
  7272. }
  7273. GLctx.uniform4fv(webglGetUniformLocation(location), view);
  7274. };
  7275. var _emscripten_glUniform4fv = _glUniform4fv;
  7276. /** @suppress {duplicate } */
  7277. var _glUniform4i = (location, v0, v1, v2, v3) => {
  7278. GLctx.uniform4i(webglGetUniformLocation(location), v0, v1, v2, v3);
  7279. };
  7280. var _emscripten_glUniform4i = _glUniform4i;
  7281. /** @suppress {duplicate } */
  7282. var _glUniform4iv = (location, count, value) => {
  7283. if (count <= 72) {
  7284. // avoid allocation when uploading few enough uniforms
  7285. var view = miniTempWebGLIntBuffers[4*count];
  7286. for (var i = 0; i < 4*count; i += 4) {
  7287. view[i] = HEAP32[(((value)+(4*i))>>2)];
  7288. view[i+1] = HEAP32[(((value)+(4*i+4))>>2)];
  7289. view[i+2] = HEAP32[(((value)+(4*i+8))>>2)];
  7290. view[i+3] = HEAP32[(((value)+(4*i+12))>>2)];
  7291. }
  7292. } else
  7293. {
  7294. var view = HEAP32.subarray((((value)>>2)), ((value+count*16)>>2));
  7295. }
  7296. GLctx.uniform4iv(webglGetUniformLocation(location), view);
  7297. };
  7298. var _emscripten_glUniform4iv = _glUniform4iv;
  7299. /** @suppress {duplicate } */
  7300. var _glUniformMatrix2fv = (location, count, transpose, value) => {
  7301. if (count <= 72) {
  7302. // avoid allocation when uploading few enough uniforms
  7303. var view = miniTempWebGLFloatBuffers[4*count];
  7304. for (var i = 0; i < 4*count; i += 4) {
  7305. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  7306. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  7307. view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];
  7308. view[i+3] = HEAPF32[(((value)+(4*i+12))>>2)];
  7309. }
  7310. } else
  7311. {
  7312. var view = HEAPF32.subarray((((value)>>2)), ((value+count*16)>>2));
  7313. }
  7314. GLctx.uniformMatrix2fv(webglGetUniformLocation(location), !!transpose, view);
  7315. };
  7316. var _emscripten_glUniformMatrix2fv = _glUniformMatrix2fv;
  7317. /** @suppress {duplicate } */
  7318. var _glUniformMatrix3fv = (location, count, transpose, value) => {
  7319. if (count <= 32) {
  7320. // avoid allocation when uploading few enough uniforms
  7321. var view = miniTempWebGLFloatBuffers[9*count];
  7322. for (var i = 0; i < 9*count; i += 9) {
  7323. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  7324. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  7325. view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];
  7326. view[i+3] = HEAPF32[(((value)+(4*i+12))>>2)];
  7327. view[i+4] = HEAPF32[(((value)+(4*i+16))>>2)];
  7328. view[i+5] = HEAPF32[(((value)+(4*i+20))>>2)];
  7329. view[i+6] = HEAPF32[(((value)+(4*i+24))>>2)];
  7330. view[i+7] = HEAPF32[(((value)+(4*i+28))>>2)];
  7331. view[i+8] = HEAPF32[(((value)+(4*i+32))>>2)];
  7332. }
  7333. } else
  7334. {
  7335. var view = HEAPF32.subarray((((value)>>2)), ((value+count*36)>>2));
  7336. }
  7337. GLctx.uniformMatrix3fv(webglGetUniformLocation(location), !!transpose, view);
  7338. };
  7339. var _emscripten_glUniformMatrix3fv = _glUniformMatrix3fv;
  7340. /** @suppress {duplicate } */
  7341. var _glUniformMatrix4fv = (location, count, transpose, value) => {
  7342. if (count <= 18) {
  7343. // avoid allocation when uploading few enough uniforms
  7344. var view = miniTempWebGLFloatBuffers[16*count];
  7345. // hoist the heap out of the loop for size and for pthreads+growth.
  7346. var heap = HEAPF32;
  7347. value = ((value)>>2);
  7348. for (var i = 0; i < 16 * count; i += 16) {
  7349. var dst = value + i;
  7350. view[i] = heap[dst];
  7351. view[i + 1] = heap[dst + 1];
  7352. view[i + 2] = heap[dst + 2];
  7353. view[i + 3] = heap[dst + 3];
  7354. view[i + 4] = heap[dst + 4];
  7355. view[i + 5] = heap[dst + 5];
  7356. view[i + 6] = heap[dst + 6];
  7357. view[i + 7] = heap[dst + 7];
  7358. view[i + 8] = heap[dst + 8];
  7359. view[i + 9] = heap[dst + 9];
  7360. view[i + 10] = heap[dst + 10];
  7361. view[i + 11] = heap[dst + 11];
  7362. view[i + 12] = heap[dst + 12];
  7363. view[i + 13] = heap[dst + 13];
  7364. view[i + 14] = heap[dst + 14];
  7365. view[i + 15] = heap[dst + 15];
  7366. }
  7367. } else
  7368. {
  7369. var view = HEAPF32.subarray((((value)>>2)), ((value+count*64)>>2));
  7370. }
  7371. GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, view);
  7372. };
  7373. var _emscripten_glUniformMatrix4fv = _glUniformMatrix4fv;
  7374. /** @suppress {duplicate } */
  7375. var _glUseProgram = (program) => {
  7376. program = GL.programs[program];
  7377. GLctx.useProgram(program);
  7378. // Record the currently active program so that we can access the uniform
  7379. // mapping table of that program.
  7380. GLctx.currentProgram = program;
  7381. };
  7382. var _emscripten_glUseProgram = _glUseProgram;
  7383. /** @suppress {duplicate } */
  7384. var _glValidateProgram = (program) => {
  7385. GLctx.validateProgram(GL.programs[program]);
  7386. };
  7387. var _emscripten_glValidateProgram = _glValidateProgram;
  7388. /** @suppress {duplicate } */
  7389. var _glVertexAttrib1f = (x0, x1) => GLctx.vertexAttrib1f(x0, x1);
  7390. var _emscripten_glVertexAttrib1f = _glVertexAttrib1f;
  7391. /** @suppress {duplicate } */
  7392. var _glVertexAttrib1fv = (index, v) => {
  7393. GLctx.vertexAttrib1f(index, HEAPF32[v>>2]);
  7394. };
  7395. var _emscripten_glVertexAttrib1fv = _glVertexAttrib1fv;
  7396. /** @suppress {duplicate } */
  7397. var _glVertexAttrib2f = (x0, x1, x2) => GLctx.vertexAttrib2f(x0, x1, x2);
  7398. var _emscripten_glVertexAttrib2f = _glVertexAttrib2f;
  7399. /** @suppress {duplicate } */
  7400. var _glVertexAttrib2fv = (index, v) => {
  7401. GLctx.vertexAttrib2f(index, HEAPF32[v>>2], HEAPF32[v+4>>2]);
  7402. };
  7403. var _emscripten_glVertexAttrib2fv = _glVertexAttrib2fv;
  7404. /** @suppress {duplicate } */
  7405. var _glVertexAttrib3f = (x0, x1, x2, x3) => GLctx.vertexAttrib3f(x0, x1, x2, x3);
  7406. var _emscripten_glVertexAttrib3f = _glVertexAttrib3f;
  7407. /** @suppress {duplicate } */
  7408. var _glVertexAttrib3fv = (index, v) => {
  7409. GLctx.vertexAttrib3f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2]);
  7410. };
  7411. var _emscripten_glVertexAttrib3fv = _glVertexAttrib3fv;
  7412. /** @suppress {duplicate } */
  7413. var _glVertexAttrib4f = (x0, x1, x2, x3, x4) => GLctx.vertexAttrib4f(x0, x1, x2, x3, x4);
  7414. var _emscripten_glVertexAttrib4f = _glVertexAttrib4f;
  7415. /** @suppress {duplicate } */
  7416. var _glVertexAttrib4fv = (index, v) => {
  7417. GLctx.vertexAttrib4f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2], HEAPF32[v+12>>2]);
  7418. };
  7419. var _emscripten_glVertexAttrib4fv = _glVertexAttrib4fv;
  7420. /** @suppress {duplicate } */
  7421. var _glVertexAttribDivisor = (index, divisor) => {
  7422. GLctx.vertexAttribDivisor(index, divisor);
  7423. };
  7424. /** @suppress {duplicate } */
  7425. var _glVertexAttribDivisorANGLE = _glVertexAttribDivisor;
  7426. var _emscripten_glVertexAttribDivisorANGLE = _glVertexAttribDivisorANGLE;
  7427. /** @suppress {duplicate } */
  7428. var _glVertexAttribPointer = (index, size, type, normalized, stride, ptr) => {
  7429. GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr);
  7430. };
  7431. var _emscripten_glVertexAttribPointer = _glVertexAttribPointer;
  7432. /** @suppress {duplicate } */
  7433. var _glViewport = (x0, x1, x2, x3) => GLctx.viewport(x0, x1, x2, x3);
  7434. var _emscripten_glViewport = _glViewport;
  7435. var _emscripten_has_asyncify = () => 0;
  7436. var doRequestFullscreen = (target, strategy) => {
  7437. if (!JSEvents.fullscreenEnabled()) return -1;
  7438. target = findEventTarget(target);
  7439. if (!target) return -4;
  7440. if (!target.requestFullscreen
  7441. && !target.webkitRequestFullscreen
  7442. ) {
  7443. return -3;
  7444. }
  7445. var canPerformRequests = JSEvents.canPerformEventHandlerRequests();
  7446. // Queue this function call if we're not currently in an event handler and the user saw it appropriate to do so.
  7447. if (!canPerformRequests) {
  7448. if (strategy.deferUntilInEventHandler) {
  7449. JSEvents.deferCall(JSEvents_requestFullscreen, 1 /* priority over pointer lock */, [target, strategy]);
  7450. return 1;
  7451. }
  7452. return -2;
  7453. }
  7454. return JSEvents_requestFullscreen(target, strategy);
  7455. };
  7456. var _emscripten_request_fullscreen_strategy = (target, deferUntilInEventHandler, fullscreenStrategy) => {
  7457. var strategy = {
  7458. scaleMode: HEAP32[((fullscreenStrategy)>>2)],
  7459. canvasResolutionScaleMode: HEAP32[(((fullscreenStrategy)+(4))>>2)],
  7460. filteringMode: HEAP32[(((fullscreenStrategy)+(8))>>2)],
  7461. deferUntilInEventHandler,
  7462. canvasResizedCallback: HEAP32[(((fullscreenStrategy)+(12))>>2)],
  7463. canvasResizedCallbackUserData: HEAP32[(((fullscreenStrategy)+(16))>>2)]
  7464. };
  7465. return doRequestFullscreen(target, strategy);
  7466. };
  7467. var _emscripten_request_pointerlock = (target, deferUntilInEventHandler) => {
  7468. target = findEventTarget(target);
  7469. if (!target) return -4;
  7470. if (!target.requestPointerLock
  7471. ) {
  7472. return -1;
  7473. }
  7474. var canPerformRequests = JSEvents.canPerformEventHandlerRequests();
  7475. // Queue this function call if we're not currently in an event handler and the user saw it appropriate to do so.
  7476. if (!canPerformRequests) {
  7477. if (deferUntilInEventHandler) {
  7478. JSEvents.deferCall(requestPointerLock, 2 /* priority below fullscreen */, [target]);
  7479. return 1;
  7480. }
  7481. return -2;
  7482. }
  7483. return requestPointerLock(target);
  7484. };
  7485. var getHeapMax = () =>
  7486. // Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate
  7487. // full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side
  7488. // for any code that deals with heap sizes, which would require special
  7489. // casing all heap size related code to treat 0 specially.
  7490. 2147483648;
  7491. var growMemory = (size) => {
  7492. var b = wasmMemory.buffer;
  7493. var pages = (size - b.byteLength + 65535) / 65536;
  7494. try {
  7495. // round size grow request up to wasm page size (fixed 64KB per spec)
  7496. wasmMemory.grow(pages); // .grow() takes a delta compared to the previous size
  7497. updateMemoryViews();
  7498. return 1 /*success*/;
  7499. } catch(e) {
  7500. err(`growMemory: Attempted to grow heap from ${b.byteLength} bytes to ${size} bytes, but got error: ${e}`);
  7501. }
  7502. // implicit 0 return to save code size (caller will cast "undefined" into 0
  7503. // anyhow)
  7504. };
  7505. var _emscripten_resize_heap = (requestedSize) => {
  7506. var oldSize = HEAPU8.length;
  7507. // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
  7508. requestedSize >>>= 0;
  7509. // With multithreaded builds, races can happen (another thread might increase the size
  7510. // in between), so return a failure, and let the caller retry.
  7511. assert(requestedSize > oldSize);
  7512. // Memory resize rules:
  7513. // 1. Always increase heap size to at least the requested size, rounded up
  7514. // to next page multiple.
  7515. // 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap
  7516. // geometrically: increase the heap size according to
  7517. // MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), At most
  7518. // overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB).
  7519. // 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap
  7520. // linearly: increase the heap size by at least
  7521. // MEMORY_GROWTH_LINEAR_STEP bytes.
  7522. // 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by
  7523. // MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest
  7524. // 4. If we were unable to allocate as much memory, it may be due to
  7525. // over-eager decision to excessively reserve due to (3) above.
  7526. // Hence if an allocation fails, cut down on the amount of excess
  7527. // growth, in an attempt to succeed to perform a smaller allocation.
  7528. // A limit is set for how much we can grow. We should not exceed that
  7529. // (the wasm binary specifies it, so if we tried, we'd fail anyhow).
  7530. var maxHeapSize = getHeapMax();
  7531. if (requestedSize > maxHeapSize) {
  7532. err(`Cannot enlarge memory, requested ${requestedSize} bytes, but the limit is ${maxHeapSize} bytes!`);
  7533. return false;
  7534. }
  7535. var alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple;
  7536. // Loop through potential heap size increases. If we attempt a too eager
  7537. // reservation that fails, cut down on the attempted size and reserve a
  7538. // smaller bump instead. (max 3 times, chosen somewhat arbitrarily)
  7539. for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
  7540. var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); // ensure geometric growth
  7541. // but limit overreserving (default to capping at +96MB overgrowth at most)
  7542. overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296 );
  7543. var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536));
  7544. var replacement = growMemory(newSize);
  7545. if (replacement) {
  7546. return true;
  7547. }
  7548. }
  7549. err(`Failed to grow the heap from ${oldSize} bytes to ${newSize} bytes, not enough memory!`);
  7550. return false;
  7551. };
  7552. /** @suppress {checkTypes} */
  7553. var _emscripten_sample_gamepad_data = () => {
  7554. try {
  7555. if (navigator.getGamepads) return (JSEvents.lastGamepadState = navigator.getGamepads())
  7556. ? 0 : -1;
  7557. } catch(e) {
  7558. err(`navigator.getGamepads() exists, but failed to execute with exception ${e}. Disabling Gamepad access.`);
  7559. navigator.getGamepads = null; // Disable getGamepads() so that it won't be attempted to be used again.
  7560. }
  7561. return -1;
  7562. };
  7563. var registerBeforeUnloadEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString) => {
  7564. var beforeUnloadEventHandlerFunc = (e = event) => {
  7565. // Note: This is always called on the main browser thread, since it needs synchronously return a value!
  7566. var confirmationMessage = getWasmTableEntry(callbackfunc)(eventTypeId, 0, userData);
  7567. if (confirmationMessage) {
  7568. confirmationMessage = UTF8ToString(confirmationMessage);
  7569. }
  7570. if (confirmationMessage) {
  7571. e.preventDefault();
  7572. e.returnValue = confirmationMessage;
  7573. return confirmationMessage;
  7574. }
  7575. };
  7576. var eventHandler = {
  7577. target: findEventTarget(target),
  7578. eventTypeString,
  7579. callbackfunc,
  7580. handlerFunc: beforeUnloadEventHandlerFunc,
  7581. useCapture
  7582. };
  7583. return JSEvents.registerOrRemoveHandler(eventHandler);
  7584. };
  7585. var _emscripten_set_beforeunload_callback_on_thread = (userData, callbackfunc, targetThread) => {
  7586. if (typeof onbeforeunload == 'undefined') return -1;
  7587. // beforeunload callback can only be registered on the main browser thread, because the page will go away immediately after returning from the handler,
  7588. // and there is no time to start proxying it anywhere.
  7589. if (targetThread !== 1) return -5;
  7590. return registerBeforeUnloadEventCallback(2, userData, true, callbackfunc, 28, "beforeunload");
  7591. };
  7592. var registerFocusEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7593. if (!JSEvents.focusEvent) JSEvents.focusEvent = _malloc(256);
  7594. var focusEventHandlerFunc = (e = event) => {
  7595. var nodeName = JSEvents.getNodeNameForTarget(e.target);
  7596. var id = e.target.id ? e.target.id : '';
  7597. var focusEvent = JSEvents.focusEvent;
  7598. stringToUTF8(nodeName, focusEvent + 0, 128);
  7599. stringToUTF8(id, focusEvent + 128, 128);
  7600. if (getWasmTableEntry(callbackfunc)(eventTypeId, focusEvent, userData)) e.preventDefault();
  7601. };
  7602. var eventHandler = {
  7603. target: findEventTarget(target),
  7604. eventTypeString,
  7605. callbackfunc,
  7606. handlerFunc: focusEventHandlerFunc,
  7607. useCapture
  7608. };
  7609. return JSEvents.registerOrRemoveHandler(eventHandler);
  7610. };
  7611. var _emscripten_set_blur_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7612. registerFocusEventCallback(target, userData, useCapture, callbackfunc, 12, "blur", targetThread);
  7613. var _emscripten_set_element_css_size = (target, width, height) => {
  7614. target = findEventTarget(target);
  7615. if (!target) return -4;
  7616. target.style.width = width + "px";
  7617. target.style.height = height + "px";
  7618. return 0;
  7619. };
  7620. var _emscripten_set_focus_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7621. registerFocusEventCallback(target, userData, useCapture, callbackfunc, 13, "focus", targetThread);
  7622. var fillFullscreenChangeEventData = (eventStruct) => {
  7623. var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
  7624. var isFullscreen = !!fullscreenElement;
  7625. // Assigning a boolean to HEAP32 with expected type coercion.
  7626. /** @suppress{checkTypes} */
  7627. HEAP32[((eventStruct)>>2)] = isFullscreen;
  7628. HEAP32[(((eventStruct)+(4))>>2)] = JSEvents.fullscreenEnabled();
  7629. // If transitioning to fullscreen, report info about the element that is now fullscreen.
  7630. // If transitioning to windowed mode, report info about the element that just was fullscreen.
  7631. var reportedElement = isFullscreen ? fullscreenElement : JSEvents.previousFullscreenElement;
  7632. var nodeName = JSEvents.getNodeNameForTarget(reportedElement);
  7633. var id = reportedElement?.id || '';
  7634. stringToUTF8(nodeName, eventStruct + 8, 128);
  7635. stringToUTF8(id, eventStruct + 136, 128);
  7636. HEAP32[(((eventStruct)+(264))>>2)] = reportedElement ? reportedElement.clientWidth : 0;
  7637. HEAP32[(((eventStruct)+(268))>>2)] = reportedElement ? reportedElement.clientHeight : 0;
  7638. HEAP32[(((eventStruct)+(272))>>2)] = screen.width;
  7639. HEAP32[(((eventStruct)+(276))>>2)] = screen.height;
  7640. if (isFullscreen) {
  7641. JSEvents.previousFullscreenElement = fullscreenElement;
  7642. }
  7643. };
  7644. var registerFullscreenChangeEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7645. if (!JSEvents.fullscreenChangeEvent) JSEvents.fullscreenChangeEvent = _malloc(280);
  7646. var fullscreenChangeEventhandlerFunc = (e = event) => {
  7647. var fullscreenChangeEvent = JSEvents.fullscreenChangeEvent;
  7648. fillFullscreenChangeEventData(fullscreenChangeEvent);
  7649. if (getWasmTableEntry(callbackfunc)(eventTypeId, fullscreenChangeEvent, userData)) e.preventDefault();
  7650. };
  7651. var eventHandler = {
  7652. target,
  7653. eventTypeString,
  7654. callbackfunc,
  7655. handlerFunc: fullscreenChangeEventhandlerFunc,
  7656. useCapture
  7657. };
  7658. return JSEvents.registerOrRemoveHandler(eventHandler);
  7659. };
  7660. var _emscripten_set_fullscreenchange_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => {
  7661. if (!JSEvents.fullscreenEnabled()) return -1;
  7662. target = findEventTarget(target);
  7663. if (!target) return -4;
  7664. // Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
  7665. // 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.
  7666. registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "webkitfullscreenchange", targetThread);
  7667. return registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "fullscreenchange", targetThread);
  7668. };
  7669. var registerGamepadEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7670. if (!JSEvents.gamepadEvent) JSEvents.gamepadEvent = _malloc(1432);
  7671. var gamepadEventHandlerFunc = (e = event) => {
  7672. var gamepadEvent = JSEvents.gamepadEvent;
  7673. fillGamepadEventData(gamepadEvent, e["gamepad"]);
  7674. if (getWasmTableEntry(callbackfunc)(eventTypeId, gamepadEvent, userData)) e.preventDefault();
  7675. };
  7676. var eventHandler = {
  7677. target: findEventTarget(target),
  7678. allowsDeferredCalls: true,
  7679. eventTypeString,
  7680. callbackfunc,
  7681. handlerFunc: gamepadEventHandlerFunc,
  7682. useCapture
  7683. };
  7684. return JSEvents.registerOrRemoveHandler(eventHandler);
  7685. };
  7686. var _emscripten_set_gamepadconnected_callback_on_thread = (userData, useCapture, callbackfunc, targetThread) => {
  7687. if (_emscripten_sample_gamepad_data()) return -1;
  7688. return registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 26, "gamepadconnected", targetThread);
  7689. };
  7690. var _emscripten_set_gamepaddisconnected_callback_on_thread = (userData, useCapture, callbackfunc, targetThread) => {
  7691. if (_emscripten_sample_gamepad_data()) return -1;
  7692. return registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 27, "gamepaddisconnected", targetThread);
  7693. };
  7694. var registerKeyEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7695. if (!JSEvents.keyEvent) JSEvents.keyEvent = _malloc(176);
  7696. var keyEventHandlerFunc = (e) => {
  7697. assert(e);
  7698. var keyEventData = JSEvents.keyEvent;
  7699. HEAPF64[((keyEventData)>>3)] = e.timeStamp;
  7700. var idx =((keyEventData)>>2);
  7701. HEAP32[idx + 2] = e.location;
  7702. HEAP32[idx + 3] = e.ctrlKey;
  7703. HEAP32[idx + 4] = e.shiftKey;
  7704. HEAP32[idx + 5] = e.altKey;
  7705. HEAP32[idx + 6] = e.metaKey;
  7706. HEAP32[idx + 7] = e.repeat;
  7707. HEAP32[idx + 8] = e.charCode;
  7708. HEAP32[idx + 9] = e.keyCode;
  7709. HEAP32[idx + 10] = e.which;
  7710. stringToUTF8(e.key || '', keyEventData + 44, 32);
  7711. stringToUTF8(e.code || '', keyEventData + 76, 32);
  7712. stringToUTF8(e.char || '', keyEventData + 108, 32);
  7713. stringToUTF8(e.locale || '', keyEventData + 140, 32);
  7714. if (getWasmTableEntry(callbackfunc)(eventTypeId, keyEventData, userData)) e.preventDefault();
  7715. };
  7716. var eventHandler = {
  7717. target: findEventTarget(target),
  7718. eventTypeString,
  7719. callbackfunc,
  7720. handlerFunc: keyEventHandlerFunc,
  7721. useCapture
  7722. };
  7723. return JSEvents.registerOrRemoveHandler(eventHandler);
  7724. };
  7725. var _emscripten_set_keydown_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7726. registerKeyEventCallback(target, userData, useCapture, callbackfunc, 2, "keydown", targetThread);
  7727. var _emscripten_set_keypress_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7728. registerKeyEventCallback(target, userData, useCapture, callbackfunc, 1, "keypress", targetThread);
  7729. var _emscripten_set_keyup_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7730. registerKeyEventCallback(target, userData, useCapture, callbackfunc, 3, "keyup", targetThread);
  7731. var _emscripten_set_main_loop = (func, fps, simulateInfiniteLoop) => {
  7732. var browserIterationFunc = getWasmTableEntry(func);
  7733. setMainLoop(browserIterationFunc, fps, simulateInfiniteLoop);
  7734. };
  7735. var fillMouseEventData = (eventStruct, e, target) => {
  7736. assert(eventStruct % 4 == 0);
  7737. HEAPF64[((eventStruct)>>3)] = e.timeStamp;
  7738. var idx = ((eventStruct)>>2);
  7739. HEAP32[idx + 2] = e.screenX;
  7740. HEAP32[idx + 3] = e.screenY;
  7741. HEAP32[idx + 4] = e.clientX;
  7742. HEAP32[idx + 5] = e.clientY;
  7743. HEAP32[idx + 6] = e.ctrlKey;
  7744. HEAP32[idx + 7] = e.shiftKey;
  7745. HEAP32[idx + 8] = e.altKey;
  7746. HEAP32[idx + 9] = e.metaKey;
  7747. HEAP16[idx*2 + 20] = e.button;
  7748. HEAP16[idx*2 + 21] = e.buttons;
  7749. HEAP32[idx + 11] = e["movementX"]
  7750. ;
  7751. HEAP32[idx + 12] = e["movementY"]
  7752. ;
  7753. // Note: rect contains doubles (truncated to placate SAFE_HEAP, which is the same behaviour when writing to HEAP32 anyway)
  7754. var rect = getBoundingClientRect(target);
  7755. HEAP32[idx + 13] = e.clientX - (rect.left | 0);
  7756. HEAP32[idx + 14] = e.clientY - (rect.top | 0);
  7757. };
  7758. var registerMouseEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7759. if (!JSEvents.mouseEvent) JSEvents.mouseEvent = _malloc(72);
  7760. target = findEventTarget(target);
  7761. var mouseEventHandlerFunc = (e = event) => {
  7762. // TODO: Make this access thread safe, or this could update live while app is reading it.
  7763. fillMouseEventData(JSEvents.mouseEvent, e, target);
  7764. if (getWasmTableEntry(callbackfunc)(eventTypeId, JSEvents.mouseEvent, userData)) e.preventDefault();
  7765. };
  7766. var eventHandler = {
  7767. target,
  7768. allowsDeferredCalls: eventTypeString != 'mousemove' && eventTypeString != 'mouseenter' && eventTypeString != 'mouseleave', // Mouse move events do not allow fullscreen/pointer lock requests to be handled in them!
  7769. eventTypeString,
  7770. callbackfunc,
  7771. handlerFunc: mouseEventHandlerFunc,
  7772. useCapture
  7773. };
  7774. return JSEvents.registerOrRemoveHandler(eventHandler);
  7775. };
  7776. var _emscripten_set_mousedown_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7777. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 5, "mousedown", targetThread);
  7778. var _emscripten_set_mouseenter_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7779. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 33, "mouseenter", targetThread);
  7780. var _emscripten_set_mouseleave_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7781. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 34, "mouseleave", targetThread);
  7782. var _emscripten_set_mousemove_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7783. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 8, "mousemove", targetThread);
  7784. var _emscripten_set_mouseup_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7785. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 6, "mouseup", targetThread);
  7786. var fillPointerlockChangeEventData = (eventStruct) => {
  7787. var pointerLockElement = document.pointerLockElement || document.mozPointerLockElement || document.webkitPointerLockElement || document.msPointerLockElement;
  7788. var isPointerlocked = !!pointerLockElement;
  7789. // Assigning a boolean to HEAP32 with expected type coercion.
  7790. /** @suppress{checkTypes} */
  7791. HEAP32[((eventStruct)>>2)] = isPointerlocked;
  7792. var nodeName = JSEvents.getNodeNameForTarget(pointerLockElement);
  7793. var id = pointerLockElement?.id || '';
  7794. stringToUTF8(nodeName, eventStruct + 4, 128);
  7795. stringToUTF8(id, eventStruct + 132, 128);
  7796. };
  7797. var registerPointerlockChangeEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7798. if (!JSEvents.pointerlockChangeEvent) JSEvents.pointerlockChangeEvent = _malloc(260);
  7799. var pointerlockChangeEventHandlerFunc = (e = event) => {
  7800. var pointerlockChangeEvent = JSEvents.pointerlockChangeEvent;
  7801. fillPointerlockChangeEventData(pointerlockChangeEvent);
  7802. if (getWasmTableEntry(callbackfunc)(eventTypeId, pointerlockChangeEvent, userData)) e.preventDefault();
  7803. };
  7804. var eventHandler = {
  7805. target,
  7806. eventTypeString,
  7807. callbackfunc,
  7808. handlerFunc: pointerlockChangeEventHandlerFunc,
  7809. useCapture
  7810. };
  7811. return JSEvents.registerOrRemoveHandler(eventHandler);
  7812. };
  7813. /** @suppress {missingProperties} */
  7814. var _emscripten_set_pointerlockchange_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => {
  7815. // TODO: Currently not supported in pthreads or in --proxy-to-worker mode. (In pthreads mode, document object is not defined)
  7816. if (!document || !document.body || (!document.body.requestPointerLock && !document.body.mozRequestPointerLock && !document.body.webkitRequestPointerLock && !document.body.msRequestPointerLock)) {
  7817. return -1;
  7818. }
  7819. target = findEventTarget(target);
  7820. if (!target) return -4;
  7821. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "mozpointerlockchange", targetThread);
  7822. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "webkitpointerlockchange", targetThread);
  7823. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "mspointerlockchange", targetThread);
  7824. return registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "pointerlockchange", targetThread);
  7825. };
  7826. var registerUiEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7827. if (!JSEvents.uiEvent) JSEvents.uiEvent = _malloc(36);
  7828. target = findEventTarget(target);
  7829. var uiEventHandlerFunc = (e = event) => {
  7830. if (e.target != target) {
  7831. // Never take ui events such as scroll via a 'bubbled' route, but always from the direct element that
  7832. // was targeted. Otherwise e.g. if app logs a message in response to a page scroll, the Emscripten log
  7833. // message box could cause to scroll, generating a new (bubbled) scroll message, causing a new log print,
  7834. // causing a new scroll, etc..
  7835. return;
  7836. }
  7837. var b = document.body; // Take document.body to a variable, Closure compiler does not outline access to it on its own.
  7838. if (!b) {
  7839. // During a page unload 'body' can be null, with "Cannot read property 'clientWidth' of null" being thrown
  7840. return;
  7841. }
  7842. var uiEvent = JSEvents.uiEvent;
  7843. HEAP32[((uiEvent)>>2)] = 0; // always zero for resize and scroll
  7844. HEAP32[(((uiEvent)+(4))>>2)] = b.clientWidth;
  7845. HEAP32[(((uiEvent)+(8))>>2)] = b.clientHeight;
  7846. HEAP32[(((uiEvent)+(12))>>2)] = innerWidth;
  7847. HEAP32[(((uiEvent)+(16))>>2)] = innerHeight;
  7848. HEAP32[(((uiEvent)+(20))>>2)] = outerWidth;
  7849. HEAP32[(((uiEvent)+(24))>>2)] = outerHeight;
  7850. HEAP32[(((uiEvent)+(28))>>2)] = pageXOffset | 0; // scroll offsets are float
  7851. HEAP32[(((uiEvent)+(32))>>2)] = pageYOffset | 0;
  7852. if (getWasmTableEntry(callbackfunc)(eventTypeId, uiEvent, userData)) e.preventDefault();
  7853. };
  7854. var eventHandler = {
  7855. target,
  7856. eventTypeString,
  7857. callbackfunc,
  7858. handlerFunc: uiEventHandlerFunc,
  7859. useCapture
  7860. };
  7861. return JSEvents.registerOrRemoveHandler(eventHandler);
  7862. };
  7863. var _emscripten_set_resize_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7864. registerUiEventCallback(target, userData, useCapture, callbackfunc, 10, "resize", targetThread);
  7865. var registerTouchEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7866. if (!JSEvents.touchEvent) JSEvents.touchEvent = _malloc(1696);
  7867. target = findEventTarget(target);
  7868. var touchEventHandlerFunc = (e) => {
  7869. assert(e);
  7870. var t, touches = {}, et = e.touches;
  7871. // To ease marshalling different kinds of touches that browser reports (all touches are listed in e.touches,
  7872. // only changed touches in e.changedTouches, and touches on target at a.targetTouches), mark a boolean in
  7873. // each Touch object so that we can later loop only once over all touches we see to marshall over to Wasm.
  7874. for (var i = 0; i < et.length; ++i) {
  7875. t = et[i];
  7876. // Browser might recycle the generated Touch objects between each frame (Firefox on Android), so reset any
  7877. // changed/target states we may have set from previous frame.
  7878. t.isChanged = t.onTarget = 0;
  7879. touches[t.identifier] = t;
  7880. }
  7881. // Mark which touches are part of the changedTouches list.
  7882. for (var i = 0; i < e.changedTouches.length; ++i) {
  7883. t = e.changedTouches[i];
  7884. t.isChanged = 1;
  7885. touches[t.identifier] = t;
  7886. }
  7887. // Mark which touches are part of the targetTouches list.
  7888. for (var i = 0; i < e.targetTouches.length; ++i) {
  7889. touches[e.targetTouches[i].identifier].onTarget = 1;
  7890. }
  7891. var touchEvent = JSEvents.touchEvent;
  7892. HEAPF64[((touchEvent)>>3)] = e.timeStamp;
  7893. var idx =((touchEvent)>>2);// Pre-shift the ptr to index to HEAP32 to save code size
  7894. HEAP32[idx + 3] = e.ctrlKey;
  7895. HEAP32[idx + 4] = e.shiftKey;
  7896. HEAP32[idx + 5] = e.altKey;
  7897. HEAP32[idx + 6] = e.metaKey;
  7898. idx += 7; // Advance to the start of the touch array.
  7899. var targetRect = getBoundingClientRect(target);
  7900. var numTouches = 0;
  7901. for (var i in touches) {
  7902. t = touches[i];
  7903. HEAP32[idx + 0] = t.identifier;
  7904. HEAP32[idx + 1] = t.screenX;
  7905. HEAP32[idx + 2] = t.screenY;
  7906. HEAP32[idx + 3] = t.clientX;
  7907. HEAP32[idx + 4] = t.clientY;
  7908. HEAP32[idx + 5] = t.pageX;
  7909. HEAP32[idx + 6] = t.pageY;
  7910. HEAP32[idx + 7] = t.isChanged;
  7911. HEAP32[idx + 8] = t.onTarget;
  7912. HEAP32[idx + 9] = t.clientX - (targetRect.left | 0);
  7913. HEAP32[idx + 10] = t.clientY - (targetRect.top | 0);
  7914. idx += 13;
  7915. if (++numTouches > 31) {
  7916. break;
  7917. }
  7918. }
  7919. HEAP32[(((touchEvent)+(8))>>2)] = numTouches;
  7920. if (getWasmTableEntry(callbackfunc)(eventTypeId, touchEvent, userData)) e.preventDefault();
  7921. };
  7922. var eventHandler = {
  7923. target,
  7924. allowsDeferredCalls: eventTypeString == 'touchstart' || eventTypeString == 'touchend',
  7925. eventTypeString,
  7926. callbackfunc,
  7927. handlerFunc: touchEventHandlerFunc,
  7928. useCapture
  7929. };
  7930. return JSEvents.registerOrRemoveHandler(eventHandler);
  7931. };
  7932. var _emscripten_set_touchcancel_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7933. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 25, "touchcancel", targetThread);
  7934. var _emscripten_set_touchend_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7935. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 23, "touchend", targetThread);
  7936. var _emscripten_set_touchmove_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7937. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 24, "touchmove", targetThread);
  7938. var _emscripten_set_touchstart_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7939. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 22, "touchstart", targetThread);
  7940. var fillVisibilityChangeEventData = (eventStruct) => {
  7941. var visibilityStates = [ "hidden", "visible", "prerender", "unloaded" ];
  7942. var visibilityState = visibilityStates.indexOf(document.visibilityState);
  7943. // Assigning a boolean to HEAP32 with expected type coercion.
  7944. /** @suppress{checkTypes} */
  7945. HEAP32[((eventStruct)>>2)] = document.hidden;
  7946. HEAP32[(((eventStruct)+(4))>>2)] = visibilityState;
  7947. };
  7948. var registerVisibilityChangeEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7949. if (!JSEvents.visibilityChangeEvent) JSEvents.visibilityChangeEvent = _malloc(8);
  7950. var visibilityChangeEventHandlerFunc = (e = event) => {
  7951. var visibilityChangeEvent = JSEvents.visibilityChangeEvent;
  7952. fillVisibilityChangeEventData(visibilityChangeEvent);
  7953. if (getWasmTableEntry(callbackfunc)(eventTypeId, visibilityChangeEvent, userData)) e.preventDefault();
  7954. };
  7955. var eventHandler = {
  7956. target,
  7957. eventTypeString,
  7958. callbackfunc,
  7959. handlerFunc: visibilityChangeEventHandlerFunc,
  7960. useCapture
  7961. };
  7962. return JSEvents.registerOrRemoveHandler(eventHandler);
  7963. };
  7964. var _emscripten_set_visibilitychange_callback_on_thread = (userData, useCapture, callbackfunc, targetThread) => {
  7965. if (!specialHTMLTargets[1]) {
  7966. return -4;
  7967. }
  7968. return registerVisibilityChangeEventCallback(specialHTMLTargets[1], userData, useCapture, callbackfunc, 21, "visibilitychange", targetThread);
  7969. };
  7970. var registerWheelEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7971. if (!JSEvents.wheelEvent) JSEvents.wheelEvent = _malloc(104);
  7972. // The DOM Level 3 events spec event 'wheel'
  7973. var wheelHandlerFunc = (e = event) => {
  7974. var wheelEvent = JSEvents.wheelEvent;
  7975. fillMouseEventData(wheelEvent, e, target);
  7976. HEAPF64[(((wheelEvent)+(72))>>3)] = e["deltaX"];
  7977. HEAPF64[(((wheelEvent)+(80))>>3)] = e["deltaY"];
  7978. HEAPF64[(((wheelEvent)+(88))>>3)] = e["deltaZ"];
  7979. HEAP32[(((wheelEvent)+(96))>>2)] = e["deltaMode"];
  7980. if (getWasmTableEntry(callbackfunc)(eventTypeId, wheelEvent, userData)) e.preventDefault();
  7981. };
  7982. var eventHandler = {
  7983. target,
  7984. allowsDeferredCalls: true,
  7985. eventTypeString,
  7986. callbackfunc,
  7987. handlerFunc: wheelHandlerFunc,
  7988. useCapture
  7989. };
  7990. return JSEvents.registerOrRemoveHandler(eventHandler);
  7991. };
  7992. var _emscripten_set_wheel_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => {
  7993. target = findEventTarget(target);
  7994. if (!target) return -4;
  7995. if (typeof target.onwheel != 'undefined') {
  7996. return registerWheelEventCallback(target, userData, useCapture, callbackfunc, 9, "wheel", targetThread);
  7997. } else {
  7998. return -1;
  7999. }
  8000. };
  8001. var _emscripten_set_window_title = (title) => document.title = UTF8ToString(title);
  8002. var _emscripten_sleep = () => {
  8003. throw 'Please compile your program with async support in order to use asynchronous operations like emscripten_sleep';
  8004. };
  8005. var ENV = {
  8006. };
  8007. var getExecutableName = () => {
  8008. return thisProgram || './this.program';
  8009. };
  8010. var getEnvStrings = () => {
  8011. if (!getEnvStrings.strings) {
  8012. // Default values.
  8013. // Browser language detection #8751
  8014. var lang = ((typeof navigator == 'object' && navigator.languages && navigator.languages[0]) || 'C').replace('-', '_') + '.UTF-8';
  8015. var env = {
  8016. 'USER': 'web_user',
  8017. 'LOGNAME': 'web_user',
  8018. 'PATH': '/',
  8019. 'PWD': '/',
  8020. 'HOME': '/home/web_user',
  8021. 'LANG': lang,
  8022. '_': getExecutableName()
  8023. };
  8024. // Apply the user-provided values, if any.
  8025. for (var x in ENV) {
  8026. // x is a key in ENV; if ENV[x] is undefined, that means it was
  8027. // explicitly set to be so. We allow user code to do that to
  8028. // force variables with default values to remain unset.
  8029. if (ENV[x] === undefined) delete env[x];
  8030. else env[x] = ENV[x];
  8031. }
  8032. var strings = [];
  8033. for (var x in env) {
  8034. strings.push(`${x}=${env[x]}`);
  8035. }
  8036. getEnvStrings.strings = strings;
  8037. }
  8038. return getEnvStrings.strings;
  8039. };
  8040. var stringToAscii = (str, buffer) => {
  8041. for (var i = 0; i < str.length; ++i) {
  8042. assert(str.charCodeAt(i) === (str.charCodeAt(i) & 0xff));
  8043. HEAP8[buffer++] = str.charCodeAt(i);
  8044. }
  8045. // Null-terminate the string
  8046. HEAP8[buffer] = 0;
  8047. };
  8048. var _environ_get = (__environ, environ_buf) => {
  8049. var bufSize = 0;
  8050. getEnvStrings().forEach((string, i) => {
  8051. var ptr = environ_buf + bufSize;
  8052. HEAPU32[(((__environ)+(i*4))>>2)] = ptr;
  8053. stringToAscii(string, ptr);
  8054. bufSize += string.length + 1;
  8055. });
  8056. return 0;
  8057. };
  8058. var _environ_sizes_get = (penviron_count, penviron_buf_size) => {
  8059. var strings = getEnvStrings();
  8060. HEAPU32[((penviron_count)>>2)] = strings.length;
  8061. var bufSize = 0;
  8062. strings.forEach((string) => bufSize += string.length + 1);
  8063. HEAPU32[((penviron_buf_size)>>2)] = bufSize;
  8064. return 0;
  8065. };
  8066. function _fd_close(fd) {
  8067. try {
  8068. var stream = SYSCALLS.getStreamFromFD(fd);
  8069. FS.close(stream);
  8070. return 0;
  8071. } catch (e) {
  8072. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  8073. return e.errno;
  8074. }
  8075. }
  8076. /** @param {number=} offset */
  8077. var doReadv = (stream, iov, iovcnt, offset) => {
  8078. var ret = 0;
  8079. for (var i = 0; i < iovcnt; i++) {
  8080. var ptr = HEAPU32[((iov)>>2)];
  8081. var len = HEAPU32[(((iov)+(4))>>2)];
  8082. iov += 8;
  8083. var curr = FS.read(stream, HEAP8, ptr, len, offset);
  8084. if (curr < 0) return -1;
  8085. ret += curr;
  8086. if (curr < len) break; // nothing more to read
  8087. if (typeof offset != 'undefined') {
  8088. offset += curr;
  8089. }
  8090. }
  8091. return ret;
  8092. };
  8093. function _fd_read(fd, iov, iovcnt, pnum) {
  8094. try {
  8095. var stream = SYSCALLS.getStreamFromFD(fd);
  8096. var num = doReadv(stream, iov, iovcnt);
  8097. HEAPU32[((pnum)>>2)] = num;
  8098. return 0;
  8099. } catch (e) {
  8100. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  8101. return e.errno;
  8102. }
  8103. }
  8104. function _fd_seek(fd, offset, whence, newOffset) {
  8105. offset = bigintToI53Checked(offset);
  8106. try {
  8107. if (isNaN(offset)) return 61;
  8108. var stream = SYSCALLS.getStreamFromFD(fd);
  8109. FS.llseek(stream, offset, whence);
  8110. HEAP64[((newOffset)>>3)] = BigInt(stream.position);
  8111. if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; // reset readdir state
  8112. return 0;
  8113. } catch (e) {
  8114. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  8115. return e.errno;
  8116. }
  8117. ;
  8118. }
  8119. /** @param {number=} offset */
  8120. var doWritev = (stream, iov, iovcnt, offset) => {
  8121. var ret = 0;
  8122. for (var i = 0; i < iovcnt; i++) {
  8123. var ptr = HEAPU32[((iov)>>2)];
  8124. var len = HEAPU32[(((iov)+(4))>>2)];
  8125. iov += 8;
  8126. var curr = FS.write(stream, HEAP8, ptr, len, offset);
  8127. if (curr < 0) return -1;
  8128. ret += curr;
  8129. if (typeof offset != 'undefined') {
  8130. offset += curr;
  8131. }
  8132. }
  8133. return ret;
  8134. };
  8135. function _fd_write(fd, iov, iovcnt, pnum) {
  8136. try {
  8137. var stream = SYSCALLS.getStreamFromFD(fd);
  8138. var num = doWritev(stream, iov, iovcnt);
  8139. HEAPU32[((pnum)>>2)] = num;
  8140. return 0;
  8141. } catch (e) {
  8142. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  8143. return e.errno;
  8144. }
  8145. }
  8146. var listenOnce = (object, event, func) => {
  8147. object.addEventListener(event, func, { 'once': true });
  8148. };
  8149. /** @param {Object=} elements */
  8150. var autoResumeAudioContext = (ctx, elements) => {
  8151. if (!elements) {
  8152. elements = [document, document.getElementById('canvas')];
  8153. }
  8154. ['keydown', 'mousedown', 'touchstart'].forEach((event) => {
  8155. elements.forEach((element) => {
  8156. if (element) {
  8157. listenOnce(element, event, () => {
  8158. if (ctx.state === 'suspended') ctx.resume();
  8159. });
  8160. }
  8161. });
  8162. });
  8163. };
  8164. var dynCall = (sig, ptr, args = []) => {
  8165. assert(getWasmTableEntry(ptr), `missing table entry in dynCall: ${ptr}`);
  8166. var rtn = getWasmTableEntry(ptr)(...args);
  8167. return rtn;
  8168. };
  8169. var getCFunc = (ident) => {
  8170. var func = Module['_' + ident]; // closure exported function
  8171. assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported');
  8172. return func;
  8173. };
  8174. var writeArrayToMemory = (array, buffer) => {
  8175. assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)')
  8176. HEAP8.set(array, buffer);
  8177. };
  8178. /**
  8179. * @param {string|null=} returnType
  8180. * @param {Array=} argTypes
  8181. * @param {Arguments|Array=} args
  8182. * @param {Object=} opts
  8183. */
  8184. var ccall = (ident, returnType, argTypes, args, opts) => {
  8185. // For fast lookup of conversion functions
  8186. var toC = {
  8187. 'string': (str) => {
  8188. var ret = 0;
  8189. if (str !== null && str !== undefined && str !== 0) { // null string
  8190. // at most 4 bytes per UTF-8 code point, +1 for the trailing '\0'
  8191. ret = stringToUTF8OnStack(str);
  8192. }
  8193. return ret;
  8194. },
  8195. 'array': (arr) => {
  8196. var ret = stackAlloc(arr.length);
  8197. writeArrayToMemory(arr, ret);
  8198. return ret;
  8199. }
  8200. };
  8201. function convertReturnValue(ret) {
  8202. if (returnType === 'string') {
  8203. return UTF8ToString(ret);
  8204. }
  8205. if (returnType === 'boolean') return Boolean(ret);
  8206. return ret;
  8207. }
  8208. var func = getCFunc(ident);
  8209. var cArgs = [];
  8210. var stack = 0;
  8211. assert(returnType !== 'array', 'Return type should not be "array".');
  8212. if (args) {
  8213. for (var i = 0; i < args.length; i++) {
  8214. var converter = toC[argTypes[i]];
  8215. if (converter) {
  8216. if (stack === 0) stack = stackSave();
  8217. cArgs[i] = converter(args[i]);
  8218. } else {
  8219. cArgs[i] = args[i];
  8220. }
  8221. }
  8222. }
  8223. var ret = func(...cArgs);
  8224. function onDone(ret) {
  8225. if (stack !== 0) stackRestore(stack);
  8226. return convertReturnValue(ret);
  8227. }
  8228. ret = onDone(ret);
  8229. return ret;
  8230. };
  8231. /**
  8232. * @param {string=} returnType
  8233. * @param {Array=} argTypes
  8234. * @param {Object=} opts
  8235. */
  8236. var cwrap = (ident, returnType, argTypes, opts) => {
  8237. return (...args) => ccall(ident, returnType, argTypes, args, opts);
  8238. };
  8239. FS.createPreloadedFile = FS_createPreloadedFile;
  8240. FS.staticInit();;
  8241. // exports
  8242. Module["requestFullscreen"] = Browser.requestFullscreen;
  8243. Module["requestFullScreen"] = Browser.requestFullScreen;
  8244. Module["requestAnimationFrame"] = Browser.requestAnimationFrame;
  8245. Module["setCanvasSize"] = Browser.setCanvasSize;
  8246. Module["pauseMainLoop"] = Browser.mainLoop.pause;
  8247. Module["resumeMainLoop"] = Browser.mainLoop.resume;
  8248. Module["getUserMedia"] = Browser.getUserMedia;
  8249. Module["createContext"] = Browser.createContext;
  8250. var preloadedImages = {};
  8251. var preloadedAudios = {};;
  8252. var GLctx;;
  8253. for (var i = 0; i < 32; ++i) tempFixedLengthArray.push(new Array(i));;
  8254. var miniTempWebGLFloatBuffersStorage = new Float32Array(288);
  8255. for (/**@suppress{duplicate}*/var i = 0; i < 288; ++i) {
  8256. miniTempWebGLFloatBuffers[i] = miniTempWebGLFloatBuffersStorage.subarray(0, i);
  8257. };
  8258. var miniTempWebGLIntBuffersStorage = new Int32Array(288);
  8259. for (/**@suppress{duplicate}*/var i = 0; i < 288; ++i) {
  8260. miniTempWebGLIntBuffers[i] = miniTempWebGLIntBuffersStorage.subarray(0, i);
  8261. };
  8262. function checkIncomingModuleAPI() {
  8263. ignoredModuleProp('fetchSettings');
  8264. }
  8265. var wasmImports = {
  8266. /** @export */
  8267. __syscall_fcntl64: ___syscall_fcntl64,
  8268. /** @export */
  8269. __syscall_ioctl: ___syscall_ioctl,
  8270. /** @export */
  8271. __syscall_openat: ___syscall_openat,
  8272. /** @export */
  8273. _abort_js: __abort_js,
  8274. /** @export */
  8275. _emscripten_get_now_is_monotonic: __emscripten_get_now_is_monotonic,
  8276. /** @export */
  8277. _emscripten_throw_longjmp: __emscripten_throw_longjmp,
  8278. /** @export */
  8279. _gmtime_js: __gmtime_js,
  8280. /** @export */
  8281. _tzset_js: __tzset_js,
  8282. /** @export */
  8283. eglBindAPI: _eglBindAPI,
  8284. /** @export */
  8285. eglChooseConfig: _eglChooseConfig,
  8286. /** @export */
  8287. eglCreateContext: _eglCreateContext,
  8288. /** @export */
  8289. eglCreateWindowSurface: _eglCreateWindowSurface,
  8290. /** @export */
  8291. eglDestroyContext: _eglDestroyContext,
  8292. /** @export */
  8293. eglDestroySurface: _eglDestroySurface,
  8294. /** @export */
  8295. eglGetConfigAttrib: _eglGetConfigAttrib,
  8296. /** @export */
  8297. eglGetDisplay: _eglGetDisplay,
  8298. /** @export */
  8299. eglGetError: _eglGetError,
  8300. /** @export */
  8301. eglInitialize: _eglInitialize,
  8302. /** @export */
  8303. eglMakeCurrent: _eglMakeCurrent,
  8304. /** @export */
  8305. eglQueryString: _eglQueryString,
  8306. /** @export */
  8307. eglSwapBuffers: _eglSwapBuffers,
  8308. /** @export */
  8309. eglSwapInterval: _eglSwapInterval,
  8310. /** @export */
  8311. eglTerminate: _eglTerminate,
  8312. /** @export */
  8313. eglWaitGL: _eglWaitGL,
  8314. /** @export */
  8315. eglWaitNative: _eglWaitNative,
  8316. /** @export */
  8317. emscripten_asm_const_int: _emscripten_asm_const_int,
  8318. /** @export */
  8319. emscripten_asm_const_int_sync_on_main_thread: _emscripten_asm_const_int_sync_on_main_thread,
  8320. /** @export */
  8321. emscripten_asm_const_ptr: _emscripten_asm_const_ptr,
  8322. /** @export */
  8323. emscripten_asm_const_ptr_sync_on_main_thread: _emscripten_asm_const_ptr_sync_on_main_thread,
  8324. /** @export */
  8325. emscripten_cancel_main_loop: _emscripten_cancel_main_loop,
  8326. /** @export */
  8327. emscripten_date_now: _emscripten_date_now,
  8328. /** @export */
  8329. emscripten_exit_fullscreen: _emscripten_exit_fullscreen,
  8330. /** @export */
  8331. emscripten_exit_pointerlock: _emscripten_exit_pointerlock,
  8332. /** @export */
  8333. emscripten_force_exit: _emscripten_force_exit,
  8334. /** @export */
  8335. emscripten_get_device_pixel_ratio: _emscripten_get_device_pixel_ratio,
  8336. /** @export */
  8337. emscripten_get_element_css_size: _emscripten_get_element_css_size,
  8338. /** @export */
  8339. emscripten_get_gamepad_status: _emscripten_get_gamepad_status,
  8340. /** @export */
  8341. emscripten_get_now: _emscripten_get_now,
  8342. /** @export */
  8343. emscripten_get_num_gamepads: _emscripten_get_num_gamepads,
  8344. /** @export */
  8345. emscripten_get_screen_size: _emscripten_get_screen_size,
  8346. /** @export */
  8347. emscripten_glActiveTexture: _emscripten_glActiveTexture,
  8348. /** @export */
  8349. emscripten_glAttachShader: _emscripten_glAttachShader,
  8350. /** @export */
  8351. emscripten_glBeginQueryEXT: _emscripten_glBeginQueryEXT,
  8352. /** @export */
  8353. emscripten_glBindAttribLocation: _emscripten_glBindAttribLocation,
  8354. /** @export */
  8355. emscripten_glBindBuffer: _emscripten_glBindBuffer,
  8356. /** @export */
  8357. emscripten_glBindFramebuffer: _emscripten_glBindFramebuffer,
  8358. /** @export */
  8359. emscripten_glBindRenderbuffer: _emscripten_glBindRenderbuffer,
  8360. /** @export */
  8361. emscripten_glBindTexture: _emscripten_glBindTexture,
  8362. /** @export */
  8363. emscripten_glBindVertexArrayOES: _emscripten_glBindVertexArrayOES,
  8364. /** @export */
  8365. emscripten_glBlendColor: _emscripten_glBlendColor,
  8366. /** @export */
  8367. emscripten_glBlendEquation: _emscripten_glBlendEquation,
  8368. /** @export */
  8369. emscripten_glBlendEquationSeparate: _emscripten_glBlendEquationSeparate,
  8370. /** @export */
  8371. emscripten_glBlendFunc: _emscripten_glBlendFunc,
  8372. /** @export */
  8373. emscripten_glBlendFuncSeparate: _emscripten_glBlendFuncSeparate,
  8374. /** @export */
  8375. emscripten_glBufferData: _emscripten_glBufferData,
  8376. /** @export */
  8377. emscripten_glBufferSubData: _emscripten_glBufferSubData,
  8378. /** @export */
  8379. emscripten_glCheckFramebufferStatus: _emscripten_glCheckFramebufferStatus,
  8380. /** @export */
  8381. emscripten_glClear: _emscripten_glClear,
  8382. /** @export */
  8383. emscripten_glClearColor: _emscripten_glClearColor,
  8384. /** @export */
  8385. emscripten_glClearDepthf: _emscripten_glClearDepthf,
  8386. /** @export */
  8387. emscripten_glClearStencil: _emscripten_glClearStencil,
  8388. /** @export */
  8389. emscripten_glColorMask: _emscripten_glColorMask,
  8390. /** @export */
  8391. emscripten_glCompileShader: _emscripten_glCompileShader,
  8392. /** @export */
  8393. emscripten_glCompressedTexImage2D: _emscripten_glCompressedTexImage2D,
  8394. /** @export */
  8395. emscripten_glCompressedTexSubImage2D: _emscripten_glCompressedTexSubImage2D,
  8396. /** @export */
  8397. emscripten_glCopyTexImage2D: _emscripten_glCopyTexImage2D,
  8398. /** @export */
  8399. emscripten_glCopyTexSubImage2D: _emscripten_glCopyTexSubImage2D,
  8400. /** @export */
  8401. emscripten_glCreateProgram: _emscripten_glCreateProgram,
  8402. /** @export */
  8403. emscripten_glCreateShader: _emscripten_glCreateShader,
  8404. /** @export */
  8405. emscripten_glCullFace: _emscripten_glCullFace,
  8406. /** @export */
  8407. emscripten_glDeleteBuffers: _emscripten_glDeleteBuffers,
  8408. /** @export */
  8409. emscripten_glDeleteFramebuffers: _emscripten_glDeleteFramebuffers,
  8410. /** @export */
  8411. emscripten_glDeleteProgram: _emscripten_glDeleteProgram,
  8412. /** @export */
  8413. emscripten_glDeleteQueriesEXT: _emscripten_glDeleteQueriesEXT,
  8414. /** @export */
  8415. emscripten_glDeleteRenderbuffers: _emscripten_glDeleteRenderbuffers,
  8416. /** @export */
  8417. emscripten_glDeleteShader: _emscripten_glDeleteShader,
  8418. /** @export */
  8419. emscripten_glDeleteTextures: _emscripten_glDeleteTextures,
  8420. /** @export */
  8421. emscripten_glDeleteVertexArraysOES: _emscripten_glDeleteVertexArraysOES,
  8422. /** @export */
  8423. emscripten_glDepthFunc: _emscripten_glDepthFunc,
  8424. /** @export */
  8425. emscripten_glDepthMask: _emscripten_glDepthMask,
  8426. /** @export */
  8427. emscripten_glDepthRangef: _emscripten_glDepthRangef,
  8428. /** @export */
  8429. emscripten_glDetachShader: _emscripten_glDetachShader,
  8430. /** @export */
  8431. emscripten_glDisable: _emscripten_glDisable,
  8432. /** @export */
  8433. emscripten_glDisableVertexAttribArray: _emscripten_glDisableVertexAttribArray,
  8434. /** @export */
  8435. emscripten_glDrawArrays: _emscripten_glDrawArrays,
  8436. /** @export */
  8437. emscripten_glDrawArraysInstancedANGLE: _emscripten_glDrawArraysInstancedANGLE,
  8438. /** @export */
  8439. emscripten_glDrawBuffersWEBGL: _emscripten_glDrawBuffersWEBGL,
  8440. /** @export */
  8441. emscripten_glDrawElements: _emscripten_glDrawElements,
  8442. /** @export */
  8443. emscripten_glDrawElementsInstancedANGLE: _emscripten_glDrawElementsInstancedANGLE,
  8444. /** @export */
  8445. emscripten_glEnable: _emscripten_glEnable,
  8446. /** @export */
  8447. emscripten_glEnableVertexAttribArray: _emscripten_glEnableVertexAttribArray,
  8448. /** @export */
  8449. emscripten_glEndQueryEXT: _emscripten_glEndQueryEXT,
  8450. /** @export */
  8451. emscripten_glFinish: _emscripten_glFinish,
  8452. /** @export */
  8453. emscripten_glFlush: _emscripten_glFlush,
  8454. /** @export */
  8455. emscripten_glFramebufferRenderbuffer: _emscripten_glFramebufferRenderbuffer,
  8456. /** @export */
  8457. emscripten_glFramebufferTexture2D: _emscripten_glFramebufferTexture2D,
  8458. /** @export */
  8459. emscripten_glFrontFace: _emscripten_glFrontFace,
  8460. /** @export */
  8461. emscripten_glGenBuffers: _emscripten_glGenBuffers,
  8462. /** @export */
  8463. emscripten_glGenFramebuffers: _emscripten_glGenFramebuffers,
  8464. /** @export */
  8465. emscripten_glGenQueriesEXT: _emscripten_glGenQueriesEXT,
  8466. /** @export */
  8467. emscripten_glGenRenderbuffers: _emscripten_glGenRenderbuffers,
  8468. /** @export */
  8469. emscripten_glGenTextures: _emscripten_glGenTextures,
  8470. /** @export */
  8471. emscripten_glGenVertexArraysOES: _emscripten_glGenVertexArraysOES,
  8472. /** @export */
  8473. emscripten_glGenerateMipmap: _emscripten_glGenerateMipmap,
  8474. /** @export */
  8475. emscripten_glGetActiveAttrib: _emscripten_glGetActiveAttrib,
  8476. /** @export */
  8477. emscripten_glGetActiveUniform: _emscripten_glGetActiveUniform,
  8478. /** @export */
  8479. emscripten_glGetAttachedShaders: _emscripten_glGetAttachedShaders,
  8480. /** @export */
  8481. emscripten_glGetAttribLocation: _emscripten_glGetAttribLocation,
  8482. /** @export */
  8483. emscripten_glGetBooleanv: _emscripten_glGetBooleanv,
  8484. /** @export */
  8485. emscripten_glGetBufferParameteriv: _emscripten_glGetBufferParameteriv,
  8486. /** @export */
  8487. emscripten_glGetError: _emscripten_glGetError,
  8488. /** @export */
  8489. emscripten_glGetFloatv: _emscripten_glGetFloatv,
  8490. /** @export */
  8491. emscripten_glGetFramebufferAttachmentParameteriv: _emscripten_glGetFramebufferAttachmentParameteriv,
  8492. /** @export */
  8493. emscripten_glGetIntegerv: _emscripten_glGetIntegerv,
  8494. /** @export */
  8495. emscripten_glGetProgramInfoLog: _emscripten_glGetProgramInfoLog,
  8496. /** @export */
  8497. emscripten_glGetProgramiv: _emscripten_glGetProgramiv,
  8498. /** @export */
  8499. emscripten_glGetQueryObjecti64vEXT: _emscripten_glGetQueryObjecti64vEXT,
  8500. /** @export */
  8501. emscripten_glGetQueryObjectivEXT: _emscripten_glGetQueryObjectivEXT,
  8502. /** @export */
  8503. emscripten_glGetQueryObjectui64vEXT: _emscripten_glGetQueryObjectui64vEXT,
  8504. /** @export */
  8505. emscripten_glGetQueryObjectuivEXT: _emscripten_glGetQueryObjectuivEXT,
  8506. /** @export */
  8507. emscripten_glGetQueryivEXT: _emscripten_glGetQueryivEXT,
  8508. /** @export */
  8509. emscripten_glGetRenderbufferParameteriv: _emscripten_glGetRenderbufferParameteriv,
  8510. /** @export */
  8511. emscripten_glGetShaderInfoLog: _emscripten_glGetShaderInfoLog,
  8512. /** @export */
  8513. emscripten_glGetShaderPrecisionFormat: _emscripten_glGetShaderPrecisionFormat,
  8514. /** @export */
  8515. emscripten_glGetShaderSource: _emscripten_glGetShaderSource,
  8516. /** @export */
  8517. emscripten_glGetShaderiv: _emscripten_glGetShaderiv,
  8518. /** @export */
  8519. emscripten_glGetString: _emscripten_glGetString,
  8520. /** @export */
  8521. emscripten_glGetTexParameterfv: _emscripten_glGetTexParameterfv,
  8522. /** @export */
  8523. emscripten_glGetTexParameteriv: _emscripten_glGetTexParameteriv,
  8524. /** @export */
  8525. emscripten_glGetUniformLocation: _emscripten_glGetUniformLocation,
  8526. /** @export */
  8527. emscripten_glGetUniformfv: _emscripten_glGetUniformfv,
  8528. /** @export */
  8529. emscripten_glGetUniformiv: _emscripten_glGetUniformiv,
  8530. /** @export */
  8531. emscripten_glGetVertexAttribPointerv: _emscripten_glGetVertexAttribPointerv,
  8532. /** @export */
  8533. emscripten_glGetVertexAttribfv: _emscripten_glGetVertexAttribfv,
  8534. /** @export */
  8535. emscripten_glGetVertexAttribiv: _emscripten_glGetVertexAttribiv,
  8536. /** @export */
  8537. emscripten_glHint: _emscripten_glHint,
  8538. /** @export */
  8539. emscripten_glIsBuffer: _emscripten_glIsBuffer,
  8540. /** @export */
  8541. emscripten_glIsEnabled: _emscripten_glIsEnabled,
  8542. /** @export */
  8543. emscripten_glIsFramebuffer: _emscripten_glIsFramebuffer,
  8544. /** @export */
  8545. emscripten_glIsProgram: _emscripten_glIsProgram,
  8546. /** @export */
  8547. emscripten_glIsQueryEXT: _emscripten_glIsQueryEXT,
  8548. /** @export */
  8549. emscripten_glIsRenderbuffer: _emscripten_glIsRenderbuffer,
  8550. /** @export */
  8551. emscripten_glIsShader: _emscripten_glIsShader,
  8552. /** @export */
  8553. emscripten_glIsTexture: _emscripten_glIsTexture,
  8554. /** @export */
  8555. emscripten_glIsVertexArrayOES: _emscripten_glIsVertexArrayOES,
  8556. /** @export */
  8557. emscripten_glLineWidth: _emscripten_glLineWidth,
  8558. /** @export */
  8559. emscripten_glLinkProgram: _emscripten_glLinkProgram,
  8560. /** @export */
  8561. emscripten_glPixelStorei: _emscripten_glPixelStorei,
  8562. /** @export */
  8563. emscripten_glPolygonOffset: _emscripten_glPolygonOffset,
  8564. /** @export */
  8565. emscripten_glQueryCounterEXT: _emscripten_glQueryCounterEXT,
  8566. /** @export */
  8567. emscripten_glReadPixels: _emscripten_glReadPixels,
  8568. /** @export */
  8569. emscripten_glReleaseShaderCompiler: _emscripten_glReleaseShaderCompiler,
  8570. /** @export */
  8571. emscripten_glRenderbufferStorage: _emscripten_glRenderbufferStorage,
  8572. /** @export */
  8573. emscripten_glSampleCoverage: _emscripten_glSampleCoverage,
  8574. /** @export */
  8575. emscripten_glScissor: _emscripten_glScissor,
  8576. /** @export */
  8577. emscripten_glShaderBinary: _emscripten_glShaderBinary,
  8578. /** @export */
  8579. emscripten_glShaderSource: _emscripten_glShaderSource,
  8580. /** @export */
  8581. emscripten_glStencilFunc: _emscripten_glStencilFunc,
  8582. /** @export */
  8583. emscripten_glStencilFuncSeparate: _emscripten_glStencilFuncSeparate,
  8584. /** @export */
  8585. emscripten_glStencilMask: _emscripten_glStencilMask,
  8586. /** @export */
  8587. emscripten_glStencilMaskSeparate: _emscripten_glStencilMaskSeparate,
  8588. /** @export */
  8589. emscripten_glStencilOp: _emscripten_glStencilOp,
  8590. /** @export */
  8591. emscripten_glStencilOpSeparate: _emscripten_glStencilOpSeparate,
  8592. /** @export */
  8593. emscripten_glTexImage2D: _emscripten_glTexImage2D,
  8594. /** @export */
  8595. emscripten_glTexParameterf: _emscripten_glTexParameterf,
  8596. /** @export */
  8597. emscripten_glTexParameterfv: _emscripten_glTexParameterfv,
  8598. /** @export */
  8599. emscripten_glTexParameteri: _emscripten_glTexParameteri,
  8600. /** @export */
  8601. emscripten_glTexParameteriv: _emscripten_glTexParameteriv,
  8602. /** @export */
  8603. emscripten_glTexSubImage2D: _emscripten_glTexSubImage2D,
  8604. /** @export */
  8605. emscripten_glUniform1f: _emscripten_glUniform1f,
  8606. /** @export */
  8607. emscripten_glUniform1fv: _emscripten_glUniform1fv,
  8608. /** @export */
  8609. emscripten_glUniform1i: _emscripten_glUniform1i,
  8610. /** @export */
  8611. emscripten_glUniform1iv: _emscripten_glUniform1iv,
  8612. /** @export */
  8613. emscripten_glUniform2f: _emscripten_glUniform2f,
  8614. /** @export */
  8615. emscripten_glUniform2fv: _emscripten_glUniform2fv,
  8616. /** @export */
  8617. emscripten_glUniform2i: _emscripten_glUniform2i,
  8618. /** @export */
  8619. emscripten_glUniform2iv: _emscripten_glUniform2iv,
  8620. /** @export */
  8621. emscripten_glUniform3f: _emscripten_glUniform3f,
  8622. /** @export */
  8623. emscripten_glUniform3fv: _emscripten_glUniform3fv,
  8624. /** @export */
  8625. emscripten_glUniform3i: _emscripten_glUniform3i,
  8626. /** @export */
  8627. emscripten_glUniform3iv: _emscripten_glUniform3iv,
  8628. /** @export */
  8629. emscripten_glUniform4f: _emscripten_glUniform4f,
  8630. /** @export */
  8631. emscripten_glUniform4fv: _emscripten_glUniform4fv,
  8632. /** @export */
  8633. emscripten_glUniform4i: _emscripten_glUniform4i,
  8634. /** @export */
  8635. emscripten_glUniform4iv: _emscripten_glUniform4iv,
  8636. /** @export */
  8637. emscripten_glUniformMatrix2fv: _emscripten_glUniformMatrix2fv,
  8638. /** @export */
  8639. emscripten_glUniformMatrix3fv: _emscripten_glUniformMatrix3fv,
  8640. /** @export */
  8641. emscripten_glUniformMatrix4fv: _emscripten_glUniformMatrix4fv,
  8642. /** @export */
  8643. emscripten_glUseProgram: _emscripten_glUseProgram,
  8644. /** @export */
  8645. emscripten_glValidateProgram: _emscripten_glValidateProgram,
  8646. /** @export */
  8647. emscripten_glVertexAttrib1f: _emscripten_glVertexAttrib1f,
  8648. /** @export */
  8649. emscripten_glVertexAttrib1fv: _emscripten_glVertexAttrib1fv,
  8650. /** @export */
  8651. emscripten_glVertexAttrib2f: _emscripten_glVertexAttrib2f,
  8652. /** @export */
  8653. emscripten_glVertexAttrib2fv: _emscripten_glVertexAttrib2fv,
  8654. /** @export */
  8655. emscripten_glVertexAttrib3f: _emscripten_glVertexAttrib3f,
  8656. /** @export */
  8657. emscripten_glVertexAttrib3fv: _emscripten_glVertexAttrib3fv,
  8658. /** @export */
  8659. emscripten_glVertexAttrib4f: _emscripten_glVertexAttrib4f,
  8660. /** @export */
  8661. emscripten_glVertexAttrib4fv: _emscripten_glVertexAttrib4fv,
  8662. /** @export */
  8663. emscripten_glVertexAttribDivisorANGLE: _emscripten_glVertexAttribDivisorANGLE,
  8664. /** @export */
  8665. emscripten_glVertexAttribPointer: _emscripten_glVertexAttribPointer,
  8666. /** @export */
  8667. emscripten_glViewport: _emscripten_glViewport,
  8668. /** @export */
  8669. emscripten_has_asyncify: _emscripten_has_asyncify,
  8670. /** @export */
  8671. emscripten_request_fullscreen_strategy: _emscripten_request_fullscreen_strategy,
  8672. /** @export */
  8673. emscripten_request_pointerlock: _emscripten_request_pointerlock,
  8674. /** @export */
  8675. emscripten_resize_heap: _emscripten_resize_heap,
  8676. /** @export */
  8677. emscripten_sample_gamepad_data: _emscripten_sample_gamepad_data,
  8678. /** @export */
  8679. emscripten_set_beforeunload_callback_on_thread: _emscripten_set_beforeunload_callback_on_thread,
  8680. /** @export */
  8681. emscripten_set_blur_callback_on_thread: _emscripten_set_blur_callback_on_thread,
  8682. /** @export */
  8683. emscripten_set_canvas_element_size: _emscripten_set_canvas_element_size,
  8684. /** @export */
  8685. emscripten_set_element_css_size: _emscripten_set_element_css_size,
  8686. /** @export */
  8687. emscripten_set_focus_callback_on_thread: _emscripten_set_focus_callback_on_thread,
  8688. /** @export */
  8689. emscripten_set_fullscreenchange_callback_on_thread: _emscripten_set_fullscreenchange_callback_on_thread,
  8690. /** @export */
  8691. emscripten_set_gamepadconnected_callback_on_thread: _emscripten_set_gamepadconnected_callback_on_thread,
  8692. /** @export */
  8693. emscripten_set_gamepaddisconnected_callback_on_thread: _emscripten_set_gamepaddisconnected_callback_on_thread,
  8694. /** @export */
  8695. emscripten_set_keydown_callback_on_thread: _emscripten_set_keydown_callback_on_thread,
  8696. /** @export */
  8697. emscripten_set_keypress_callback_on_thread: _emscripten_set_keypress_callback_on_thread,
  8698. /** @export */
  8699. emscripten_set_keyup_callback_on_thread: _emscripten_set_keyup_callback_on_thread,
  8700. /** @export */
  8701. emscripten_set_main_loop: _emscripten_set_main_loop,
  8702. /** @export */
  8703. emscripten_set_mousedown_callback_on_thread: _emscripten_set_mousedown_callback_on_thread,
  8704. /** @export */
  8705. emscripten_set_mouseenter_callback_on_thread: _emscripten_set_mouseenter_callback_on_thread,
  8706. /** @export */
  8707. emscripten_set_mouseleave_callback_on_thread: _emscripten_set_mouseleave_callback_on_thread,
  8708. /** @export */
  8709. emscripten_set_mousemove_callback_on_thread: _emscripten_set_mousemove_callback_on_thread,
  8710. /** @export */
  8711. emscripten_set_mouseup_callback_on_thread: _emscripten_set_mouseup_callback_on_thread,
  8712. /** @export */
  8713. emscripten_set_pointerlockchange_callback_on_thread: _emscripten_set_pointerlockchange_callback_on_thread,
  8714. /** @export */
  8715. emscripten_set_resize_callback_on_thread: _emscripten_set_resize_callback_on_thread,
  8716. /** @export */
  8717. emscripten_set_touchcancel_callback_on_thread: _emscripten_set_touchcancel_callback_on_thread,
  8718. /** @export */
  8719. emscripten_set_touchend_callback_on_thread: _emscripten_set_touchend_callback_on_thread,
  8720. /** @export */
  8721. emscripten_set_touchmove_callback_on_thread: _emscripten_set_touchmove_callback_on_thread,
  8722. /** @export */
  8723. emscripten_set_touchstart_callback_on_thread: _emscripten_set_touchstart_callback_on_thread,
  8724. /** @export */
  8725. emscripten_set_visibilitychange_callback_on_thread: _emscripten_set_visibilitychange_callback_on_thread,
  8726. /** @export */
  8727. emscripten_set_wheel_callback_on_thread: _emscripten_set_wheel_callback_on_thread,
  8728. /** @export */
  8729. emscripten_set_window_title: _emscripten_set_window_title,
  8730. /** @export */
  8731. emscripten_sleep: _emscripten_sleep,
  8732. /** @export */
  8733. environ_get: _environ_get,
  8734. /** @export */
  8735. environ_sizes_get: _environ_sizes_get,
  8736. /** @export */
  8737. fd_close: _fd_close,
  8738. /** @export */
  8739. fd_read: _fd_read,
  8740. /** @export */
  8741. fd_seek: _fd_seek,
  8742. /** @export */
  8743. fd_write: _fd_write,
  8744. /** @export */
  8745. invoke_ii,
  8746. /** @export */
  8747. invoke_iii,
  8748. /** @export */
  8749. invoke_iiii,
  8750. /** @export */
  8751. invoke_iiiii,
  8752. /** @export */
  8753. invoke_iiiiii,
  8754. /** @export */
  8755. invoke_v,
  8756. /** @export */
  8757. invoke_vii
  8758. };
  8759. var wasmExports = createWasm();
  8760. var ___wasm_call_ctors = createExportWrapper('__wasm_call_ctors', 0);
  8761. var _main = Module['_main'] = createExportWrapper('__main_argc_argv', 2);
  8762. var _fflush = createExportWrapper('fflush', 1);
  8763. var _free = Module['_free'] = createExportWrapper('free', 1);
  8764. var _malloc = Module['_malloc'] = createExportWrapper('malloc', 1);
  8765. var _meg4_insert = Module['_meg4_insert'] = createExportWrapper('meg4_insert', 3);
  8766. var ___funcs_on_exit = createExportWrapper('__funcs_on_exit', 0);
  8767. var _setThrew = createExportWrapper('setThrew', 2);
  8768. var _emscripten_stack_init = () => (_emscripten_stack_init = wasmExports['emscripten_stack_init'])();
  8769. var _emscripten_stack_get_free = () => (_emscripten_stack_get_free = wasmExports['emscripten_stack_get_free'])();
  8770. var _emscripten_stack_get_base = () => (_emscripten_stack_get_base = wasmExports['emscripten_stack_get_base'])();
  8771. var _emscripten_stack_get_end = () => (_emscripten_stack_get_end = wasmExports['emscripten_stack_get_end'])();
  8772. var __emscripten_stack_restore = (a0) => (__emscripten_stack_restore = wasmExports['_emscripten_stack_restore'])(a0);
  8773. var __emscripten_stack_alloc = (a0) => (__emscripten_stack_alloc = wasmExports['_emscripten_stack_alloc'])(a0);
  8774. var _emscripten_stack_get_current = () => (_emscripten_stack_get_current = wasmExports['emscripten_stack_get_current'])();
  8775. function invoke_ii(index,a1) {
  8776. var sp = stackSave();
  8777. try {
  8778. return getWasmTableEntry(index)(a1);
  8779. } catch(e) {
  8780. stackRestore(sp);
  8781. if (e !== e+0) throw e;
  8782. _setThrew(1, 0);
  8783. }
  8784. }
  8785. function invoke_iii(index,a1,a2) {
  8786. var sp = stackSave();
  8787. try {
  8788. return getWasmTableEntry(index)(a1,a2);
  8789. } catch(e) {
  8790. stackRestore(sp);
  8791. if (e !== e+0) throw e;
  8792. _setThrew(1, 0);
  8793. }
  8794. }
  8795. function invoke_iiiiii(index,a1,a2,a3,a4,a5) {
  8796. var sp = stackSave();
  8797. try {
  8798. return getWasmTableEntry(index)(a1,a2,a3,a4,a5);
  8799. } catch(e) {
  8800. stackRestore(sp);
  8801. if (e !== e+0) throw e;
  8802. _setThrew(1, 0);
  8803. }
  8804. }
  8805. function invoke_v(index) {
  8806. var sp = stackSave();
  8807. try {
  8808. getWasmTableEntry(index)();
  8809. } catch(e) {
  8810. stackRestore(sp);
  8811. if (e !== e+0) throw e;
  8812. _setThrew(1, 0);
  8813. }
  8814. }
  8815. function invoke_iiiii(index,a1,a2,a3,a4) {
  8816. var sp = stackSave();
  8817. try {
  8818. return getWasmTableEntry(index)(a1,a2,a3,a4);
  8819. } catch(e) {
  8820. stackRestore(sp);
  8821. if (e !== e+0) throw e;
  8822. _setThrew(1, 0);
  8823. }
  8824. }
  8825. function invoke_iiii(index,a1,a2,a3) {
  8826. var sp = stackSave();
  8827. try {
  8828. return getWasmTableEntry(index)(a1,a2,a3);
  8829. } catch(e) {
  8830. stackRestore(sp);
  8831. if (e !== e+0) throw e;
  8832. _setThrew(1, 0);
  8833. }
  8834. }
  8835. function invoke_vii(index,a1,a2) {
  8836. var sp = stackSave();
  8837. try {
  8838. getWasmTableEntry(index)(a1,a2);
  8839. } catch(e) {
  8840. stackRestore(sp);
  8841. if (e !== e+0) throw e;
  8842. _setThrew(1, 0);
  8843. }
  8844. }
  8845. // include: postamble.js
  8846. // === Auto-generated postamble setup entry stuff ===
  8847. Module['ccall'] = ccall;
  8848. Module['cwrap'] = cwrap;
  8849. var missingLibrarySymbols = [
  8850. 'writeI53ToI64Clamped',
  8851. 'writeI53ToI64Signaling',
  8852. 'writeI53ToU64Clamped',
  8853. 'writeI53ToU64Signaling',
  8854. 'convertI32PairToI53',
  8855. 'convertI32PairToI53Checked',
  8856. 'convertU32PairToI53',
  8857. 'getTempRet0',
  8858. 'setTempRet0',
  8859. 'isLeapYear',
  8860. 'ydayFromDate',
  8861. 'arraySum',
  8862. 'addDays',
  8863. 'inetPton4',
  8864. 'inetNtop4',
  8865. 'inetPton6',
  8866. 'inetNtop6',
  8867. 'readSockaddr',
  8868. 'writeSockaddr',
  8869. 'emscriptenLog',
  8870. 'getDynCaller',
  8871. 'asmjsMangle',
  8872. 'HandleAllocator',
  8873. 'getNativeTypeSize',
  8874. 'STACK_SIZE',
  8875. 'STACK_ALIGN',
  8876. 'POINTER_SIZE',
  8877. 'ASSERTIONS',
  8878. 'uleb128Encode',
  8879. 'sigToWasmTypes',
  8880. 'generateFuncType',
  8881. 'convertJsFunctionToWasm',
  8882. 'getEmptyTableSlot',
  8883. 'updateTableMap',
  8884. 'getFunctionAddress',
  8885. 'addFunction',
  8886. 'removeFunction',
  8887. 'reallyNegative',
  8888. 'unSign',
  8889. 'strLen',
  8890. 'reSign',
  8891. 'formatString',
  8892. 'intArrayToString',
  8893. 'AsciiToString',
  8894. 'UTF16ToString',
  8895. 'stringToUTF16',
  8896. 'lengthBytesUTF16',
  8897. 'UTF32ToString',
  8898. 'stringToUTF32',
  8899. 'lengthBytesUTF32',
  8900. 'fillDeviceOrientationEventData',
  8901. 'registerDeviceOrientationEventCallback',
  8902. 'fillDeviceMotionEventData',
  8903. 'registerDeviceMotionEventCallback',
  8904. 'screenOrientation',
  8905. 'fillOrientationChangeEventData',
  8906. 'registerOrientationChangeEventCallback',
  8907. 'hideEverythingExceptGivenElement',
  8908. 'restoreHiddenElements',
  8909. 'softFullscreenResizeWebGLRenderTarget',
  8910. 'registerPointerlockErrorEventCallback',
  8911. 'fillBatteryEventData',
  8912. 'battery',
  8913. 'registerBatteryEventCallback',
  8914. 'jsStackTrace',
  8915. 'getCallstack',
  8916. 'convertPCtoSourceLocation',
  8917. 'checkWasiClock',
  8918. 'wasiRightsToMuslOFlags',
  8919. 'wasiOFlagsToMuslOFlags',
  8920. 'createDyncallWrapper',
  8921. 'setImmediateWrapped',
  8922. 'clearImmediateWrapped',
  8923. 'polyfillSetImmediate',
  8924. 'getPromise',
  8925. 'makePromise',
  8926. 'idsToPromises',
  8927. 'makePromiseCallback',
  8928. 'ExceptionInfo',
  8929. 'findMatchingCatch',
  8930. 'Browser_asyncPrepareDataCounter',
  8931. 'getSocketFromFD',
  8932. 'getSocketAddress',
  8933. 'FS_unlink',
  8934. 'FS_mkdirTree',
  8935. '_setNetworkCallback',
  8936. 'writeGLArray',
  8937. 'registerWebGlEventCallback',
  8938. 'runAndAbortIfError',
  8939. 'ALLOC_NORMAL',
  8940. 'ALLOC_STACK',
  8941. 'allocate',
  8942. 'writeStringToMemory',
  8943. 'writeAsciiToMemory',
  8944. 'setErrNo',
  8945. 'demangle',
  8946. 'stackTrace',
  8947. ];
  8948. missingLibrarySymbols.forEach(missingLibrarySymbol)
  8949. var unexportedSymbols = [
  8950. 'run',
  8951. 'addOnPreRun',
  8952. 'addOnInit',
  8953. 'addOnPreMain',
  8954. 'addOnExit',
  8955. 'addOnPostRun',
  8956. 'addRunDependency',
  8957. 'removeRunDependency',
  8958. 'out',
  8959. 'err',
  8960. 'callMain',
  8961. 'abort',
  8962. 'wasmMemory',
  8963. 'wasmExports',
  8964. 'writeStackCookie',
  8965. 'checkStackCookie',
  8966. 'writeI53ToI64',
  8967. 'readI53FromI64',
  8968. 'readI53FromU64',
  8969. 'MAX_INT53',
  8970. 'MIN_INT53',
  8971. 'bigintToI53Checked',
  8972. 'stackSave',
  8973. 'stackRestore',
  8974. 'stackAlloc',
  8975. 'ptrToString',
  8976. 'zeroMemory',
  8977. 'exitJS',
  8978. 'getHeapMax',
  8979. 'growMemory',
  8980. 'ENV',
  8981. 'MONTH_DAYS_REGULAR',
  8982. 'MONTH_DAYS_LEAP',
  8983. 'MONTH_DAYS_REGULAR_CUMULATIVE',
  8984. 'MONTH_DAYS_LEAP_CUMULATIVE',
  8985. 'ERRNO_CODES',
  8986. 'ERRNO_MESSAGES',
  8987. 'DNS',
  8988. 'Protocols',
  8989. 'Sockets',
  8990. 'initRandomFill',
  8991. 'randomFill',
  8992. 'timers',
  8993. 'warnOnce',
  8994. 'readEmAsmArgsArray',
  8995. 'readEmAsmArgs',
  8996. 'runEmAsmFunction',
  8997. 'runMainThreadEmAsm',
  8998. 'jstoi_q',
  8999. 'jstoi_s',
  9000. 'getExecutableName',
  9001. 'listenOnce',
  9002. 'autoResumeAudioContext',
  9003. 'dynCall',
  9004. 'handleException',
  9005. 'keepRuntimeAlive',
  9006. 'runtimeKeepalivePush',
  9007. 'runtimeKeepalivePop',
  9008. 'callUserCallback',
  9009. 'maybeExit',
  9010. 'asyncLoad',
  9011. 'alignMemory',
  9012. 'mmapAlloc',
  9013. 'wasmTable',
  9014. 'noExitRuntime',
  9015. 'getCFunc',
  9016. 'freeTableIndexes',
  9017. 'functionsInTableMap',
  9018. 'setValue',
  9019. 'getValue',
  9020. 'PATH',
  9021. 'PATH_FS',
  9022. 'UTF8Decoder',
  9023. 'UTF8ArrayToString',
  9024. 'UTF8ToString',
  9025. 'stringToUTF8Array',
  9026. 'stringToUTF8',
  9027. 'lengthBytesUTF8',
  9028. 'intArrayFromString',
  9029. 'stringToAscii',
  9030. 'UTF16Decoder',
  9031. 'stringToNewUTF8',
  9032. 'stringToUTF8OnStack',
  9033. 'writeArrayToMemory',
  9034. 'JSEvents',
  9035. 'registerKeyEventCallback',
  9036. 'specialHTMLTargets',
  9037. 'maybeCStringToJsString',
  9038. 'findEventTarget',
  9039. 'findCanvasEventTarget',
  9040. 'getBoundingClientRect',
  9041. 'fillMouseEventData',
  9042. 'registerMouseEventCallback',
  9043. 'registerWheelEventCallback',
  9044. 'registerUiEventCallback',
  9045. 'registerFocusEventCallback',
  9046. 'fillFullscreenChangeEventData',
  9047. 'registerFullscreenChangeEventCallback',
  9048. 'JSEvents_requestFullscreen',
  9049. 'JSEvents_resizeCanvasForFullscreen',
  9050. 'registerRestoreOldStyle',
  9051. 'setLetterbox',
  9052. 'currentFullscreenStrategy',
  9053. 'restoreOldWindowedStyle',
  9054. 'doRequestFullscreen',
  9055. 'fillPointerlockChangeEventData',
  9056. 'registerPointerlockChangeEventCallback',
  9057. 'requestPointerLock',
  9058. 'fillVisibilityChangeEventData',
  9059. 'registerVisibilityChangeEventCallback',
  9060. 'registerTouchEventCallback',
  9061. 'fillGamepadEventData',
  9062. 'registerGamepadEventCallback',
  9063. 'registerBeforeUnloadEventCallback',
  9064. 'setCanvasElementSize',
  9065. 'getCanvasElementSize',
  9066. 'UNWIND_CACHE',
  9067. 'ExitStatus',
  9068. 'getEnvStrings',
  9069. 'doReadv',
  9070. 'doWritev',
  9071. 'safeSetTimeout',
  9072. 'promiseMap',
  9073. 'uncaughtExceptionCount',
  9074. 'exceptionLast',
  9075. 'exceptionCaught',
  9076. 'Browser',
  9077. 'setMainLoop',
  9078. 'getPreloadedImageData__data',
  9079. 'wget',
  9080. 'SYSCALLS',
  9081. 'preloadPlugins',
  9082. 'FS_createPreloadedFile',
  9083. 'FS_modeStringToFlags',
  9084. 'FS_getMode',
  9085. 'FS_stdin_getChar_buffer',
  9086. 'FS_stdin_getChar',
  9087. 'FS_createPath',
  9088. 'FS_createDevice',
  9089. 'FS_readFile',
  9090. 'FS',
  9091. 'FS_createDataFile',
  9092. 'FS_createLazyFile',
  9093. 'MEMFS',
  9094. 'TTY',
  9095. 'PIPEFS',
  9096. 'SOCKFS',
  9097. 'tempFixedLengthArray',
  9098. 'miniTempWebGLFloatBuffers',
  9099. 'miniTempWebGLIntBuffers',
  9100. 'heapObjectForWebGLType',
  9101. 'toTypedArrayIndex',
  9102. 'webgl_enable_ANGLE_instanced_arrays',
  9103. 'webgl_enable_OES_vertex_array_object',
  9104. 'webgl_enable_WEBGL_draw_buffers',
  9105. 'webgl_enable_WEBGL_multi_draw',
  9106. 'GL',
  9107. 'emscriptenWebGLGet',
  9108. 'computeUnpackAlignedImageSize',
  9109. 'colorChannelsInGlTextureFormat',
  9110. 'emscriptenWebGLGetTexPixelData',
  9111. 'emscriptenWebGLGetUniform',
  9112. 'webglGetUniformLocation',
  9113. 'webglPrepareUniformLocationsBeforeFirstUse',
  9114. 'webglGetLeftBracePos',
  9115. 'emscriptenWebGLGetVertexAttrib',
  9116. '__glGetActiveAttribOrUniform',
  9117. 'AL',
  9118. 'GLUT',
  9119. 'EGL',
  9120. 'GLEW',
  9121. 'IDBStore',
  9122. 'allocateUTF8',
  9123. 'allocateUTF8OnStack',
  9124. 'print',
  9125. 'printErr',
  9126. ];
  9127. unexportedSymbols.forEach(unexportedRuntimeSymbol);
  9128. var calledRun;
  9129. dependenciesFulfilled = function runCaller() {
  9130. // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
  9131. if (!calledRun) run();
  9132. if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
  9133. };
  9134. function callMain(args = []) {
  9135. assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])');
  9136. assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
  9137. var entryFunction = _main;
  9138. args.unshift(thisProgram);
  9139. var argc = args.length;
  9140. var argv = stackAlloc((argc + 1) * 4);
  9141. var argv_ptr = argv;
  9142. args.forEach((arg) => {
  9143. HEAPU32[((argv_ptr)>>2)] = stringToUTF8OnStack(arg);
  9144. argv_ptr += 4;
  9145. });
  9146. HEAPU32[((argv_ptr)>>2)] = 0;
  9147. try {
  9148. var ret = entryFunction(argc, argv);
  9149. // if we're not running an evented main loop, it's time to exit
  9150. exitJS(ret, /* implicit = */ true);
  9151. return ret;
  9152. }
  9153. catch (e) {
  9154. return handleException(e);
  9155. }
  9156. }
  9157. function stackCheckInit() {
  9158. // This is normally called automatically during __wasm_call_ctors but need to
  9159. // get these values before even running any of the ctors so we call it redundantly
  9160. // here.
  9161. _emscripten_stack_init();
  9162. // TODO(sbc): Move writeStackCookie to native to to avoid this.
  9163. writeStackCookie();
  9164. }
  9165. function run(args = arguments_) {
  9166. if (runDependencies > 0) {
  9167. return;
  9168. }
  9169. stackCheckInit();
  9170. preRun();
  9171. // a preRun added a dependency, run will be called later
  9172. if (runDependencies > 0) {
  9173. return;
  9174. }
  9175. function doRun() {
  9176. // run may have just been called through dependencies being fulfilled just in this very frame,
  9177. // or while the async setStatus time below was happening
  9178. if (calledRun) return;
  9179. calledRun = true;
  9180. Module['calledRun'] = true;
  9181. if (ABORT) return;
  9182. initRuntime();
  9183. preMain();
  9184. if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();
  9185. if (shouldRunNow) callMain(args);
  9186. postRun();
  9187. }
  9188. if (Module['setStatus']) {
  9189. Module['setStatus']('Running...');
  9190. setTimeout(function() {
  9191. setTimeout(function() {
  9192. Module['setStatus']('');
  9193. }, 1);
  9194. doRun();
  9195. }, 1);
  9196. } else
  9197. {
  9198. doRun();
  9199. }
  9200. checkStackCookie();
  9201. }
  9202. if (Module['preInit']) {
  9203. if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
  9204. while (Module['preInit'].length > 0) {
  9205. Module['preInit'].pop()();
  9206. }
  9207. }
  9208. // shouldRunNow refers to calling main(), not run().
  9209. var shouldRunNow = true;
  9210. if (Module['noInitialRun']) shouldRunNow = false;
  9211. run();
  9212. // end include: postamble.js