diff --git a/README.md b/README.md index 8f13ce7..58f8a7c 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,14 @@ Animator Pro, where this started, but they are why the output looks right — modern conveniences belong in the workflow, not the output. See [docs/design.md](docs/design.md). +## ClojureScript port + +The active port has reached [step 6 of the port plan](docs/port-plan.md): it plays +the synthetic take and can load extracted real footage as a rotoscoped mouth. +See [frontend/README.md](frontend/README.md) for setup and the **load frames** +workflow. The rest of this README describes the older JS prototype, which still +runs separately on port 8777. + ## Run ```sh diff --git a/docs/port-plan.md b/docs/port-plan.md index ec27b04..8dd0f7e 100644 --- a/docs/port-plan.md +++ b/docs/port-plan.md @@ -2,6 +2,11 @@ Self-contained. You should not need any prior conversation to execute this. +**Implementation status (2026-09-27):** steps 0–6 are in the CLJS frontend. +Step 6 reads extracted footage from the manifest, detects landmarks with local +MediaPipe assets, and runs the same freeze path as the synthetic take. Step 7 is +next: eyes, brows and the pixel-derived mouth interior. + ## What arthur is A tool that turns live-action video into 2D animation that reads as diff --git a/frontend/README.md b/frontend/README.md index 11652cb..9992540 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -66,7 +66,7 @@ Then open **** — with the `/index.html`, not bare `/`. This shadow-cljs does no directory-index resolution, so `/` is a 404 whatever the roots are. -Four clips, on buttons in the transport: +Four built-in clips, on buttons in the transport: | | | | --- | --- | @@ -78,9 +78,28 @@ Four clips, on buttons in the transport: `take` and `locked` are the pair worth looking at together, because switching between them is the whole of what "stabilisation is a channel, not a mode" means. -The demo scene itself is `src/arthur/demo/scene.edn`; the take is built in -`src/arthur/demo/take.cljs`, which is also the only place the seven stages are -composed in order. +The demo scene itself is `src/arthur/demo/scene.edn`. Both the synthetic take +and real footage use `src/arthur/flow/take.cljs` for the measurement order and +`src/arthur/flow/freeze.cljs` for the landmark-to-channel conversion. + +### Real footage (port step 6) + +From the repo root, extract a clip, then click **load frames** in the CLJS app: + +```sh +./extract.sh /path/to/clip.mov 12 +``` + +This writes `frames/0001.png` onward, `audio.wav`, and `manifest.json` at the +repo root. The manifest supplies the exact frame count, fps and audio path. +Loading detects one face per frame, freezes the measured mouth into channels, +and adds a button for the footage clip. Detection happens once when you load; +playback only resolves channels and paints. Frames without a detection remain +marked absent even though their neighbouring poses are used to condition the +track. The stage stays 320×200 regardless of the footage dimensions. + +MediaPipe's JS, wasm and model are under `public/mediapipe/` and served locally. +No CDN is used by this app. See that directory's README for provenance. Port 8778 is deliberately not 8777. `python3 serve.py` from the repo root still runs the old JS tool on 8777, and the two are meant to run side by side. diff --git a/frontend/package-lock.json b/frontend/package-lock.json index debf393..a4c5be8 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,6 +8,7 @@ "name": "arthur-frontend", "version": "0.0.1", "dependencies": { + "@mediapipe/tasks-vision": "1.0.1", "react": "^18.3.1", "react-dom": "^18.3.1" }, @@ -15,6 +16,12 @@ "shadow-cljs": "^2.28.21" } }, + "node_modules/@mediapipe/tasks-vision": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-1.0.1.tgz", + "integrity": "sha512-rvRE2FmAZ6ZxKSw7wq+e+jQDpN3t1B/tD2mJz9SmAzb1msoDkd4dMoE4wAh8Z30Um0PQwLiHr9QtomhmXk3aUQ==", + "license": "Apache-2.0" + }, "node_modules/asn1.js": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index 2bdaea0..8cb1e39 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,6 +9,7 @@ "browser": "node --experimental-websocket test/browser/take.mjs" }, "dependencies": { + "@mediapipe/tasks-vision": "1.0.1", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/frontend/public/index.html b/frontend/public/index.html index b822379..36021fc 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -19,22 +19,25 @@ .stage { display: block; background: #12141c; } audio { display: none; } .transport { margin-top: 12px; width: 640px; } - .transport .row { display: flex; gap: 6px; align-items: center; } + .transport .row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; } .transport .gap { flex: 1; } button { font: inherit; color: var(--fg); background: #1c1f2b; border: 1px solid #2b3040; padding: 3px 10px; cursor: pointer; } button:hover { background: #242836; } + button:disabled { opacity: .45; cursor: wait; } button.on { background: #3a4258; border-color: #556080; } .scrub { width: 100%; margin: 10px 0 6px; } .readout { display: flex; gap: 18px; opacity: .55; font-size: 12px; } .readout .warn { color: #d98f5a; opacity: 1; } + .load-status { margin-top: 6px; font-size: 12px; opacity: .75; } .note { opacity: .35; font-size: 12px; max-width: 640px; }
+ diff --git a/frontend/public/mediapipe/LICENSE b/frontend/public/mediapipe/LICENSE new file mode 100644 index 0000000..0e03e39 --- /dev/null +++ b/frontend/public/mediapipe/LICENSE @@ -0,0 +1,218 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +=========================================================================== +For files under tasks/cc/text/language_detector/custom_ops/utils/utf/ +=========================================================================== +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ diff --git a/frontend/public/mediapipe/README.md b/frontend/public/mediapipe/README.md new file mode 100644 index 0000000..ce82aaa --- /dev/null +++ b/frontend/public/mediapipe/README.md @@ -0,0 +1,17 @@ +# Local MediaPipe assets + +`vision_bundle.js` and the four wasm loader/binary files under `wasm/` come +from `@mediapipe/tasks-vision` **1.0.1**, pinned in `frontend/package.json`. +`FilesetResolver.forVisionTasks` uses the SIMD pair where supported and the +no-SIMD pair elsewhere. The package and these files are Apache-2.0; see +[LICENSE](LICENSE). + +`face_landmarker.task` is the official [Face Landmarker model](https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task). +Its SHA-256 is +`64184e229b263107bc2b804c6625db1341ff2bb731874b0bcc2fe6544e0bc9ff`. + +These are served from `/mediapipe/` so detection needs no CDN at runtime. The +browser bundle is loaded as a script before the CLJS app because Shadow CLJS +cannot parse the package's CommonJS bundle (its dynamic `import()` is unsupported +by the current compiler). `flow/detect.cljs` is the sole call site for its +`Vision` global. diff --git a/frontend/public/mediapipe/face_landmarker.task b/frontend/public/mediapipe/face_landmarker.task new file mode 100644 index 0000000..c50c845 Binary files /dev/null and b/frontend/public/mediapipe/face_landmarker.task differ diff --git a/frontend/public/mediapipe/vision_bundle.js b/frontend/public/mediapipe/vision_bundle.js new file mode 100644 index 0000000..d70f04f --- /dev/null +++ b/frontend/public/mediapipe/vision_bundle.js @@ -0,0 +1,2 @@ +var Vision=function(t){"use strict";var e="undefined"!=typeof self?self:{};function r(t,r){t:{for(var n=["CLOSURE_FLAGS"],i=e,s=0;s>6|192;else{if(e>=55296&&e<=57343){if(e<=56319&&i=56320&&s<=57343){e=1024*(e-55296)+s-56320+65536,n[r++]=e>>18|240,n[r++]=e>>12&63|128,n[r++]=e>>6&63|128,n[r++]=63&e|128;continue}i--}e=65533}n[r++]=e>>12|224,n[r++]=e>>6&63|128}n[r++]=63&e|128}}t=r===n.length?n:n.subarray(0,r)}return t}function d(t){e.setTimeout(()=>{throw t},0)}var f=r(610401301,!1),p=r(748402147,!0);function g(){var t=e.navigator;return t&&(t=t.userAgent)?t:""}var m,v=e.navigator;function _(t){return _[" "](t),t}m=v&&v.userAgentData||null,_[" "]=function(){};var y={},E=null;function A(t){var e=t.length,r=3*e/4;r%3?r=Math.floor(r):-1!="=.".indexOf(t[e-1])&&(r=-1!="=.".indexOf(t[e-2])?r-2:r-1);var n=new Uint8Array(r),i=0;return function(t,e){function r(e){for(;n>4),64!=i&&(e(n<<4&240|i>>2),64!=s&&e(i<<6&192|s))}}(t,function(t){n[i++]=t}),i!==r?n.subarray(0,i):n}function w(){if(!E){E={};var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split(""),e=["+/=","+/","-_=","-_.","-_"];for(let r=0;r<5;r++){let n=t.concat(e[r].split(""));y[r]=n;for(let t=0;t0)&&(-1!=g().indexOf("Trident")||-1!=g().indexOf("MSIE")))&&"function"==typeof btoa,k=/[-_.]/g,S={"-":"+",_:"/",".":"="};function L(t){return S[t]||""}function x(t){if(!T)return A(t);t=k.test(t)?t.replace(k,L):t,t=atob(t);var e=new Uint8Array(t.length);for(let r=0;r=e||(r[t]=n+1,D(t=Error(),"incident"),d(t))}}function B(){return"function"==typeof BigInt}var G="function"==typeof Symbol&&"symbol"==typeof Symbol();function j(t,e,r=!1){return"function"==typeof Symbol&&"symbol"==typeof Symbol()?r&&Symbol.for&&t?Symbol.for(t):null!=t?Symbol(t):Symbol():e}var V,H=j("jas",void 0,!0),K=j(void 0,"0di"),X=j(void 0,"1oa"),W=j(void 0,Symbol()),z=j(void 0,"0ub"),Y=j(void 0,"0ubs"),q=j(void 0,"0ubsb"),J=j(void 0,"0actk"),Z=j("m_m","kb",!0),Q=j(),tt={Va:{value:0,configurable:!0,writable:!0,enumerable:!1}},et=Object.defineProperties,rt=G?H:"Va",nt=[];function it(t,e){G||rt in t||et(t,tt),t[rt]|=e}function st(t,e){G||rt in t||et(t,tt),t[rt]=e}function ot(t){return it(t,34),t}function at(t){return it(t,8192),t}st(nt,7),V=Object.freeze(nt);var ht={};function ut(t,e){return void 0===e?t.h!==ct&&!!(2&t.A[rt]):!!(2&e)&&t.h!==ct}var ct={};function lt(t,e){if(null!=t)if("string"==typeof t)t=t?new M(t,I):F();else if(t.constructor!==M)if(R(t))t=t.length?new M(new Uint8Array(t),I):F();else{if(!e)throw Error();t=void 0}return t}class dt{constructor(t,e,r){this.g=t,this.h=e,this.j=r}next(){var t=this.g.next();return t.done||(t.value=this.h.call(this.j,t.value)),t}[Symbol.iterator](){return this}}var ft=Object.freeze({});function pt(t,e,r){var n,i=128&e?0:-1,s=t.length;(n=!!s)&&(n=null!=(n=t[s-1])&&"object"==typeof n&&n.constructor===Object);var o=s+(n?-1:0);for(e=128&e?1:0;e"number"==typeof t),yt=vt(t=>"string"==typeof t),Et=vt(t=>"boolean"==typeof t),At="function"==typeof e.BigInt&&"bigint"==typeof e.BigInt(0);function wt(t){var e=t;if(yt(e)){if(!/^\s*(?:-?[1-9]\d*|0)?\s*$/.test(e))throw Error(String(e))}else if(_t(e)&&!Number.isSafeInteger(e))throw Error(String(e));return At?BigInt(t):t=Et(t)?t?"1":"0":yt(t)?t.trim()||"0":String(t)}var bt=vt(t=>At?t>=kt&&t<=Lt:"-"===t[0]?xt(t,Tt):xt(t,St)),Tt=Number.MIN_SAFE_INTEGER.toString(),kt=At?BigInt(Number.MIN_SAFE_INTEGER):void 0,St=Number.MAX_SAFE_INTEGER.toString(),Lt=At?BigInt(Number.MAX_SAFE_INTEGER):void 0;function xt(t,e){if(t.length>e.length)return!1;if(t.lengthi)return!1;if(n>>0;Ft=e,Ct=(t-e)/4294967296>>>0}function Mt(t){if(t<0){Nt(-t);let[e,r]=Vt(Ft,Ct);Ft=e>>>0,Ct=r>>>0}else Nt(t)}function Ot(t){var e=Rt||=new DataView(new ArrayBuffer(8));e.setFloat32(0,+t,!0),Ct=0,Ft=e.getUint32(0,!0)}function Dt(t,e){var r=4294967296*e+(t>>>0);return Number.isSafeInteger(r)?r:Ut(t,e)}function Pt(t,e){return wt(B()?BigInt.asUintN(64,(BigInt(e>>>0)<>>0)):Ut(t,e))}function $t(t,e){return B()?wt(BigInt.asIntN(64,(BigInt.asUintN(32,BigInt(e))<>>=0,(e>>>=0)<=2097151)var r=""+(4294967296*e+t);else B()?r=""+(BigInt(e)<>>24|e<<8))+6710656*(e=e>>16&65535),r+=8147497*e,e*=2,t>=1e7&&(r+=t/1e7>>>0,t%=1e7),r>=1e7&&(e+=r/1e7>>>0,r%=1e7),r=e+Bt(r)+Bt(t));return r}function Bt(t){return t=String(t),"0000000".slice(t.length)+t}function Gt(t,e){if(2147483648&e)if(B())t=""+(BigInt(0|e)<>>0));else{let[r,n]=Vt(t,e);t="-"+Ut(r,n)}else t=Ut(t,e);return t}function jt(t){if(t.length<16)Mt(Number(t));else if(B())t=BigInt(t),Ft=Number(t&BigInt(4294967295))>>>0,Ct=Number(t>>BigInt(32)&BigInt(4294967295));else{let e=+("-"===t[0]);Ct=Ft=0;let r=t.length;for(let n=e,i=(r-e)%6+e;i<=r;n=i,i+=6){let e=Number(t.slice(n,i));Ct*=1e6,(Ft=1e6*Ft+e)>=4294967296&&(Ct+=Math.trunc(Ft/4294967296),Ct>>>=0,Ft>>>=0)}if(e){let[t,e]=Vt(Ft,Ct);Ft=t,Ct=e}}}function Vt(t,e){return e=~e,t?t=1+~t:e+=1,[t,e]}function Ht(t){return Array.prototype.slice.call(t)}var Kt="function"==typeof BigInt?BigInt.asIntN:void 0,Xt="function"==typeof BigInt?BigInt.asUintN:void 0,Wt=Number.isSafeInteger,zt=Number.isFinite,Yt=Math.trunc,qt=wt(0);function Jt(t){if("number"!=typeof t)throw Error(`Value of float/double field must be a number, found ${typeof t}: ${t}`);return t}function Zt(t){return null==t||"number"==typeof t?t:"NaN"===t||"Infinity"===t||"-Infinity"===t?Number(t):void 0}function Qt(t){if("boolean"!=typeof t){var e=typeof t;throw Error(`Expected boolean but got ${"object"!=e?e:t?Array.isArray(t)?"array":e:"null"}: ${t}`)}return t}var te=/^-?([1-9][0-9]*|0)(\.[0-9]+)?$/;function ee(t){switch(typeof t){case"bigint":return!0;case"number":return zt(t);case"string":return te.test(t);default:return!1}}function re(t){if(null!=t){if(!zt(t))throw $("enum");t|=0}return t}function ne(t){if(null==t)return t;if("string"==typeof t&&t)t=+t;else if("number"!=typeof t)return;return zt(t)?0|t:void 0}function ie(t){if(null==t)return t;if("string"==typeof t&&t)t=+t;else if("number"!=typeof t)return;return zt(t)?t>>>0:void 0}function se(t,e){if(e??=1024,!ee(t))throw $("int64");var r=typeof t;switch(e){case 512:switch(r){case"string":return le(t);case"bigint":return String(Kt(64,t));default:return ce(t)}case 1024:switch(r){case"string":return de(t);case"bigint":return wt(Kt(64,t));default:return fe(t)}case 0:switch(r){case"string":return le(t);case"bigint":return wt(Kt(64,t));default:return he(t)}default:return function(t,e=`unexpected value ${t}!`){throw Error(e)}(e,"Unknown format requested type for int64")}}function oe(t){var e=t.length;return("-"===t[0]?e<20||20===e&&t<="-9223372036854775808":e<19||19===e&&t<="9223372036854775807")?t:(jt(t),Gt(Ft,Ct))}function ae(t){if("-"===t[0])var e=!1;else e=(e=t.length)<20||20===e&&t<="18446744073709551615";return e?t:(jt(t),Ut(Ft,Ct))}function he(t){if(t=Yt(t),!Wt(t)){Mt(t);var e=Ft,r=Ct;(t=2147483648&r)&&(r=~r>>>0,0==(e=1+~e>>>0)&&(r=r+1>>>0)),t="number"==typeof(e=Dt(e,r))?t?-e:e:t?"-"+e:e}return t}function ue(t){return(t=Yt(t))>=0&&Wt(t)||(Mt(t),t=Dt(Ft,Ct)),t}function ce(t){return t=Yt(t),Wt(t)?t=String(t):(Mt(t),t=Gt(Ft,Ct)),t}function le(t){var e=Yt(Number(t));return Wt(e)?String(e):(-1!==(e=t.indexOf("."))&&(t=t.substring(0,e)),oe(t))}function de(t){var e=Yt(Number(t));return Wt(e)?wt(e):(-1!==(e=t.indexOf("."))&&(t=t.substring(0,e)),B()?wt(Kt(64,BigInt(t))):wt(oe(t)))}function fe(t){return Wt(t)?wt(he(t)):wt(ce(t))}function pe(t){var e=typeof t;return null==t?t:"bigint"===e?wt(Kt(64,t)):ee(t)?"string"===e?de(t):fe(t):void 0}function ge(t){if(null==t)return t;var e=typeof t;if("bigint"===e)return String(Kt(64,t));if(ee(t)){if("string"===e)return le(t);if("number"===e)return he(t)}}function me(t){if(null==t||"string"==typeof t||t instanceof M)return t}function ve(t){if("string"!=typeof t)throw Error();return t}function _e(t){if(null!=t&&"string"!=typeof t)throw Error();return t}function ye(t){return null==t||"string"==typeof t?t:void 0}function Ee(t,e,r,n){return null!=t&&t[Z]===ht?t:Array.isArray(t)?((n=(r=0|t[rt])|32&n|2&n)!==r&&st(t,n),new e(t)):(r?2&n?((t=e[K])||(ot((t=new e).A),t=e[K]=t),e=t):e=new e:e=void 0,e)}function Ae(t,e,r){return null==(t=e?se(t,1024):pe(t))?r?qt:void 0:t}function we(t){return t}var be={},Te=function(){try{return _(new class extends Map{constructor(){super()}}),!1}catch{return!0}}();class ke{constructor(){this.g=new Map}get(t){return this.g.get(t)}set(t,e){return this.g.set(t,e),this.size=this.g.size,this}delete(t){return t=this.g.delete(t),this.size=this.g.size,t}clear(){this.g.clear(),this.size=this.g.size}has(t){return this.g.has(t)}entries(){return this.g.entries()}keys(){return this.g.keys()}values(){return this.g.values()}forEach(t,e){return this.g.forEach(t,e)}[Symbol.iterator](){return this.entries()}}var Se=Te?(Object.setPrototypeOf(ke.prototype,Map.prototype),Object.defineProperties(ke.prototype,{size:{value:0,configurable:!0,enumerable:!0,writable:!0}}),ke):class extends Map{constructor(){super()}};function Le(t){return t}function xe(t){if(2&t.M)throw Error("Cannot mutate an immutable Map")}var Re,Ie=class extends Se{constructor(t,e,r=Le,n=Le){super(),this.M=0|t[rt],this.N=e,this.ba=r,this.na=this.N?Fe:n;for(let i=0;i{t.call(e,i.get(n),n,i)}):super.forEach(t,e)}set(t,e){return xe(this),null==(t=this.ba(t,!0,!1))?this:null==e?(super.delete(t),this):super.set(t,this.na(e,!0,!0,this.N,!1,this.M))}gb(t){var e=this.ba(t[0],!1,!0);t=t[1],t=this.N?void 0===t?null:t:this.na(t,!1,!0,void 0,!1,this.M),super.set(e,t)}has(t){return super.has(this.ba(t,!1,!1))}get(t){t=this.ba(t,!1,!1);var e=super.get(t);if(void 0!==e){var r=this.N;return r?((r=this.na(e,!1,!0,r,this.Fa,this.M))!==e&&super.set(t,r),r):e}}[Symbol.iterator](){return this.entries()}};function Fe(t,e,r,n,i,s){return t=Ee(t,n,r,s),i&&(t=Qe(t)),t}function Ce(t){return[t,this.get(t)]}function Ne(){return Re||=new Ie(ot([]),void 0,void 0,void 0,be)}function Me(t){return W?t[W]:void 0}function Oe(t,e){for(let r in t)!isNaN(r)&&e(t,+r,t[r])}Ie.prototype.toJSON=void 0;var De,Pe,$e,Ue=class{},Be={cb:!0};function Ge(t,e){e<100||U(Y,1)}function je(t,e,r,n){var i=void 0!==n;n=!!n;var s,o=W;!i&&G&&o&&(s=t[o])&&Oe(s,Ge),o=[];var a=t.length;s=4294967295;var h=!1,u=!!(64&e),c=u?128&e?0:-1:void 0;if(!(1&e)){var l=a&&t[a-1];null!=l&&"object"==typeof l&&l.constructor===Object?s=--a:l=void 0,!u||128&e||i||(h=!0,s=(De??we)(s-c,c,t,l,void 0)+c)}e=void 0;for(var d=0;d=s){let t=d-c;(e??={})[t]=i}else o[d]=i}if(l)for(let t in l){if(null==(a=l[t])||null==(a=r(a,n)))continue;let i;d=+t,u&&!Number.isNaN(d)&&(i=d+c){e[r]=Ht(n)}),e.ka=t.ka,e}(t)),o}function Ve(t){return t[0]=He(t[0]),t[1]=He(t[1]),t}function He(t){switch(typeof t){case"number":return Number.isFinite(t)?t:""+t;case"bigint":return bt(t)?Number(t):""+t;case"boolean":return t?1:0;case"object":if(Array.isArray(t)){var e=0|t[rt];return 0===t.length&&1&e?void 0:je(t,e,He)}if(null!=t&&t[Z]===ht)return Ke(t);if(t instanceof M){if(null==(e=t.g))t="";else if("string"==typeof e)t=e;else{if(T){for(var r="",n=0,i=e.length-10240;n>2];s=r[(3&s)<<4|o>>4],o=r[(15&o)<<2|a>>6],a=r[63&a],n[u++]=h+s+o+a}switch(h=0,a=i,e.length-t){case 2:a=r[(15&(h=e[t+1]))<<2]||i;case 1:e=e[t],n[u]=r[e>>2]+r[(3&e)<<4|h>>4]+a+i}e=n.join("")}t=t.g=e}return t}return t instanceof Ie?t=0!==t.size?t.ea(Ve):void 0:void 0}return t}function Ke(t){return je(t=t.A,0|t[rt],He)}function Xe(t,e){return We(t,e[0],e[1])}function We(t,e,r,n=0){if(null==t){var i=32;r?(t=[r],i|=128):t=[],e&&(i=-16760833&i|(1023&e)<<14)}else{if(!Array.isArray(t))throw Error("narr");if(i=0|t[rt],p&&1&i)throw Error("rfarr");if(2048&i&&!(2&i)&&function(){if(p)throw Error("carr");U(J,5)}(),256&i)throw Error("farr");if(64&i)return(i|n)!==i&&st(t,i|n),t;if(r&&(i|=128,r!==t[0]))throw Error("mid");t:{i|=64;var s=(r=t).length;if(s){var o=s-1;let t=r[o];if(null!=t&&"object"==typeof t&&t.constructor===Object){if((o-=e=128&i?0:-1)>=1024)throw Error("pvtlmt");for(var a in t)(s=+a)1024)throw Error("spvt");i=-16760833&i|(1023&a)<<14}}}return st(t,64|i|n),t}function ze(t,e){if("object"!=typeof t)return t;if(Array.isArray(t)){var r=0|t[rt];return 0===t.length&&1&r?void 0:Ye(t,r,e)}if(null!=t&&t[Z]===ht)return Je(t);if(t instanceof Ie){if(2&(e=t.M))return t;if(!t.size)return;if(r=ot(t.ea()),t.N)for(t=0;t=s){var o=t[s];if(null!=o&&"object"==typeof o&&o.constructor===Object){r=o[e];var a=!0}else{if(i!==s)return;r=o}}else r=t[i];if(n&&null!=r){if(null==(n=n(r)))return n;if(!Object.is(n,r))return a?o[e]=n:t[i]=n,n}return r}}function hr(t,e,r,n){er(t);var i=t.A;return ur(i,0|i[rt],e,r,n),t}function ur(t,e,r,n,i){var s=r+(i?0:-1),o=t.length-1;if(o>=1+(i?0:-1)&&s>=o){let i=t[o];if(null!=i&&"object"==typeof i&&i.constructor===Object)return i[r]=n,e}return s<=o?(t[s]=n,e):(void 0!==n&&(r>=(o=(e??=0|t[rt])>>14&1023||536870912)?null!=n&&(t[o+(i?0:-1)]={[r]:n}):t[s]=n),e)}function cr(t,e,r,n){var i=t.A;return void 0!==Sr(i,0|i[rt],e,t=Ar(t,n)===r?r:-1)}function lr(){return void 0===ft?2:4}function dr(t,e,r,n,i){var s=t.A,o=0|s[rt];n=ut(t,o)?1:n,i=!!i||3===n,2===n&&tr(t)&&(o=0|(s=t.A)[rt]);var a=(t=pr(s,e))===V?7:0|t[rt],h=gr(a,o),u=!(4&h);if(u){4&h&&(t=Ht(t),a=0,h=Mr(h,o),o=ur(s,o,e,t));let n=0,i=0;for(;n{var n=Ee(t,r,!1,e);return s=n!==t&&null!=n,n})))return s&&!ut(n)&&rr(t,e),n}function Lr(t,e,r,n){var i=t.A,s=0|i[rt];if(null==(e=Sr(i,s,e,r,n)))return e;if(!ut(t,s=0|i[rt])){let o=Qe(e);o!==e&&(tr(t)&&(s=0|(i=t.A)[rt]),rr(i,s=ur(i,s,r,e=o,n)))}return e}function xr(t,e,r,n,i,s,o,a){var h=ut(t,r);s=h?1:s,o=!!o||3===s,h=a&&!h,(2===s||h)&&tr(t)&&(r=0|(e=t.A)[rt]);var u=(t=pr(e,i))===V?7:0|t[rt],c=gr(u,r);if(a=!(4&c)){var l=t,d=r;let e=!!(2&c);e&&(d|=2);let i=!e,s=!0,o=0,a=0;for(;o=0?t=wt(e):(-1!==(e=t.indexOf("."))&&(t=t.substring(0,e)),t=B()?wt(Xt(64,BigInt(t))):wt(ae(t))),t;case"bigint":return wt(Xt(64,t));default:return Wt(t)?t=wt(ue(t)):((t=Yt(t))>=0&&Wt(t)?t=String(t):(Mt(t),t=Ut(Ft,Ct)),t=wt(t)),t}}(r))}function Vr(t,e,r){hr(t,e,null==r?r:Jt(r))}function Hr(t,e,r){yr(t,e,null==r?r:Jt(r),0)}function Kr(t,e,r){yr(t,e,_e(r),"")}function Xr(t,e,r){{er(t);let o=t.A,a=0|o[rt];if(null==r)ur(o,a,e);else{var n=t=r===V?7:0|r[rt],i=mr(t),s=i||Object.isFrozen(r);for(i||(t=0),s||(r=Ht(r),n=0,t=Mr(t,a),s=!1),t|=5,t|=(4&t?512&t?512:1024&t?1024:0:void 0)??1024,i=0;i32)for(n|=(127&a)>>4,i=3;i<32&&128&a;i+=7)n|=(127&(a=s[o++]))<>>0,n>>>0);throw Error()}function Jr(t){for(var e=0,r=t.g,n=r+10,i=t.h;r>>0}function tn(t){return qr(t,$t)}function en(t){var e=t.h,r=t.g,n=e[r],i=e[r+1],s=e[r+2];return e=e[r+3],sn(t,t.g+4),(n|i<<8|s<<16|e<<24)>>>0}function rn(t){var e=en(t);t=2*(e>>31)+1;var r=e>>>23&255;return e&=8388607,255==r?e?NaN:t*(1/0):0==r?1401298464324817e-60*t*e:t*Math.pow(2,r-150)*(e+8388608)}function nn(t){return Zr(t)}function sn(t,e){if(t.g=e,e>t.j)throw Error()}function on(t,e){if(e<0)throw Error();var r=t.g;if((e=r+e)>t.j)throw Error();return t.g=e,r}function an(t,e){if(0==e)return F();var r=on(t,e);return t.fa&&t.o?r=t.h.subarray(r,r+e):(t=t.h,r=r===(e=r+e)?new Uint8Array(0):It?t.slice(r,e):new Uint8Array(t.subarray(r,e))),0==r.length?F():new M(r,I)}var hn=class{constructor(t,e,r,n){this.h=null,this.o=!1,this.g=this.j=this.m=0,this.init(t,e,r,n)}init(t,e,r,{fa:n=!1,ma:i=!1}={}){this.fa=n,this.ma=i,t&&(t=Yr(t,this.ma),this.h=t.buffer,this.o=t.g,this.m=e||0,this.j=void 0!==r?this.m+r:this.h.length,this.g=this.m)}clear(){this.h=null,this.o=!1,this.g=this.j=this.m=0,this.fa=!1}},un=[],cn=0;function ln(t,e,r,n){if(An.length){let i=An.pop();return i.v(n),i.g.init(t,e,r,n),i}return new En(t,e,r,n)}function dn(t){t.g.clear(),t.j=-1,t.h=-1,An.length<100&&An.push(t)}function fn(t){var e=t.g;if(e.g==e.j)return!1;t.m=t.g.g;var r=Qr(t.g);if(e=r>>>3,!((r&=7)>=0&&r<=5))throw Error();if(e<1)throw Error();return t.j=e,t.h=r,!0}function pn(t){try{switch(t.h){case 0:0!=t.h?pn(t):Jr(t.g);break;case 1:var e=t.g;sn(e,e.g+8);break;case 2:if(2!=t.h)pn(t);else{var r=Qr(t.g),n=t.g;sn(n,n.g+r)}break;case 5:var i=t.g;sn(i,i.g+4);break;case 3:gn();let s=t.j;try{for(;;){if(!fn(t))throw Error();if(4==t.h){if(t.j!=s)throw Error();break}pn(t)}}catch(t){if(t instanceof RangeError)throw new SyntaxError;throw t}finally{cn>0&&cn--}break;default:throw Error()}}catch(t){if(t instanceof RangeError)throw new SyntaxError;throw t}}function gn(){if(cn>=100)throw new SyntaxError;cn++}function mn(t,e,r){var n=t.g.j,i=Qr(t.g),s=(i=t.g.g+i)-n;if(s<=0&&(t.g.j=i,r(e,t,void 0,void 0,void 0),s=i-t.g.g),s)throw Error();return t.g.g=i,t.g.j=n,e}function vn(t){var e=Qr(t.g),r=on(t=t.g,e);if(t=t.h,u){var n,a=t;(n=o)||(n=o=new TextDecoder("utf-8",{fatal:!0})),e=r+e,a=0===r&&e===a.length?a:a.subarray(r,e);try{var c=n.decode(a)}catch(t){if(void 0===h){try{n.decode(new Uint8Array([128]))}catch(t){}try{n.decode(new Uint8Array([97])),h=!0}catch(t){h=!1}}throw!h&&(o=void 0),t}}else{e=(c=r)+e,r=[];let o,h=null;for(;c=e?i():(o=t[c++],l<194||128!=(192&o)?(c--,i()):r.push((31&l)<<6|63&o)):l<240?c>=e-1?i():(o=t[c++],128!=(192&o)||224===l&&o<160||237===l&&o>=160||128!=(192&(n=t[c++]))?(c--,i()):r.push((15&l)<<12|(63&o)<<6|63&n)):l<=244?c>=e-2?i():(o=t[c++],128!=(192&o)||o-144+(l<<28)>>30||128!=(192&(n=t[c++]))||128!=(192&(a=t[c++]))?(c--,i()):(l=(7&l)<<18|(63&o)<<12|(63&n)<<6|63&a,l-=65536,r.push(55296+(l>>10&1023),56320+(1023&l)))):i(),r.length>=8192&&(h=s(h,r),r.length=0)}c=s(h,r)}return c}function _n(t){var e=Qr(t.g);return an(t.g,e)}function yn(t,e,r){var n=Qr(t.g);for(n=t.g.g+n;t.g.g>>0,this.g=e>>>0}};function Sn(t){return new Dn(4294967295&t,Math.floor(t/4294967296))}function Ln(t){return t?/^-?\d+$/.test(t)?(jt(t),new Dn(Ft,Ct)):null:xn||=new Dn(0,0)}var xn,Rn,In,Fn,Cn,Nn,Mn,On,Dn=class{constructor(t,e){this.h=t>>>0,this.g=e>>>0}};function Pn(t,e,r){return"undefined"!=typeof BigInt64Array?(Mn||(Mn=new BigInt64Array(1),On=new Uint32Array(Mn.buffer),Mn[0]=BigInt(1),Nn=1===On[0]),Mn[0]=t,new e(On[t=Nn?0:1],On[1-t])):(Cn||(Rn=BigInt(Number.MIN_SAFE_INTEGER),In=BigInt(Number.MAX_SAFE_INTEGER),Fn=BigInt(4294967295),Cn=BigInt(32)),t>=Rn&&t<=In?r(Number(t)):(t=BigInt.asUintN(64,t),new e(Number(t&Fn),Number(t>>Cn))))}function $n(t,e,r){for(;r>0||e>127;)t.g.push(127&e|128),e=(e>>>7|r<<25)>>>0,r>>>=7;t.g.push(e)}function Un(t,e){for(;e>127;)t.g.push(127&e|128),e>>>=7;t.g.push(e)}function Bn(t,e){if(e>=0)Un(t,e);else{for(let r=0;r<9;r++)t.g.push(127&e|128),e>>=7;t.g.push(1)}}function Gn(t,e){jt(e),function(t){var e=Ct>>31;t(Ft<<1^e,(Ct<<1|Ft>>>31)^e)}((e,r)=>{$n(t,e>>>0,r>>>0)})}function jn(t,e){t.g.push(e>>>0&255),t.g.push(e>>>8&255),t.g.push(e>>>16&255),t.g.push(e>>>24&255)}var Vn=class{constructor(){this.g=[]}length(){return this.g.length}end(){var t=this.g;return this.g=[],t}};function Hn(t,e){0!==e.length&&(t.j.push(e),t.h+=e.length)}function Kn(t,e,r){Un(t.g,8*e+r)}function Xn(t,e){return Kn(t,e,2),e=t.g.end(),Hn(t,e),e.push(t.h),e}function Wn(t,e){var r=e.pop();for(r=t.h+t.g.length()-r;r>127;)e.push(127&r|128),r>>>=7,t.h++;e.push(r),t.h++}function zn(t,e,r){if(null!=r)switch(Kn(t,e,0),typeof r){case"number":t=t.g,Mt(r),$n(t,Ft,Ct);break;case"bigint":r=Pn(r,Dn,Sn),$n(t.g,r.h,r.g);break;default:r=Ln(r),$n(t.g,r.h,r.g)}}function Yn(t,e,r){Kn(t,e,2),Un(t.g,r.length),Hn(t,t.g.end()),Hn(t,r)}function qn(t,e,r,n){null!=r&&(e=Xn(t,e),n(r,t),Wn(t,e))}var Jn=class{constructor(){this.j=[],this.h=0,this.g=new Vn}};function Zn(t){if("string"==typeof t)Ln(t)}function Qn(){var t=class{constructor(){throw Error()}};return Object.setPrototypeOf(t,t.prototype),t}var ti=Qn(),ei=Qn(),ri=Qn(),ni=Qn(),ii=Qn(),si=Qn(),oi=Qn(),ai=Qn(),hi=Qn(),ui=Qn(),ci=Qn(),li=Qn();function di(t,e,r){var n=t.A;W&&W in n&&(n=n[W])&&delete n[e.g],e.h?e.o(t,e.h,e.g,r,e.j):e.o(t,e.g,r,e.j)}var fi=class{constructor(t,e){this.A=We(t,e,void 0,2048)}toJSON(){return Ke(this)}o(){var t=Na,e=this.A,r=t.g,n=W;if(G&&n&&null!=e[n]?.[r]&&U(z,3),e=t.g,Q&&W&&void 0===Q&&(n=(r=this.A)[W])&&(n=n.ka))try{n(r,e,Be)}catch(t){d(t)}return t.h?t.m(this,t.h,t.g,t.j):t.m(this,t.g,t.defaultValue,t.j)}clone(){var t=this.A,e=0|t[rt];return nr(this,t,e)?qe(this,t,!0):new this.constructor(Ze(t,e,!1))}};fi.prototype[Z]=ht,fi.prototype.toString=function(){return this.A.toString()};var pi=class{constructor(t,e,r){this.g=t,this.h=e,t=ti,this.j=!!t&&r===t||!1}};function gi(t,e){return new pi(t,e,ti)}function mi(t,e,r,n,i){qn(t,r,xi(e,n),i)}var vi,_i,yi=gi(function(t,e,r,n,i){return 2===t.h&&(mn(t,kr(e,n,r),i),!0)},mi),Ei=gi(function(t,e,r,n,i){return 2===t.h&&(mn(t,kr(e,n,r),i),!0)},mi),Ai=Symbol(),wi=Symbol(),bi=Symbol(),Ti=Symbol(),ki=Symbol();function Si(t,e,r,n){var i=n[t];if(i)return i;(i={}).Ea=n,i.ca=function(t){switch(typeof t){case"boolean":return Pe||=[0,void 0,!0];case"number":return t>0?void 0:0===t?$e||=[0,void 0]:[-t,void 0];case"string":return[0,t];case"object":return t}}(n[0]);var s=n[1],o=1;s&&s.constructor===Object&&(i.ia=s,"function"==typeof(s=n[++o])&&(i.wa=!0,vi??=s,_i??=n[o+1],s=n[o+=2]));for(var a={};s&&Array.isArray(s)&&s.length&&"number"==typeof s[0]&&s[0]>0;){for(var h=0;hi(t,e,r,n):i}function Ii(t,e,r,n,i){var s,o,a=r.g;t[e]=(t,e,r)=>a(t,e,r,o||=Si(wi,Ri,Ii,n).ca,s||=Fi(n),i)}function Fi(t){var e=t[bi];if(null!=e)return e;var r=Si(wi,Ri,Ii,t);return e=r.wa?(t,e)=>vi(t,e,r):(t,e)=>{t:{gn();try{for(;fn(e)&&4!=e.h;){let h=e.j,u=r[h];if(null==u){let t=r.ia;if(t){let e=t[h];if(e){let t=Ni(e);null!=t&&(u=r[h]=t)}}}if(null==u||!u(e,t,h)){var n=e;let r=n.m;if(pn(n),n.ra)var i=void 0;else{let t=n.g.g-r;n.g.g=r,i=an(n.g,t)}n=void 0;var s=t,o=h,a=i;a&&((n=s[W]??(s[W]=new Ue))[o]??(n[o]=[])).push(a)}}let u=Me(t);u&&(u.ka=r.Ea[ki]);var h=!0;break t}catch(t){if(t instanceof RangeError)throw new SyntaxError;throw t}finally{cn>0&&cn--}h=void 0}return h},t[bi]=e,t[ki]=Ci.bind(t),e}function Ci(t,e,r,n){var i=this[wi],s=this[bi],o=Xe(void 0,i.ca),a=Me(t);if(a){var h=!1,u=i.ia;if(u){if(i=(e,r,i)=>{if(0!==i.length)if(u[r])for(let t of i){e=ln(t);try{h=!0,s(o,e)}finally{dn(e)}}else n?.(t,r,i)},null==e)Oe(a,i);else if(null!=a){let t=a[e];t&&i(a,e,t)}if(h){let n=0|t[rt];if(2&n&&2048&n&&!r?.cb)throw Error();let i=mt(n),s=(e,s)=>{if(null!=ar(t,e,i)){if(1===r?.lb)return;throw Error()}null!=s&&(n=ur(t,n,e,s,i)),delete a[e]};null==e?pt(o,0|o[rt],(t,e)=>{s(t,e)}):s(e,ar(o,e,i))}}}}function Ni(t){var e=(t=Li(t))[0].g;if(t=t[1]){let r=Fi(t),n=Si(wi,Ri,Ii,t).ca;return(t,i,s)=>e(t,i,s,n,r)}return e}function Mi(t,e,r){t[e]=r.h}function Oi(t,e,r,n){var i,s,o=r.h;t[e]=(t,e,r)=>o(t,e,r,s||=Si(Ai,Mi,Oi,n).ca,i||=Di(n))}function Di(t){var e=t[Ti];if(!e){let r=Si(Ai,Mi,Oi,t);e=(t,e)=>Pi(t,e,r),t[Ti]=e}return e}function Pi(t,e,r){pt(t,0|t[rt],(t,n)=>{if(null!=n){var i=function(t,e){var r=t[e];if(r)return r;if((r=t.ia)&&(r=r[e])){var n=(r=Li(r))[0].h;if(r=r[1]){let e=Di(r),i=Si(Ai,Mi,Oi,r).ca;r=t.wa?_i(i,e):(t,r,s)=>n(t,r,s,i,e)}else r=n;return t[e]=r}}(r,t);i?i(e,n,t):t<500||U(q,3)}}),(t=Me(t))&&Oe(t,(t,r,n)=>{for(Hn(e,e.g.end()),t=0;t{var r=new Jn;Pi(t.A,r,Si(Ai,Mi,Oi,e)),Hn(r,r.g.end()),t=new Uint8Array(r.h);var n=(e=r.j).length,i=0;for(let r=0;r{qn(t,r,Xe([s,e],n),i)});else if(Array.isArray(e)){for(let s=0;s>31)+1;var s=i>>>20&2047;return t=4294967296*(1048575&i)+t,Vi(e,r,2047==s?t?NaN:n*(1/0):0==s?5e-324*n*t:n*Math.pow(2,s-1075)*(t+4503599627370496)),!0},function(t,e,r){null!=(e=Zt(e))&&(Kn(t,r,1),t=t.g,(r=Rt||=new DataView(new ArrayBuffer(8))).setFloat64(0,+e,!0),Ft=r.getUint32(0,!0),Ct=r.getUint32(4,!0),jn(t,Ft),jn(t,Ct))},ui),ss=Gi(function(t,e,r){return 5===t.h&&(Vi(e,r,rn(t.g)),!0)},Ki,hi),os=ji(ts,function(t,e,r){if(null!=(e=Ui(Zt,e,!0)))for(let o=0;o=0?t=String(e):(-1!==(e=t.indexOf("."))&&(t=t.substring(0,e)),t=ae(t)),t;if("number"===e)return ue(t)}}(e),null!=e){if("string"==typeof e)bn(e);if(null!=e)switch(Kn(t,r,0),typeof e){case"number":t=t.g,Mt(e),$n(t,Ft,Ct);break;case"bigint":r=Pn(e,kn,wn),$n(t.g,r.h,r.g);break;default:r=bn(e),$n(t.g,r.h,r.g)}}},oi),ps=Gi(function(t,e,r){return 0===t.h&&(Vi(e,r,Zr(t.g)),!0)},Wi,ni),gs=ji(rs,function(t,e,r){if(null!=(e=Ui(ne,e,!0)))for(let o=0;o{var r=-(1&t);return $t(t=(t>>>1|e<<31)^r,e>>>1^r)})}(t.g)),t=!0),t},function(t,e,r){if(null!=(e=ge(e))&&(Zn(e),null!=e))switch(Kn(t,r,0),typeof e){case"number":t=t.g,e=(r=e)<0,Nt(r=2*Math.abs(r)),r=Ft;let n=Ct;e&&(0==r?0==n?n=r=4294967295:(n--,r=4294967295):r--),$n(t,Ft=r,Ct=n);break;case"bigint":t=t.g,e=e<>BigInt(63),Ft=Number(BigInt.asUintN(32,e)),Ct=Number(BigInt.asUintN(32,e>>BigInt(32))),$n(t,Ft,Ct);break;default:Gn(t.g,e)}},ai);class Ns{constructor(t,e){var r=io;this.g=t,this.h=e,this.m=Lr,this.o=Fr,this.defaultValue=void 0,this.j=null!=r.jb?gt:void 0}register(){_(this)}}function Ms(t,e){return new Ns(t,e)}function Os(t,e){return(r,n)=>{t:{let s={ma:!0};n&&Object.assign(s,n),r=ln(r,void 0,void 0,s);try{let n=new t,s=n.A;Fi(e)(s,r);var i=n;break t}catch(t){if(t instanceof RangeError)throw new SyntaxError;throw t}finally{dn(r)}i=void 0}return i}}function Ds(t){return e=>Bi(e,t)}function Ps(t){return function(){return Bi(this,t)}}var $s=[0,ks,Ss,_s,ws],Us=[0,As,[0,Fs,[0,ds,vs],Fs,-1,[0,Is],Fs,-1],Gi(ns,Ji,ci)];var Bs,Gs=class extends fi{constructor(t){super(t)}},js=[0,As,Gi(ns,function(t,e,r){if(null!=e){if(e instanceof fi){let n=e.mb;return void(n?(e=n(e),null!=e&&Yn(t,r,Yr(e,!0).buffer)):U(q,3))}if(Array.isArray(e))return void U(q,3)}Ji(t,e,r)},ci)],Vs=[0,1,[0,12,ps,10,_s],[0,7,[0,ps,-1]]],Hs=globalThis.trustedTypes;var Ks=class{constructor(t){this.g=t}toString(){return this.g+""}};function Xs(t){var e;return void 0===Bs&&(Bs=function(){var t=null;if(!Hs)return t;try{let e=t=>t;t=Hs.createPolicy("goog#html",{createHTML:e,createScript:e,createScriptURL:e})}catch(t){}return t}()),t=(e=Bs)?e.createScriptURL(t):t,new Ks(t)}function Ws(t,...e){if(0===e.length)return Xs(t[0]);var r=t[0];for(let n=0;n({index:Dr(t,1)??0??-1,score:Pr(t,2)??0,categoryName:ye(or(t,3))??""??"",displayName:ye(or(t,4))??""??""})),headIndex:e,headName:r}}function Za(t){var e={classifications:Rr(t,Oo,1).map(t=>Ja(Lr(t,Ao,4)?.g()??[],Dr(t,2)??0,ye(or(t,3))??""))};return null!=function(t){return null==t?t:"bigint"==typeof t?(bt(t)?t=Number(t):(t=Kt(64,t),t=bt(t)?Number(t):String(t)),t):ee(t)?"number"==typeof t?he(t):le(t):void 0}(or(t,2,void 0,pe))&&(e.timestampMs=qa(or(t,2,void 0,pe)??ir)),e}function Qa(t){var e=dr(t,3,Zt,lr()),r=dr(t,2,ne,lr()),n=dr(t,1,ye,lr()),i=dr(t,9,ye,lr()),s={categories:[],keypoints:[]};for(let t=0;tt>127?t-256:t)}function nh(t,e){if(t.length!==e.length)throw Error(`Cannot compute cosine similarity between embeddings of different sizes (${t.length} vs. ${e.length}).`);var r=0,n=0,i=0;for(let s=0;s0?setTimeout(()=>{n.abort()},t.la):void 0;try{let i=await fetch(t.url,{method:t.bb,headers:{...t.ab},...t.body&&{body:t.body},...t.withCredentials&&{credentials:"include"},signal:t.la&&n?n.signal:null});200===i.status?e?.(await i.text()):r?.(i.status)}catch(t){if("AbortError"===t?.name)r?.(408);else r?.(400)}finally{clearTimeout(i)}}},wh=class extends fi{constructor(t){super(t,37)}},bh=[-4,{},Vs,Is,Us],Th=[0,ws,Is,1,ws,-1,Is,1,Is,1,cs],kh=[0,Is,ws,-2],Sh=[0,ws,Is],Lh=[0,ws,Is],xh=[0,_s,-3],Rh=[0,Is,ws,-1,cs,ps,-1,ws,-5,bs,[0,ws,-4],-1,_s,[0,_s,-3],Is];var Ih=class extends fi{constructor(t){super(t,19)}},Fh=Ds([-19,{},[0,Is,1,[0,ws,-6,cs,ps,ws,-1,cs],1,[0,ws,1,ws,-5],ws,-1,[0,Is,ws,-8],[0,ws,-3],[0,ws,Is,ws,-2],[0,ws,-1,Is,ws,-1,Is,ws,-1,[0,bs,[0,ws,-1],_s,ws,-5],[0,Is,_s,ps,-2]],cs,[0,ws,-3,cs,ps,ws,-1],[0,Is,ws,-1],[0,ws,-9],[0,ws,-6,Is,ws,1,ws,_s,Is,-1,_s,ws,-2,Is,ws,Is,ws,ps,-1],1,[0,Is],1,[0,ws,-4],1,Th,[0,[1,2,3,4,5,6],Ts,Th,Ts,Sh,Ts,Lh,Ts,[0,Is],Ts,Rh,Ts,kh],Sh,Lh,Rh,[0,[0,Is,ws,-1,cs,ps,-1,ws,-4,bs,[0,ws,-4],-1,1,xh],[0,Is,ws,-1,cs,ps,-1,ws,-4,xh]],kh,[0,ws,[0,ps,-3,Is],Is,-2,[0,ps,-1],_s],4,[0,ws,Is,ws,-1,cs,Is,ws,-1,Is,ps,-1]],Is,bs,[-37,{},us,ws,bs,[0,ws,-1],ks,1,ks,[0,Es,-1,gs,ls,-1],ws,[0,ps,ws,-1],_s,ps,cs,ws,-1,Cs,$s,us,ks,Is,gs,cs,-1,[0,Is,-1],ws,_s,ws,ms,ws,-1,is,1,is,bh,_s,[0,Is,[0,ss,ps,-2],[0,ss]],[0,Is,cs]],us,Ss,ws,-1,us,Is,-1,[0,_s,-1,Is,_s],[0,cs,-1,ws],[0,us,_s,cs],cs,1,Ls,1,bh]),Ch=class{constructor(t){this.h=[],this.m=new Ah,this.j=t??"",this.g=setInterval(()=>{this.flush()},6e4)}close(){void 0!==this.g&&(clearInterval(this.g),this.g=void 0),this.flush()}flush(t,e){if(this.error)e?.("net-send-failed");else if(0===this.h.length)t?.();else{var r=this.h;this.h=[],r=function(t){var e=new Ih;return Nr(e=hr(e,2,re(1786)),3,t)}(r),r=Fh(r),this.m.send({url:"https://odml.pa.googleapis.com/v1/log",bb:"POST",la:1e4,body:r,hb:2,ab:{"Content-Type":"application/x-protobuf","x-goog-api-key":this.j},withCredentials:!1},()=>{t?.()},t=>{this.error=Error(`Logging failed with HTTP error: ${t}`),this.h=[],void 0!==this.g&&(clearInterval(this.g),this.g=void 0),e?.("net-send-failed",t)})}}};class Nh{constructor(){this.aa=this.U=this.X=this.R=this.V=this.T=this.P=0}}function Mh(t,e){var r=new Eh;r=Fr(r,0,1,t.B),r=Fr(r,0,2,e),e=hr(e=new wh,6,lt(r=r.g(),!1)),(t=t.l).error||t.h.push(e)}function Oh(t,e){var r={P:e.P-t.j.P,T:e.T-t.j.T,V:e.V-t.j.V,R:e.R-t.j.R,X:e.X-t.j.X,U:e.U,aa:e.aa},n=mh(gh(new vh,t.C),1);r=Dh(t,r),Mh(t,n=Cr(n,4,_h,r)),t.j=e}function Dh(t,e){var r=new lh;return t=jr(t=Gr(t=hr(r,1,re(t.D)),7,e.R),5,e.U),t=jr(t,6,e.aa),e.V>0&&jr(t,4,e.X/e.V),0!==e.P&&(r=Gr(r=uh(3),2,e.P),Or(t,8,ch,r)),0!==e.T&&(e=Gr(r=uh(4),2,e.T),Or(t,8,ch,e)),t}var Ph=class{constructor(t,e,r){this.u=performance.now(),this.m=performance.now(),this.h=new Map,this.o=0,this.g=new Nh,this.j=new Nh,this.l=new Ch(r),this.C=function(t){switch(t){case"AudioClassifier":return 4;case"AudioEmbedder":return 5;case"TextClassifier":return 6;case"TextEmbedder":return 7;case"GestureRecognizer":return 8;case"HandDetector":return 9;case"HandLandmarker":return 10;case"ImageClassifier":return 11;case"ImageEmbedder":return 12;case"ImageSegmenter":return 13;case"ObjectDetector":return 14;case"FaceDetector":return 15;case"FaceLandmarker":return 16;case"InteractiveSegmenter":case"InteractiveSegmenterLegacy":return 18;case"HolisticLandmarker":return 20;case"LlmInference":return 21;case"LanguageDetector":return 22;case"PoseLandmarker":return 23;default:return 0}}(t),this.D=function(t){switch(t){case"IMAGE":return 11;case"VIDEO":return 12;case"LIVE_STREAM":return 13;case"AUDIO_CLIPS":return 14;case"AUDIO_STREAM":return 15;default:return 10}}(e),t=new yh,"undefined"==typeof window?e=0:(e=navigator.userAgent,e=/Android/i.test(e)?1:/iPhone|iPad|iPod/i.test(e)?2:/Windows/i.test(e)?5:/Macintosh/i.test(e)?4:/Linux/i.test(e)?3:0),t=hr(t,1,re(e)),t=hr(t,2,_e("")),t=hr(t,3,_e("")),t=hr(t,4,_e("1.0.1")),t=hr(t,5,_e("")),this.B=hr(t,6,re(4))}ya(){var t=new ph;t=jr(t=hr(t,1,re(this.D)),3,performance.now()-this.u),Mh(this,t=Cr(mh(gh(new vh,this.C),0),3,_h,t)),this.m=performance.now()}za(t){var e=this.h.get(t);if(void 0!==e&&(this.h.delete(t),t=performance.now()-e,++this.g.V,this.g.X+=t,this.g.U=Math.max(this.g.U,t),this.o=Math.max(this.o,t),performance.now()>this.m+3e4)){for(let[r,n]of this.h.entries())t=r,n=1&&Number(t[1])>=17))}async function Uh(t){if("function"!=typeof importScripts){let e=document.createElement("script");return e.src=t.toString(),e.crossOrigin="anonymous",new Promise((t,r)=>{e.addEventListener("load",()=>{t()},!1),e.addEventListener("error",t=>{r(t)},!1),document.body.appendChild(e)})}try{importScripts(t.toString())}catch(e){if(!(e instanceof TypeError))throw e;{let e=self.import;e?await e(t.toString()):await import(t.toString())}}}function Bh(t){return void 0!==t.videoWidth?[t.videoWidth,t.videoHeight]:void 0!==t.naturalWidth?[t.naturalWidth,t.naturalHeight]:void 0!==t.displayWidth?[t.displayWidth,t.displayHeight]:[t.width,t.height]}function Gh(t,e,r){t.m||console.error("No wasm multistream support detected: ensure dependency inclusion of :gl_graph_runner_internal_multi_input target"),r(e=t.i.stringToNewUTF8(e)),t.i._free(e)}function jh(t,e,r){if(!t.i.canvas)throw Error("No OpenGL canvas configured.");if(r?t.i._bindTextureToStream(r):t.i._bindTextureToCanvas(),!(r=t.i.canvas.getContext("webgl2")||t.i.canvas.getContext("webgl")))throw Error("Failed to obtain WebGL context from the provided canvas. `getContext()` should only be invoked with `webgl` or `webgl2`.");t.i.gpuOriginForWebTexturesIsBottomLeft&&r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,!0),r.texImage2D(r.TEXTURE_2D,0,r.RGBA,r.RGBA,r.UNSIGNED_BYTE,e),t.i.gpuOriginForWebTexturesIsBottomLeft&&r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,!1);var[n,i]=Bh(e);return!t.j||n===t.i.canvas.width&&i===t.i.canvas.height||(t.i.canvas.width=n,t.i.canvas.height=i),[n,i]}function Vh(t,e,r){t.m||console.error("No wasm multistream support detected: ensure dependency inclusion of :gl_graph_runner_internal_multi_input target");var n=new Uint32Array(e.length);for(let r=0;r>2),r(e);for(let e of n)t.i._free(e);t.i._free(e)}function Hh(t,e,r){t.i.simpleListeners=t.i.simpleListeners||{},t.i.simpleListeners[e]=r}function Kh(t,e,r){var n=[];t.i.simpleListeners=t.i.simpleListeners||{},t.i.simpleListeners[e]=(t,e,i)=>{e?(r(n,i),n=[]):n.push(t)}}var Xh=class{constructor(t,e){this.j=!0,this.i=t,this.g=null,this.h=0,this.m="function"==typeof this.i._addIntToInputStream,void 0!==e?this.i.canvas=e:$h()?this.i.canvas=new OffscreenCanvas(1,1):(console.warn("OffscreenCanvas not supported and GraphRunner constructor glCanvas parameter is undefined. Creating backup canvas."),this.i.canvas=document.createElement("canvas"))}async initializeGraph(t){var e=await(await fetch(t)).arrayBuffer();t=!(t.endsWith(".pbtxt")||t.endsWith(".textproto")),this.setGraph(new Uint8Array(e),t)}setGraphFromString(t){this.setGraph((new TextEncoder).encode(t),!1)}setGraph(t,e){var r=t.length,n=this.i._malloc(r);this.i.HEAPU8.set(t,n),e?this.i._changeBinaryGraph(r,n):this.i._changeTextGraph(r,n),this.i._free(n)}configureAudio(t,e,r,n,i){this.i._configureAudio||console.warn('Attempting to use configureAudio without support for input audio. Is build dep ":gl_graph_runner_audio" missing?'),Gh(this,n||"input_audio",n=>{Gh(this,i=i||"audio_header",i=>{this.i._configureAudio(n,i,t,e??0,r)})})}setAutoResizeCanvas(t){this.j=t}setAutoRenderToScreen(t){this.i._setAutoRenderToScreen(t)}setGpuBufferVerticalFlip(t){this.i.gpuOriginForWebTexturesIsBottomLeft=t}ja(t){Hh(this,"__graph_config__",e=>{t(e)}),Gh(this,"__graph_config__",t=>{this.i._getGraphConfig(t,void 0)}),delete this.i.simpleListeners.__graph_config__}attachErrorListener(t){this.i.errorListener=t}attachEmptyPacketListener(t,e){this.i.emptyPacketListeners=this.i.emptyPacketListeners||{},this.i.emptyPacketListeners[t]=e}addAudioToStream(t,e,r){this.addAudioToStreamWithShape(t,0,0,e,r)}addAudioToStreamWithShape(t,e,r,n,i){var s=4*t.length;this.h!==s&&(this.g&&this.i._free(this.g),this.g=this.i._malloc(s),this.h=s),this.i.HEAPF32.set(t,this.g/4),Gh(this,n,t=>{this.i._addAudioToInputStream(this.g,e,r,t,i)})}addGpuBufferToStream(t,e,r){Gh(this,e,e=>{var[n,i]=jh(this,t,e);this.i._addBoundTextureToStream(e,n,i,r)})}addBoolToStream(t,e,r){Gh(this,e,e=>{this.i._addBoolToInputStream(t,e,r)})}addDoubleToStream(t,e,r){Gh(this,e,e=>{this.i._addDoubleToInputStream(t,e,r)})}addFloatToStream(t,e,r){Gh(this,e,e=>{this.i._addFloatToInputStream(t,e,r)})}addIntToStream(t,e,r){Gh(this,e,e=>{this.i._addIntToInputStream(t,e,r)})}addUintToStream(t,e,r){Gh(this,e,e=>{this.i._addUintToInputStream(t,e,r)})}addStringToStream(t,e,r){Gh(this,e,e=>{Gh(this,t,t=>{this.i._addStringToInputStream(t,e,r)})})}addStringRecordToStream(t,e,r){Gh(this,e,e=>{Vh(this,Object.keys(t),n=>{Vh(this,Object.values(t),i=>{this.i._addFlatHashMapToInputStream(n,i,Object.keys(t).length,e,r)})})})}addProtoToStream(t,e,r,n){Gh(this,r,r=>{Gh(this,e,e=>{var i=this.i._malloc(t.length);this.i.HEAPU8.set(t,i),this.i._addProtoToInputStream(i,t.length,e,r,n),this.i._free(i)})})}addEmptyPacketToStream(t,e){Gh(this,t,t=>{this.i._addEmptyPacketToInputStream(t,e)})}addBoolVectorToStream(t,e,r){Gh(this,e,e=>{var n=this.i._allocateBoolVector(t.length);if(!n)throw Error("Unable to allocate new bool vector on heap.");for(let e of t)this.i._addBoolVectorEntry(n,e);this.i._addBoolVectorToInputStream(n,e,r)})}addDoubleVectorToStream(t,e,r){Gh(this,e,e=>{var n=this.i._allocateDoubleVector(t.length);if(!n)throw Error("Unable to allocate new double vector on heap.");for(let e of t)this.i._addDoubleVectorEntry(n,e);this.i._addDoubleVectorToInputStream(n,e,r)})}addFloatVectorToStream(t,e,r){Gh(this,e,e=>{var n=this.i._allocateFloatVector(t.length);if(!n)throw Error("Unable to allocate new float vector on heap.");for(let e of t)this.i._addFloatVectorEntry(n,e);this.i._addFloatVectorToInputStream(n,e,r)})}addIntVectorToStream(t,e,r){Gh(this,e,e=>{var n=this.i._allocateIntVector(t.length);if(!n)throw Error("Unable to allocate new int vector on heap.");for(let e of t)this.i._addIntVectorEntry(n,e);this.i._addIntVectorToInputStream(n,e,r)})}addUintVectorToStream(t,e,r){Gh(this,e,e=>{var n=this.i._allocateUintVector(t.length);if(!n)throw Error("Unable to allocate new unsigned int vector on heap.");for(let e of t)this.i._addUintVectorEntry(n,e);this.i._addUintVectorToInputStream(n,e,r)})}addStringVectorToStream(t,e,r){Gh(this,e,e=>{var n=this.i._allocateStringVector(t.length);if(!n)throw Error("Unable to allocate new string vector on heap.");for(let e of t)Gh(this,e,t=>{this.i._addStringVectorEntry(n,t)});this.i._addStringVectorToInputStream(n,e,r)})}addBoolToInputSidePacket(t,e){Gh(this,e,e=>{this.i._addBoolToInputSidePacket(t,e)})}addDoubleToInputSidePacket(t,e){Gh(this,e,e=>{this.i._addDoubleToInputSidePacket(t,e)})}addFloatToInputSidePacket(t,e){Gh(this,e,e=>{this.i._addFloatToInputSidePacket(t,e)})}addIntToInputSidePacket(t,e){Gh(this,e,e=>{this.i._addIntToInputSidePacket(t,e)})}addUintToInputSidePacket(t,e){Gh(this,e,e=>{this.i._addUintToInputSidePacket(t,e)})}addStringToInputSidePacket(t,e){Gh(this,e,e=>{Gh(this,t,t=>{this.i._addStringToInputSidePacket(t,e)})})}addProtoToInputSidePacket(t,e,r){Gh(this,r,r=>{Gh(this,e,e=>{var n=this.i._malloc(t.length);this.i.HEAPU8.set(t,n),this.i._addProtoToInputSidePacket(n,t.length,e,r),this.i._free(n)})})}addBoolVectorToInputSidePacket(t,e){Gh(this,e,e=>{var r=this.i._allocateBoolVector(t.length);if(!r)throw Error("Unable to allocate new bool vector on heap.");for(let e of t)this.i._addBoolVectorEntry(r,e);this.i._addBoolVectorToInputSidePacket(r,e)})}addDoubleVectorToInputSidePacket(t,e){Gh(this,e,e=>{var r=this.i._allocateDoubleVector(t.length);if(!r)throw Error("Unable to allocate new double vector on heap.");for(let e of t)this.i._addDoubleVectorEntry(r,e);this.i._addDoubleVectorToInputSidePacket(r,e)})}addFloatVectorToInputSidePacket(t,e){Gh(this,e,e=>{var r=this.i._allocateFloatVector(t.length);if(!r)throw Error("Unable to allocate new float vector on heap.");for(let e of t)this.i._addFloatVectorEntry(r,e);this.i._addFloatVectorToInputSidePacket(r,e)})}addIntVectorToInputSidePacket(t,e){Gh(this,e,e=>{var r=this.i._allocateIntVector(t.length);if(!r)throw Error("Unable to allocate new int vector on heap.");for(let e of t)this.i._addIntVectorEntry(r,e);this.i._addIntVectorToInputSidePacket(r,e)})}addUintVectorToInputSidePacket(t,e){Gh(this,e,e=>{var r=this.i._allocateUintVector(t.length);if(!r)throw Error("Unable to allocate new unsigned int vector on heap.");for(let e of t)this.i._addUintVectorEntry(r,e);this.i._addUintVectorToInputSidePacket(r,e)})}addStringVectorToInputSidePacket(t,e){Gh(this,e,e=>{var r=this.i._allocateStringVector(t.length);if(!r)throw Error("Unable to allocate new string vector on heap.");for(let e of t)Gh(this,e,t=>{this.i._addStringVectorEntry(r,t)});this.i._addStringVectorToInputSidePacket(r,e)})}attachBoolListener(t,e){Hh(this,t,e),Gh(this,t,t=>{this.i._attachBoolListener(t)})}attachBoolVectorListener(t,e){Kh(this,t,e),Gh(this,t,t=>{this.i._attachBoolVectorListener(t)})}attachIntListener(t,e){Hh(this,t,e),Gh(this,t,t=>{this.i._attachIntListener(t)})}attachIntVectorListener(t,e){Kh(this,t,e),Gh(this,t,t=>{this.i._attachIntVectorListener(t)})}attachUintListener(t,e){Hh(this,t,e),Gh(this,t,t=>{this.i._attachUintListener(t)})}attachUintVectorListener(t,e){Kh(this,t,e),Gh(this,t,t=>{this.i._attachUintVectorListener(t)})}attachDoubleListener(t,e){Hh(this,t,e),Gh(this,t,t=>{this.i._attachDoubleListener(t)})}attachDoubleVectorListener(t,e){Kh(this,t,e),Gh(this,t,t=>{this.i._attachDoubleVectorListener(t)})}attachFloatListener(t,e){Hh(this,t,e),Gh(this,t,t=>{this.i._attachFloatListener(t)})}attachFloatVectorListener(t,e){Kh(this,t,e),Gh(this,t,t=>{this.i._attachFloatVectorListener(t)})}attachStringListener(t,e){Hh(this,t,e),Gh(this,t,t=>{this.i._attachStringListener(t)})}attachStringVectorListener(t,e){Kh(this,t,e),Gh(this,t,t=>{this.i._attachStringVectorListener(t)})}attachProtoListener(t,e,r){Hh(this,t,e),Gh(this,t,t=>{this.i._attachProtoListener(t,r||!1)})}attachProtoVectorListener(t,e,r){Kh(this,t,e),Gh(this,t,t=>{this.i._attachProtoVectorListener(t,r||!1)})}attachAudioListener(t,e,r){this.i._attachAudioListener||console.warn('Attempting to use attachAudioListener without support for output audio. Is build dep ":gl_graph_runner_audio_out" missing?'),Hh(this,t,(t,r)=>{t=new Float32Array(t.buffer,t.byteOffset,t.length/4),e(t,r)}),Gh(this,t,t=>{this.i._attachAudioListener(t,r||!1)})}finishProcessing(){this.i._waitUntilIdle()}closeGraph(){this.i._closeGraph(),this.i.simpleListeners=void 0,this.i.emptyPacketListeners=void 0}};function Wh(t){return class extends t{get pa(){return this.i}Sa(){if("function"==typeof this.pa._mediapipeLoggerGetEncodedApiKey){let t=this.pa._mediapipeLoggerGetEncodedApiKey();return this.pa._decodeBase64(t)}}}}function zh(t){return class extends t{Za(){this.i._registerModelResourcesGraphService()}}}var Yh=Wh(zh(Xh)),qh=class extends Yh{};async function Jh(t,e,r,n){return t=await(async(t,e,r,n,i)=>{if(e&&await Uh(e),!self.ModuleFactory)throw Error("ModuleFactory not set.");if(r&&(await Uh(r),!self.ModuleFactory))throw Error("ModuleFactory not set.");return self.Module&&i&&((e=self.Module).locateFile=i.locateFile,i.mainScriptUrlOrBlob&&(e.mainScriptUrlOrBlob=i.mainScriptUrlOrBlob)),i=await self.ModuleFactory(self.Module||i),self.ModuleFactory=self.Module=void 0,new t(i,n)})(t,r.wasmLoaderPath,r.assetLoaderPath,e,{locateFile:t=>t.endsWith(".wasm")?r.wasmBinaryPath.toString():r.assetBinaryPath&&t.endsWith(".data")?r.assetBinaryPath.toString():t}),function(t,e){e=e.runningMode??"";var r=t.g.Sa();t.m=new Ph(t.C(),e,r)}(t,n),await t.v(n),t}async function Zh(t,e,r,n){return Jh(t,e,r,n)}function Qh(t,e){var r=Lr(t.baseOptions,zo,1)||new zo;"string"==typeof e?(hr(r,2,_e(e)),hr(r,1)):e instanceof Uint8Array&&(hr(r,1,lt(e,!1)),hr(r,2)),Fr(t.baseOptions,0,1,r)}function tu(t){try{let e=t.K.length;if(1===e)throw Error(t.K[0].message);if(e>1)throw Error("Encountered multiple errors: "+t.K.map(t=>t.message).join(", "))}finally{t.K=[]}}function eu(t,e){t.I=Math.max(t.I,e)}function ru(t,e){t.D=new uo,Kr(t.D,2,"PassThroughCalculator"),ao(t.D,"free_memory"),ho(t.D,"free_memory_unused_out"),go(e,"free_memory"),po(e,t.D)}function nu(t,e){ao(t.D,e),ho(t.D,e+"_unused_out")}function iu(t){t.g.addBoolToStream(!0,"free_memory",t.I)}var su=class{constructor(t){this.g=t,this.K=[],this.I=0,this.g.setAutoRenderToScreen(!1)}j(t,e=!0){if(e){let e=t.baseOptions||{};if(t.baseOptions?.modelAssetBuffer&&t.baseOptions?.modelAssetPath)throw Error("Cannot set both baseOptions.modelAssetPath and baseOptions.modelAssetBuffer");if(!(Lr(this.baseOptions,zo,1)?.g()||Lr(this.baseOptions,zo,1)?.j()||t.baseOptions?.modelAssetBuffer||t.baseOptions?.modelAssetPath))throw Error("Either baseOptions.modelAssetPath or baseOptions.modelAssetBuffer must be set");if(function(t,e){var r=Lr(t.baseOptions,Xo,3);if(!r){var n=r=new Xo,i=new to;Cr(n,4,Wo,i)}"delegate"in e&&("GPU"===e.delegate?(e=r,n=new qs,Cr(e,2,Wo,n)):(e=r,n=new to,Cr(e,4,Wo,n))),Fr(t.baseOptions,0,3,r)}(this,e),e.modelAssetPath)return fetch(e.modelAssetPath.toString()).then(t=>{if(t.ok)return t.arrayBuffer();throw Error(`Failed to fetch model: ${e.modelAssetPath} (${t.status})`)}).then(t=>{try{this.g.i.FS_unlink("/model.dat")}catch{}this.g.i.FS_createDataFile("/","model.dat",new Uint8Array(t),!0,!1,!1),Qh(this,"/model.dat"),this.o(),this.L()});if(e.modelAssetBuffer instanceof Uint8Array)Qh(this,e.modelAssetBuffer);else if(e.modelAssetBuffer)return async function(t){for(var e=[],r=0;;){let{done:n,value:i}=await t.read();if(n)break;e.push(i),r+=i.length}if(0===e.length)return new Uint8Array(0);if(1===e.length)return e[0];t=new Uint8Array(r),r=0;for(let n of e)t.set(n,r),r+=n.length;return t}(e.modelAssetBuffer).then(t=>{Qh(this,t),this.o(),this.L()})}return this.o(),this.L(),Promise.resolve()}L(){}ja(){var t;if(this.g.ja(e=>{t=yo(e)}),!t)throw Error("Failed to retrieve CalculatorGraphConfig");return t}setGraph(t,e){this.g.attachErrorListener((t,e)=>{this.K.push(Error(e))}),this.g.Za(),this.g.setGraph(t,e),this.m?.ya(),this.D=void 0,tu(this)}finishProcessing(t){this.g.finishProcessing(),tu(this),this.m&&void 0!==t&&this.m.za(t)}close(){this.D=void 0,this.m?.xa(),this.m?.close(),this.g.closeGraph()}};function ou(t,e){if(!t)throw Error(`Unable to obtain required WebGL resource: ${e}`);return t}su.prototype.close=su.prototype.close;class au{constructor(t,e,r,n){this.g=t,this.h=e,this.m=r,this.j=n}bind(){this.g.bindVertexArray(this.h)}close(){this.g.deleteVertexArray(this.h),this.g.deleteBuffer(this.m),this.g.deleteBuffer(this.j)}}function hu(t,e,r){var n=t.g;if(r=ou(n.createShader(r),"Failed to create WebGL shader"),n.shaderSource(r,e),n.compileShader(r),!n.getShaderParameter(r,n.COMPILE_STATUS))throw Error(`Could not compile WebGL shader: ${n.getShaderInfoLog(r)}`);return n.attachShader(t.h,r),r}function uu(t,e){var r=t.g,n=ou(r.createVertexArray(),"Failed to create vertex array");r.bindVertexArray(n);var i=ou(r.createBuffer(),"Failed to create buffer");r.bindBuffer(r.ARRAY_BUFFER,i),r.enableVertexAttribArray(t.F),r.vertexAttribPointer(t.F,2,r.FLOAT,!1,0,0),r.bufferData(r.ARRAY_BUFFER,new Float32Array([-1,-1,-1,1,1,1,1,-1]),r.STATIC_DRAW);var s=ou(r.createBuffer(),"Failed to create buffer");return r.bindBuffer(r.ARRAY_BUFFER,s),r.enableVertexAttribArray(t.K),r.vertexAttribPointer(t.K,2,r.FLOAT,!1,0,0),r.bufferData(r.ARRAY_BUFFER,new Float32Array(e?[0,1,0,0,1,0,1,1]:[0,0,0,1,1,1,1,0]),r.STATIC_DRAW),r.bindBuffer(r.ARRAY_BUFFER,null),r.bindVertexArray(null),new au(r,n,i,s)}function cu(t,e){if(t.g){if(e!==t.g)throw Error("Cannot change GL context once initialized")}else t.g=e}function lu(t,e,r,n){return cu(t,e),t.h||(t.m(),t.I()),r?(t.l||(t.l=uu(t,!0)),r=t.l):(t.D||(t.D=uu(t,!1)),r=t.D),e.useProgram(t.h),r.bind(),t.j(),t=n(),r.g.bindVertexArray(null),t}function du(t,e,r){return cu(t,e),t=ou(e.createTexture(),"Failed to create texture"),e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,r??e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,r??e.LINEAR),e.bindTexture(e.TEXTURE_2D,null),t}function fu(t,e,r){cu(t,e),t.C||(t.C=ou(e.createFramebuffer(),"Failed to create framebuffe.")),e.bindFramebuffer(e.FRAMEBUFFER,t.C),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,r,0)}function pu(t){t.g?.bindFramebuffer(t.g.FRAMEBUFFER,null)}var gu=class{B(){return"\n precision mediump float;\n varying vec2 vTex;\n uniform sampler2D inputTexture;\n void main() {\n gl_FragColor = texture2D(inputTexture, vTex);\n }\n "}m(){var t=this.g;if(this.h=ou(t.createProgram(),"Failed to create WebGL program"),this.da=hu(this,"\n attribute vec2 aVertex;\n attribute vec2 aTex;\n varying vec2 vTex;\n void main(void) {\n gl_Position = vec4(aVertex, 0.0, 1.0);\n vTex = aTex;\n }",t.VERTEX_SHADER),this.Z=hu(this,this.B(),t.FRAGMENT_SHADER),t.linkProgram(this.h),!t.getProgramParameter(this.h,t.LINK_STATUS))throw Error(`Error during program linking: ${t.getProgramInfoLog(this.h)}`);this.F=t.getAttribLocation(this.h,"aVertex"),this.K=t.getAttribLocation(this.h,"aTex")}I(){}j(){}close(){if(this.h){let t=this.g;t.deleteProgram(this.h),t.deleteShader(this.da),t.deleteShader(this.Z)}this.C&&this.g.deleteFramebuffer(this.C),this.D&&this.D.close(),this.l&&this.l.close()}};var mu=class extends gu{B(){return"\n precision mediump float;\n uniform sampler2D backgroundTexture;\n uniform sampler2D maskTexture;\n uniform sampler2D colorMappingTexture;\n varying vec2 vTex;\n void main() {\n vec4 backgroundColor = texture2D(backgroundTexture, vTex);\n float category = texture2D(maskTexture, vTex).r;\n vec4 categoryColor = texture2D(colorMappingTexture, vec2(category, 0.0));\n gl_FragColor = mix(backgroundColor, categoryColor, categoryColor.a);\n }\n "}I(){var t=this.g;t.activeTexture(t.TEXTURE1),this.u=du(this,t,t.LINEAR),t.activeTexture(t.TEXTURE2),this.o=du(this,t,t.NEAREST)}m(){super.m();var t=this.g;this.O=ou(t.getUniformLocation(this.h,"backgroundTexture"),"Uniform location"),this.Y=ou(t.getUniformLocation(this.h,"colorMappingTexture"),"Uniform location"),this.L=ou(t.getUniformLocation(this.h,"maskTexture"),"Uniform location")}j(){super.j();var t=this.g;t.uniform1i(this.L,0),t.uniform1i(this.O,1),t.uniform1i(this.Y,2)}close(){this.u&&this.g.deleteTexture(this.u),this.o&&this.g.deleteTexture(this.o),super.close()}},vu=class extends gu{B(){return"\n precision mediump float;\n uniform sampler2D maskTexture;\n uniform sampler2D defaultTexture;\n uniform sampler2D overlayTexture;\n varying vec2 vTex;\n void main() {\n float confidence = texture2D(maskTexture, vTex).r;\n vec4 defaultColor = texture2D(defaultTexture, vTex);\n vec4 overlayColor = texture2D(overlayTexture, vTex);\n // Apply the alpha from the overlay and merge in the default color\n overlayColor = mix(defaultColor, overlayColor, overlayColor.a);\n gl_FragColor = mix(defaultColor, overlayColor, confidence);\n }\n "}I(){var t=this.g;t.activeTexture(t.TEXTURE1),this.o=du(this,t),t.activeTexture(t.TEXTURE2),this.u=du(this,t)}m(){super.m();var t=this.g;this.L=ou(t.getUniformLocation(this.h,"defaultTexture"),"Uniform location"),this.O=ou(t.getUniformLocation(this.h,"overlayTexture"),"Uniform location"),this.J=ou(t.getUniformLocation(this.h,"maskTexture"),"Uniform location")}j(){super.j();var t=this.g;t.uniform1i(this.J,0),t.uniform1i(this.L,1),t.uniform1i(this.O,2)}close(){this.o&&this.g.deleteTexture(this.o),this.u&&this.g.deleteTexture(this.u),super.close()}};function _u(t,e){switch(e){case 0:return t.g.find(t=>t instanceof Uint8Array);case 1:return t.g.find(t=>t instanceof Float32Array);case 2:return t.g.find(t=>"undefined"!=typeof WebGLTexture&&t instanceof WebGLTexture);default:throw Error(`Type is not supported: ${e}`)}}function yu(t){var e=_u(t,1);if(!e){if(e=_u(t,0))e=new Float32Array(e).map(t=>t/255);else{e=new Float32Array(t.width*t.height);let n=Au(t);var r=bu(t);if(fu(r,n,Eu(t)),"iPad Simulator;iPhone Simulator;iPod Simulator;iPad;iPhone;iPod".split(";").includes(navigator.platform)||navigator.userAgent.includes("Mac")&&"document"in self&&"ontouchend"in self.document){r=new Float32Array(t.width*t.height*4),n.readPixels(0,0,t.width,t.height,n.RGBA,n.FLOAT,r);for(let t=0,n=0;tMath.round(255*t))),t.g.push(e)),e;var t,e}sa(){return yu(this)}S(){return Eu(this)}clone(){var t=[];for(let e of this.g){let r;if(e instanceof Uint8Array)r=new Uint8Array(e);else if(e instanceof Float32Array)r=new Float32Array(e);else{if(!(e instanceof WebGLTexture))throw Error(`Type is not supported: ${e}`);{let t=Au(this),e=bu(this);t.activeTexture(t.TEXTURE1),r=du(e,t,this.m?t.LINEAR:t.NEAREST),t.bindTexture(t.TEXTURE_2D,r);let n=wu(this);t.texImage2D(t.TEXTURE_2D,0,n,this.width,this.height,0,t.RED,t.FLOAT,null),t.bindTexture(t.TEXTURE_2D,null),fu(e,t,r),lu(e,t,!1,()=>{Tu(this),t.clearColor(0,0,0,0),t.clear(t.COLOR_BUFFER_BIT),t.drawArrays(t.TRIANGLE_FAN,0,4),ku(this)}),pu(e),ku(this)}}t.push(r)}return new Lu(t,this.m,this.W(),this.canvas,this.j,this.width,this.height)}close(){this.o&&Au(this).deleteTexture(_u(this,2)),xu=-1}};Lu.prototype.close=Lu.prototype.close,Lu.prototype.clone=Lu.prototype.clone,Lu.prototype.getAsWebGLTexture=Lu.prototype.S,Lu.prototype.getAsFloat32Array=Lu.prototype.sa,Lu.prototype.getAsUint8Array=Lu.prototype.ta,Lu.prototype.hasWebGLTexture=Lu.prototype.W,Lu.prototype.hasFloat32Array=Lu.prototype.ua,Lu.prototype.hasUint8Array=Lu.prototype.Ua;var xu=250,Ru={color:"white",lineWidth:4,radius:6};function Iu(t){return{...Ru,fillColor:(t=t||{}).color,...t}}function Fu(t,e){return t instanceof Function?t(e):t}function Cu(t,e,r){return Math.max(Math.min(e,r),Math.min(Math.max(e,r),t))}function Nu(t){if(!t.j)throw Error("CPU rendering requested but CanvasRenderingContext2D not provided.");return t.j}function Mu(t){if(!t.o)throw Error("GPU rendering requested but WebGL2RenderingContext not provided.");return t.o}function Ou(t,e,r){if(e.W())r(e.S());else{let n=e.ua()?e.sa():e.ta();t.m=t.m??new gu;let i=Mu(t);r((t=new Lu([n],e.m,!1,i.canvas,t.m,e.width,e.height)).S()),t.close()}}function Du(t,e,r,n){var i=function(t){return t.g||(t.g=new mu),t.g}(t),s=Mu(t),o=Array.isArray(r)?new ImageData(new Uint8ClampedArray(r),1,1):r;lu(i,s,!0,()=>{!function(t,e,r,n){var i=t.g;if(i.activeTexture(i.TEXTURE0),i.bindTexture(i.TEXTURE_2D,e),i.activeTexture(i.TEXTURE1),i.bindTexture(i.TEXTURE_2D,t.u),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,i.RGBA,i.UNSIGNED_BYTE,r),t.J&&function(t,e){if(t!==e)return!1;t=t.entries(),e=e.entries();for(let[r,n]of t){t=r;let i=n,s=e.next();if(s.done)return!1;let[o,a]=s.value;if(t!==o||i[0]!==a[0]||i[1]!==a[1]||i[2]!==a[2]||i[3]!==a[3])return!1}return!!e.next().done}(t.J,n))i.activeTexture(i.TEXTURE2),i.bindTexture(i.TEXTURE_2D,t.o);else{t.J=n;let e=Array(1024).fill(0);n.forEach((t,r)=>{if(4!==t.length)throw Error(`Color at index ${r} is not a four-channel value.`);e[4*r]=t[0],e[4*r+1]=t[1],e[4*r+2]=t[2],e[4*r+3]=t[3]}),i.activeTexture(i.TEXTURE2),i.bindTexture(i.TEXTURE_2D,t.o),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,256,1,0,i.RGBA,i.UNSIGNED_BYTE,new Uint8Array(e))}}(i,e,o,n),s.clearColor(0,0,0,0),s.clear(s.COLOR_BUFFER_BIT),s.drawArrays(s.TRIANGLE_FAN,0,4);var t=i.g;t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,null),t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,null),t.activeTexture(t.TEXTURE2),t.bindTexture(t.TEXTURE_2D,null)})}function Pu(t,e,r,n){var i=Mu(t),s=function(t){return t.h||(t.h=new vu),t.h}(t),o=Array.isArray(r)?new ImageData(new Uint8ClampedArray(r),1,1):r,a=Array.isArray(n)?new ImageData(new Uint8ClampedArray(n),1,1):n;lu(s,i,!0,()=>{var t=s.g;t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,e),t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,s.o),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,o),t.activeTexture(t.TEXTURE2),t.bindTexture(t.TEXTURE_2D,s.u),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,a),i.clearColor(0,0,0,0),i.clear(i.COLOR_BUFFER_BIT),i.drawArrays(i.TRIANGLE_FAN,0,4),i.bindTexture(i.TEXTURE_2D,null),(t=s.g).activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,null),t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,null),t.activeTexture(t.TEXTURE2),t.bindTexture(t.TEXTURE_2D,null)})}var $u=class{constructor(t,e){"undefined"!=typeof CanvasRenderingContext2D&&t instanceof CanvasRenderingContext2D||t instanceof OffscreenCanvasRenderingContext2D?(this.j=t,this.o=e):this.o=t}Ma(t,e){if(t){var r=Nu(this);e=Iu(e),r.save();var n=r.canvas,i=0;for(let s of t)r.fillStyle=Fu(e.fillColor,{index:i,from:s}),r.strokeStyle=Fu(e.color,{index:i,from:s}),r.lineWidth=Fu(e.lineWidth,{index:i,from:s}),(t=new Path2D).arc(s.x*n.width,s.y*n.height,Fu(e.radius,{index:i,from:s}),0,2*Math.PI),r.fill(t),r.stroke(t),++i;r.restore()}}La(t,e,r){if(t&&e){var n=Nu(this);r=Iu(r),n.save();var i=n.canvas,s=0;for(let o of e){n.beginPath(),e=t[o.start];let a=t[o.end];e&&a&&(n.strokeStyle=Fu(r.color,{index:s,from:e,to:a}),n.lineWidth=Fu(r.lineWidth,{index:s,from:e,to:a}),n.moveTo(e.x*i.width,e.y*i.height),n.lineTo(a.x*i.width,a.y*i.height)),++s,n.stroke()}n.restore()}}Ia(t,e){var r=Nu(this);e=Iu(e),r.save(),r.beginPath(),r.lineWidth=Fu(e.lineWidth,{}),r.strokeStyle=Fu(e.color,{}),r.fillStyle=Fu(e.fillColor,{}),r.moveTo(t.originX,t.originY),r.lineTo(t.originX+t.width,t.originY),r.lineTo(t.originX+t.width,t.originY+t.height),r.lineTo(t.originX,t.originY+t.height),r.lineTo(t.originX,t.originY),r.stroke(),r.fill(),r.restore()}Ja(t,e,r=[0,0,0,255]){this.j?function(t,e,r,n){var i=Mu(t);Ou(t,e,e=>{Du(t,e,r,n),(e=Nu(t)).drawImage(i.canvas,0,0,e.canvas.width,e.canvas.height)})}(this,t,r,e):Du(this,t.S(),r,e)}Ka(t,e,r){this.j?function(t,e,r,n){var i=Mu(t);Ou(t,e,e=>{Pu(t,e,r,n),(e=Nu(t)).drawImage(i.canvas,0,0,e.canvas.width,e.canvas.height)})}(this,t,e,r):Pu(this,t.S(),e,r)}close(){this.g?.close(),this.g=void 0,this.h?.close(),this.h=void 0,this.m?.close(),this.m=void 0}};function Uu(t,e){switch(e){case 0:return t.g.find(t=>t instanceof ImageData);case 1:return t.g.find(t=>"undefined"!=typeof ImageBitmap&&t instanceof ImageBitmap);case 2:return t.g.find(t=>"undefined"!=typeof WebGLTexture&&t instanceof WebGLTexture);default:throw Error(`Type is not supported: ${e}`)}}function Bu(t){var e=Uu(t,0);if(!e){e=ju(t);let r=Vu(t),n=new Uint8Array(t.width*t.height*4);fu(r,e,Gu(t)),e.readPixels(0,0,t.width,t.height,e.RGBA,e.UNSIGNED_BYTE,n),pu(r),e=new ImageData(new Uint8ClampedArray(n.buffer),t.width,t.height),t.g.push(e)}return e}function Gu(t){var e=Uu(t,2);if(!e){let r=ju(t);e=Hu(t);let n=Uu(t,1)||Bu(t);r.texImage2D(r.TEXTURE_2D,0,r.RGBA,r.RGBA,r.UNSIGNED_BYTE,n),Ku(t)}return e}function ju(t){if(!t.canvas)throw Error("Conversion to different image formats require that a canvas is passed when initializing the image.");return t.h||(t.h=ou(t.canvas.getContext("webgl2"),"You cannot use a canvas that is already bound to a different type of rendering context.")),t.h}function Vu(t){return t.j||(t.j=new gu),t.j}function Hu(t){var e=ju(t);e.viewport(0,0,t.width,t.height),e.activeTexture(e.TEXTURE0);var r=Uu(t,2);return r||(r=du(Vu(t),e),t.g.push(r),t.m=!0),e.bindTexture(e.TEXTURE_2D,r),r}function Ku(t){t.h.bindTexture(t.h.TEXTURE_2D,null)}function Xu(t){var e=ju(t);return lu(Vu(t),e,!0,()=>function(t,e){var r=t.canvas;if(r.width===t.width&&r.height===t.height)return e();var n=r.width,i=r.height;return r.width=t.width,r.height=t.height,t=e(),r.width=n,r.height=i,t}(t,()=>{if(e.bindFramebuffer(e.FRAMEBUFFER,null),e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT),e.drawArrays(e.TRIANGLE_FAN,0,4),!(t.canvas instanceof OffscreenCanvas))throw Error("Conversion to ImageBitmap requires that the MediaPipe Tasks is initialized with an OffscreenCanvas");return t.canvas.transferToImageBitmap()}))}$u.prototype.close=$u.prototype.close,$u.prototype.drawConfidenceMask=$u.prototype.Ka,$u.prototype.drawCategoryMask=$u.prototype.Ja,$u.prototype.drawBoundingBox=$u.prototype.Ia,$u.prototype.drawConnectors=$u.prototype.La,$u.prototype.drawLandmarks=$u.prototype.Ma,$u.lerp=function(t,e,r,n,i){return Cu(n*(1-(t-e)/(r-e))+i*(1-(r-t)/(r-e)),n,i)},$u.clamp=Cu;var Wu=class{constructor(t,e,r,n,i,s,o){this.g=t,this.o=e,this.m=r,this.canvas=n,this.j=i,this.width=s,this.height=o,(this.o||this.m)&&(0===--zu&&console.error("You seem to be creating MPImage instances without invoking .close(). This leaks resources."))}Ta(){return!!Uu(this,0)}va(){return!!Uu(this,1)}W(){return!!Uu(this,2)}Qa(){return Bu(this)}Pa(){var t=Uu(this,1);return t||(Gu(this),Hu(this),t=Xu(this),Ku(this),this.g.push(t),this.o=!0),t}S(){return Gu(this)}clone(){var t=[];for(let e of this.g){let r;if(e instanceof ImageData)r=new ImageData(e.data,this.width,this.height);else if(e instanceof WebGLTexture){let t=ju(this),e=Vu(this);t.activeTexture(t.TEXTURE1),r=du(e,t),t.bindTexture(t.TEXTURE_2D,r),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.width,this.height,0,t.RGBA,t.UNSIGNED_BYTE,null),t.bindTexture(t.TEXTURE_2D,null),fu(e,t,r),lu(e,t,!1,()=>{Hu(this),t.clearColor(0,0,0,0),t.clear(t.COLOR_BUFFER_BIT),t.drawArrays(t.TRIANGLE_FAN,0,4),Ku(this)}),pu(e),Ku(this)}else{if(!(e instanceof ImageBitmap))throw Error(`Type is not supported: ${e}`);Gu(this),Hu(this),r=Xu(this),Ku(this)}t.push(r)}return new Wu(t,this.va(),this.W(),this.canvas,this.j,this.width,this.height)}close(){this.o&&Uu(this,1).close(),this.m&&ju(this).deleteTexture(Uu(this,2)),zu=-1}};Wu.prototype.close=Wu.prototype.close,Wu.prototype.clone=Wu.prototype.clone,Wu.prototype.getAsWebGLTexture=Wu.prototype.S,Wu.prototype.getAsImageBitmap=Wu.prototype.Pa,Wu.prototype.getAsImageData=Wu.prototype.Qa,Wu.prototype.hasWebGLTexture=Wu.prototype.W,Wu.prototype.hasImageBitmap=Wu.prototype.va,Wu.prototype.hasImageData=Wu.prototype.Ta;var zu=250;function Yu(...t){return t.map(([t,e])=>({start:t,end:e}))}var qu,Ju=zh((qu=Wh(Xh),class extends qu{get oa(){return this.i}Da(t,e,r){Gh(this,e,e=>{var[n,i]=jh(this,t,e);this.oa._addBoundTextureAsImageToStream(e,n,i,r)})}ga(t,e){Hh(this,t,e),Gh(this,t,t=>{this.oa._attachImageListener(t)})}ha(t,e){Kh(this,t,e),Gh(this,t,t=>{this.oa._attachImageVectorListener(t)})}})),Zu=class extends Ju{};async function Qu(t,e,r){return Zh(t,r.canvas??($h()?void 0:document.createElement("canvas")),e,r)}function tc(t,e,r,n){if(t.m&&void 0!==n)if(Lr(t.baseOptions,Xo,3)?.g()){var i=t.m;++i.g.T,i.h.set(n,performance.now())}else++(i=t.m).g.P,i.h.set(n,performance.now());if(t.qa){if(i=new Mo,r?.regionOfInterest){if(!t.Ca)throw Error("This task doesn't support region-of-interest.");var s=r.regionOfInterest;if(s.left>=s.right||s.top>=s.bottom)throw Error("Expected RectF with left < right and top < bottom.");if(s.left<0||s.top<0||s.right>1||s.bottom>1)throw Error("Expected RectF values to be in [0,1].");Vr(i,1,(s.left+s.right)/2),Vr(i,2,(s.top+s.bottom)/2),Vr(i,4,s.right-s.left),Vr(i,3,s.bottom-s.top)}else Vr(i,1,.5),Vr(i,2,.5),Vr(i,4,1),Vr(i,3,1);if(r?.rotationDegrees){if(r?.rotationDegrees%90!=0)throw Error("Expected rotation to be a multiple of 90°.");if(Vr(i,5,-Math.PI*r.rotationDegrees/180),r?.rotationDegrees%180!=0){let[t,n]=Bh(e);r=Pr(i,3)*n/t,s=Pr(i,4)*t/n,Vr(i,4,r),Vr(i,3,s)}}t.g.addProtoToStream(i.g(),"mediapipe.NormalizedRect",t.qa,n)}t.g.Da(e,t.Ba,n??performance.now()),t.finishProcessing(n)}function ec(t,e,r){if(t.J)throw Error("Task is not initialized with image mode. 'runningMode' must be set to 'IMAGE'.");tc(t,e,r,t.I+1)}function rc(t,e,r,n){if(!t.J)throw Error("Task is not initialized with video mode. 'runningMode' must be set to 'VIDEO'.");tc(t,e,r,n)}function nc(t,e,r,n){var i=e.data,s=e.width,o=s*(e=e.height);if((i instanceof Uint8Array||i instanceof Float32Array)&&i.length!==o)throw Error("Unsupported channel count: "+i.length/o);return t=new Lu([i],r,!1,t.g.i.canvas,t.da,s,e),n?t.clone():t}var ic=class extends su{constructor(t,e,r,n){super(t),this.g=t,this.Ba=e,this.qa=r,this.Ca=n,this.da=new gu,this.J=!1}j(t,e=!0){if("runningMode"in t){var r=this.J=!!t.runningMode&&"IMAGE"!==t.runningMode;hr(this.baseOptions,2,null==r?r:Qt(r))}if(void 0!==t.canvas&&this.g.i.canvas!==t.canvas)throw Error("You must create a new task to reset the canvas.");return super.j(t,e)}close(){this.da.close(),super.close()}};ic.prototype.close=ic.prototype.close;var sc=class extends ic{constructor(t,e){super(new Zu(t,e),"image_in","norm_rect_in",!1),this.l={detections:[]},Fr(t=this.h=new Qo,0,1,e=new Yo),Vr(this.h,2,.5),Vr(this.h,3,.3)}C(){return"FaceDetector"}get baseOptions(){return Lr(this.h,Yo,1)}set baseOptions(t){Fr(this.h,0,1,t)}v(t){return"minDetectionConfidence"in t&&Vr(this.h,2,t.minDetectionConfidence??.5),"minSuppressionThreshold"in t&&Vr(this.h,3,t.minSuppressionThreshold??.3),this.j(t)}G(t,e){return this.l={detections:[]},ec(this,t,e),this.l}H(t,e,r){return this.l={detections:[]},rc(this,t,r,e),this.l}o(){var t=new vo;go(t,"image_in"),go(t,"norm_rect_in"),mo(t,"detections");var e=new io;di(e,ea,this.h);var r=new uo;Kr(r,2,"mediapipe.tasks.vision.face_detector.FaceDetectorGraph"),ao(r,"IMAGE:image_in"),ao(r,"NORM_RECT:norm_rect_in"),ho(r,"DETECTIONS:detections"),r.v(e),po(t,r),this.g.attachProtoVectorListener("detections",(t,e)=>{for(let e of t)t=Lo(e),this.l.detections.push(Qa(t));eu(this,e)}),this.g.attachEmptyPacketListener("detections",t=>{eu(this,t)}),t=t.g(),this.setGraph(new Uint8Array(t),!0)}};sc.prototype.detectForVideo=sc.prototype.H,sc.prototype.detect=sc.prototype.G,sc.prototype.setOptions=sc.prototype.v,sc.createFromModelPath=async function(t,e){return Qu(sc,t,{baseOptions:{modelAssetPath:e}})},sc.createFromModelBuffer=function(t,e){return Qu(sc,t,{baseOptions:{modelAssetBuffer:e}})},sc.createFromOptions=function(t,e){return Qu(sc,t,e)};var oc=Yu([61,146],[146,91],[91,181],[181,84],[84,17],[17,314],[314,405],[405,321],[321,375],[375,291],[61,185],[185,40],[40,39],[39,37],[37,0],[0,267],[267,269],[269,270],[270,409],[409,291],[78,95],[95,88],[88,178],[178,87],[87,14],[14,317],[317,402],[402,318],[318,324],[324,308],[78,191],[191,80],[80,81],[81,82],[82,13],[13,312],[312,311],[311,310],[310,415],[415,308]),ac=Yu([263,249],[249,390],[390,373],[373,374],[374,380],[380,381],[381,382],[382,362],[263,466],[466,388],[388,387],[387,386],[386,385],[385,384],[384,398],[398,362]),hc=Yu([276,283],[283,282],[282,295],[295,285],[300,293],[293,334],[334,296],[296,336]),uc=Yu([474,475],[475,476],[476,477],[477,474]),cc=Yu([33,7],[7,163],[163,144],[144,145],[145,153],[153,154],[154,155],[155,133],[33,246],[246,161],[161,160],[160,159],[159,158],[158,157],[157,173],[173,133]),lc=Yu([46,53],[53,52],[52,65],[65,55],[70,63],[63,105],[105,66],[66,107]),dc=Yu([469,470],[470,471],[471,472],[472,469]),fc=Yu([10,338],[338,297],[297,332],[332,284],[284,251],[251,389],[389,356],[356,454],[454,323],[323,361],[361,288],[288,397],[397,365],[365,379],[379,378],[378,400],[400,377],[377,152],[152,148],[148,176],[176,149],[149,150],[150,136],[136,172],[172,58],[58,132],[132,93],[93,234],[234,127],[127,162],[162,21],[21,54],[54,103],[103,67],[67,109],[109,10]),pc=[...oc,...ac,...hc,...cc,...lc,...fc],gc=Yu([127,34],[34,139],[139,127],[11,0],[0,37],[37,11],[232,231],[231,120],[120,232],[72,37],[37,39],[39,72],[128,121],[121,47],[47,128],[232,121],[121,128],[128,232],[104,69],[69,67],[67,104],[175,171],[171,148],[148,175],[118,50],[50,101],[101,118],[73,39],[39,40],[40,73],[9,151],[151,108],[108,9],[48,115],[115,131],[131,48],[194,204],[204,211],[211,194],[74,40],[40,185],[185,74],[80,42],[42,183],[183,80],[40,92],[92,186],[186,40],[230,229],[229,118],[118,230],[202,212],[212,214],[214,202],[83,18],[18,17],[17,83],[76,61],[61,146],[146,76],[160,29],[29,30],[30,160],[56,157],[157,173],[173,56],[106,204],[204,194],[194,106],[135,214],[214,192],[192,135],[203,165],[165,98],[98,203],[21,71],[71,68],[68,21],[51,45],[45,4],[4,51],[144,24],[24,23],[23,144],[77,146],[146,91],[91,77],[205,50],[50,187],[187,205],[201,200],[200,18],[18,201],[91,106],[106,182],[182,91],[90,91],[91,181],[181,90],[85,84],[84,17],[17,85],[206,203],[203,36],[36,206],[148,171],[171,140],[140,148],[92,40],[40,39],[39,92],[193,189],[189,244],[244,193],[159,158],[158,28],[28,159],[247,246],[246,161],[161,247],[236,3],[3,196],[196,236],[54,68],[68,104],[104,54],[193,168],[168,8],[8,193],[117,228],[228,31],[31,117],[189,193],[193,55],[55,189],[98,97],[97,99],[99,98],[126,47],[47,100],[100,126],[166,79],[79,218],[218,166],[155,154],[154,26],[26,155],[209,49],[49,131],[131,209],[135,136],[136,150],[150,135],[47,126],[126,217],[217,47],[223,52],[52,53],[53,223],[45,51],[51,134],[134,45],[211,170],[170,140],[140,211],[67,69],[69,108],[108,67],[43,106],[106,91],[91,43],[230,119],[119,120],[120,230],[226,130],[130,247],[247,226],[63,53],[53,52],[52,63],[238,20],[20,242],[242,238],[46,70],[70,156],[156,46],[78,62],[62,96],[96,78],[46,53],[53,63],[63,46],[143,34],[34,227],[227,143],[123,117],[117,111],[111,123],[44,125],[125,19],[19,44],[236,134],[134,51],[51,236],[216,206],[206,205],[205,216],[154,153],[153,22],[22,154],[39,37],[37,167],[167,39],[200,201],[201,208],[208,200],[36,142],[142,100],[100,36],[57,212],[212,202],[202,57],[20,60],[60,99],[99,20],[28,158],[158,157],[157,28],[35,226],[226,113],[113,35],[160,159],[159,27],[27,160],[204,202],[202,210],[210,204],[113,225],[225,46],[46,113],[43,202],[202,204],[204,43],[62,76],[76,77],[77,62],[137,123],[123,116],[116,137],[41,38],[38,72],[72,41],[203,129],[129,142],[142,203],[64,98],[98,240],[240,64],[49,102],[102,64],[64,49],[41,73],[73,74],[74,41],[212,216],[216,207],[207,212],[42,74],[74,184],[184,42],[169,170],[170,211],[211,169],[170,149],[149,176],[176,170],[105,66],[66,69],[69,105],[122,6],[6,168],[168,122],[123,147],[147,187],[187,123],[96,77],[77,90],[90,96],[65,55],[55,107],[107,65],[89,90],[90,180],[180,89],[101,100],[100,120],[120,101],[63,105],[105,104],[104,63],[93,137],[137,227],[227,93],[15,86],[86,85],[85,15],[129,102],[102,49],[49,129],[14,87],[87,86],[86,14],[55,8],[8,9],[9,55],[100,47],[47,121],[121,100],[145,23],[23,22],[22,145],[88,89],[89,179],[179,88],[6,122],[122,196],[196,6],[88,95],[95,96],[96,88],[138,172],[172,136],[136,138],[215,58],[58,172],[172,215],[115,48],[48,219],[219,115],[42,80],[80,81],[81,42],[195,3],[3,51],[51,195],[43,146],[146,61],[61,43],[171,175],[175,199],[199,171],[81,82],[82,38],[38,81],[53,46],[46,225],[225,53],[144,163],[163,110],[110,144],[52,65],[65,66],[66,52],[229,228],[228,117],[117,229],[34,127],[127,234],[234,34],[107,108],[108,69],[69,107],[109,108],[108,151],[151,109],[48,64],[64,235],[235,48],[62,78],[78,191],[191,62],[129,209],[209,126],[126,129],[111,35],[35,143],[143,111],[117,123],[123,50],[50,117],[222,65],[65,52],[52,222],[19,125],[125,141],[141,19],[221,55],[55,65],[65,221],[3,195],[195,197],[197,3],[25,7],[7,33],[33,25],[220,237],[237,44],[44,220],[70,71],[71,139],[139,70],[122,193],[193,245],[245,122],[247,130],[130,33],[33,247],[71,21],[21,162],[162,71],[170,169],[169,150],[150,170],[188,174],[174,196],[196,188],[216,186],[186,92],[92,216],[2,97],[97,167],[167,2],[141,125],[125,241],[241,141],[164,167],[167,37],[37,164],[72,38],[38,12],[12,72],[38,82],[82,13],[13,38],[63,68],[68,71],[71,63],[226,35],[35,111],[111,226],[101,50],[50,205],[205,101],[206,92],[92,165],[165,206],[209,198],[198,217],[217,209],[165,167],[167,97],[97,165],[220,115],[115,218],[218,220],[133,112],[112,243],[243,133],[239,238],[238,241],[241,239],[214,135],[135,169],[169,214],[190,173],[173,133],[133,190],[171,208],[208,32],[32,171],[125,44],[44,237],[237,125],[86,87],[87,178],[178,86],[85,86],[86,179],[179,85],[84,85],[85,180],[180,84],[83,84],[84,181],[181,83],[201,83],[83,182],[182,201],[137,93],[93,132],[132,137],[76,62],[62,183],[183,76],[61,76],[76,184],[184,61],[57,61],[61,185],[185,57],[212,57],[57,186],[186,212],[214,207],[207,187],[187,214],[34,143],[143,156],[156,34],[79,239],[239,237],[237,79],[123,137],[137,177],[177,123],[44,1],[1,4],[4,44],[201,194],[194,32],[32,201],[64,102],[102,129],[129,64],[213,215],[215,138],[138,213],[59,166],[166,219],[219,59],[242,99],[99,97],[97,242],[2,94],[94,141],[141,2],[75,59],[59,235],[235,75],[24,110],[110,228],[228,24],[25,130],[130,226],[226,25],[23,24],[24,229],[229,23],[22,23],[23,230],[230,22],[26,22],[22,231],[231,26],[112,26],[26,232],[232,112],[189,190],[190,243],[243,189],[221,56],[56,190],[190,221],[28,56],[56,221],[221,28],[27,28],[28,222],[222,27],[29,27],[27,223],[223,29],[30,29],[29,224],[224,30],[247,30],[30,225],[225,247],[238,79],[79,20],[20,238],[166,59],[59,75],[75,166],[60,75],[75,240],[240,60],[147,177],[177,215],[215,147],[20,79],[79,166],[166,20],[187,147],[147,213],[213,187],[112,233],[233,244],[244,112],[233,128],[128,245],[245,233],[128,114],[114,188],[188,128],[114,217],[217,174],[174,114],[131,115],[115,220],[220,131],[217,198],[198,236],[236,217],[198,131],[131,134],[134,198],[177,132],[132,58],[58,177],[143,35],[35,124],[124,143],[110,163],[163,7],[7,110],[228,110],[110,25],[25,228],[356,389],[389,368],[368,356],[11,302],[302,267],[267,11],[452,350],[350,349],[349,452],[302,303],[303,269],[269,302],[357,343],[343,277],[277,357],[452,453],[453,357],[357,452],[333,332],[332,297],[297,333],[175,152],[152,377],[377,175],[347,348],[348,330],[330,347],[303,304],[304,270],[270,303],[9,336],[336,337],[337,9],[278,279],[279,360],[360,278],[418,262],[262,431],[431,418],[304,408],[408,409],[409,304],[310,415],[415,407],[407,310],[270,409],[409,410],[410,270],[450,348],[348,347],[347,450],[422,430],[430,434],[434,422],[313,314],[314,17],[17,313],[306,307],[307,375],[375,306],[387,388],[388,260],[260,387],[286,414],[414,398],[398,286],[335,406],[406,418],[418,335],[364,367],[367,416],[416,364],[423,358],[358,327],[327,423],[251,284],[284,298],[298,251],[281,5],[5,4],[4,281],[373,374],[374,253],[253,373],[307,320],[320,321],[321,307],[425,427],[427,411],[411,425],[421,313],[313,18],[18,421],[321,405],[405,406],[406,321],[320,404],[404,405],[405,320],[315,16],[16,17],[17,315],[426,425],[425,266],[266,426],[377,400],[400,369],[369,377],[322,391],[391,269],[269,322],[417,465],[465,464],[464,417],[386,257],[257,258],[258,386],[466,260],[260,388],[388,466],[456,399],[399,419],[419,456],[284,332],[332,333],[333,284],[417,285],[285,8],[8,417],[346,340],[340,261],[261,346],[413,441],[441,285],[285,413],[327,460],[460,328],[328,327],[355,371],[371,329],[329,355],[392,439],[439,438],[438,392],[382,341],[341,256],[256,382],[429,420],[420,360],[360,429],[364,394],[394,379],[379,364],[277,343],[343,437],[437,277],[443,444],[444,283],[283,443],[275,440],[440,363],[363,275],[431,262],[262,369],[369,431],[297,338],[338,337],[337,297],[273,375],[375,321],[321,273],[450,451],[451,349],[349,450],[446,342],[342,467],[467,446],[293,334],[334,282],[282,293],[458,461],[461,462],[462,458],[276,353],[353,383],[383,276],[308,324],[324,325],[325,308],[276,300],[300,293],[293,276],[372,345],[345,447],[447,372],[352,345],[345,340],[340,352],[274,1],[1,19],[19,274],[456,248],[248,281],[281,456],[436,427],[427,425],[425,436],[381,256],[256,252],[252,381],[269,391],[391,393],[393,269],[200,199],[199,428],[428,200],[266,330],[330,329],[329,266],[287,273],[273,422],[422,287],[250,462],[462,328],[328,250],[258,286],[286,384],[384,258],[265,353],[353,342],[342,265],[387,259],[259,257],[257,387],[424,431],[431,430],[430,424],[342,353],[353,276],[276,342],[273,335],[335,424],[424,273],[292,325],[325,307],[307,292],[366,447],[447,345],[345,366],[271,303],[303,302],[302,271],[423,266],[266,371],[371,423],[294,455],[455,460],[460,294],[279,278],[278,294],[294,279],[271,272],[272,304],[304,271],[432,434],[434,427],[427,432],[272,407],[407,408],[408,272],[394,430],[430,431],[431,394],[395,369],[369,400],[400,395],[334,333],[333,299],[299,334],[351,417],[417,168],[168,351],[352,280],[280,411],[411,352],[325,319],[319,320],[320,325],[295,296],[296,336],[336,295],[319,403],[403,404],[404,319],[330,348],[348,349],[349,330],[293,298],[298,333],[333,293],[323,454],[454,447],[447,323],[15,16],[16,315],[315,15],[358,429],[429,279],[279,358],[14,15],[15,316],[316,14],[285,336],[336,9],[9,285],[329,349],[349,350],[350,329],[374,380],[380,252],[252,374],[318,402],[402,403],[403,318],[6,197],[197,419],[419,6],[318,319],[319,325],[325,318],[367,364],[364,365],[365,367],[435,367],[367,397],[397,435],[344,438],[438,439],[439,344],[272,271],[271,311],[311,272],[195,5],[5,281],[281,195],[273,287],[287,291],[291,273],[396,428],[428,199],[199,396],[311,271],[271,268],[268,311],[283,444],[444,445],[445,283],[373,254],[254,339],[339,373],[282,334],[334,296],[296,282],[449,347],[347,346],[346,449],[264,447],[447,454],[454,264],[336,296],[296,299],[299,336],[338,10],[10,151],[151,338],[278,439],[439,455],[455,278],[292,407],[407,415],[415,292],[358,371],[371,355],[355,358],[340,345],[345,372],[372,340],[346,347],[347,280],[280,346],[442,443],[443,282],[282,442],[19,94],[94,370],[370,19],[441,442],[442,295],[295,441],[248,419],[419,197],[197,248],[263,255],[255,359],[359,263],[440,275],[275,274],[274,440],[300,383],[383,368],[368,300],[351,412],[412,465],[465,351],[263,467],[467,466],[466,263],[301,368],[368,389],[389,301],[395,378],[378,379],[379,395],[412,351],[351,419],[419,412],[436,426],[426,322],[322,436],[2,164],[164,393],[393,2],[370,462],[462,461],[461,370],[164,0],[0,267],[267,164],[302,11],[11,12],[12,302],[268,12],[12,13],[13,268],[293,300],[300,301],[301,293],[446,261],[261,340],[340,446],[330,266],[266,425],[425,330],[426,423],[423,391],[391,426],[429,355],[355,437],[437,429],[391,327],[327,326],[326,391],[440,457],[457,438],[438,440],[341,382],[382,362],[362,341],[459,457],[457,461],[461,459],[434,430],[430,394],[394,434],[414,463],[463,362],[362,414],[396,369],[369,262],[262,396],[354,461],[461,457],[457,354],[316,403],[403,402],[402,316],[315,404],[404,403],[403,315],[314,405],[405,404],[404,314],[313,406],[406,405],[405,313],[421,418],[418,406],[406,421],[366,401],[401,361],[361,366],[306,408],[408,407],[407,306],[291,409],[409,408],[408,291],[287,410],[410,409],[409,287],[432,436],[436,410],[410,432],[434,416],[416,411],[411,434],[264,368],[368,383],[383,264],[309,438],[438,457],[457,309],[352,376],[376,401],[401,352],[274,275],[275,4],[4,274],[421,428],[428,262],[262,421],[294,327],[327,358],[358,294],[433,416],[416,367],[367,433],[289,455],[455,439],[439,289],[462,370],[370,326],[326,462],[2,326],[326,370],[370,2],[305,460],[460,455],[455,305],[254,449],[449,448],[448,254],[255,261],[261,446],[446,255],[253,450],[450,449],[449,253],[252,451],[451,450],[450,252],[256,452],[452,451],[451,256],[341,453],[453,452],[452,341],[413,464],[464,463],[463,413],[441,413],[413,414],[414,441],[258,442],[442,441],[441,258],[257,443],[443,442],[442,257],[259,444],[444,443],[443,259],[260,445],[445,444],[444,260],[467,342],[342,445],[445,467],[459,458],[458,250],[250,459],[289,392],[392,290],[290,289],[290,328],[328,460],[460,290],[376,433],[433,435],[435,376],[250,290],[290,392],[392,250],[411,416],[416,433],[433,411],[341,463],[463,464],[464,341],[453,464],[464,465],[465,453],[357,465],[465,412],[412,357],[343,412],[412,399],[399,343],[360,363],[363,440],[440,360],[437,399],[399,456],[456,437],[420,456],[456,363],[363,420],[401,435],[435,288],[288,401],[372,383],[383,353],[353,372],[339,255],[255,249],[249,339],[448,261],[261,255],[255,448],[133,243],[243,190],[190,133],[133,155],[155,112],[112,133],[33,246],[246,247],[247,33],[33,130],[130,25],[25,33],[398,384],[384,286],[286,398],[362,398],[398,414],[414,362],[362,463],[463,341],[341,362],[263,359],[359,467],[467,263],[263,249],[249,255],[255,263],[466,467],[467,260],[260,466],[75,60],[60,166],[166,75],[238,239],[239,79],[79,238],[162,127],[127,139],[139,162],[72,11],[11,37],[37,72],[121,232],[232,120],[120,121],[73,72],[72,39],[39,73],[114,128],[128,47],[47,114],[233,232],[232,128],[128,233],[103,104],[104,67],[67,103],[152,175],[175,148],[148,152],[119,118],[118,101],[101,119],[74,73],[73,40],[40,74],[107,9],[9,108],[108,107],[49,48],[48,131],[131,49],[32,194],[194,211],[211,32],[184,74],[74,185],[185,184],[191,80],[80,183],[183,191],[185,40],[40,186],[186,185],[119,230],[230,118],[118,119],[210,202],[202,214],[214,210],[84,83],[83,17],[17,84],[77,76],[76,146],[146,77],[161,160],[160,30],[30,161],[190,56],[56,173],[173,190],[182,106],[106,194],[194,182],[138,135],[135,192],[192,138],[129,203],[203,98],[98,129],[54,21],[21,68],[68,54],[5,51],[51,4],[4,5],[145,144],[144,23],[23,145],[90,77],[77,91],[91,90],[207,205],[205,187],[187,207],[83,201],[201,18],[18,83],[181,91],[91,182],[182,181],[180,90],[90,181],[181,180],[16,85],[85,17],[17,16],[205,206],[206,36],[36,205],[176,148],[148,140],[140,176],[165,92],[92,39],[39,165],[245,193],[193,244],[244,245],[27,159],[159,28],[28,27],[30,247],[247,161],[161,30],[174,236],[236,196],[196,174],[103,54],[54,104],[104,103],[55,193],[193,8],[8,55],[111,117],[117,31],[31,111],[221,189],[189,55],[55,221],[240,98],[98,99],[99,240],[142,126],[126,100],[100,142],[219,166],[166,218],[218,219],[112,155],[155,26],[26,112],[198,209],[209,131],[131,198],[169,135],[135,150],[150,169],[114,47],[47,217],[217,114],[224,223],[223,53],[53,224],[220,45],[45,134],[134,220],[32,211],[211,140],[140,32],[109,67],[67,108],[108,109],[146,43],[43,91],[91,146],[231,230],[230,120],[120,231],[113,226],[226,247],[247,113],[105,63],[63,52],[52,105],[241,238],[238,242],[242,241],[124,46],[46,156],[156,124],[95,78],[78,96],[96,95],[70,46],[46,63],[63,70],[116,143],[143,227],[227,116],[116,123],[123,111],[111,116],[1,44],[44,19],[19,1],[3,236],[236,51],[51,3],[207,216],[216,205],[205,207],[26,154],[154,22],[22,26],[165,39],[39,167],[167,165],[199,200],[200,208],[208,199],[101,36],[36,100],[100,101],[43,57],[57,202],[202,43],[242,20],[20,99],[99,242],[56,28],[28,157],[157,56],[124,35],[35,113],[113,124],[29,160],[160,27],[27,29],[211,204],[204,210],[210,211],[124,113],[113,46],[46,124],[106,43],[43,204],[204,106],[96,62],[62,77],[77,96],[227,137],[137,116],[116,227],[73,41],[41,72],[72,73],[36,203],[203,142],[142,36],[235,64],[64,240],[240,235],[48,49],[49,64],[64,48],[42,41],[41,74],[74,42],[214,212],[212,207],[207,214],[183,42],[42,184],[184,183],[210,169],[169,211],[211,210],[140,170],[170,176],[176,140],[104,105],[105,69],[69,104],[193,122],[122,168],[168,193],[50,123],[123,187],[187,50],[89,96],[96,90],[90,89],[66,65],[65,107],[107,66],[179,89],[89,180],[180,179],[119,101],[101,120],[120,119],[68,63],[63,104],[104,68],[234,93],[93,227],[227,234],[16,15],[15,85],[85,16],[209,129],[129,49],[49,209],[15,14],[14,86],[86,15],[107,55],[55,9],[9,107],[120,100],[100,121],[121,120],[153,145],[145,22],[22,153],[178,88],[88,179],[179,178],[197,6],[6,196],[196,197],[89,88],[88,96],[96,89],[135,138],[138,136],[136,135],[138,215],[215,172],[172,138],[218,115],[115,219],[219,218],[41,42],[42,81],[81,41],[5,195],[195,51],[51,5],[57,43],[43,61],[61,57],[208,171],[171,199],[199,208],[41,81],[81,38],[38,41],[224,53],[53,225],[225,224],[24,144],[144,110],[110,24],[105,52],[52,66],[66,105],[118,229],[229,117],[117,118],[227,34],[34,234],[234,227],[66,107],[107,69],[69,66],[10,109],[109,151],[151,10],[219,48],[48,235],[235,219],[183,62],[62,191],[191,183],[142,129],[129,126],[126,142],[116,111],[111,143],[143,116],[118,117],[117,50],[50,118],[223,222],[222,52],[52,223],[94,19],[19,141],[141,94],[222,221],[221,65],[65,222],[196,3],[3,197],[197,196],[45,220],[220,44],[44,45],[156,70],[70,139],[139,156],[188,122],[122,245],[245,188],[139,71],[71,162],[162,139],[149,170],[170,150],[150,149],[122,188],[188,196],[196,122],[206,216],[216,92],[92,206],[164,2],[2,167],[167,164],[242,141],[141,241],[241,242],[0,164],[164,37],[37,0],[11,72],[72,12],[12,11],[12,38],[38,13],[13,12],[70,63],[63,71],[71,70],[31,226],[226,111],[111,31],[36,101],[101,205],[205,36],[203,206],[206,165],[165,203],[126,209],[209,217],[217,126],[98,165],[165,97],[97,98],[237,220],[220,218],[218,237],[237,239],[239,241],[241,237],[210,214],[214,169],[169,210],[140,171],[171,32],[32,140],[241,125],[125,237],[237,241],[179,86],[86,178],[178,179],[180,85],[85,179],[179,180],[181,84],[84,180],[180,181],[182,83],[83,181],[181,182],[194,201],[201,182],[182,194],[177,137],[137,132],[132,177],[184,76],[76,183],[183,184],[185,61],[61,184],[184,185],[186,57],[57,185],[185,186],[216,212],[212,186],[186,216],[192,214],[214,187],[187,192],[139,34],[34,156],[156,139],[218,79],[79,237],[237,218],[147,123],[123,177],[177,147],[45,44],[44,4],[4,45],[208,201],[201,32],[32,208],[98,64],[64,129],[129,98],[192,213],[213,138],[138,192],[235,59],[59,219],[219,235],[141,242],[242,97],[97,141],[97,2],[2,141],[141,97],[240,75],[75,235],[235,240],[229,24],[24,228],[228,229],[31,25],[25,226],[226,31],[230,23],[23,229],[229,230],[231,22],[22,230],[230,231],[232,26],[26,231],[231,232],[233,112],[112,232],[232,233],[244,189],[189,243],[243,244],[189,221],[221,190],[190,189],[222,28],[28,221],[221,222],[223,27],[27,222],[222,223],[224,29],[29,223],[223,224],[225,30],[30,224],[224,225],[113,247],[247,225],[225,113],[99,60],[60,240],[240,99],[213,147],[147,215],[215,213],[60,20],[20,166],[166,60],[192,187],[187,213],[213,192],[243,112],[112,244],[244,243],[244,233],[233,245],[245,244],[245,128],[128,188],[188,245],[188,114],[114,174],[174,188],[134,131],[131,220],[220,134],[174,217],[217,236],[236,174],[236,198],[198,134],[134,236],[215,177],[177,58],[58,215],[156,143],[143,124],[124,156],[25,110],[110,7],[7,25],[31,228],[228,25],[25,31],[264,356],[356,368],[368,264],[0,11],[11,267],[267,0],[451,452],[452,349],[349,451],[267,302],[302,269],[269,267],[350,357],[357,277],[277,350],[350,452],[452,357],[357,350],[299,333],[333,297],[297,299],[396,175],[175,377],[377,396],[280,347],[347,330],[330,280],[269,303],[303,270],[270,269],[151,9],[9,337],[337,151],[344,278],[278,360],[360,344],[424,418],[418,431],[431,424],[270,304],[304,409],[409,270],[272,310],[310,407],[407,272],[322,270],[270,410],[410,322],[449,450],[450,347],[347,449],[432,422],[422,434],[434,432],[18,313],[313,17],[17,18],[291,306],[306,375],[375,291],[259,387],[387,260],[260,259],[424,335],[335,418],[418,424],[434,364],[364,416],[416,434],[391,423],[423,327],[327,391],[301,251],[251,298],[298,301],[275,281],[281,4],[4,275],[254,373],[373,253],[253,254],[375,307],[307,321],[321,375],[280,425],[425,411],[411,280],[200,421],[421,18],[18,200],[335,321],[321,406],[406,335],[321,320],[320,405],[405,321],[314,315],[315,17],[17,314],[423,426],[426,266],[266,423],[396,377],[377,369],[369,396],[270,322],[322,269],[269,270],[413,417],[417,464],[464,413],[385,386],[386,258],[258,385],[248,456],[456,419],[419,248],[298,284],[284,333],[333,298],[168,417],[417,8],[8,168],[448,346],[346,261],[261,448],[417,413],[413,285],[285,417],[326,327],[327,328],[328,326],[277,355],[355,329],[329,277],[309,392],[392,438],[438,309],[381,382],[382,256],[256,381],[279,429],[429,360],[360,279],[365,364],[364,379],[379,365],[355,277],[277,437],[437,355],[282,443],[443,283],[283,282],[281,275],[275,363],[363,281],[395,431],[431,369],[369,395],[299,297],[297,337],[337,299],[335,273],[273,321],[321,335],[348,450],[450,349],[349,348],[359,446],[446,467],[467,359],[283,293],[293,282],[282,283],[250,458],[458,462],[462,250],[300,276],[276,383],[383,300],[292,308],[308,325],[325,292],[283,276],[276,293],[293,283],[264,372],[372,447],[447,264],[346,352],[352,340],[340,346],[354,274],[274,19],[19,354],[363,456],[456,281],[281,363],[426,436],[436,425],[425,426],[380,381],[381,252],[252,380],[267,269],[269,393],[393,267],[421,200],[200,428],[428,421],[371,266],[266,329],[329,371],[432,287],[287,422],[422,432],[290,250],[250,328],[328,290],[385,258],[258,384],[384,385],[446,265],[265,342],[342,446],[386,387],[387,257],[257,386],[422,424],[424,430],[430,422],[445,342],[342,276],[276,445],[422,273],[273,424],[424,422],[306,292],[292,307],[307,306],[352,366],[366,345],[345,352],[268,271],[271,302],[302,268],[358,423],[423,371],[371,358],[327,294],[294,460],[460,327],[331,279],[279,294],[294,331],[303,271],[271,304],[304,303],[436,432],[432,427],[427,436],[304,272],[272,408],[408,304],[395,394],[394,431],[431,395],[378,395],[395,400],[400,378],[296,334],[334,299],[299,296],[6,351],[351,168],[168,6],[376,352],[352,411],[411,376],[307,325],[325,320],[320,307],[285,295],[295,336],[336,285],[320,319],[319,404],[404,320],[329,330],[330,349],[349,329],[334,293],[293,333],[333,334],[366,323],[323,447],[447,366],[316,15],[15,315],[315,316],[331,358],[358,279],[279,331],[317,14],[14,316],[316,317],[8,285],[285,9],[9,8],[277,329],[329,350],[350,277],[253,374],[374,252],[252,253],[319,318],[318,403],[403,319],[351,6],[6,419],[419,351],[324,318],[318,325],[325,324],[397,367],[367,365],[365,397],[288,435],[435,397],[397,288],[278,344],[344,439],[439,278],[310,272],[272,311],[311,310],[248,195],[195,281],[281,248],[375,273],[273,291],[291,375],[175,396],[396,199],[199,175],[312,311],[311,268],[268,312],[276,283],[283,445],[445,276],[390,373],[373,339],[339,390],[295,282],[282,296],[296,295],[448,449],[449,346],[346,448],[356,264],[264,454],[454,356],[337,336],[336,299],[299,337],[337,338],[338,151],[151,337],[294,278],[278,455],[455,294],[308,292],[292,415],[415,308],[429,358],[358,355],[355,429],[265,340],[340,372],[372,265],[352,346],[346,280],[280,352],[295,442],[442,282],[282,295],[354,19],[19,370],[370,354],[285,441],[441,295],[295,285],[195,248],[248,197],[197,195],[457,440],[440,274],[274,457],[301,300],[300,368],[368,301],[417,351],[351,465],[465,417],[251,301],[301,389],[389,251],[394,395],[395,379],[379,394],[399,412],[412,419],[419,399],[410,436],[436,322],[322,410],[326,2],[2,393],[393,326],[354,370],[370,461],[461,354],[393,164],[164,267],[267,393],[268,302],[302,12],[12,268],[312,268],[268,13],[13,312],[298,293],[293,301],[301,298],[265,446],[446,340],[340,265],[280,330],[330,425],[425,280],[322,426],[426,391],[391,322],[420,429],[429,437],[437,420],[393,391],[391,326],[326,393],[344,440],[440,438],[438,344],[458,459],[459,461],[461,458],[364,434],[434,394],[394,364],[428,396],[396,262],[262,428],[274,354],[354,457],[457,274],[317,316],[316,402],[402,317],[316,315],[315,403],[403,316],[315,314],[314,404],[404,315],[314,313],[313,405],[405,314],[313,421],[421,406],[406,313],[323,366],[366,361],[361,323],[292,306],[306,407],[407,292],[306,291],[291,408],[408,306],[291,287],[287,409],[409,291],[287,432],[432,410],[410,287],[427,434],[434,411],[411,427],[372,264],[264,383],[383,372],[459,309],[309,457],[457,459],[366,352],[352,401],[401,366],[1,274],[274,4],[4,1],[418,421],[421,262],[262,418],[331,294],[294,358],[358,331],[435,433],[433,367],[367,435],[392,289],[289,439],[439,392],[328,462],[462,326],[326,328],[94,2],[2,370],[370,94],[289,305],[305,455],[455,289],[339,254],[254,448],[448,339],[359,255],[255,446],[446,359],[254,253],[253,449],[449,254],[253,252],[252,450],[450,253],[252,256],[256,451],[451,252],[256,341],[341,452],[452,256],[414,413],[413,463],[463,414],[286,441],[441,414],[414,286],[286,258],[258,441],[441,286],[258,257],[257,442],[442,258],[257,259],[259,443],[443,257],[259,260],[260,444],[444,259],[260,467],[467,445],[445,260],[309,459],[459,250],[250,309],[305,289],[289,290],[290,305],[305,290],[290,460],[460,305],[401,376],[376,435],[435,401],[309,250],[250,392],[392,309],[376,411],[411,433],[433,376],[453,341],[341,464],[464,453],[357,453],[453,465],[465,357],[343,357],[357,412],[412,343],[437,343],[343,399],[399,437],[344,360],[360,440],[440,344],[420,437],[437,456],[456,420],[360,420],[420,363],[363,360],[361,401],[401,288],[288,361],[265,372],[372,353],[353,265],[390,339],[339,249],[249,390],[339,448],[448,255],[255,339]);function mc(t){t.l={faceLandmarks:[],faceBlendshapes:[],facialTransformationMatrixes:[]}}var vc=class extends ic{constructor(t,e){super(new Zu(t,e),"image_in","norm_rect",!1),this.l={faceLandmarks:[],faceBlendshapes:[],facialTransformationMatrixes:[]},this.outputFacialTransformationMatrixes=this.outputFaceBlendshapes=!1,Fr(t=this.h=new ia,0,1,e=new Yo),this.B=new na,Fr(this.h,0,3,this.B),this.u=new Qo,Fr(this.h,0,2,this.u),Br(this.u,4,1),Vr(this.u,2,.5),Vr(this.B,2,.5),Vr(this.h,4,.5)}C(){return"FaceLandmarker"}get baseOptions(){return Lr(this.h,Yo,1)}set baseOptions(t){Fr(this.h,0,1,t)}v(t){return"numFaces"in t&&Br(this.u,4,t.numFaces??1),"minFaceDetectionConfidence"in t&&Vr(this.u,2,t.minFaceDetectionConfidence??.5),"minTrackingConfidence"in t&&Vr(this.h,4,t.minTrackingConfidence??.5),"minFacePresenceConfidence"in t&&Vr(this.B,2,t.minFacePresenceConfidence??.5),"outputFaceBlendshapes"in t&&(this.outputFaceBlendshapes=!!t.outputFaceBlendshapes),"outputFacialTransformationMatrixes"in t&&(this.outputFacialTransformationMatrixes=!!t.outputFacialTransformationMatrixes),this.j(t)}G(t,e){return mc(this),ec(this,t,e),this.l}H(t,e,r){return mc(this),rc(this,t,r,e),this.l}o(){var t=new vo;go(t,"image_in"),go(t,"norm_rect"),mo(t,"face_landmarks");var e=new io;di(e,oa,this.h);var r=new uo;Kr(r,2,"mediapipe.tasks.vision.face_landmarker.FaceLandmarkerGraph"),ao(r,"IMAGE:image_in"),ao(r,"NORM_RECT:norm_rect"),ho(r,"NORM_LANDMARKS:face_landmarks"),r.v(e),po(t,r),this.g.attachProtoVectorListener("face_landmarks",(t,e)=>{for(let e of t)t=Fo(e),this.l.faceLandmarks.push(th(t));eu(this,e)}),this.g.attachEmptyPacketListener("face_landmarks",t=>{eu(this,t)}),this.outputFaceBlendshapes&&(mo(t,"blendshapes"),ho(r,"BLENDSHAPES:blendshapes"),this.g.attachProtoVectorListener("blendshapes",(t,e)=>{if(this.outputFaceBlendshapes)for(let e of t)t=bo(e),this.l.faceBlendshapes.push(Ja(t.g()??[]));eu(this,e)}),this.g.attachEmptyPacketListener("blendshapes",t=>{eu(this,t)})),this.outputFacialTransformationMatrixes&&(mo(t,"face_geometry"),ho(r,"FACE_GEOMETRY:face_geometry"),this.g.attachProtoVectorListener("face_geometry",(t,e)=>{if(this.outputFacialTransformationMatrixes)for(let e of t)(t=Lr(t=ra(e),Co,2))&&this.l.facialTransformationMatrixes.push({rows:Dr(t,1)??0??0,columns:Dr(t,2)??0??0,data:dr(t,3,Zt,lr()).slice()??[]});eu(this,e)}),this.g.attachEmptyPacketListener("face_geometry",t=>{eu(this,t)})),t=t.g(),this.setGraph(new Uint8Array(t),!0)}};vc.prototype.detectForVideo=vc.prototype.H,vc.prototype.detect=vc.prototype.G,vc.prototype.setOptions=vc.prototype.v,vc.createFromModelPath=function(t,e){return Qu(vc,t,{baseOptions:{modelAssetPath:e}})},vc.createFromModelBuffer=function(t,e){return Qu(vc,t,{baseOptions:{modelAssetBuffer:e}})},vc.createFromOptions=function(t,e){return Qu(vc,t,e)},vc.FACE_LANDMARKS_LIPS=oc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$face_landmarker$face_landmarker.FaceLandmarker.FACE_LANDMARKS_LIPS",vc.FACE_LANDMARKS_LIPS),vc.FACE_LANDMARKS_LEFT_EYE=ac,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$face_landmarker$face_landmarker.FaceLandmarker.FACE_LANDMARKS_LEFT_EYE",vc.FACE_LANDMARKS_LEFT_EYE),vc.FACE_LANDMARKS_LEFT_EYEBROW=hc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$face_landmarker$face_landmarker.FaceLandmarker.FACE_LANDMARKS_LEFT_EYEBROW",vc.FACE_LANDMARKS_LEFT_EYEBROW),vc.FACE_LANDMARKS_LEFT_IRIS=uc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$face_landmarker$face_landmarker.FaceLandmarker.FACE_LANDMARKS_LEFT_IRIS",vc.FACE_LANDMARKS_LEFT_IRIS),vc.FACE_LANDMARKS_RIGHT_EYE=cc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$face_landmarker$face_landmarker.FaceLandmarker.FACE_LANDMARKS_RIGHT_EYE",vc.FACE_LANDMARKS_RIGHT_EYE),vc.FACE_LANDMARKS_RIGHT_EYEBROW=lc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$face_landmarker$face_landmarker.FaceLandmarker.FACE_LANDMARKS_RIGHT_EYEBROW",vc.FACE_LANDMARKS_RIGHT_EYEBROW),vc.FACE_LANDMARKS_RIGHT_IRIS=dc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$face_landmarker$face_landmarker.FaceLandmarker.FACE_LANDMARKS_RIGHT_IRIS",vc.FACE_LANDMARKS_RIGHT_IRIS),vc.FACE_LANDMARKS_FACE_OVAL=fc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$face_landmarker$face_landmarker.FaceLandmarker.FACE_LANDMARKS_FACE_OVAL",vc.FACE_LANDMARKS_FACE_OVAL),vc.FACE_LANDMARKS_CONTOURS=pc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$face_landmarker$face_landmarker.FaceLandmarker.FACE_LANDMARKS_CONTOURS",vc.FACE_LANDMARKS_CONTOURS),vc.FACE_LANDMARKS_TESSELATION=gc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$face_landmarker$face_landmarker.FaceLandmarker.FACE_LANDMARKS_TESSELATION",vc.FACE_LANDMARKS_TESSELATION);var _c=Yu([0,1],[1,2],[2,3],[3,4],[0,5],[5,6],[6,7],[7,8],[5,9],[9,10],[10,11],[11,12],[9,13],[13,14],[14,15],[15,16],[13,17],[0,17],[17,18],[18,19],[19,20]);function yc(t){t.gestures=[],t.landmarks=[],t.worldLandmarks=[],t.handedness=[]}function Ec(t){return 0===t.gestures.length?{gestures:[],landmarks:[],worldLandmarks:[],handedness:[],handednesses:[]}:{gestures:t.gestures,landmarks:t.landmarks,worldLandmarks:t.worldLandmarks,handedness:t.handedness,handednesses:t.handedness}}function Ac(t,e=!0){var r=[];for(let i of t){var n=bo(i);t=[];for(let r of n.g())n=e&&null!=Dr(r,1)?Dr(r,1)??0:-1,t.push({score:Pr(r,2)??0,index:n,categoryName:ye(or(r,3))??""??"",displayName:ye(or(r,4))??""??""});r.push(t)}return r}var wc=class extends ic{constructor(t,e){super(new Zu(t,e),"image_in","norm_rect",!1),this.gestures=[],this.landmarks=[],this.worldLandmarks=[],this.handedness=[],Fr(t=this.l=new fa,0,1,e=new Yo),this.u=new da,Fr(this.l,0,2,this.u),this.F=new la,Fr(this.u,0,3,this.F),this.B=new ca,Fr(this.u,0,2,this.B),this.h=new ua,Fr(this.l,0,3,this.h),Vr(this.B,2,.5),Vr(this.u,4,.5),Vr(this.F,2,.5)}C(){return"GestureRecognizer"}get baseOptions(){return Lr(this.l,Yo,1)}set baseOptions(t){Fr(this.l,0,1,t)}v(t){if(Br(this.B,3,t.numHands??1),"minHandDetectionConfidence"in t&&Vr(this.B,2,t.minHandDetectionConfidence??.5),"minTrackingConfidence"in t&&Vr(this.u,4,t.minTrackingConfidence??.5),"minHandPresenceConfidence"in t&&Vr(this.F,2,t.minHandPresenceConfidence??.5),t.cannedGesturesClassifierOptions){var e=new aa,r=e,n=Ya(t.cannedGesturesClassifierOptions,Lr(this.h,aa,3)?.j());Fr(r,0,2,n),Fr(this.h,0,3,e)}else void 0===t.cannedGesturesClassifierOptions&&Lr(this.h,aa,3)?.g();return t.customGesturesClassifierOptions?(Fr(r=e=new aa,0,2,n=Ya(t.customGesturesClassifierOptions,Lr(this.h,aa,4)?.j())),Fr(this.h,0,4,e)):void 0===t.customGesturesClassifierOptions&&Lr(this.h,aa,4)?.g(),this.j(t)}Xa(t,e){return yc(this),ec(this,t,e),Ec(this)}Ya(t,e,r){return yc(this),rc(this,t,r,e),Ec(this)}o(){var t=new vo;go(t,"image_in"),go(t,"norm_rect"),mo(t,"hand_gestures"),mo(t,"hand_landmarks"),mo(t,"world_hand_landmarks"),mo(t,"handedness");var e=new io;di(e,_a,this.l);var r=new uo;Kr(r,2,"mediapipe.tasks.vision.gesture_recognizer.GestureRecognizerGraph"),ao(r,"IMAGE:image_in"),ao(r,"NORM_RECT:norm_rect"),ho(r,"HAND_GESTURES:hand_gestures"),ho(r,"LANDMARKS:hand_landmarks"),ho(r,"WORLD_LANDMARKS:world_hand_landmarks"),ho(r,"HANDEDNESS:handedness"),r.v(e),po(t,r),this.g.attachProtoVectorListener("hand_landmarks",(t,e)=>{for(let e of t){t=Fo(e);let r=[];for(let e of Rr(t,Io,1))r.push({x:Pr(e,1)??0,y:Pr(e,2)??0,z:Pr(e,3)??0,visibility:Pr(e,4)??0});this.landmarks.push(r)}eu(this,e)}),this.g.attachEmptyPacketListener("hand_landmarks",t=>{eu(this,t)}),this.g.attachProtoVectorListener("world_hand_landmarks",(t,e)=>{for(let e of t){t=Ro(e);let r=[];for(let e of Rr(t,xo,1))r.push({x:Pr(e,1)??0,y:Pr(e,2)??0,z:Pr(e,3)??0,visibility:Pr(e,4)??0});this.worldLandmarks.push(r)}eu(this,e)}),this.g.attachEmptyPacketListener("world_hand_landmarks",t=>{eu(this,t)}),this.g.attachProtoVectorListener("hand_gestures",(t,e)=>{this.gestures.push(...Ac(t,!1)),eu(this,e)}),this.g.attachEmptyPacketListener("hand_gestures",t=>{eu(this,t)}),this.g.attachProtoVectorListener("handedness",(t,e)=>{this.handedness.push(...Ac(t)),eu(this,e)}),this.g.attachEmptyPacketListener("handedness",t=>{eu(this,t)}),t=t.g(),this.setGraph(new Uint8Array(t),!0)}};function bc(t){return{landmarks:t.landmarks,worldLandmarks:t.worldLandmarks,handednesses:t.handedness,handedness:t.handedness}}wc.prototype.recognizeForVideo=wc.prototype.Ya,wc.prototype.recognize=wc.prototype.Xa,wc.prototype.setOptions=wc.prototype.v,wc.createFromModelPath=function(t,e){return Qu(wc,t,{baseOptions:{modelAssetPath:e}})},wc.createFromModelBuffer=function(t,e){return Qu(wc,t,{baseOptions:{modelAssetBuffer:e}})},wc.createFromOptions=function(t,e){return Qu(wc,t,e)},wc.HAND_CONNECTIONS=_c,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$gesture_recognizer$gesture_recognizer.GestureRecognizer.HAND_CONNECTIONS",wc.HAND_CONNECTIONS);var Tc=class extends ic{constructor(t,e){super(new Zu(t,e),"image_in","norm_rect",!1),this.landmarks=[],this.worldLandmarks=[],this.handedness=[],Fr(t=this.h=new da,0,1,e=new Yo),this.u=new la,Fr(this.h,0,3,this.u),this.l=new ca,Fr(this.h,0,2,this.l),Br(this.l,3,1),Vr(this.l,2,.5),Vr(this.u,2,.5),Vr(this.h,4,.5)}C(){return"HandLandmarker"}get baseOptions(){return Lr(this.h,Yo,1)}set baseOptions(t){Fr(this.h,0,1,t)}v(t){return"numHands"in t&&Br(this.l,3,t.numHands??1),"minHandDetectionConfidence"in t&&Vr(this.l,2,t.minHandDetectionConfidence??.5),"minTrackingConfidence"in t&&Vr(this.h,4,t.minTrackingConfidence??.5),"minHandPresenceConfidence"in t&&Vr(this.u,2,t.minHandPresenceConfidence??.5),this.j(t)}G(t,e){return this.landmarks=[],this.worldLandmarks=[],this.handedness=[],ec(this,t,e),bc(this)}H(t,e,r){return this.landmarks=[],this.worldLandmarks=[],this.handedness=[],rc(this,t,r,e),bc(this)}o(){var t=new vo;go(t,"image_in"),go(t,"norm_rect"),mo(t,"hand_landmarks"),mo(t,"world_hand_landmarks"),mo(t,"handedness");var e=new io;di(e,ya,this.h);var r=new uo;Kr(r,2,"mediapipe.tasks.vision.hand_landmarker.HandLandmarkerGraph"),ao(r,"IMAGE:image_in"),ao(r,"NORM_RECT:norm_rect"),ho(r,"LANDMARKS:hand_landmarks"),ho(r,"WORLD_LANDMARKS:world_hand_landmarks"),ho(r,"HANDEDNESS:handedness"),r.v(e),po(t,r),this.g.attachProtoVectorListener("hand_landmarks",(t,e)=>{for(let e of t)t=Fo(e),this.landmarks.push(th(t));eu(this,e)}),this.g.attachEmptyPacketListener("hand_landmarks",t=>{eu(this,t)}),this.g.attachProtoVectorListener("world_hand_landmarks",(t,e)=>{for(let e of t)t=Ro(e),this.worldLandmarks.push(eh(t));eu(this,e)}),this.g.attachEmptyPacketListener("world_hand_landmarks",t=>{eu(this,t)}),this.g.attachProtoVectorListener("handedness",(t,e)=>{var r=this.handedness,n=r.push,i=[];for(let e of t){t=bo(e);let r=[];for(let e of t.g())r.push({score:Pr(e,2)??0,index:Dr(e,1)??0??-1,categoryName:ye(or(e,3))??""??"",displayName:ye(or(e,4))??""??""});i.push(r)}n.call(r,...i),eu(this,e)}),this.g.attachEmptyPacketListener("handedness",t=>{eu(this,t)}),t=t.g(),this.setGraph(new Uint8Array(t),!0)}};Tc.prototype.detectForVideo=Tc.prototype.H,Tc.prototype.detect=Tc.prototype.G,Tc.prototype.setOptions=Tc.prototype.v,Tc.createFromModelPath=function(t,e){return Qu(Tc,t,{baseOptions:{modelAssetPath:e}})},Tc.createFromModelBuffer=function(t,e){return Qu(Tc,t,{baseOptions:{modelAssetBuffer:e}})},Tc.createFromOptions=function(t,e){return Qu(Tc,t,e)},Tc.HAND_CONNECTIONS=_c,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$hand_landmarker$hand_landmarker.HandLandmarker.HAND_CONNECTIONS",Tc.HAND_CONNECTIONS);var kc=Yu([0,1],[1,2],[2,3],[3,7],[0,4],[4,5],[5,6],[6,8],[9,10],[11,12],[11,13],[13,15],[15,17],[15,19],[15,21],[17,19],[12,14],[14,16],[16,18],[16,20],[16,22],[18,20],[11,23],[12,24],[23,24],[23,25],[24,26],[25,27],[26,28],[27,29],[28,30],[29,31],[30,32],[27,31],[28,32]);function Sc(t){t.h={faceLandmarks:[],faceBlendshapes:[],poseLandmarks:[],poseWorldLandmarks:[],poseSegmentationMasks:[],leftHandLandmarks:[],leftHandWorldLandmarks:[],rightHandLandmarks:[],rightHandWorldLandmarks:[]}}function Lc(t){try{if(!t.F)return t.h;t.F(t.h)}finally{iu(t)}}function xc(t,e){t=Fo(t),e.push(th(t))}var Rc=class extends ic{constructor(t,e){super(new Zu(t,e),"input_frames_image",null,!1),this.h={faceLandmarks:[],faceBlendshapes:[],poseLandmarks:[],poseWorldLandmarks:[],poseSegmentationMasks:[],leftHandLandmarks:[],leftHandWorldLandmarks:[],rightHandLandmarks:[],rightHandWorldLandmarks:[]},this.outputPoseSegmentationMasks=this.outputFaceBlendshapes=!1,Fr(t=this.l=new ba,0,1,e=new Yo),this.Y=new la,Fr(this.l,0,2,this.Y),this.Aa=new Ea,Fr(this.l,0,3,this.Aa),this.u=new Qo,Fr(this.l,0,4,this.u),this.O=new na,Fr(this.l,0,5,this.O),this.B=new Aa,Fr(this.l,0,6,this.B),this.Z=new wa,Fr(this.l,0,7,this.Z),Vr(this.u,2,.5),Vr(this.u,3,.3),Vr(this.O,2,.5),Vr(this.B,2,.5),Vr(this.B,3,.3),Vr(this.Z,2,.5),Vr(this.Y,2,.5)}C(){return"HolisticLandmarker"}get baseOptions(){return Lr(this.l,Yo,1)}set baseOptions(t){Fr(this.l,0,1,t)}v(t){return"minFaceDetectionConfidence"in t&&Vr(this.u,2,t.minFaceDetectionConfidence??.5),"minFaceSuppressionThreshold"in t&&Vr(this.u,3,t.minFaceSuppressionThreshold??.3),"minFacePresenceConfidence"in t&&Vr(this.O,2,t.minFacePresenceConfidence??.5),"outputFaceBlendshapes"in t&&(this.outputFaceBlendshapes=!!t.outputFaceBlendshapes),"minPoseDetectionConfidence"in t&&Vr(this.B,2,t.minPoseDetectionConfidence??.5),"minPoseSuppressionThreshold"in t&&Vr(this.B,3,t.minPoseSuppressionThreshold??.3),"minPosePresenceConfidence"in t&&Vr(this.Z,2,t.minPosePresenceConfidence??.5),"outputPoseSegmentationMasks"in t&&(this.outputPoseSegmentationMasks=!!t.outputPoseSegmentationMasks),"minHandLandmarksConfidence"in t&&Vr(this.Y,2,t.minHandLandmarksConfidence??.5),this.j(t)}G(t,e,r){var n="function"!=typeof e?e:{};return this.F="function"==typeof e?e:r,Sc(this),ec(this,t,n),Lc(this)}H(t,e,r,n){var i="function"!=typeof r?r:{};return this.F="function"==typeof r?r:n,Sc(this),rc(this,t,i,e),Lc(this)}o(){var t=new vo;go(t,"input_frames_image"),mo(t,"pose_landmarks"),mo(t,"pose_world_landmarks"),mo(t,"face_landmarks"),mo(t,"left_hand_landmarks"),mo(t,"left_hand_world_landmarks"),mo(t,"right_hand_landmarks"),mo(t,"right_hand_world_landmarks");var e=new io,r=new Gs;Kr(r,1,"type.googleapis.com/mediapipe.tasks.vision.holistic_landmarker.proto.HolisticLandmarkerGraphOptions"),function(t,e){if(null!=e)if(Array.isArray(e))hr(t,2,je(e,0,He));else{if(!("string"==typeof e||e instanceof M||R(e)))throw Error("invalid value in Any.value field: "+e+" expected a ByteString, a base64 encoded string, a Uint8Array or a jspb array");yr(t,2,lt(e,!1),F())}}(r,this.l.g());var n=new uo;Kr(n,2,"mediapipe.tasks.vision.holistic_landmarker.HolisticLandmarkerGraph"),Or(n,8,Gs,r),ao(n,"IMAGE:input_frames_image"),ho(n,"POSE_LANDMARKS:pose_landmarks"),ho(n,"POSE_WORLD_LANDMARKS:pose_world_landmarks"),ho(n,"FACE_LANDMARKS:face_landmarks"),ho(n,"LEFT_HAND_LANDMARKS:left_hand_landmarks"),ho(n,"LEFT_HAND_WORLD_LANDMARKS:left_hand_world_landmarks"),ho(n,"RIGHT_HAND_LANDMARKS:right_hand_landmarks"),ho(n,"RIGHT_HAND_WORLD_LANDMARKS:right_hand_world_landmarks"),n.v(e),po(t,n),ru(this,t),this.g.attachProtoListener("pose_landmarks",(t,e)=>{xc(t,this.h.poseLandmarks),eu(this,e)}),this.g.attachEmptyPacketListener("pose_landmarks",t=>{eu(this,t)}),this.g.attachProtoListener("pose_world_landmarks",(t,e)=>{var r=this.h.poseWorldLandmarks;t=Ro(t),r.push(eh(t)),eu(this,e)}),this.g.attachEmptyPacketListener("pose_world_landmarks",t=>{eu(this,t)}),this.outputPoseSegmentationMasks&&(ho(n,"POSE_SEGMENTATION_MASK:pose_segmentation_mask"),nu(this,"pose_segmentation_mask"),this.g.ga("pose_segmentation_mask",(t,e)=>{this.h.poseSegmentationMasks=[nc(this,t,!0,!this.F)],eu(this,e)}),this.g.attachEmptyPacketListener("pose_segmentation_mask",t=>{this.h.poseSegmentationMasks=[],eu(this,t)})),this.g.attachProtoListener("face_landmarks",(t,e)=>{xc(t,this.h.faceLandmarks),eu(this,e)}),this.g.attachEmptyPacketListener("face_landmarks",t=>{eu(this,t)}),this.outputFaceBlendshapes&&(mo(t,"extra_blendshapes"),ho(n,"FACE_BLENDSHAPES:extra_blendshapes"),this.g.attachProtoListener("extra_blendshapes",(t,e)=>{var r=this.h.faceBlendshapes;this.outputFaceBlendshapes&&(t=bo(t),r.push(Ja(t.g()??[]))),eu(this,e)}),this.g.attachEmptyPacketListener("extra_blendshapes",t=>{eu(this,t)})),this.g.attachProtoListener("left_hand_landmarks",(t,e)=>{xc(t,this.h.leftHandLandmarks),eu(this,e)}),this.g.attachEmptyPacketListener("left_hand_landmarks",t=>{eu(this,t)}),this.g.attachProtoListener("left_hand_world_landmarks",(t,e)=>{var r=this.h.leftHandWorldLandmarks;t=Ro(t),r.push(eh(t)),eu(this,e)}),this.g.attachEmptyPacketListener("left_hand_world_landmarks",t=>{eu(this,t)}),this.g.attachProtoListener("right_hand_landmarks",(t,e)=>{xc(t,this.h.rightHandLandmarks),eu(this,e)}),this.g.attachEmptyPacketListener("right_hand_landmarks",t=>{eu(this,t)}),this.g.attachProtoListener("right_hand_world_landmarks",(t,e)=>{var r=this.h.rightHandWorldLandmarks;t=Ro(t),r.push(eh(t)),eu(this,e)}),this.g.attachEmptyPacketListener("right_hand_world_landmarks",t=>{eu(this,t)}),t=t.g(),this.setGraph(new Uint8Array(t),!0)}};Rc.prototype.detectForVideo=Rc.prototype.H,Rc.prototype.detect=Rc.prototype.G,Rc.prototype.setOptions=Rc.prototype.v,Rc.createFromModelPath=function(t,e){return Qu(Rc,t,{baseOptions:{modelAssetPath:e}})},Rc.createFromModelBuffer=function(t,e){return Qu(Rc,t,{baseOptions:{modelAssetBuffer:e}})},Rc.createFromOptions=function(t,e){return Qu(Rc,t,e)},Rc.HAND_CONNECTIONS=_c,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$holistic_landmarker$holistic_landmarker.HolisticLandmarker.HAND_CONNECTIONS",Rc.HAND_CONNECTIONS),Rc.POSE_CONNECTIONS=kc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$holistic_landmarker$holistic_landmarker.HolisticLandmarker.POSE_CONNECTIONS",Rc.POSE_CONNECTIONS),Rc.FACE_LANDMARKS_LIPS=oc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$holistic_landmarker$holistic_landmarker.HolisticLandmarker.FACE_LANDMARKS_LIPS",Rc.FACE_LANDMARKS_LIPS),Rc.FACE_LANDMARKS_LEFT_EYE=ac,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$holistic_landmarker$holistic_landmarker.HolisticLandmarker.FACE_LANDMARKS_LEFT_EYE",Rc.FACE_LANDMARKS_LEFT_EYE),Rc.FACE_LANDMARKS_LEFT_EYEBROW=hc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$holistic_landmarker$holistic_landmarker.HolisticLandmarker.FACE_LANDMARKS_LEFT_EYEBROW",Rc.FACE_LANDMARKS_LEFT_EYEBROW),Rc.FACE_LANDMARKS_LEFT_IRIS=uc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$holistic_landmarker$holistic_landmarker.HolisticLandmarker.FACE_LANDMARKS_LEFT_IRIS",Rc.FACE_LANDMARKS_LEFT_IRIS),Rc.FACE_LANDMARKS_RIGHT_EYE=cc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$holistic_landmarker$holistic_landmarker.HolisticLandmarker.FACE_LANDMARKS_RIGHT_EYE",Rc.FACE_LANDMARKS_RIGHT_EYE),Rc.FACE_LANDMARKS_RIGHT_EYEBROW=lc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$holistic_landmarker$holistic_landmarker.HolisticLandmarker.FACE_LANDMARKS_RIGHT_EYEBROW",Rc.FACE_LANDMARKS_RIGHT_EYEBROW),Rc.FACE_LANDMARKS_RIGHT_IRIS=dc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$holistic_landmarker$holistic_landmarker.HolisticLandmarker.FACE_LANDMARKS_RIGHT_IRIS",Rc.FACE_LANDMARKS_RIGHT_IRIS),Rc.FACE_LANDMARKS_FACE_OVAL=fc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$holistic_landmarker$holistic_landmarker.HolisticLandmarker.FACE_LANDMARKS_FACE_OVAL",Rc.FACE_LANDMARKS_FACE_OVAL),Rc.FACE_LANDMARKS_CONTOURS=pc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$holistic_landmarker$holistic_landmarker.HolisticLandmarker.FACE_LANDMARKS_CONTOURS",Rc.FACE_LANDMARKS_CONTOURS),Rc.FACE_LANDMARKS_TESSELATION=gc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$holistic_landmarker$holistic_landmarker.HolisticLandmarker.FACE_LANDMARKS_TESSELATION",Rc.FACE_LANDMARKS_TESSELATION);var Ic=class extends ic{constructor(t,e){super(new Zu(t,e),"input_image","norm_rect",!0),this.l={classifications:[]},Fr(t=this.h=new Sa,0,1,e=new Yo)}C(){return"ImageClassifier"}get baseOptions(){return Lr(this.h,Yo,1)}set baseOptions(t){Fr(this.h,0,1,t)}v(t){return Fr(this.h,0,2,Ya(t,Lr(this.h,jo,2))),this.j(t)}Ga(t,e){return this.l={classifications:[]},ec(this,t,e),this.l}Ha(t,e,r){return this.l={classifications:[]},rc(this,t,r,e),this.l}o(){var t=new vo;go(t,"input_image"),go(t,"norm_rect"),mo(t,"classifications");var e=new io;di(e,La,this.h);var r=new uo;Kr(r,2,"mediapipe.tasks.vision.image_classifier.ImageClassifierGraph"),ao(r,"IMAGE:input_image"),ao(r,"NORM_RECT:norm_rect"),ho(r,"CLASSIFICATIONS:classifications"),r.v(e),po(t,r),this.g.attachProtoListener("classifications",(t,e)=>{this.l=Za(Do(t)),eu(this,e)}),this.g.attachEmptyPacketListener("classifications",t=>{eu(this,t)}),t=t.g(),this.setGraph(new Uint8Array(t),!0)}};Ic.prototype.classifyForVideo=Ic.prototype.Ha,Ic.prototype.classify=Ic.prototype.Ga,Ic.prototype.setOptions=Ic.prototype.v,Ic.createFromModelPath=function(t,e){return Qu(Ic,t,{baseOptions:{modelAssetPath:e}})},Ic.createFromModelBuffer=function(t,e){return Qu(Ic,t,{baseOptions:{modelAssetBuffer:e}})},Ic.createFromOptions=function(t,e){return Qu(Ic,t,e)};var Fc=class extends ic{constructor(t,e){super(new Zu(t,e),"image_in","norm_rect",!0),this.h=new xa,this.embeddings={embeddings:[]},Fr(t=this.h,0,1,e=new Yo)}C(){return"ImageEmbedder"}get baseOptions(){return Lr(this.h,Yo,1)}set baseOptions(t){Fr(this.h,0,1,t)}v(t){var e=this.h,r=Lr(this.h,Ho,2);if(r=r?r.clone():new Ho,void 0!==t.l2Normalize){var n=t.l2Normalize;hr(r,1,null==n?n:Qt(n))}else"l2Normalize"in t&&hr(r,1);return void 0!==t.quantize?hr(r,2,null==(n=t.quantize)?n:Qt(n)):"quantize"in t&&hr(r,2),Fr(e,0,2,r),this.j(t)}Na(t,e){return ec(this,t,e),this.embeddings}Oa(t,e,r){return rc(this,t,r,e),this.embeddings}o(){var t=new vo;go(t,"image_in"),go(t,"norm_rect"),mo(t,"embeddings_out");var e=new io;di(e,Ra,this.h);var r=new uo;Kr(r,2,"mediapipe.tasks.vision.image_embedder.ImageEmbedderGraph"),ao(r,"IMAGE:image_in"),ao(r,"NORM_RECT:norm_rect"),ho(r,"EMBEDDINGS:embeddings_out"),r.v(e),po(t,r),this.g.attachProtoListener("embeddings_out",(t,e)=>{t=Go(t),this.embeddings=function(t){return{embeddings:Rr(t,Uo,1).map(t=>{var e={headIndex:Dr(t,3)??0??-1,headName:ye(or(t,4))??""??""};if(cr(t,Po,1,Bo))t=dr(t=$r(t,Po,1),1,Zt,lr()),e.floatEmbedding=t.slice();else{let r=new Uint8Array(0);e.quantizedEmbedding=$r(t,$o,2)?.g()?.h()??r}return e}),timestampMs:qa(or(t,2,void 0,pe)??ir)}}(t),eu(this,e)}),this.g.attachEmptyPacketListener("embeddings_out",t=>{eu(this,t)}),t=t.g(),this.setGraph(new Uint8Array(t),!0)}};Fc.cosineSimilarity=function(t,e){if(t.floatEmbedding&&e.floatEmbedding)t=nh(t.floatEmbedding,e.floatEmbedding);else{if(!t.quantizedEmbedding||!e.quantizedEmbedding)throw Error("Cannot compute cosine similarity between quantized and float embeddings.");t=nh(rh(t.quantizedEmbedding),rh(e.quantizedEmbedding))}return t},Fc.prototype.embedForVideo=Fc.prototype.Oa,Fc.prototype.embed=Fc.prototype.Na,Fc.prototype.setOptions=Fc.prototype.v,Fc.createFromModelPath=function(t,e){return Qu(Fc,t,{baseOptions:{modelAssetPath:e}})},Fc.createFromModelBuffer=function(t,e){return Qu(Fc,t,{baseOptions:{modelAssetBuffer:e}})},Fc.createFromOptions=function(t,e){return Qu(Fc,t,e)};var Cc=class{constructor(t,e,r){this.confidenceMasks=t,this.categoryMask=e,this.qualityScores=r}close(){this.confidenceMasks?.forEach(t=>{t.close()}),this.categoryMask?.close()}};function Nc(t){var e=function(t){return Rr(t,uo,1)}(t.ja()).filter(t=>(ye(or(t,1))??"").includes("mediapipe.tasks.TensorsToSegmentationCalculator"));if(t.u=[],e.length>1)throw Error("The graph has more than one mediapipe.tasks.TensorsToSegmentationCalculator.");1===e.length&&(Lr(e[0],io,7)?.o()?.g()??new Map).forEach((e,r)=>{t.u[Number(r)]=ye(or(e,1))??""})}function Mc(t){t.categoryMask=void 0,t.confidenceMasks=void 0,t.qualityScores=void 0}function Oc(t){try{let e=new Cc(t.confidenceMasks,t.categoryMask,t.qualityScores);if(!t.l)return e;t.l(e)}finally{iu(t)}}Cc.prototype.close=Cc.prototype.close;var Dc=class extends ic{constructor(t,e){super(new Zu(t,e),"image_in","norm_rect",!1),this.u=[],this.outputCategoryMask=!1,this.outputConfidenceMasks=!0,this.h=new Ma,this.B=new Ia,Fr(this.h,0,3,this.B),Fr(t=this.h,0,1,e=new Yo)}C(){return"ImageSegmenter"}get baseOptions(){return Lr(this.h,Yo,1)}set baseOptions(t){Fr(this.h,0,1,t)}v(t){return void 0!==t.displayNamesLocale?hr(this.h,2,_e(t.displayNamesLocale)):"displayNamesLocale"in t&&hr(this.h,2),"outputCategoryMask"in t&&(this.outputCategoryMask=t.outputCategoryMask??!1),"outputConfidenceMasks"in t&&(this.outputConfidenceMasks=t.outputConfidenceMasks??!0),super.j(t)}L(){Nc(this)}segment(t,e,r){var n="function"!=typeof e?e:{};return this.l="function"==typeof e?e:r,Mc(this),ec(this,t,n),Oc(this)}eb(t,e,r,n){var i="function"!=typeof r?r:{};return this.l="function"==typeof r?r:n,Mc(this),rc(this,t,i,e),Oc(this)}Ra(){return this.u}o(){var t=new vo;go(t,"image_in"),go(t,"norm_rect");var e=new io;di(e,Oa,this.h);var r=new uo;Kr(r,2,"mediapipe.tasks.vision.image_segmenter.ImageSegmenterGraph"),ao(r,"IMAGE:image_in"),ao(r,"NORM_RECT:norm_rect"),r.v(e),po(t,r),ru(this,t),this.outputConfidenceMasks&&(mo(t,"confidence_masks"),ho(r,"CONFIDENCE_MASKS:confidence_masks"),nu(this,"confidence_masks"),this.g.ha("confidence_masks",(t,e)=>{this.confidenceMasks=t.map(t=>nc(this,t,!0,!this.l)),eu(this,e)}),this.g.attachEmptyPacketListener("confidence_masks",t=>{this.confidenceMasks=[],eu(this,t)})),this.outputCategoryMask&&(mo(t,"category_mask"),ho(r,"CATEGORY_MASK:category_mask"),nu(this,"category_mask"),this.g.ga("category_mask",(t,e)=>{this.categoryMask=nc(this,t,!1,!this.l),eu(this,e)}),this.g.attachEmptyPacketListener("category_mask",t=>{this.categoryMask=void 0,eu(this,t)})),mo(t,"quality_scores"),ho(r,"QUALITY_SCORES:quality_scores"),this.g.attachFloatVectorListener("quality_scores",(t,e)=>{this.qualityScores=t,eu(this,e)}),this.g.attachEmptyPacketListener("quality_scores",t=>{this.categoryMask=void 0,eu(this,t)}),t=t.g(),this.setGraph(new Uint8Array(t),!0)}};Dc.prototype.getLabels=Dc.prototype.Ra,Dc.prototype.segmentForVideo=Dc.prototype.eb,Dc.prototype.segment=Dc.prototype.segment,Dc.prototype.setOptions=Dc.prototype.v,Dc.createFromModelPath=function(t,e){return Qu(Dc,t,{baseOptions:{modelAssetPath:e}})},Dc.createFromModelBuffer=function(t,e){return Qu(Dc,t,{baseOptions:{modelAssetBuffer:e}})},Dc.createFromOptions=function(t,e){return Qu(Dc,t,e)};var Pc={0:0,1:1,2:2,3:3};function $c(){return $h()?void 0:document.createElement("canvas")}var Uc=class extends su{constructor(t,e){super(new qh(t,e)),this.u=new gu,this.delegate="CPU",this.h=0,this.baseOptions=new Yo,this.B=this.l=0}C(){return"InteractiveSegmenter"}get i(){return this.g.i}v(t){return this.delegate=t.baseOptions?.delegate??"CPU",super.j(t)}fb(t){if(0===this.h)throw Error("Segmenter is not initialized.");var e;if(0!==this.l&&(this.i._free(this.l),this.l=0),!(e="undefined"!=typeof ImageData&&t instanceof ImageData))if("object"!=typeof t||null===t)e=!1;else{e=t.data;var r=t.width,n=t.height;e=Number.isInteger(r)&&r>0&&Number.isInteger(n)&&n>0&&(e instanceof Uint8ClampedArray||e instanceof Uint8Array)}if(e)e=t.width,r=t.height,t=t.data;else{if([e,r]=Bh(t),"undefined"!=typeof OffscreenCanvas)n=new OffscreenCanvas(e,r);else{if("undefined"==typeof document)throw Error("Canvas is not supported in this environment.");n=document.createElement("canvas")}if(n.width=e,n.height=r,!(n=n.getContext("2d")))throw Error("Canvas 2D context is not supported in this environment.");n.drawImage(t,0,0),t=n.getImageData(0,0,e,r).data}if(!t)throw Error("Unsupported image source or failed to extract image pixels.");n=function({Wa:t,width:e,height:r}){if(e<=0||r<=0)throw Error(`Invalid image dimensions: ${e}x${r}. Dimensions must be positive.`);if(t%(e*r)!==0)throw Error(`Invalid image dimensions or pixel data length. Pixel data length ${t} is not a multiple of the number of pixels (${e*r}).`);if(4!==(t/=e*r)&&3!==t&&1!==t)throw Error(`Invalid image dimensions or pixel data length. Calculated channels: ${t}. Expected 1, 3, or 4.`);return t}({Wa:t.length,width:e,height:r});var i=this.i._malloc(t.length);if(this.i.HEAPU8.set(t,i),this.l=i,!this.i._interactive_segmenter_set_image(this.h,i,e,r,n))throw Error("Failed to set image on native engine.")}segment(t){if(0===this.h)throw Error("Segmenter is not initialized.");var e=function(t){t=t.map(({isCompleted:t,brushMode:e,point:r})=>{e=Pc[e]??0,r=r.map(({x:t,y:e})=>{var r=new Da;return Hr(r,1,t),Hr(r,2,e),r});var n=new Pa;return Ur(n,t),yr(n,1,re(e),0),Nr(n,2,r),n});var e=new $a;return Nr(e,1,t),Ua(e)}(t);t=this.i._malloc(e.length),this.i.HEAPU8.set(e,t);var r=this.i._malloc(12),n=r+4,i=r+8,s=0,o=this.B++;try{if(this.m)if("GPU"===this.delegate){var a=this.m;++a.g.T,a.h.set(o,performance.now())}else{var h=this.m;++h.g.P,h.h.set(o,performance.now())}if(0===(s=this.i._interactive_segmenter_segment(this.h,t,e.length,r,n,i)))throw Error("Segmentation failed.");this.m?.za(o);let c=this.i.HEAPU32[r/4],l=this.i.HEAPU32[n/4],d=new Float32Array(this.i.HEAPU8.buffer,s,this.i.HEAPU32[i/4]/4);var u=new Float32Array(d);if(a=c*l,(u instanceof Uint8Array||u instanceof Float32Array)&&u.length!==a)throw Error("Unsupported channel count: "+u.length/a);return new Lu([u],!0,!1,this.g.i.canvas??void 0,this.u,c,l)}finally{0!==t&&this.i._free(t),0!==r&&this.i._free(r),0!==s&&this.i._free(s)}}o(){0!==this.h&&(this.m?.xa(),this.i._interactive_segmenter_close(this.h),this.h=0),0!==this.l&&(this.i._free(this.l),this.l=0);var t=new Xo;if("GPU"===this.delegate){var e=new qs;Cr(t,2,Wo,e)}else Br(e=new ro,1,4),Cr(t,1,Wo,e);if(Fr(this.baseOptions,0,3,t),t=Zo(this.baseOptions),e=this.i._malloc(t.length),this.i.HEAPU8.set(t,e),this.h=this.i._interactive_segmenter_create(e,t.length),this.i._free(e),0===this.h)throw Error("Failed to create native InteractiveSegmenter engine.");this.m?.ya()}close(){0!==this.h&&(this.i._interactive_segmenter_close(this.h),this.h=0),0!==this.l&&(this.i._free(this.l),this.l=0),this.u.close(),super.close()}};Uc.prototype.close=Uc.prototype.close,Uc.prototype.segment=Uc.prototype.segment,Uc.prototype.setImage=Uc.prototype.fb,Uc.prototype.setOptions=Uc.prototype.v,Uc.createFromModelPath=function(t,e){return Zh(Uc,$c(),t,{baseOptions:{modelAssetPath:e}})},Uc.createFromModelBuffer=function(t,e){return Zh(Uc,$c(),t,{baseOptions:{modelAssetBuffer:e}})},Uc.createFromOptions=function(t,e){var r=e.canvas??$c();return Zh(Uc,r,t,e)};var Bc=class{constructor(t,e,r){this.confidenceMasks=t,this.categoryMask=e,this.qualityScores=r}close(){this.confidenceMasks?.forEach(t=>{t.close()}),this.categoryMask?.close()}};Bc.prototype.close=Bc.prototype.close;var Gc=class extends ic{constructor(t,e){super(new Zu(t,e),"image_in","norm_rect_in",!1),this.outputCategoryMask=!1,this.outputConfidenceMasks=!0,this.h=new Ma,this.u=new Ia,Fr(this.h,0,3,this.u),Fr(t=this.h,0,1,e=new Yo)}C(){return"InteractiveSegmenterLegacy"}get baseOptions(){return Lr(this.h,Yo,1)}set baseOptions(t){Fr(this.h,0,1,t)}v(t){return"outputCategoryMask"in t&&(this.outputCategoryMask=t.outputCategoryMask??!1),"outputConfidenceMasks"in t&&(this.outputConfidenceMasks=t.outputConfidenceMasks??!0),super.j(t)}segment(t,e,r,n){var i="function"!=typeof r?r:{};if(this.l="function"==typeof r?r:n,this.qualityScores=this.categoryMask=this.confidenceMasks=void 0,r=this.I+1,n=new Va,e.keypoint&&e.scribble)throw Error("Cannot provide both keypoint and scribble.");if(e.keypoint){var s=new Ba;Ur(s,!0),Hr(s,1,e.keypoint.x),Hr(s,2,e.keypoint.y),Cr(n,1,Ha,s)}else{if(!e.scribble)throw Error("Must provide either a keypoint or a scribble.");{let t=new ja;for(s of e.scribble)Ur(e=new Ba,!0),Hr(e,1,s.x),Hr(e,2,s.y),Or(t,1,Ba,e);Cr(n,2,Ha,t)}}this.g.addProtoToStream(n.g(),"mediapipe.tasks.vision.interactive_segmenter_legacy.proto.RegionOfInterest","roi_in",r),ec(this,t,i);t:{try{let t=new Bc(this.confidenceMasks,this.categoryMask,this.qualityScores);if(!this.l){var o=t;break t}this.l(t)}finally{iu(this)}o=void 0}return o}o(){var t=new vo;go(t,"image_in"),go(t,"roi_in"),go(t,"norm_rect_in");var e=new io;di(e,Oa,this.h);var r=new uo;Kr(r,2,"mediapipe.tasks.vision.interactive_segmenter_legacy.InteractiveSegmenterGraphV2"),ao(r,"IMAGE:image_in"),ao(r,"ROI:roi_in"),ao(r,"NORM_RECT:norm_rect_in"),r.v(e),po(t,r),ru(this,t),this.outputConfidenceMasks&&(mo(t,"confidence_masks"),ho(r,"CONFIDENCE_MASKS:confidence_masks"),nu(this,"confidence_masks"),this.g.ha("confidence_masks",(t,e)=>{this.confidenceMasks=t.map(t=>nc(this,t,!0,!this.l)),eu(this,e)}),this.g.attachEmptyPacketListener("confidence_masks",t=>{this.confidenceMasks=[],eu(this,t)})),this.outputCategoryMask&&(mo(t,"category_mask"),ho(r,"CATEGORY_MASK:category_mask"),nu(this,"category_mask"),this.g.ga("category_mask",(t,e)=>{this.categoryMask=nc(this,t,!1,!this.l),eu(this,e)}),this.g.attachEmptyPacketListener("category_mask",t=>{this.categoryMask=void 0,eu(this,t)})),mo(t,"quality_scores"),ho(r,"QUALITY_SCORES:quality_scores"),this.g.attachFloatVectorListener("quality_scores",(t,e)=>{this.qualityScores=t,eu(this,e)}),this.g.attachEmptyPacketListener("quality_scores",t=>{this.categoryMask=void 0,eu(this,t)}),t=t.g(),this.setGraph(new Uint8Array(t),!0)}};Gc.prototype.segment=Gc.prototype.segment,Gc.prototype.setOptions=Gc.prototype.v,Gc.createFromModelPath=function(t,e){return Qu(Gc,t,{baseOptions:{modelAssetPath:e}})},Gc.createFromModelBuffer=function(t,e){return Qu(Gc,t,{baseOptions:{modelAssetBuffer:e}})},Gc.createFromOptions=function(t,e){return Qu(Gc,t,e)};var jc=class extends ic{constructor(t,e){super(new Zu(t,e),"input_frame_gpu","norm_rect",!1),this.l={detections:[]},Fr(t=this.h=new Ka,0,1,e=new Yo)}C(){return"ObjectDetector"}get baseOptions(){return Lr(this.h,Yo,1)}set baseOptions(t){Fr(this.h,0,1,t)}v(t){return void 0!==t.displayNamesLocale?hr(this.h,2,_e(t.displayNamesLocale)):"displayNamesLocale"in t&&hr(this.h,2),void 0!==t.maxResults?Br(this.h,3,t.maxResults):"maxResults"in t&&hr(this.h,3),void 0!==t.scoreThreshold?Vr(this.h,4,t.scoreThreshold):"scoreThreshold"in t&&hr(this.h,4),void 0!==t.categoryAllowlist?Xr(this.h,5,t.categoryAllowlist):"categoryAllowlist"in t&&hr(this.h,5),void 0!==t.categoryDenylist?Xr(this.h,6,t.categoryDenylist):"categoryDenylist"in t&&hr(this.h,6),this.j(t)}G(t,e){return this.l={detections:[]},ec(this,t,e),this.l}H(t,e,r){return this.l={detections:[]},rc(this,t,r,e),this.l}o(){var t=new vo;go(t,"input_frame_gpu"),go(t,"norm_rect"),mo(t,"detections");var e=new io;di(e,Xa,this.h);var r=new uo;Kr(r,2,"mediapipe.tasks.vision.ObjectDetectorGraph"),ao(r,"IMAGE:input_frame_gpu"),ao(r,"NORM_RECT:norm_rect"),ho(r,"DETECTIONS:detections"),r.v(e),po(t,r),this.g.attachProtoVectorListener("detections",(t,e)=>{for(let e of t)t=Lo(e),this.l.detections.push(Qa(t));eu(this,e)}),this.g.attachEmptyPacketListener("detections",t=>{eu(this,t)}),t=t.g(),this.setGraph(new Uint8Array(t),!0)}};jc.prototype.detectForVideo=jc.prototype.H,jc.prototype.detect=jc.prototype.G,jc.prototype.setOptions=jc.prototype.v,jc.createFromModelPath=async function(t,e){return Qu(jc,t,{baseOptions:{modelAssetPath:e}})},jc.createFromModelBuffer=function(t,e){return Qu(jc,t,{baseOptions:{modelAssetBuffer:e}})},jc.createFromOptions=function(t,e){return Qu(jc,t,e)};var Vc=class{constructor(t,e,r){this.landmarks=t,this.worldLandmarks=e,this.segmentationMasks=r}close(){this.segmentationMasks?.forEach(t=>{t.close()})}};function Hc(t){t.landmarks=[],t.worldLandmarks=[],t.segmentationMasks=void 0}function Kc(t){try{let e=new Vc(t.landmarks,t.worldLandmarks,t.segmentationMasks);if(!t.u)return e;t.u(e)}finally{iu(t)}}Vc.prototype.close=Vc.prototype.close;var Xc=class extends ic{constructor(t,e){super(new Zu(t,e),"image_in","norm_rect",!1),this.landmarks=[],this.worldLandmarks=[],this.outputSegmentationMasks=!1,Fr(t=this.h=new Wa,0,1,e=new Yo),this.B=new wa,Fr(this.h,0,3,this.B),this.l=new Aa,Fr(this.h,0,2,this.l),Br(this.l,4,1),Vr(this.l,2,.5),Vr(this.B,2,.5),Vr(this.h,4,.5)}C(){return"PoseLandmarker"}get baseOptions(){return Lr(this.h,Yo,1)}set baseOptions(t){Fr(this.h,0,1,t)}v(t){return"numPoses"in t&&Br(this.l,4,t.numPoses??1),"minPoseDetectionConfidence"in t&&Vr(this.l,2,t.minPoseDetectionConfidence??.5),"minTrackingConfidence"in t&&Vr(this.h,4,t.minTrackingConfidence??.5),"minPosePresenceConfidence"in t&&Vr(this.B,2,t.minPosePresenceConfidence??.5),"outputSegmentationMasks"in t&&(this.outputSegmentationMasks=t.outputSegmentationMasks??!1),this.j(t)}G(t,e,r){var n="function"!=typeof e?e:{};return this.u="function"==typeof e?e:r,Hc(this),ec(this,t,n),Kc(this)}H(t,e,r,n){var i="function"!=typeof r?r:{};return this.u="function"==typeof r?r:n,Hc(this),rc(this,t,i,e),Kc(this)}o(){var t=new vo;go(t,"image_in"),go(t,"norm_rect"),mo(t,"normalized_landmarks"),mo(t,"world_landmarks"),mo(t,"segmentation_masks");var e=new io;di(e,za,this.h);var r=new uo;Kr(r,2,"mediapipe.tasks.vision.pose_landmarker.PoseLandmarkerGraph"),ao(r,"IMAGE:image_in"),ao(r,"NORM_RECT:norm_rect"),ho(r,"NORM_LANDMARKS:normalized_landmarks"),ho(r,"WORLD_LANDMARKS:world_landmarks"),r.v(e),po(t,r),ru(this,t),this.g.attachProtoVectorListener("normalized_landmarks",(t,e)=>{this.landmarks=[];for(let e of t)t=Fo(e),this.landmarks.push(th(t));eu(this,e)}),this.g.attachEmptyPacketListener("normalized_landmarks",t=>{this.landmarks=[],eu(this,t)}),this.g.attachProtoVectorListener("world_landmarks",(t,e)=>{this.worldLandmarks=[];for(let e of t)t=Ro(e),this.worldLandmarks.push(eh(t));eu(this,e)}),this.g.attachEmptyPacketListener("world_landmarks",t=>{this.worldLandmarks=[],eu(this,t)}),this.outputSegmentationMasks&&(ho(r,"SEGMENTATION_MASK:segmentation_masks"),nu(this,"segmentation_masks"),this.g.ha("segmentation_masks",(t,e)=>{this.segmentationMasks=t.map(t=>nc(this,t,!0,!this.u)),eu(this,e)}),this.g.attachEmptyPacketListener("segmentation_masks",t=>{this.segmentationMasks=[],eu(this,t)})),t=t.g(),this.setGraph(new Uint8Array(t),!0)}};return Xc.prototype.detectForVideo=Xc.prototype.H,Xc.prototype.detect=Xc.prototype.G,Xc.prototype.setOptions=Xc.prototype.v,Xc.createFromModelPath=function(t,e){return Qu(Xc,t,{baseOptions:{modelAssetPath:e}})},Xc.createFromModelBuffer=function(t,e){return Qu(Xc,t,{baseOptions:{modelAssetBuffer:e}})},Xc.createFromOptions=function(t,e){return Qu(Xc,t,e)},Xc.POSE_CONNECTIONS=kc,n("module$exports$google3$third_party$mediapipe$tasks$web$vision$pose_landmarker$pose_landmarker.PoseLandmarker.POSE_CONNECTIONS",Xc.POSE_CONNECTIONS),t.DrawingUtils=$u,t.FaceDetector=sc,t.FaceLandmarker=vc,t.FilesetResolver=hh,t.GestureRecognizer=wc,t.HandLandmarker=Tc,t.HolisticLandmarker=Rc,t.ImageClassifier=Ic,t.ImageEmbedder=Fc,t.ImageSegmenter=Dc,t.ImageSegmenterResult=Cc,t.InteractiveSegmenter=Uc,t.InteractiveSegmenterLegacy=Gc,t.InteractiveSegmenterLegacyResult=Bc,t.MPImage=Wu,t.MPMask=Lu,t.ObjectDetector=jc,t.PoseLandmarker=Xc,t.TaskRunner=su,t.VisionTaskRunner=ic,t}({}); +//# sourceMappingURL=vision_bundle_iife.js.map diff --git a/frontend/public/mediapipe/wasm/vision_wasm_internal.js b/frontend/public/mediapipe/wasm/vision_wasm_internal.js new file mode 100644 index 0000000..3b1516a --- /dev/null +++ b/frontend/public/mediapipe/wasm/vision_wasm_internal.js @@ -0,0 +1,8840 @@ +// This code implements the `-sMODULARIZE` settings by taking the generated +// JS program code (INNER_JS_CODE) and wrapping it in a factory function. + +// Single threaded MINIMAL_RUNTIME programs do not need access to +// document.currentScript, so a simple export declaration is enough. +var ModuleFactory = (() => { + // When MODULARIZE this JS may be executed later, + // after document.currentScript is gone, so we save it. + // In EXPORT_ES6 mode we can just use 'import.meta.url'. + var _scriptName = globalThis.document?.currentScript?.src; + return async function(moduleArg = {}) { + var Module = moduleArg; +// include: shell.js +// include: minimum_runtime_check.js +// end include: minimum_runtime_check.js +// The Module object: Our interface to the outside world. We import +// and export values on it. There are various ways Module can be used: +// 1. Not defined. We create it here +// 2. A function parameter, function(moduleArg) => Promise +// 3. pre-run appended it, var Module = {}; ..generated code.. +// 4. External script tag defines var Module. +// We need to check if Module already exists (e.g. case 3 above). +// Substitution will be replaced with actual code on later stage of the build, +// this way Closure Compiler will not mangle it (e.g. case 4. above). +// Note that if you want to run closure, and also to use Module +// after the generated code, you will need to define var Module = {}; +// before the code. Then that object will be used in the code, and you +// can continue to use Module afterwards as well. +// Determine the runtime environment we are in. You can customize this by +// setting the ENVIRONMENT setting at compile time (see settings.js). +// Attempt to auto-detect the environment +var ENVIRONMENT_IS_WEB = !!globalThis.window; + +var ENVIRONMENT_IS_WORKER = !!globalThis.WorkerGlobalScope; + +// N.b. Electron.js environment is simultaneously a NODE-environment, but +// also a web environment. +var ENVIRONMENT_IS_NODE = globalThis.process?.versions?.node && globalThis.process?.type != "renderer"; + +// --pre-jses are emitted after the Module integration code, so that they can +// refer to Module (if they choose; they can also define Module) +var programArgs = []; + +var thisProgram = "./this.program"; + +var quit_ = (status, toThrow) => { + throw toThrow; +}; + +if (typeof __filename != "undefined") { + // Node + _scriptName = __filename; +} else if (ENVIRONMENT_IS_WORKER) { + _scriptName = self.location.href; +} + +// `/` should be present at the end if `scriptDirectory` is not empty +var scriptDirectory = ""; + +function locateFile(path) { + if (Module["locateFile"]) { + return Module["locateFile"](path, scriptDirectory); + } + return scriptDirectory + path; +} + +// Hooks that are implemented differently in different runtime environments. +var readAsync, readBinary; + +if (ENVIRONMENT_IS_NODE) { + // These modules will usually be used on Node.js. Load them eagerly to avoid + // the complexity of lazy-loading. + var fs = require("node:fs"); + scriptDirectory = __dirname + "/"; + // include: node_shell_read.js + readBinary = filename => { + // We need to re-wrap `file://` strings to URLs. + filename = isFileURI(filename) ? new URL(filename) : filename; + var ret = fs.readFileSync(filename); + return ret; + }; + readAsync = async (filename, binary = true) => { + // See the comment in the `readBinary` function. + filename = isFileURI(filename) ? new URL(filename) : filename; + var ret = fs.readFileSync(filename, binary ? undefined : "utf8"); + return ret; + }; + // end include: node_shell_read.js + if (process.argv.length > 1) { + thisProgram = process.argv[1].replace(/\\/g, "/"); + } + programArgs = process.argv.slice(2); + quit_ = (status, toThrow) => { + process.exitCode = status; + throw toThrow; + }; +} else // Note that this includes Node.js workers when relevant (pthreads is enabled). +// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and +// ENVIRONMENT_IS_NODE. +if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { + try { + scriptDirectory = new URL(".", _scriptName).href; + } catch {} + { + // include: web_or_worker_shell_read.js + if (ENVIRONMENT_IS_WORKER) { + readBinary = url => { + var xhr = new XMLHttpRequest; + xhr.open("GET", url, false); + xhr.responseType = "arraybuffer"; + xhr.send(null); + return new Uint8Array(/** @type{!ArrayBuffer} */ (xhr.response)); + }; + } + readAsync = async url => { + // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url. + // See https://github.com/github/fetch/pull/92#issuecomment-140665932 + // Cordova or Electron apps are typically loaded from a file:// url. + // So use XHR on webview if URL is a file URL. + if (isFileURI(url)) { + return new Promise((resolve, reject) => { + var xhr = new XMLHttpRequest; + xhr.open("GET", url, true); + xhr.responseType = "arraybuffer"; + xhr.onload = () => { + if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { + // file URLs can return 0 + resolve(xhr.response); + return; + } + reject(xhr.status); + }; + xhr.onerror = reject; + xhr.send(null); + }); + } + var response = await fetch(url, { + credentials: "same-origin" + }); + if (response.ok) { + return response.arrayBuffer(); + } + throw new Error(response.status + " : " + response.url); + }; + } +} else {} + +var out = console.log.bind(console); + +var err = console.error.bind(console); + +// end include: shell.js +// include: preamble.js +// === Preamble library stuff === +// Documentation for the public APIs defined in this file must be updated in: +// site/source/docs/api_reference/preamble.js.rst +// A prebuilt local version of the documentation is available at: +// site/build/text/docs/api_reference/preamble.js.txt +// You can also build docs locally as HTML or other formats in site/ +// An online HTML version (which may be of a different version of Emscripten) +// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html +var wasmBinary; + +// Wasm globals +//======================================== +// Runtime essentials +//======================================== +// whether we are quitting the application. no code should run after this. +// set in exit() and abort() +var ABORT = false; + +// set by exit() and abort(). Passed to 'onExit' handler. +// NOTE: This is also used as the process return code in shell environments +// but only when noExitRuntime is false. +var EXITSTATUS; + +// In STRICT mode, we only define assert() when ASSERTIONS is set. i.e. we +// don't define it at all in release modes. This matches the behaviour of +// MINIMAL_RUNTIME. +// TODO(sbc): Make this the default even without STRICT enabled. +/** @type {function(*, string=)} */ function assert(condition, text) { + if (!condition) { + // This build was created without ASSERTIONS defined. `assert()` should not + // ever be called in this configuration but in case there are callers in + // the wild leave this simple abort() implementation here for now. + abort(text); + } +} + +/** + * Indicates whether filename is delivered via file protocol (as opposed to http/https) + * @noinline + */ var isFileURI = filename => filename.startsWith("file://"); + +// include: runtime_common.js +// include: runtime_stack_check.js +// end include: runtime_stack_check.js +// include: runtime_exceptions.js +// Base Emscripten EH error class +class EmscriptenEH {} + +class EmscriptenSjLj extends EmscriptenEH {} + +// end include: runtime_exceptions.js +// include: runtime_debug.js +// end include: runtime_debug.js +// Memory management +var runtimeInitialized = false; + +function updateMemoryViews() { + var b = wasmMemory.buffer; + HEAP8 = new Int8Array(b); + HEAP16 = new Int16Array(b); + Module["HEAPU8"] = HEAPU8 = new Uint8Array(b); + HEAPU16 = new Uint16Array(b); + HEAP32 = new Int32Array(b); + Module["HEAPU32"] = HEAPU32 = new Uint32Array(b); + Module["HEAPF32"] = HEAPF32 = new Float32Array(b); + Module["HEAPF64"] = HEAPF64 = new Float64Array(b); +} + +// include: memoryprofiler.js +// end include: memoryprofiler.js +// end include: runtime_common.js +function preRun() { + if (Module["preRun"]) { + if (typeof Module["preRun"] == "function") Module["preRun"] = [ Module["preRun"] ]; + while (Module["preRun"].length) { + addOnPreRun(Module["preRun"].shift()); + } + } + // Begin ATPRERUNS hooks + callRuntimeCallbacks(onPreRuns); +} + +function initRuntime() { + runtimeInitialized = true; + // Begin ATINITS hooks + if (!Module["noFSInit"] && !FS.initialized) FS.init(); + TTY.init(); + // End ATINITS hooks + wasmExports["kd"](); + // Begin ATPOSTCTORS hooks + FS.ignorePermissions = false; +} + +function postRun() { + // PThreads reuse the runtime from the main thread. + if (Module["postRun"]) { + if (typeof Module["postRun"] == "function") Module["postRun"] = [ Module["postRun"] ]; + while (Module["postRun"].length) { + addOnPostRun(Module["postRun"].shift()); + } + } + // Begin ATPOSTRUNS hooks + callRuntimeCallbacks(onPostRuns); +} + +/** + * @param {string|number=} what + */ function abort(what) { + Module["onAbort"]?.(what); + what = `Aborted(${what})`; + // TODO(sbc): Should we remove printing and leave it up to whoever + // catches the exception? + err(what); + ABORT = true; + what += ". Build with -sASSERTIONS for more info."; + // Use a wasm runtime error, because a JS error might be seen as a foreign + // exception, which means we'd run destructors on it. We need the error to + // simply make the program stop. + // FIXME This approach does not work in Wasm EH because it currently does not assume + // all RuntimeErrors are from traps; it decides whether a RuntimeError is from + // a trap or not based on a hidden field within the object. So at the moment + // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that + // allows this in the wasm spec. + // Suppress closure compiler warning here. Closure compiler's builtin extern + // definition for WebAssembly.RuntimeError claims it takes no arguments even + // though it can. + // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed. + /** @suppress {checkTypes} */ var e = new WebAssembly.RuntimeError(what); + // Throw the error whether or not MODULARIZE is set because abort is used + // in code paths apart from instantiation where an exception is expected + // to be thrown when abort is called. + throw e; +} + +var wasmBinaryFile; + +function findWasmBinary() { + return locateFile("vision_wasm_internal.wasm"); +} + +function getBinarySync(file) { + if (file == wasmBinaryFile && wasmBinary) { + return new Uint8Array(wasmBinary); + } + if (readBinary) { + return readBinary(file); + } + // Throwing a plain string here, even though it not normally advisable since + // this gets turning into an `abort` in instantiateArrayBuffer. + throw "both async and sync fetching of the wasm failed"; +} + +async function getWasmBinary(binaryFile) { + // If we don't have the binary yet, load it asynchronously using readAsync. + if (!wasmBinary) { + // Fetch the binary using readAsync + try { + var response = await readAsync(binaryFile); + return new Uint8Array(response); + } catch {} + } + // Otherwise, getBinarySync should be able to get it synchronously + return getBinarySync(binaryFile); +} + +async function instantiateArrayBuffer(binaryFile, imports) { + try { + var binary = await getWasmBinary(binaryFile); + var instance = await WebAssembly.instantiate(binary, imports); + return instance; + } catch (reason) { + err(`failed to asynchronously prepare wasm: ${reason}`); + abort(reason); + } +} + +async function instantiateAsync(binary, binaryFile, imports) { + if (!binary && !isFileURI(binaryFile) && !ENVIRONMENT_IS_NODE) { + try { + var response = fetch(binaryFile, { + credentials: "same-origin" + }); + var instantiationResult = await WebAssembly.instantiateStreaming(response, imports); + return instantiationResult; + } catch (reason) { + // We expect the most common failure cause to be a bad MIME type for the binary, + // in which case falling back to ArrayBuffer instantiation should work. + err(`wasm streaming compile failed: ${reason}`); + err("falling back to ArrayBuffer instantiation"); + } + } + return instantiateArrayBuffer(binaryFile, imports); +} + +function getWasmImports() { + // prepare imports + var imports = { + "a": wasmImports + }; + return imports; +} + +// Create the wasm instance. +// Receives the wasm imports, returns the exports. +async function createWasm() { + // Load the wasm module and create an instance of using native support in the JS engine. + // handle a generated wasm instance, receiving its exports and + // performing other necessary setup + /** @param {WebAssembly.Module=} module*/ function receiveInstance(instance, module) { + wasmExports = instance.exports; + assignWasmExports(wasmExports); + updateMemoryViews(); + return wasmExports; + } + // Prefer streaming instantiation if available. + function receiveInstantiationResult(result) { + // 'result' is a ResultObject object which has both the module and instance. + // receiveInstance() will swap in the exports (to Module.asm) so they can be called + // 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. + // When the regression is fixed, can restore the above PTHREADS-enabled path. + return receiveInstance(result["instance"]); + } + var info = getWasmImports(); + // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback + // to manually instantiate the Wasm module themselves. This allows pages to + // run the instantiation parallel to any other async startup actions they are + // performing. + // Also pthreads and wasm workers initialize the wasm instance through this + // path. + if (Module["instantiateWasm"]) { + return new Promise((resolve, reject) => { + Module["instantiateWasm"](info, (inst, mod) => { + resolve(receiveInstance(inst, mod)); + }); + }); + } + wasmBinaryFile ??= findWasmBinary(); + var result = await instantiateAsync(wasmBinary, wasmBinaryFile, info); + var exports = receiveInstantiationResult(result); + return exports; +} + +// Globals used by JS i64 conversions (see makeSetValue) +var tempDouble; + +var tempI64; + +// end include: preamble.js +// Begin JS library code +var handleException = e => { + // Certain exception types we do not treat as errors since they are used for + // internal control flow. + // 1. ExitStatus, which is thrown by exit() + // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others + // that wish to return to JS event loop. + if (e instanceof ExitStatus || e == "unwind") { + return EXITSTATUS; + } + quit_(1, e); +}; + +class ExitStatus { + name="ExitStatus"; + constructor(status) { + this.message = `Program terminated with exit(${status})`; + this.status = status; + } +} + +var runtimeKeepaliveCounter = 0; + +var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0; + +var _proc_exit = code => { + EXITSTATUS = code; + if (!keepRuntimeAlive()) { + Module["onExit"]?.(code); + ABORT = true; + } + quit_(code, new ExitStatus(code)); +}; + +/** @param {boolean|number=} implicit */ var exitJS = (status, implicit) => { + EXITSTATUS = status; + _proc_exit(status); +}; + +var _exit = exitJS; + +var maybeExit = () => { + if (!keepRuntimeAlive()) { + try { + _exit(EXITSTATUS); + } catch (e) { + handleException(e); + } + } +}; + +var callUserCallback = func => { + if (ABORT) { + return; + } + try { + return func(); + } catch (e) { + handleException(e); + } finally { + maybeExit(); + } +}; + +function getFullscreenElement() { + return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.webkitCurrentFullScreenElement || document.msFullscreenElement; +} + +/** @param {number=} timeout */ var safeSetTimeout = (func, timeout) => setTimeout(() => { + callUserCallback(func); +}, timeout); + +var warnOnce = text => { + warnOnce.shown ||= {}; + if (!warnOnce.shown[text]) { + warnOnce.shown[text] = 1; + if (ENVIRONMENT_IS_NODE) text = "warning: " + text; + err(text); + } +}; + +var preloadPlugins = []; + +var Browser = { + useWebGL: false, + isFullscreen: false, + pointerLock: false, + moduleContextCreatedCallbacks: [], + workers: [], + preloadedImages: {}, + preloadedAudios: {}, + getCanvas: () => Module["canvas"], + init() { + if (Browser.initted) return; + Browser.initted = true; + // Support for plugins that can process preloaded files. You can add more of these to + // your app by creating and appending to preloadPlugins. + // Each plugin is asked if it can handle a file based on the file's name. If it can, + // it is given the file's raw data. When it is done, it calls a callback with the file's + // (possibly modified) data. For example, a plugin might decompress a file, or it + // might create some side data structure for use later (like an Image element, etc.). + var imagePlugin = {}; + imagePlugin["canHandle"] = name => !Module["noImageDecoding"] && /\.(jpg|jpeg|png|bmp|webp)$/i.test(name); + imagePlugin["handle"] = async (byteArray, name) => { + var b = new Blob([ byteArray ], { + type: Browser.getMimetype(name) + }); + if (b.size !== byteArray.length) { + // Safari bug #118630 + // Safari's Blob can only take an ArrayBuffer + b = new Blob([ (new Uint8Array(byteArray)).buffer ], { + type: Browser.getMimetype(name) + }); + } + var url = URL.createObjectURL(b); + return new Promise((resolve, reject) => { + var img = new Image; + img.onload = () => { + var canvas = /** @type {!HTMLCanvasElement} */ (document.createElement("canvas")); + canvas.width = img.width; + canvas.height = img.height; + var ctx = canvas.getContext("2d"); + ctx.drawImage(img, 0, 0); + Browser.preloadedImages[name] = canvas; + URL.revokeObjectURL(url); + resolve(byteArray); + }; + img.onerror = event => { + err(`Image ${url} could not be decoded`); + reject(); + }; + img.src = url; + }); + }; + preloadPlugins.push(imagePlugin); + var audioPlugin = {}; + audioPlugin["canHandle"] = name => !Module["noAudioDecoding"] && name.slice(-4) in { + ".ogg": 1, + ".wav": 1, + ".mp3": 1 + }; + audioPlugin["handle"] = async (byteArray, name) => new Promise((resolve, reject) => { + var done = false; + function finish(audio) { + if (done) return; + done = true; + Browser.preloadedAudios[name] = audio; + resolve(byteArray); + } + var b = new Blob([ byteArray ], { + type: Browser.getMimetype(name) + }); + var url = URL.createObjectURL(b); + // XXX we never revoke this! + var audio = new Audio; + audio.addEventListener("canplaythrough", () => finish(audio), false); + // use addEventListener due to chromium bug 124926 + audio.onerror = event => { + if (done) return; + err(`warning: browser could not fully decode audio ${name}, trying slower base64 approach`); + function encode64(data) { + var BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var PAD = "="; + var ret = ""; + var leftchar = 0; + var leftbits = 0; + for (var i = 0; i < data.length; i++) { + leftchar = (leftchar << 8) | data[i]; + leftbits += 8; + while (leftbits >= 6) { + var curr = (leftchar >> (leftbits - 6)) & 63; + leftbits -= 6; + ret += BASE[curr]; + } + } + if (leftbits == 2) { + ret += BASE[(leftchar & 3) << 4]; + ret += PAD + PAD; + } else if (leftbits == 4) { + ret += BASE[(leftchar & 15) << 2]; + ret += PAD; + } + return ret; + } + audio.src = "data:audio/x-" + name.slice(-3) + ";base64," + encode64(byteArray); + finish(audio); + }; + audio.src = url; + // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror + safeSetTimeout(() => { + finish(audio); + }, 1e4); + }); + preloadPlugins.push(audioPlugin); + // Canvas event setup + function pointerLockChange() { + var canvas = Browser.getCanvas(); + Browser.pointerLock = document.pointerLockElement === canvas; + } + var canvas = Browser.getCanvas(); + if (canvas) { + // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module + // Module['forcedAspectRatio'] = 4 / 3; + document.addEventListener("pointerlockchange", pointerLockChange, false); + if (Module["elementPointerLock"]) { + canvas.addEventListener("click", ev => { + if (!Browser.pointerLock && Browser.getCanvas().requestPointerLock) { + Browser.getCanvas().requestPointerLock(); + ev.preventDefault(); + } + }, false); + } + } + }, + createContext(/** @type {HTMLCanvasElement} */ canvas, useWebGL, setInModule, webGLContextAttributes) { + if (useWebGL && Module["ctx"] && canvas == Browser.getCanvas()) return Module["ctx"]; + // no need to recreate GL context if it's already been created for this canvas. + var ctx; + var contextHandle; + if (useWebGL) { + // For GLES2/desktop GL compatibility, adjust a few defaults to be different to WebGL defaults, so that they align better with the desktop defaults. + var contextAttributes = { + antialias: false, + alpha: false, + majorVersion: (typeof WebGL2RenderingContext != "undefined") ? 2 : 1 + }; + if (webGLContextAttributes) { + for (var attribute in webGLContextAttributes) { + contextAttributes[attribute] = webGLContextAttributes[attribute]; + } + } + // 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 + // actually compiled in because application is not doing any GL operations. TODO: Ideally if GL is not being used, this function + // Browser.createContext() should not even be emitted. + if (typeof GL != "undefined") { + contextHandle = GL.createContext(canvas, contextAttributes); + if (contextHandle) { + ctx = GL.getContext(contextHandle).GLctx; + } + } + } else { + ctx = canvas.getContext("2d"); + } + if (!ctx) return null; + if (setInModule) { + Module["ctx"] = ctx; + if (useWebGL) GL.makeContextCurrent(contextHandle); + Browser.useWebGL = useWebGL; + Browser.moduleContextCreatedCallbacks.forEach(callback => callback()); + Browser.init(); + } + return ctx; + }, + fullscreenHandlersInstalled: false, + lockPointer: undefined, + resizeCanvas: undefined, + requestFullscreen(lockPointer, resizeCanvas) { + Browser.lockPointer = lockPointer; + Browser.resizeCanvas = resizeCanvas; + if (typeof Browser.lockPointer == "undefined") Browser.lockPointer = true; + if (typeof Browser.resizeCanvas == "undefined") Browser.resizeCanvas = false; + var canvas = Browser.getCanvas(); + function fullscreenChange() { + Browser.isFullscreen = false; + var canvasContainer = canvas.parentNode; + if (getFullscreenElement() === canvasContainer) { + canvas.exitFullscreen = Browser.exitFullscreen; + if (Browser.lockPointer) canvas.requestPointerLock(); + Browser.isFullscreen = true; + if (Browser.resizeCanvas) { + Browser.setFullscreenCanvasSize(); + } else { + Browser.updateCanvasDimensions(canvas); + } + } else { + // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen + canvasContainer.parentNode.insertBefore(canvas, canvasContainer); + canvasContainer.parentNode.removeChild(canvasContainer); + if (Browser.resizeCanvas) { + Browser.setWindowedCanvasSize(); + } else { + Browser.updateCanvasDimensions(canvas); + } + } + Module["onFullScreen"]?.(Browser.isFullscreen); + Module["onFullscreen"]?.(Browser.isFullscreen); + } + if (!Browser.fullscreenHandlersInstalled) { + Browser.fullscreenHandlersInstalled = true; + document.addEventListener("fullscreenchange", fullscreenChange, false); + document.addEventListener("mozfullscreenchange", fullscreenChange, false); + document.addEventListener("webkitfullscreenchange", fullscreenChange, false); + document.addEventListener("MSFullscreenChange", fullscreenChange, false); + } + // 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 + var canvasContainer = document.createElement("div"); + canvas.parentNode.insertBefore(canvasContainer, canvas); + canvasContainer.appendChild(canvas); + // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size) + canvasContainer.requestFullscreen = canvasContainer["requestFullscreen"] || canvasContainer["mozRequestFullScreen"] || canvasContainer["msRequestFullscreen"] || (canvasContainer["webkitRequestFullscreen"] ? () => canvasContainer["webkitRequestFullscreen"](Element["ALLOW_KEYBOARD_INPUT"]) : null) || (canvasContainer["webkitRequestFullScreen"] ? () => canvasContainer["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"]) : null); + canvasContainer.requestFullscreen(); + }, + exitFullscreen() { + // This is workaround for chrome. Trying to exit from fullscreen + // not in fullscreen state will cause "TypeError: Document not active" + // in chrome. See https://github.com/emscripten-core/emscripten/pull/8236 + if (!Browser.isFullscreen) { + return false; + } + var CFS = document["exitFullscreen"] || document["cancelFullScreen"] || document["mozCancelFullScreen"] || document["msExitFullscreen"] || document["webkitCancelFullScreen"] || (() => {}); + CFS.apply(document, []); + return true; + }, + safeSetTimeout(func, timeout) { + // Legacy function, this is used by the SDL2 port so we need to keep it + // around at least until that is updated. + // See https://github.com/libsdl-org/SDL/pull/6304 + return safeSetTimeout(func, timeout); + }, + getMimetype(name) { + return { + "jpg": "image/jpeg", + "jpeg": "image/jpeg", + "png": "image/png", + "bmp": "image/bmp", + "ogg": "audio/ogg", + "wav": "audio/wav", + "mp3": "audio/mpeg" + }[name.slice(name.lastIndexOf(".") + 1)]; + }, + getUserMedia(func) { + window.getUserMedia ||= navigator["getUserMedia"] || navigator["mozGetUserMedia"]; + window.getUserMedia(func); + }, + getMovementX(event) { + return event["movementX"] || event["mozMovementX"] || event["webkitMovementX"] || 0; + }, + getMovementY(event) { + return event["movementY"] || event["mozMovementY"] || event["webkitMovementY"] || 0; + }, + getMouseWheelDelta(event) { + var delta = 0; + switch (event.type) { + case "DOMMouseScroll": + // 3 lines make up a step + delta = event.detail / 3; + break; + + case "mousewheel": + // 120 units make up a step + delta = event.wheelDelta / 120; + break; + + case "wheel": + delta = event.deltaY; + switch (event.deltaMode) { + case 0: + // DOM_DELTA_PIXEL: 100 pixels make up a step + delta /= 100; + break; + + case 1: + // DOM_DELTA_LINE: 3 lines make up a step + delta /= 3; + break; + + case 2: + // DOM_DELTA_PAGE: A page makes up 80 steps + delta *= 80; + break; + + default: + abort("unrecognized mouse wheel delta mode: " + event.deltaMode); + } + break; + + default: + abort("unrecognized mouse wheel event: " + event.type); + } + return delta; + }, + mouseX: 0, + mouseY: 0, + mouseMovementX: 0, + mouseMovementY: 0, + touches: {}, + lastTouches: {}, + calculateMouseCoords(pageX, pageY) { + // Calculate the movement based on the changes + // in the coordinates. + var canvas = Browser.getCanvas(); + var rect = canvas.getBoundingClientRect(); + var adjustedX = pageX - (window.scrollX + rect.left); + var adjustedY = pageY - (window.scrollY + rect.top); + // the canvas might be CSS-scaled compared to its backbuffer; + // SDL-using content will want mouse coordinates in terms + // of backbuffer units. + adjustedX = adjustedX * (canvas.width / rect.width); + adjustedY = adjustedY * (canvas.height / rect.height); + return { + x: adjustedX, + y: adjustedY + }; + }, + setMouseCoords(pageX, pageY) { + const {x, y} = Browser.calculateMouseCoords(pageX, pageY); + Browser.mouseMovementX = x - Browser.mouseX; + Browser.mouseMovementY = y - Browser.mouseY; + Browser.mouseX = x; + Browser.mouseY = y; + }, + calculateMouseEvent(event) { + // event should be mousemove, mousedown or mouseup + if (Browser.pointerLock) { + // When the pointer is locked, calculate the coordinates + // based on the movement of the mouse. + // Workaround for Firefox bug 764498 + if (event.type != "mousemove" && ("mozMovementX" in event)) { + Browser.mouseMovementX = Browser.mouseMovementY = 0; + } else { + Browser.mouseMovementX = Browser.getMovementX(event); + Browser.mouseMovementY = Browser.getMovementY(event); + } + // add the mouse delta to the current absolute mouse position + Browser.mouseX += Browser.mouseMovementX; + Browser.mouseY += Browser.mouseMovementY; + } else { + if (event.type === "touchstart" || event.type === "touchend" || event.type === "touchmove") { + var touch = event.touch; + if (touch === undefined) { + return; + } + var coords = Browser.calculateMouseCoords(touch.pageX, touch.pageY); + if (event.type === "touchstart") { + Browser.lastTouches[touch.identifier] = coords; + Browser.touches[touch.identifier] = coords; + } else if (event.type === "touchend" || event.type === "touchmove") { + var last = Browser.touches[touch.identifier]; + last ||= coords; + Browser.lastTouches[touch.identifier] = last; + Browser.touches[touch.identifier] = coords; + } + return; + } + Browser.setMouseCoords(event.pageX, event.pageY); + } + }, + resizeListeners: [], + updateResizeListeners() { + var canvas = Browser.getCanvas(); + Browser.resizeListeners.forEach(listener => listener(canvas.width, canvas.height)); + }, + setCanvasSize(width, height, noUpdates) { + var canvas = Browser.getCanvas(); + Browser.updateCanvasDimensions(canvas, width, height); + if (!noUpdates) Browser.updateResizeListeners(); + }, + windowedWidth: 0, + windowedHeight: 0, + setFullscreenCanvasSize() { + // check if SDL is available + if (typeof SDL != "undefined") { + var flags = HEAPU32[((SDL.screen) >> 2)]; + flags = flags | 8388608; + // set SDL_FULLSCREEN flag + HEAP32[((SDL.screen) >> 2)] = flags; + } + Browser.updateCanvasDimensions(Browser.getCanvas()); + Browser.updateResizeListeners(); + }, + setWindowedCanvasSize() { + // check if SDL is available + if (typeof SDL != "undefined") { + var flags = HEAPU32[((SDL.screen) >> 2)]; + flags = flags & ~8388608; + // clear SDL_FULLSCREEN flag + HEAP32[((SDL.screen) >> 2)] = flags; + } + Browser.updateCanvasDimensions(Browser.getCanvas()); + Browser.updateResizeListeners(); + }, + updateCanvasDimensions(canvas, wNative, hNative) { + if (wNative && hNative) { + canvas.widthNative = wNative; + canvas.heightNative = hNative; + } else { + wNative = canvas.widthNative; + hNative = canvas.heightNative; + } + var w = wNative; + var h = hNative; + if (Module["forcedAspectRatio"] > 0) { + if (w / h < Module["forcedAspectRatio"]) { + w = Math.round(h * Module["forcedAspectRatio"]); + } else { + h = Math.round(w / Module["forcedAspectRatio"]); + } + } + if ((getFullscreenElement() === canvas.parentNode) && (typeof screen != "undefined")) { + var factor = Math.min(screen.width / w, screen.height / h); + w = Math.round(w * factor); + h = Math.round(h * factor); + } + if (Browser.resizeCanvas) { + if (canvas.width != w) canvas.width = w; + if (canvas.height != h) canvas.height = h; + if (typeof canvas.style != "undefined") { + canvas.style.removeProperty("width"); + canvas.style.removeProperty("height"); + } + } else { + if (canvas.width != wNative) canvas.width = wNative; + if (canvas.height != hNative) canvas.height = hNative; + if (typeof canvas.style != "undefined") { + if (w != wNative || h != hNative) { + canvas.style.setProperty("width", w + "px", "important"); + canvas.style.setProperty("height", h + "px", "important"); + } else { + canvas.style.removeProperty("width"); + canvas.style.removeProperty("height"); + } + } + } + } +}; + +/** @type {!Int16Array} */ var HEAP16; + +/** @type {!Int32Array} */ var HEAP32; + +/** @type {!Int8Array} */ var HEAP8; + +/** @type {!Float32Array} */ var HEAPF32; + +/** @type {!Float64Array} */ var HEAPF64; + +/** @type {!Uint16Array} */ var HEAPU16; + +/** @type {!Uint32Array} */ var HEAPU32; + +/** @type {!Uint8Array} */ var HEAPU8; + +var callRuntimeCallbacks = callbacks => { + while (callbacks.length > 0) { + // Pass the module as the first argument. + callbacks.shift()(Module); + } +}; + +var onPostRuns = []; + +var addOnPostRun = cb => onPostRuns.push(cb); + +var onPreRuns = []; + +var addOnPreRun = cb => onPreRuns.push(cb); + +var noExitRuntime = true; + +var stackRestore = val => __emscripten_stack_restore(val); + +var stackSave = () => _emscripten_stack_get_current(); + +class ExceptionInfo { + // excPtr - Thrown object pointer to wrap. Metadata pointer is calculated from it. + constructor(excPtr) { + this.excPtr = excPtr; + this.ptr = excPtr - 24; + } + set_type(type) { + HEAPU32[(((this.ptr) + (4)) >> 2)] = type; + } + get_type() { + return HEAPU32[(((this.ptr) + (4)) >> 2)]; + } + set_destructor(destructor) { + HEAPU32[(((this.ptr) + (8)) >> 2)] = destructor; + } + get_destructor() { + return HEAPU32[(((this.ptr) + (8)) >> 2)]; + } + set_caught(caught) { + caught = caught ? 1 : 0; + HEAP8[(this.ptr) + (12)] = caught; + } + get_caught() { + return HEAP8[(this.ptr) + (12)] != 0; + } + set_rethrown(rethrown) { + rethrown = rethrown ? 1 : 0; + HEAP8[(this.ptr) + (13)] = rethrown; + } + get_rethrown() { + return HEAP8[(this.ptr) + (13)] != 0; + } + // Initialize native structure fields. Should be called once after allocated. + init(type, destructor) { + this.set_adjusted_ptr(0); + this.set_type(type); + this.set_destructor(destructor); + } + set_adjusted_ptr(adjustedPtr) { + HEAPU32[(((this.ptr) + (16)) >> 2)] = adjustedPtr; + } + get_adjusted_ptr() { + return HEAPU32[(((this.ptr) + (16)) >> 2)]; + } +} + +var uncaughtExceptionCount = 0; + +var ___cxa_throw = (ptr, type, destructor) => { + var info = new ExceptionInfo(ptr); + // Initialize ExceptionInfo content after it was allocated in __cxa_allocate_exception. + info.init(type, destructor); + uncaughtExceptionCount++; + abort(); +}; + +var PATH = { + isAbs: path => path.charAt(0) === "/", + splitPath: filename => { + var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; + return splitPathRe.exec(filename).slice(1); + }, + normalizeArray: (parts, allowAboveRoot) => { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === ".") { + parts.splice(i, 1); + } else if (last === "..") { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (;up; up--) { + parts.unshift(".."); + } + } + return parts; + }, + normalize: path => { + var isAbsolute = PATH.isAbs(path), trailingSlash = path.slice(-1) === "/"; + // Normalize the path + path = PATH.normalizeArray(path.split("/").filter(p => !!p), !isAbsolute).join("/"); + if (!path && !isAbsolute) { + path = "."; + } + if (path && trailingSlash) { + path += "/"; + } + return (isAbsolute ? "/" : "") + path; + }, + dirname: path => { + var result = PATH.splitPath(path), root = result[0], dir = result[1]; + if (!root && !dir) { + // No dirname whatsoever + return "."; + } + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.slice(0, -1); + } + return root + dir; + }, + basename: path => path && path.match(/([^\/]+|\/)\/*$/)[1], + join: (...paths) => PATH.normalize(paths.join("/")), + join2: (l, r) => PATH.normalize(l + "/" + r) +}; + +var initRandomFill = () => { + // This block is not needed on v19+ since crypto.getRandomValues is builtin + if (ENVIRONMENT_IS_NODE) { + var nodeCrypto = require("node:crypto"); + return view => nodeCrypto.randomFillSync(view); + } + return view => (crypto.getRandomValues(view), 0); +}; + +var randomFill = view => (randomFill = initRandomFill())(view); + +var PATH_FS = { + resolve: (...args) => { + var resolvedPath = "", resolvedAbsolute = false; + for (var i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? args[i] : FS.cwd(); + // Skip empty and invalid entries + if (typeof path != "string") { + throw new TypeError("Arguments to path.resolve must be strings"); + } else if (!path) { + return ""; + } + resolvedPath = path + "/" + resolvedPath; + resolvedAbsolute = PATH.isAbs(path); + } + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + resolvedPath = PATH.normalizeArray(resolvedPath.split("/").filter(p => !!p), !resolvedAbsolute).join("/"); + return ((resolvedAbsolute ? "/" : "") + resolvedPath) || "."; + }, + relative: (from, to) => { + from = PATH_FS.resolve(from).slice(1); + to = PATH_FS.resolve(to).slice(1); + function trim(arr) { + var start = 0; + for (;start < arr.length; start++) { + if (arr[start] !== "") break; + } + var end = arr.length - 1; + for (;end >= 0; end--) { + if (arr[end] !== "") break; + } + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + var fromParts = trim(from.split("/")); + var toParts = trim(to.split("/")); + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push(".."); + } + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + return outputParts.join("/"); + } +}; + +var UTF8Decoder = new TextDecoder; + +var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => { + var maxIdx = idx + maxBytesToRead; + if (ignoreNul) return maxIdx; + // TextDecoder needs to know the byte length in advance, it doesn't stop on + // null terminator by itself. + // As a tiny code save trick, compare idx against maxIdx using a negation, + // so that maxBytesToRead=undefined/NaN means Infinity. + while (heapOrArray[idx] && !(idx >= maxIdx)) ++idx; + return idx; +}; + +/** + * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given + * array that contains uint8 values, returns a copy of that string as a + * Javascript String object. + * heapOrArray is either a regular array, or a JavaScript typed array view. + * @param {number=} idx + * @param {number=} maxBytesToRead + * @param {boolean=} ignoreNul - If true, the function will not stop on a NUL character. + * @return {string} + */ var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead, ignoreNul) => { + var endPtr = findStringEnd(heapOrArray, idx, maxBytesToRead, ignoreNul); + return UTF8Decoder.decode(heapOrArray.buffer ? heapOrArray.subarray(idx, endPtr) : new Uint8Array(heapOrArray.slice(idx, endPtr))); +}; + +var FS_stdin_getChar_buffer = []; + +var lengthBytesUTF8 = str => { + var len = 0; + for (var i = 0; i < str.length; ++i) { + // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code + // unit, not a Unicode code point of the character! So decode + // UTF16->UTF32->UTF8. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var c = str.charCodeAt(i); + // possibly a lead surrogate + if (c <= 127) { + len++; + } else if (c <= 2047) { + len += 2; + } else if (c >= 55296 && c <= 57343) { + len += 4; + ++i; + } else { + len += 3; + } + } + return len; +}; + +var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => { + // Parameter maxBytesToWrite is not optional. Negative values, 0, null, + // undefined and false each don't write out any bytes. + if (!(maxBytesToWrite > 0)) return 0; + var startIdx = outIdx; + var endIdx = outIdx + maxBytesToWrite - 1; + // -1 for string null terminator. + for (var i = 0; i < str.length; ++i) { + // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description + // and https://www.ietf.org/rfc/rfc2279.txt + // and https://tools.ietf.org/html/rfc3629 + var u = str.codePointAt(i); + if (u <= 127) { + if (outIdx >= endIdx) break; + heap[outIdx++] = u; + } else if (u <= 2047) { + if (outIdx + 1 >= endIdx) break; + heap[outIdx++] = 192 | (u >> 6); + heap[outIdx++] = 128 | (u & 63); + } else if (u <= 65535) { + if (outIdx + 2 >= endIdx) break; + heap[outIdx++] = 224 | (u >> 12); + heap[outIdx++] = 128 | ((u >> 6) & 63); + heap[outIdx++] = 128 | (u & 63); + } else { + if (outIdx + 3 >= endIdx) break; + heap[outIdx++] = 240 | (u >> 18); + heap[outIdx++] = 128 | ((u >> 12) & 63); + heap[outIdx++] = 128 | ((u >> 6) & 63); + heap[outIdx++] = 128 | (u & 63); + // Gotcha: if codePoint is over 0xFFFF, it is represented as a surrogate pair in UTF-16. + // We need to manually skip over the second code unit for correct iteration. + i++; + } + } + // Null-terminate the pointer to the buffer. + heap[outIdx] = 0; + return outIdx - startIdx; +}; + +/** @type {function(string, boolean=, number=)} */ var intArrayFromString = (stringy, dontAddNull, length) => { + var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1; + var u8array = new Array(len); + var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length); + if (dontAddNull) u8array.length = numBytesWritten; + return u8array; +}; + +var FS_stdin_getChar = () => { + if (!FS_stdin_getChar_buffer.length) { + var result = null; + if (ENVIRONMENT_IS_NODE) { + // we will read data by chunks of BUFSIZE + var BUFSIZE = 256; + var buf = Buffer.alloc(BUFSIZE); + var bytesRead = 0; + // For some reason we must suppress a closure warning here, even though + // fd definitely exists on process.stdin, and is even the proper way to + // get the fd of stdin, + // https://github.com/nodejs/help/issues/2136#issuecomment-523649904 + // This started to happen after moving this logic out of library_tty.js, + // so it is related to the surrounding code in some unclear manner. + /** @suppress {missingProperties} */ var fd = process.stdin.fd; + try { + bytesRead = fs.readSync(fd, buf, 0, BUFSIZE); + } catch (e) { + // Cross-platform differences: on Windows, reading EOF throws an + // exception, but on other OSes, reading EOF returns 0. Uniformize + // behavior by treating the EOF exception to return 0. + if (e.toString().includes("EOF")) bytesRead = 0; else throw e; + } + if (bytesRead > 0) { + result = buf.slice(0, bytesRead).toString("utf-8"); + } + } else if (globalThis.window?.prompt) { + // Browser. + result = window.prompt("Input: "); + // returns null on cancel + if (result !== null) { + result += "\n"; + } + } else {} + if (!result) { + return null; + } + FS_stdin_getChar_buffer = intArrayFromString(result, true); + } + return FS_stdin_getChar_buffer.shift(); +}; + +var TTY = { + ttys: [], + init() {}, + shutdown() {}, + register(dev, ops) { + TTY.ttys[dev] = { + input: [], + output: [], + ops + }; + FS.registerDevice(dev, TTY.stream_ops); + }, + stream_ops: { + open(stream) { + var tty = TTY.ttys[stream.node.rdev]; + if (!tty) { + throw new FS.ErrnoError(43); + } + stream.tty = tty; + stream.seekable = false; + }, + close(stream) { + // flush any pending line data + stream.tty.ops.fsync(stream.tty); + }, + fsync(stream) { + stream.tty.ops.fsync(stream.tty); + }, + read(stream, buffer, offset, length, pos) { + if (!stream.tty || !stream.tty.ops.get_char) { + throw new FS.ErrnoError(60); + } + var bytesRead = 0; + for (var i = 0; i < length; i++) { + var result; + try { + result = stream.tty.ops.get_char(stream.tty); + } catch (e) { + throw new FS.ErrnoError(29); + } + if (result === undefined && bytesRead === 0) { + throw new FS.ErrnoError(6); + } + if (result === null || result === undefined) break; + bytesRead++; + buffer[offset + i] = result; + } + if (bytesRead) { + stream.node.atime = Date.now(); + } + return bytesRead; + }, + write(stream, buffer, offset, length, pos) { + if (!stream.tty || !stream.tty.ops.put_char) { + throw new FS.ErrnoError(60); + } + try { + for (var i = 0; i < length; i++) { + stream.tty.ops.put_char(stream.tty, buffer[offset + i]); + } + } catch (e) { + throw new FS.ErrnoError(29); + } + if (length) { + stream.node.mtime = stream.node.ctime = Date.now(); + } + return i; + } + }, + default_tty_ops: { + get_char(tty) { + return FS_stdin_getChar(); + }, + put_char(tty, val) { + if (val === null || val === 10) { + out(UTF8ArrayToString(tty.output)); + tty.output = []; + } else { + if (val != 0) tty.output.push(val); + } + }, + fsync(tty) { + if (tty.output?.length > 0) { + out(UTF8ArrayToString(tty.output)); + tty.output = []; + } + }, + ioctl_tcgets(tty) { + // typical setting + return { + c_iflag: 25856, + c_oflag: 5, + c_cflag: 191, + c_lflag: 35387, + c_cc: [ 3, 28, 127, 21, 4, 0, 1, 0, 17, 19, 26, 0, 18, 15, 23, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + }; + }, + ioctl_tcsets(tty, optional_actions, data) { + // currently just ignore + return 0; + }, + ioctl_tiocgwinsz(tty) { + return [ 24, 80 ]; + } + }, + default_tty1_ops: { + put_char(tty, val) { + if (val === null || val === 10) { + err(UTF8ArrayToString(tty.output)); + tty.output = []; + } else { + if (val != 0) tty.output.push(val); + } + }, + fsync(tty) { + if (tty.output?.length > 0) { + err(UTF8ArrayToString(tty.output)); + tty.output = []; + } + } + } +}; + +var zeroMemory = (ptr, size) => HEAPU8.fill(0, ptr, ptr + size); + +var alignMemory = (size, alignment) => Math.ceil(size / alignment) * alignment; + +var mmapAlloc = size => { + size = alignMemory(size, 65536); + var ptr = _emscripten_builtin_memalign(65536, size); + if (ptr) zeroMemory(ptr, size); + return ptr; +}; + +var MEMFS = { + ops_table: null, + mount(mount) { + return MEMFS.createNode(null, "/", 16895, 0); + }, + createNode(parent, name, mode, dev) { + if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { + // not supported + throw new FS.ErrnoError(63); + } + MEMFS.ops_table ||= { + dir: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + lookup: MEMFS.node_ops.lookup, + mknod: MEMFS.node_ops.mknod, + rename: MEMFS.node_ops.rename, + unlink: MEMFS.node_ops.unlink, + rmdir: MEMFS.node_ops.rmdir, + readdir: MEMFS.node_ops.readdir, + symlink: MEMFS.node_ops.symlink + }, + stream: { + llseek: MEMFS.stream_ops.llseek + } + }, + file: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr + }, + stream: { + llseek: MEMFS.stream_ops.llseek, + read: MEMFS.stream_ops.read, + write: MEMFS.stream_ops.write, + mmap: MEMFS.stream_ops.mmap, + msync: MEMFS.stream_ops.msync + } + }, + link: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + readlink: MEMFS.node_ops.readlink + }, + stream: {} + }, + chrdev: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr + }, + stream: FS.chrdev_stream_ops + } + }; + var node = FS.createNode(parent, name, mode, dev); + if (FS.isDir(node.mode)) { + node.node_ops = MEMFS.ops_table.dir.node; + node.stream_ops = MEMFS.ops_table.dir.stream; + node.contents = {}; + } else if (FS.isFile(node.mode)) { + node.node_ops = MEMFS.ops_table.file.node; + node.stream_ops = MEMFS.ops_table.file.stream; + // The actual number of bytes used in the typed array, as opposed to + // contents.length which gives the whole capacity. + node.usedBytes = 0; + // The byte data of the file is stored in a typed array. + // Note: typed arrays are not resizable like normal JS arrays are, so + // there is a small penalty involved for appending file writes that + // continuously grow a file similar to std::vector capacity vs used. + node.contents = MEMFS.emptyFileContents ??= new Uint8Array(0); + } else if (FS.isLink(node.mode)) { + node.node_ops = MEMFS.ops_table.link.node; + node.stream_ops = MEMFS.ops_table.link.stream; + } else if (FS.isChrdev(node.mode)) { + node.node_ops = MEMFS.ops_table.chrdev.node; + node.stream_ops = MEMFS.ops_table.chrdev.stream; + } + node.atime = node.mtime = node.ctime = Date.now(); + // add the new node to the parent + if (parent) { + parent.contents[name] = node; + parent.atime = parent.mtime = parent.ctime = node.atime; + } + return node; + }, + getFileDataAsTypedArray(node) { + return node.contents.subarray(0, node.usedBytes); + }, + expandFileStorage(node, newCapacity) { + var prevCapacity = node.contents.length; + if (prevCapacity >= newCapacity) return; + // No need to expand, the storage was already large enough. + // Don't expand strictly to the given requested limit if it's only a very + // small increase, but instead geometrically grow capacity. + // For small filesizes (<1MB), perform size*2 geometric increase, but for + // large sizes, do a much more conservative size*1.125 increase to avoid + // overshooting the allocation cap by a very large margin. + var CAPACITY_DOUBLING_MAX = 1024 * 1024; + newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125)) >>> 0); + if (prevCapacity) newCapacity = Math.max(newCapacity, 256); + // At minimum allocate 256b for each file when expanding. + var oldContents = MEMFS.getFileDataAsTypedArray(node); + node.contents = new Uint8Array(newCapacity); + // Allocate new storage. + node.contents.set(oldContents); + }, + resizeFileStorage(node, newSize) { + if (node.usedBytes == newSize) return; + var oldContents = node.contents; + node.contents = new Uint8Array(newSize); + // Allocate new storage. + node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); + // Copy old data over to the new storage. + node.usedBytes = newSize; + }, + node_ops: { + getattr(node) { + var attr = {}; + // device numbers reuse inode numbers. + attr.dev = FS.isChrdev(node.mode) ? node.id : 1; + attr.ino = node.id; + attr.mode = node.mode; + attr.nlink = 1; + attr.uid = 0; + attr.gid = 0; + attr.rdev = node.rdev; + if (FS.isDir(node.mode)) { + attr.size = 4096; + } else if (FS.isFile(node.mode)) { + attr.size = node.usedBytes; + } else if (FS.isLink(node.mode)) { + attr.size = node.link.length; + } else { + attr.size = 0; + } + attr.atime = new Date(node.atime); + attr.mtime = new Date(node.mtime); + attr.ctime = new Date(node.ctime); + // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize), + // but this is not required by the standard. + attr.blksize = 4096; + attr.blocks = Math.ceil(attr.size / attr.blksize); + return attr; + }, + setattr(node, attr) { + for (const key of [ "mode", "atime", "mtime", "ctime" ]) { + if (attr[key] != null) { + node[key] = attr[key]; + } + } + if (attr.size !== undefined) { + MEMFS.resizeFileStorage(node, attr.size); + } + }, + lookup(parent, name) { + // This error may happen quite a bit. To avoid overhead we reuse it (and + // suffer a lack of stack info). + if (!MEMFS.doesNotExistError) { + MEMFS.doesNotExistError = new FS.ErrnoError(44); + /** @suppress {checkTypes} */ MEMFS.doesNotExistError.stack = ""; + } + throw MEMFS.doesNotExistError; + }, + mknod(parent, name, mode, dev) { + return MEMFS.createNode(parent, name, mode, dev); + }, + rename(old_node, new_dir, new_name) { + var new_node; + try { + new_node = FS.lookupNode(new_dir, new_name); + } catch (e) {} + if (new_node) { + if (FS.isDir(old_node.mode)) { + // if we're overwriting a directory at new_name, make sure it's empty. + for (var i in new_node.contents) { + throw new FS.ErrnoError(55); + } + } + FS.hashRemoveNode(new_node); + } + // do the internal rewiring + delete old_node.parent.contents[old_node.name]; + new_dir.contents[new_name] = old_node; + old_node.name = new_name; + new_dir.ctime = new_dir.mtime = old_node.parent.ctime = old_node.parent.mtime = Date.now(); + }, + unlink(parent, name) { + delete parent.contents[name]; + parent.ctime = parent.mtime = Date.now(); + }, + rmdir(parent, name) { + var node = FS.lookupNode(parent, name); + for (var i in node.contents) { + throw new FS.ErrnoError(55); + } + delete parent.contents[name]; + parent.ctime = parent.mtime = Date.now(); + }, + readdir(node) { + return [ ".", "..", ...Object.keys(node.contents) ]; + }, + symlink(parent, newname, oldpath) { + var node = MEMFS.createNode(parent, newname, 511 | 40960, 0); + node.link = oldpath; + return node; + }, + readlink(node) { + if (!FS.isLink(node.mode)) { + throw new FS.ErrnoError(28); + } + return node.link; + } + }, + stream_ops: { + read(stream, buffer, offset, length, position) { + var contents = stream.node.contents; + if (position >= stream.node.usedBytes) return 0; + var size = Math.min(stream.node.usedBytes - position, length); + buffer.set(contents.subarray(position, position + size), offset); + return size; + }, + write(stream, buffer, offset, length, position, canOwn) { + // If the buffer is located in main memory (HEAP), and if + // memory can grow, we can't hold on to references of the + // memory buffer, as they may get invalidated. That means we + // need to copy its contents. + if (buffer.buffer === HEAP8.buffer) { + canOwn = false; + } + if (!length) return 0; + var node = stream.node; + node.mtime = node.ctime = Date.now(); + if (canOwn) { + node.contents = buffer.subarray(offset, offset + length); + node.usedBytes = length; + } 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. + node.contents = buffer.slice(offset, offset + length); + node.usedBytes = length; + } else { + MEMFS.expandFileStorage(node, position + length); + // Use typed array write which is available. + node.contents.set(buffer.subarray(offset, offset + length), position); + node.usedBytes = Math.max(node.usedBytes, position + length); + } + return length; + }, + llseek(stream, offset, whence) { + var position = offset; + if (whence === 1) { + position += stream.position; + } else if (whence === 2) { + if (FS.isFile(stream.node.mode)) { + position += stream.node.usedBytes; + } + } + if (position < 0) { + throw new FS.ErrnoError(28); + } + return position; + }, + mmap(stream, length, position, prot, flags) { + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + var ptr; + var allocated; + var contents = stream.node.contents; + // Only make a new copy when MAP_PRIVATE is specified. + if (!(flags & 2) && contents.buffer === HEAP8.buffer) { + // We can't emulate MAP_SHARED when the file is not backed by the + // buffer we're mapping to (e.g. the HEAP buffer). + allocated = false; + ptr = contents.byteOffset; + } else { + allocated = true; + ptr = mmapAlloc(length); + if (!ptr) { + throw new FS.ErrnoError(48); + } + if (contents) { + // Try to avoid unnecessary slices. + if (position > 0 || position + length < contents.length) { + if (contents.subarray) { + contents = contents.subarray(position, position + length); + } else { + contents = Array.prototype.slice.call(contents, position, position + length); + } + } + HEAP8.set(contents, ptr); + } + } + return { + ptr, + allocated + }; + }, + msync(stream, buffer, offset, length, mmapFlags) { + MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false); + // should we check if bytesWritten and length are the same? + return 0; + } + } +}; + +var FS_modeStringToFlags = str => { + if (typeof str != "string") return str; + var flagModes = { + "r": 0, + "r+": 2, + "w": 512 | 64 | 1, + "w+": 512 | 64 | 2, + "a": 1024 | 64 | 1, + "a+": 1024 | 64 | 2 + }; + var flags = flagModes[str]; + if (typeof flags == "undefined") { + throw new Error(`Unknown file open mode: ${str}`); + } + return flags; +}; + +var FS_fileDataToTypedArray = data => { + if (typeof data == "string") { + data = intArrayFromString(data, true); + } + if (!data.subarray) { + data = new Uint8Array(data); + } + return data; +}; + +var FS_getMode = (canRead, canWrite) => { + var mode = 0; + if (canRead) mode |= 292 | 73; + if (canWrite) mode |= 146; + return mode; +}; + +var asyncLoad = async url => { + var arrayBuffer = await readAsync(url); + return new Uint8Array(arrayBuffer); +}; + +var FS_createDataFile = (...args) => FS.createDataFile(...args); + +var getUniqueRunDependency = id => id; + +var runDependencies = 0; + +var dependenciesFulfilled = null; + +var removeRunDependency = id => { + runDependencies--; + Module["monitorRunDependencies"]?.(runDependencies); + if (runDependencies == 0) { + if (dependenciesFulfilled) { + var callback = dependenciesFulfilled; + dependenciesFulfilled = null; + callback(); + } + } +}; + +var addRunDependency = id => { + runDependencies++; + Module["monitorRunDependencies"]?.(runDependencies); +}; + +var FS_handledByPreloadPlugin = async (byteArray, fullname) => { + // Ensure plugins are ready. + if (typeof Browser != "undefined") Browser.init(); + for (var plugin of preloadPlugins) { + if (plugin["canHandle"](fullname)) { + return plugin["handle"](byteArray, fullname); + } + } + // If no plugin handled this file then return the original/unmodified + // byteArray. + return byteArray; +}; + +var FS_preloadFile = async (parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish) => { + // TODO we should allow people to just pass in a complete filename instead + // of parent and name being that we just join them anyways + var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent; + var dep = getUniqueRunDependency(`cp ${fullname}`); + // might have several active requests for the same fullname + addRunDependency(dep); + try { + var byteArray = url; + if (typeof url == "string") { + byteArray = await asyncLoad(url); + } + byteArray = await FS_handledByPreloadPlugin(byteArray, fullname); + preFinish?.(); + if (!dontCreateFile) { + FS_createDataFile(parent, name, byteArray, canRead, canWrite, canOwn); + } + } finally { + removeRunDependency(dep); + } +}; + +var FS_createPreloadedFile = (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => { + FS_preloadFile(parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish).then(onload).catch(onerror); +}; + +var FS = { + root: null, + mounts: [], + devices: {}, + streams: [], + nextInode: 1, + nameTable: null, + currentPath: "/", + initialized: false, + ignorePermissions: true, + filesystems: null, + syncFSRequests: 0, + ErrnoError: class { + name="ErrnoError"; + // We set the `name` property to be able to identify `FS.ErrnoError` + // - the `name` is a standard ECMA-262 property of error objects. Kind of good to have it anyway. + // - when using PROXYFS, an error can come from an underlying FS + // as different FS objects have their own FS.ErrnoError each, + // the test `err instanceof FS.ErrnoError` won't detect an error coming from another filesystem, causing bugs. + // we'll use the reliable test `err.name == "ErrnoError"` instead + constructor(errno) { + this.errno = errno; + } + }, + FSStream: class { + shared={}; + get object() { + return this.node; + } + set object(val) { + this.node = val; + } + get isRead() { + return (this.flags & 2097155) !== 1; + } + get isWrite() { + return (this.flags & 2097155) !== 0; + } + get isAppend() { + return (this.flags & 1024); + } + get flags() { + return this.shared.flags; + } + set flags(val) { + this.shared.flags = val; + } + get position() { + return this.shared.position; + } + set position(val) { + this.shared.position = val; + } + }, + FSNode: class { + node_ops={}; + stream_ops={}; + readMode=292 | 73; + writeMode=146; + mounted=null; + constructor(parent, name, mode, rdev) { + if (!parent) { + parent = this; + } + this.parent = parent; + this.mount = parent.mount; + this.id = FS.nextInode++; + this.name = name; + this.mode = mode; + this.rdev = rdev; + this.atime = this.mtime = this.ctime = Date.now(); + } + get read() { + return (this.mode & this.readMode) === this.readMode; + } + set read(val) { + val ? this.mode |= this.readMode : this.mode &= ~this.readMode; + } + get write() { + return (this.mode & this.writeMode) === this.writeMode; + } + set write(val) { + val ? this.mode |= this.writeMode : this.mode &= ~this.writeMode; + } + get isFolder() { + return FS.isDir(this.mode); + } + get isDevice() { + return FS.isChrdev(this.mode); + } + }, + lookupPath(path, opts = {}) { + if (!path) { + throw new FS.ErrnoError(44); + } + opts.follow_mount ??= true; + if (!PATH.isAbs(path)) { + path = FS.cwd() + "/" + path; + } + // limit max consecutive symlinks to SYMLOOP_MAX. + linkloop: for (var nlinks = 0; nlinks < 40; nlinks++) { + // split the absolute path + var parts = path.split("/").filter(p => !!p); + // start at the root + var current = FS.root; + var current_path = "/"; + for (var i = 0; i < parts.length; i++) { + var islast = (i === parts.length - 1); + if (islast && opts.parent) { + // stop resolving + break; + } + if (parts[i] === ".") { + continue; + } + if (parts[i] === "..") { + current_path = PATH.dirname(current_path); + if (FS.isRoot(current)) { + path = current_path + "/" + parts.slice(i + 1).join("/"); + // We're making progress here, don't let many consecutive ..'s + // lead to ELOOP + nlinks--; + continue linkloop; + } else { + current = current.parent; + } + continue; + } + current_path = PATH.join2(current_path, parts[i]); + try { + current = FS.lookupNode(current, parts[i]); + } catch (e) { + // if noent_okay is true, suppress a ENOENT in the last component + // and return an object with an undefined node. This is needed for + // resolving symlinks in the path when creating a file. + if ((e?.errno === 44) && islast && opts.noent_okay) { + return { + path: current_path + }; + } + throw e; + } + // jump to the mount's root node if this is a mountpoint + if (FS.isMountpoint(current) && (!islast || opts.follow_mount)) { + current = current.mounted.root; + } + // by default, lookupPath will not follow a symlink if it is the final path component. + // setting opts.follow = true will override this behavior. + if (FS.isLink(current.mode) && (!islast || opts.follow)) { + if (!current.node_ops.readlink) { + throw new FS.ErrnoError(52); + } + var link = current.node_ops.readlink(current); + if (!PATH.isAbs(link)) { + link = PATH.dirname(current_path) + "/" + link; + } + path = link + "/" + parts.slice(i + 1).join("/"); + continue linkloop; + } + } + return { + path: current_path, + node: current + }; + } + throw new FS.ErrnoError(32); + }, + getPath(node) { + var path; + while (true) { + if (FS.isRoot(node)) { + var mount = node.mount.mountpoint; + if (!path) return mount; + return mount[mount.length - 1] !== "/" ? `${mount}/${path}` : mount + path; + } + path = path ? `${node.name}/${path}` : node.name; + node = node.parent; + } + }, + hashName(parentid, name) { + var hash = 0; + for (var i = 0; i < name.length; i++) { + hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0; + } + return ((parentid + hash) >>> 0) % FS.nameTable.length; + }, + hashAddNode(node) { + var hash = FS.hashName(node.parent.id, node.name); + node.name_next = FS.nameTable[hash]; + FS.nameTable[hash] = node; + }, + hashRemoveNode(node) { + var hash = FS.hashName(node.parent.id, node.name); + if (FS.nameTable[hash] === node) { + FS.nameTable[hash] = node.name_next; + } else { + var current = FS.nameTable[hash]; + while (current) { + if (current.name_next === node) { + current.name_next = node.name_next; + break; + } + current = current.name_next; + } + } + }, + lookupNode(parent, name) { + var errCode = FS.mayLookup(parent); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + var hash = FS.hashName(parent.id, name); + for (var node = FS.nameTable[hash]; node; node = node.name_next) { + var nodeName = node.name; + if (node.parent.id === parent.id && nodeName === name) { + return node; + } + } + // if we failed to find it in the cache, call into the VFS + return FS.lookup(parent, name); + }, + createNode(parent, name, mode, rdev) { + var node = new FS.FSNode(parent, name, mode, rdev); + FS.hashAddNode(node); + return node; + }, + destroyNode(node) { + FS.hashRemoveNode(node); + }, + isRoot(node) { + return node === node.parent; + }, + isMountpoint(node) { + return !!node.mounted; + }, + isFile(mode) { + return (mode & 61440) === 32768; + }, + isDir(mode) { + return (mode & 61440) === 16384; + }, + isLink(mode) { + return (mode & 61440) === 40960; + }, + isChrdev(mode) { + return (mode & 61440) === 8192; + }, + isBlkdev(mode) { + return (mode & 61440) === 24576; + }, + isFIFO(mode) { + return (mode & 61440) === 4096; + }, + isSocket(mode) { + return (mode & 49152) === 49152; + }, + flagsToPermissionString(flag) { + var perms = [ "r", "w", "rw" ][flag & 3]; + if ((flag & 512)) { + perms += "w"; + } + return perms; + }, + nodePermissions(node, perms) { + if (FS.ignorePermissions) { + return 0; + } + // return 0 if any user, group or owner bits are set. + if (perms.includes("r") && !(node.mode & 292)) { + return 2; + } + if (perms.includes("w") && !(node.mode & 146)) { + return 2; + } + if (perms.includes("x") && !(node.mode & 73)) { + return 2; + } + return 0; + }, + mayLookup(dir) { + if (!FS.isDir(dir.mode)) return 54; + var errCode = FS.nodePermissions(dir, "x"); + if (errCode) return errCode; + if (!dir.node_ops.lookup) return 2; + return 0; + }, + mayCreate(dir, name) { + if (!FS.isDir(dir.mode)) { + return 54; + } + try { + var node = FS.lookupNode(dir, name); + return 20; + } catch (e) {} + return FS.nodePermissions(dir, "wx"); + }, + mayDelete(dir, name, isdir) { + var node; + try { + node = FS.lookupNode(dir, name); + } catch (e) { + return e.errno; + } + var errCode = FS.nodePermissions(dir, "wx"); + if (errCode) { + return errCode; + } + if (isdir) { + if (!FS.isDir(node.mode)) { + return 54; + } + if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) { + return 10; + } + } else if (FS.isDir(node.mode)) { + return 31; + } + return 0; + }, + mayOpen(node, flags) { + if (!node) { + return 44; + } + if (FS.isLink(node.mode)) { + return 32; + } + var mode = FS.flagsToPermissionString(flags); + if (FS.isDir(node.mode)) { + // opening for write + // TODO: check for O_SEARCH? (== search for dir only) + if (mode !== "r" || (flags & (512 | 64))) { + return 31; + } + } + return FS.nodePermissions(node, mode); + }, + checkOpExists(op, err) { + if (!op) { + throw new FS.ErrnoError(err); + } + return op; + }, + MAX_OPEN_FDS: 4096, + nextfd() { + for (var fd = 0; fd <= FS.MAX_OPEN_FDS; fd++) { + if (!FS.streams[fd]) { + return fd; + } + } + throw new FS.ErrnoError(33); + }, + getStreamChecked(fd) { + var stream = FS.getStream(fd); + if (!stream) { + throw new FS.ErrnoError(8); + } + return stream; + }, + getStream: fd => FS.streams[fd], + createStream(stream, fd = -1) { + // clone it, so we can return an instance of FSStream + stream = Object.assign(new FS.FSStream, stream); + if (fd == -1) { + fd = FS.nextfd(); + } + stream.fd = fd; + FS.streams[fd] = stream; + return stream; + }, + closeStream(fd) { + FS.streams[fd] = null; + }, + dupStream(origStream, fd = -1) { + var stream = FS.createStream(origStream, fd); + stream.stream_ops?.dup?.(stream); + return stream; + }, + doSetAttr(stream, node, attr) { + var setattr = stream?.stream_ops.setattr; + var arg = setattr ? stream : node; + setattr ??= node.node_ops.setattr; + FS.checkOpExists(setattr, 63); + try { + setattr(arg, attr); + } catch (e) { + if (e instanceof RangeError) { + throw new FS.ErrnoError(22); + } + throw e; + } + }, + chrdev_stream_ops: { + open(stream) { + var device = FS.getDevice(stream.node.rdev); + // override node's stream ops with the device's + stream.stream_ops = device.stream_ops; + // forward the open call + stream.stream_ops.open?.(stream); + }, + llseek() { + throw new FS.ErrnoError(70); + } + }, + major: dev => ((dev) >> 8), + minor: dev => ((dev) & 255), + makedev: (ma, mi) => ((ma) << 8 | (mi)), + registerDevice(dev, ops) { + FS.devices[dev] = { + stream_ops: ops + }; + }, + getDevice: dev => FS.devices[dev], + getMounts(mount) { + var mounts = []; + var check = [ mount ]; + while (check.length) { + var m = check.pop(); + mounts.push(m); + check.push(...m.mounts); + } + return mounts; + }, + syncfs(populate, callback) { + if (typeof populate == "function") { + callback = populate; + populate = false; + } + FS.syncFSRequests++; + if (FS.syncFSRequests > 1) { + err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`); + } + var mounts = FS.getMounts(FS.root.mount); + var completed = 0; + function doCallback(errCode) { + FS.syncFSRequests--; + return callback(errCode); + } + function done(errCode) { + if (errCode) { + if (!done.errored) { + done.errored = true; + return doCallback(errCode); + } + return; + } + if (++completed >= mounts.length) { + doCallback(null); + } + } + // sync all mounts + for (var mount of mounts) { + if (mount.type.syncfs) { + mount.type.syncfs(mount, populate, done); + } else { + done(null); + } + } + }, + mount(type, opts, mountpoint) { + var root = mountpoint === "/"; + var pseudo = !mountpoint; + var node; + if (root && FS.root) { + throw new FS.ErrnoError(10); + } else if (!root && !pseudo) { + var lookup = FS.lookupPath(mountpoint, { + follow_mount: false + }); + mountpoint = lookup.path; + // use the absolute path + node = lookup.node; + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + if (!FS.isDir(node.mode)) { + throw new FS.ErrnoError(54); + } + } + var mount = { + type, + opts, + mountpoint, + mounts: [] + }; + // create a root node for the fs + var mountRoot = type.mount(mount); + mountRoot.mount = mount; + mount.root = mountRoot; + if (root) { + FS.root = mountRoot; + } else if (node) { + // set as a mountpoint + node.mounted = mount; + // add the new mount to the current mount's children + if (node.mount) { + node.mount.mounts.push(mount); + } + } + return mountRoot; + }, + unmount(mountpoint) { + var lookup = FS.lookupPath(mountpoint, { + follow_mount: false + }); + if (!FS.isMountpoint(lookup.node)) { + throw new FS.ErrnoError(28); + } + // destroy the nodes for this mount, and all its child mounts + var node = lookup.node; + var mount = node.mounted; + var mounts = FS.getMounts(mount); + for (var [hash, current] of Object.entries(FS.nameTable)) { + while (current) { + var next = current.name_next; + if (mounts.includes(current.mount)) { + FS.destroyNode(current); + } + current = next; + } + } + // no longer a mountpoint + node.mounted = null; + // remove this mount from the child mounts + var idx = node.mount.mounts.indexOf(mount); + node.mount.mounts.splice(idx, 1); + }, + lookup(parent, name) { + return parent.node_ops.lookup(parent, name); + }, + mknod(path, mode, dev) { + var lookup = FS.lookupPath(path, { + parent: true + }); + var parent = lookup.node; + var name = PATH.basename(path); + if (!name) { + throw new FS.ErrnoError(28); + } + if (name === "." || name === "..") { + throw new FS.ErrnoError(20); + } + var errCode = FS.mayCreate(parent, name); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.mknod) { + throw new FS.ErrnoError(63); + } + return parent.node_ops.mknod(parent, name, mode, dev); + }, + statfs(path) { + return FS.statfsNode(FS.lookupPath(path, { + follow: true + }).node); + }, + statfsStream(stream) { + // We keep a separate statfsStream function because noderawfs overrides + // it. In noderawfs, stream.node is sometimes null. Instead, we need to + // look at stream.path. + return FS.statfsNode(stream.node); + }, + statfsNode(node) { + // NOTE: None of the defaults here are true. We're just returning safe and + // sane values. Currently nodefs and rawfs replace these defaults, + // other file systems leave them alone. + var rtn = { + bsize: 4096, + frsize: 4096, + blocks: 1e6, + bfree: 5e5, + bavail: 5e5, + files: FS.nextInode, + ffree: FS.nextInode - 1, + fsid: 42, + flags: 2, + namelen: 255 + }; + if (node.node_ops.statfs) { + Object.assign(rtn, node.node_ops.statfs(node.mount.opts.root)); + } + return rtn; + }, + create(path, mode = 438) { + mode &= 4095; + mode |= 32768; + return FS.mknod(path, mode, 0); + }, + mkdir(path, mode = 511) { + mode &= 511 | 512; + mode |= 16384; + return FS.mknod(path, mode, 0); + }, + mkdirTree(path, mode) { + var dirs = path.split("/"); + var d = ""; + for (var dir of dirs) { + if (!dir) continue; + if (d || PATH.isAbs(path)) d += "/"; + d += dir; + try { + FS.mkdir(d, mode); + } catch (e) { + if (e.errno != 20) throw e; + } + } + }, + mkdev(path, mode, dev) { + if (typeof dev == "undefined") { + dev = mode; + mode = 438; + } + mode |= 8192; + return FS.mknod(path, mode, dev); + }, + symlink(oldpath, newpath) { + if (!PATH_FS.resolve(oldpath)) { + throw new FS.ErrnoError(44); + } + var lookup = FS.lookupPath(newpath, { + parent: true + }); + var parent = lookup.node; + if (!parent) { + throw new FS.ErrnoError(44); + } + var newname = PATH.basename(newpath); + var errCode = FS.mayCreate(parent, newname); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.symlink) { + throw new FS.ErrnoError(63); + } + return parent.node_ops.symlink(parent, newname, oldpath); + }, + rename(old_path, new_path) { + var old_dirname = PATH.dirname(old_path); + var new_dirname = PATH.dirname(new_path); + var old_name = PATH.basename(old_path); + var new_name = PATH.basename(new_path); + // parents must exist + var lookup, old_dir, new_dir; + // let the errors from non existent directories percolate up + lookup = FS.lookupPath(old_path, { + parent: true + }); + old_dir = lookup.node; + lookup = FS.lookupPath(new_path, { + parent: true + }); + new_dir = lookup.node; + if (!old_dir || !new_dir) throw new FS.ErrnoError(44); + // need to be part of the same mount + if (old_dir.mount !== new_dir.mount) { + throw new FS.ErrnoError(75); + } + // source must exist + var old_node = FS.lookupNode(old_dir, old_name); + // old path should not be an ancestor of the new path + var relative = PATH_FS.relative(old_path, new_dirname); + if (relative.charAt(0) !== ".") { + throw new FS.ErrnoError(28); + } + // new path should not be an ancestor of the old path + relative = PATH_FS.relative(new_path, old_dirname); + if (relative.charAt(0) !== ".") { + throw new FS.ErrnoError(55); + } + // see if the new path already exists + var new_node; + try { + new_node = FS.lookupNode(new_dir, new_name); + } catch (e) {} + // early out if nothing needs to change + if (old_node === new_node) { + return; + } + // we'll need to delete the old entry + var isdir = FS.isDir(old_node.mode); + var errCode = FS.mayDelete(old_dir, old_name, isdir); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + // need delete permissions if we'll be overwriting. + // need create permissions if new doesn't already exist. + errCode = new_node ? FS.mayDelete(new_dir, new_name, isdir) : FS.mayCreate(new_dir, new_name); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!old_dir.node_ops.rename) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) { + throw new FS.ErrnoError(10); + } + // if we are going to change the parent, check write permissions + if (new_dir !== old_dir) { + errCode = FS.nodePermissions(old_dir, "w"); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + } + // remove the node from the lookup hash + FS.hashRemoveNode(old_node); + // do the underlying fs rename + try { + old_dir.node_ops.rename(old_node, new_dir, new_name); + // update old node (we do this here to avoid each backend + // needing to) + old_node.parent = new_dir; + } catch (e) { + throw e; + } finally { + // add the node back to the hash (in case node_ops.rename + // changed its name) + FS.hashAddNode(old_node); + } + }, + rmdir(path) { + var lookup = FS.lookupPath(path, { + parent: true + }); + var parent = lookup.node; + var name = PATH.basename(path); + var node = FS.lookupNode(parent, name); + var errCode = FS.mayDelete(parent, name, true); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.rmdir) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + parent.node_ops.rmdir(parent, name); + FS.destroyNode(node); + }, + readdir(path) { + var lookup = FS.lookupPath(path, { + follow: true + }); + var node = lookup.node; + var readdir = FS.checkOpExists(node.node_ops.readdir, 54); + return readdir(node); + }, + unlink(path) { + var lookup = FS.lookupPath(path, { + parent: true + }); + var parent = lookup.node; + if (!parent) { + throw new FS.ErrnoError(44); + } + var name = PATH.basename(path); + var node = FS.lookupNode(parent, name); + var errCode = FS.mayDelete(parent, name, false); + if (errCode) { + // According to POSIX, we should map EISDIR to EPERM, but + // we instead do what Linux does (and we must, as we use + // the musl linux libc). + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.unlink) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + parent.node_ops.unlink(parent, name); + FS.destroyNode(node); + }, + readlink(path) { + var lookup = FS.lookupPath(path); + var link = lookup.node; + if (!link) { + throw new FS.ErrnoError(44); + } + if (!link.node_ops.readlink) { + throw new FS.ErrnoError(28); + } + return link.node_ops.readlink(link); + }, + stat(path, dontFollow) { + var lookup = FS.lookupPath(path, { + follow: !dontFollow + }); + var node = lookup.node; + var getattr = FS.checkOpExists(node.node_ops.getattr, 63); + return getattr(node); + }, + fstat(fd) { + var stream = FS.getStreamChecked(fd); + var node = stream.node; + var getattr = stream.stream_ops.getattr; + var arg = getattr ? stream : node; + getattr ??= node.node_ops.getattr; + FS.checkOpExists(getattr, 63); + return getattr(arg); + }, + lstat(path) { + return FS.stat(path, true); + }, + doChmod(stream, node, mode, dontFollow) { + FS.doSetAttr(stream, node, { + mode: (mode & 4095) | (node.mode & ~4095), + ctime: Date.now(), + dontFollow + }); + }, + chmod(path, mode, dontFollow) { + var node; + if (typeof path == "string") { + var lookup = FS.lookupPath(path, { + follow: !dontFollow + }); + node = lookup.node; + } else { + node = path; + } + FS.doChmod(null, node, mode, dontFollow); + }, + lchmod(path, mode) { + FS.chmod(path, mode, true); + }, + fchmod(fd, mode) { + var stream = FS.getStreamChecked(fd); + FS.doChmod(stream, stream.node, mode, false); + }, + doChown(stream, node, dontFollow) { + FS.doSetAttr(stream, node, { + timestamp: Date.now(), + dontFollow + }); + }, + chown(path, uid, gid, dontFollow) { + var node; + if (typeof path == "string") { + var lookup = FS.lookupPath(path, { + follow: !dontFollow + }); + node = lookup.node; + } else { + node = path; + } + FS.doChown(null, node, dontFollow); + }, + lchown(path, uid, gid) { + FS.chown(path, uid, gid, true); + }, + fchown(fd, uid, gid) { + var stream = FS.getStreamChecked(fd); + FS.doChown(stream, stream.node, false); + }, + doTruncate(stream, node, len) { + if (FS.isDir(node.mode)) { + throw new FS.ErrnoError(31); + } + if (!FS.isFile(node.mode)) { + throw new FS.ErrnoError(28); + } + var errCode = FS.nodePermissions(node, "w"); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + FS.doSetAttr(stream, node, { + size: len, + timestamp: Date.now() + }); + }, + truncate(path, len) { + if (len < 0) { + throw new FS.ErrnoError(28); + } + var node; + if (typeof path == "string") { + var lookup = FS.lookupPath(path, { + follow: true + }); + node = lookup.node; + } else { + node = path; + } + FS.doTruncate(null, node, len); + }, + ftruncate(fd, len) { + var stream = FS.getStreamChecked(fd); + if (len < 0 || (stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(28); + } + FS.doTruncate(stream, stream.node, len); + }, + utime(path, atime, mtime) { + var lookup = FS.lookupPath(path, { + follow: true + }); + var node = lookup.node; + var setattr = FS.checkOpExists(node.node_ops.setattr, 63); + setattr(node, { + atime, + mtime + }); + }, + open(path, flags, mode = 438) { + if (path === "") { + throw new FS.ErrnoError(44); + } + flags = FS_modeStringToFlags(flags); + if ((flags & 64)) { + mode = (mode & 4095) | 32768; + } else { + mode = 0; + } + var node; + var isDirPath; + if (typeof path == "object") { + node = path; + } else { + isDirPath = path.endsWith("/"); + // noent_okay makes it so that if the final component of the path + // doesn't exist, lookupPath returns `node: undefined`. `path` will be + // updated to point to the target of all symlinks. + var lookup = FS.lookupPath(path, { + follow: !(flags & 131072), + noent_okay: true + }); + node = lookup.node; + path = lookup.path; + } + // perhaps we need to create the node + var created = false; + if ((flags & 64)) { + if (node) { + // if O_CREAT and O_EXCL are set, error out if the node already exists + if ((flags & 128)) { + throw new FS.ErrnoError(20); + } + } else if (isDirPath) { + throw new FS.ErrnoError(31); + } else { + // node doesn't exist, try to create it + // Ignore the permission bits here to ensure we can `open` this new + // file below. We use chmod below to apply the permissions once the + // file is open. + node = FS.mknod(path, mode | 511, 0); + created = true; + } + } + if (!node) { + throw new FS.ErrnoError(44); + } + // can't truncate a device + if (FS.isChrdev(node.mode)) { + flags &= ~512; + } + // if asked only for a directory, then this must be one + if ((flags & 65536) && !FS.isDir(node.mode)) { + throw new FS.ErrnoError(54); + } + // check permissions, if this is not a file we just created now (it is ok to + // create and write to a file with read-only permissions; it is read-only + // for later use) + if (!created) { + var errCode = FS.mayOpen(node, flags); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + } + // do truncation if necessary + if ((flags & 512) && !created) { + FS.truncate(node, 0); + } + // we've already handled these, don't pass down to the underlying vfs + flags &= ~(128 | 512 | 131072); + // register the stream with the filesystem + var stream = FS.createStream({ + node, + path: FS.getPath(node), + // we want the absolute path to the node + flags, + seekable: true, + position: 0, + stream_ops: node.stream_ops, + // used by the file family libc calls (fopen, fwrite, ferror, etc.) + ungotten: [], + error: false + }); + // call the new stream's open function + if (stream.stream_ops.open) { + stream.stream_ops.open(stream); + } + if (created) { + FS.chmod(node, mode & 511); + } + return stream; + }, + close(stream) { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (stream.getdents) stream.getdents = null; + // free readdir state + try { + if (stream.stream_ops.close) { + stream.stream_ops.close(stream); + } + } catch (e) { + throw e; + } finally { + FS.closeStream(stream.fd); + } + stream.fd = null; + }, + isClosed(stream) { + return stream.fd === null; + }, + llseek(stream, offset, whence) { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (!stream.seekable || !stream.stream_ops.llseek) { + throw new FS.ErrnoError(70); + } + if (whence != 0 && whence != 1 && whence != 2) { + throw new FS.ErrnoError(28); + } + stream.position = stream.stream_ops.llseek(stream, offset, whence); + stream.ungotten = []; + return stream.position; + }, + read(stream, buffer, offset, length, position) { + if (length < 0 || position < 0) { + throw new FS.ErrnoError(28); + } + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 1) { + throw new FS.ErrnoError(8); + } + if (FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(31); + } + if (!stream.stream_ops.read) { + throw new FS.ErrnoError(28); + } + var seeking = typeof position != "undefined"; + if (!seeking) { + position = stream.position; + } else if (!stream.seekable) { + throw new FS.ErrnoError(70); + } + var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position); + if (!seeking) stream.position += bytesRead; + return bytesRead; + }, + write(stream, buffer, offset, length, position, canOwn) { + if (length < 0 || position < 0) { + throw new FS.ErrnoError(28); + } + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(8); + } + if (FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(31); + } + if (!stream.stream_ops.write) { + throw new FS.ErrnoError(28); + } + if (stream.seekable && stream.flags & 1024) { + // seek to the end before writing in append mode + FS.llseek(stream, 0, 2); + } + var seeking = typeof position != "undefined"; + if (!seeking) { + position = stream.position; + } else if (!stream.seekable) { + throw new FS.ErrnoError(70); + } + var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn); + if (!seeking) stream.position += bytesWritten; + return bytesWritten; + }, + mmap(stream, length, position, prot, flags) { + // User requests writing to file (prot & PROT_WRITE != 0). + // Checking if we have permissions to write to the file unless + // MAP_PRIVATE flag is set. According to POSIX spec it is possible + // to write to file opened in read-only mode with MAP_PRIVATE flag, + // as all modifications will be visible only in the memory of + // the current process. + if ((prot & 2) !== 0 && (flags & 2) === 0 && (stream.flags & 2097155) !== 2) { + throw new FS.ErrnoError(2); + } + if ((stream.flags & 2097155) === 1) { + throw new FS.ErrnoError(2); + } + if (!stream.stream_ops.mmap) { + throw new FS.ErrnoError(43); + } + if (!length) { + throw new FS.ErrnoError(28); + } + return stream.stream_ops.mmap(stream, length, position, prot, flags); + }, + msync(stream, buffer, offset, length, mmapFlags) { + if (!stream.stream_ops.msync) { + return 0; + } + return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags); + }, + ioctl(stream, cmd, arg) { + if (!stream.stream_ops.ioctl) { + throw new FS.ErrnoError(59); + } + return stream.stream_ops.ioctl(stream, cmd, arg); + }, + readFile(path, opts = {}) { + opts.flags = opts.flags ?? 0; + opts.encoding = opts.encoding ?? "binary"; + if (opts.encoding !== "utf8" && opts.encoding !== "binary") { + abort(`Invalid encoding type "${opts.encoding}"`); + } + var stream = FS.open(path, opts.flags); + var stat = FS.stat(path); + var length = stat.size; + var buf = new Uint8Array(length); + FS.read(stream, buf, 0, length, 0); + if (opts.encoding === "utf8") { + buf = UTF8ArrayToString(buf); + } + FS.close(stream); + return buf; + }, + writeFile(path, data, opts = {}) { + opts.flags = opts.flags ?? 577; + var stream = FS.open(path, opts.flags, opts.mode); + data = FS_fileDataToTypedArray(data); + FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn); + FS.close(stream); + }, + cwd: () => FS.currentPath, + chdir(path) { + var lookup = FS.lookupPath(path, { + follow: true + }); + if (lookup.node === null) { + throw new FS.ErrnoError(44); + } + if (!FS.isDir(lookup.node.mode)) { + throw new FS.ErrnoError(54); + } + var errCode = FS.nodePermissions(lookup.node, "x"); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + FS.currentPath = lookup.path; + }, + createDefaultDirectories() { + FS.mkdir("/tmp"); + FS.mkdir("/home"); + FS.mkdir("/home/web_user"); + }, + createDefaultDevices() { + // create /dev + FS.mkdir("/dev"); + // setup /dev/null + FS.registerDevice(FS.makedev(1, 3), { + read: () => 0, + write: (stream, buffer, offset, length, pos) => length, + llseek: () => 0 + }); + FS.mkdev("/dev/null", FS.makedev(1, 3)); + // setup /dev/tty and /dev/tty1 + // stderr needs to print output using err() rather than out() + // so we register a second tty just for it. + TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); + TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); + FS.mkdev("/dev/tty", FS.makedev(5, 0)); + FS.mkdev("/dev/tty1", FS.makedev(6, 0)); + // setup /dev/[u]random + // use a buffer to avoid overhead of individual crypto calls per byte + var randomBuffer = new Uint8Array(1024), randomLeft = 0; + var randomByte = () => { + if (randomLeft === 0) { + randomFill(randomBuffer); + randomLeft = randomBuffer.byteLength; + } + return randomBuffer[--randomLeft]; + }; + FS.createDevice("/dev", "random", randomByte); + FS.createDevice("/dev", "urandom", randomByte); + // we're not going to emulate the actual shm device, + // just create the tmp dirs that reside in it commonly + FS.mkdir("/dev/shm"); + FS.mkdir("/dev/shm/tmp"); + }, + createSpecialDirectories() { + // create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the + // name of the stream for fd 6 (see test_unistd_ttyname) + FS.mkdir("/proc"); + var proc_self = FS.mkdir("/proc/self"); + FS.mkdir("/proc/self/fd"); + FS.mount({ + mount() { + var node = FS.createNode(proc_self, "fd", 16895, 73); + node.stream_ops = { + llseek: MEMFS.stream_ops.llseek + }; + node.node_ops = { + lookup(parent, name) { + var fd = +name; + var stream = FS.getStreamChecked(fd); + var ret = { + parent: null, + mount: { + mountpoint: "fake" + }, + node_ops: { + readlink: () => stream.path + }, + id: fd + 1 + }; + ret.parent = ret; + // make it look like a simple root node + return ret; + }, + readdir() { + return Array.from(FS.streams.entries()).filter(([k, v]) => v).map(([k, v]) => k.toString()); + } + }; + return node; + } + }, {}, "/proc/self/fd"); + }, + createStandardStreams(input, output, error) { + // TODO deprecate the old functionality of a single + // input / output callback and that utilizes FS.createDevice + // and instead require a unique set of stream ops + // by default, we symlink the standard streams to the + // default tty devices. however, if the standard streams + // have been overwritten we create a unique device for + // them instead. + if (input) { + FS.createDevice("/dev", "stdin", input); + } else { + FS.symlink("/dev/tty", "/dev/stdin"); + } + if (output) { + FS.createDevice("/dev", "stdout", null, output); + } else { + FS.symlink("/dev/tty", "/dev/stdout"); + } + if (error) { + FS.createDevice("/dev", "stderr", null, error); + } else { + FS.symlink("/dev/tty1", "/dev/stderr"); + } + // open default streams for the stdin, stdout and stderr devices + var stdin = FS.open("/dev/stdin", 0); + var stdout = FS.open("/dev/stdout", 1); + var stderr = FS.open("/dev/stderr", 1); + }, + staticInit() { + FS.nameTable = new Array(4096); + FS.mount(MEMFS, {}, "/"); + FS.createDefaultDirectories(); + FS.createDefaultDevices(); + FS.createSpecialDirectories(); + FS.filesystems = { + "MEMFS": MEMFS + }; + }, + init(input, output, error) { + FS.initialized = true; + // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here + input ??= Module["stdin"]; + output ??= Module["stdout"]; + error ??= Module["stderr"]; + FS.createStandardStreams(input, output, error); + }, + quit() { + FS.initialized = false; + // force-flush all streams, so we get musl std streams printed out + // close all of our streams + for (var stream of FS.streams) { + if (stream) { + FS.close(stream); + } + } + }, + findObject(path, dontResolveLastLink) { + var ret = FS.analyzePath(path, dontResolveLastLink); + if (!ret.exists) { + return null; + } + return ret.object; + }, + analyzePath(path, dontResolveLastLink) { + // operate from within the context of the symlink's target + try { + var lookup = FS.lookupPath(path, { + follow: !dontResolveLastLink + }); + path = lookup.path; + } catch (e) {} + var ret = { + isRoot: false, + exists: false, + error: 0, + name: null, + path: null, + object: null, + parentExists: false, + parentPath: null, + parentObject: null + }; + try { + var lookup = FS.lookupPath(path, { + parent: true + }); + ret.parentExists = true; + ret.parentPath = lookup.path; + ret.parentObject = lookup.node; + ret.name = PATH.basename(path); + lookup = FS.lookupPath(path, { + follow: !dontResolveLastLink + }); + ret.exists = true; + ret.path = lookup.path; + ret.object = lookup.node; + ret.name = lookup.node.name; + ret.isRoot = lookup.path === "/"; + } catch (e) { + ret.error = e.errno; + } + return ret; + }, + createPath(parent, path, canRead, canWrite) { + parent = typeof parent == "string" ? parent : FS.getPath(parent); + var parts = path.split("/").reverse(); + while (parts.length) { + var part = parts.pop(); + if (!part) continue; + var current = PATH.join2(parent, part); + try { + FS.mkdir(current); + } catch (e) { + if (e.errno != 20) throw e; + } + parent = current; + } + return current; + }, + createFile(parent, name, properties, canRead, canWrite) { + var path = PATH.join2(typeof parent == "string" ? parent : FS.getPath(parent), name); + var mode = FS_getMode(canRead, canWrite); + return FS.create(path, mode); + }, + createDataFile(parent, name, data, canRead, canWrite, canOwn) { + var path = name; + if (parent) { + parent = typeof parent == "string" ? parent : FS.getPath(parent); + path = name ? PATH.join2(parent, name) : parent; + } + var mode = FS_getMode(canRead, canWrite); + var node = FS.create(path, mode); + if (data) { + data = FS_fileDataToTypedArray(data); + // make sure we can write to the file + FS.chmod(node, mode | 146); + var stream = FS.open(node, 577); + FS.write(stream, data, 0, data.length, 0, canOwn); + FS.close(stream); + FS.chmod(node, mode); + } + }, + createDevice(parent, name, input, output) { + var path = PATH.join2(typeof parent == "string" ? parent : FS.getPath(parent), name); + var mode = FS_getMode(!!input, !!output); + FS.createDevice.major ??= 64; + var dev = FS.makedev(FS.createDevice.major++, 0); + // Create a fake device that a set of stream ops to emulate + // the old behavior. + FS.registerDevice(dev, { + open(stream) { + stream.seekable = false; + }, + close(stream) { + // flush any pending line data + if (output?.buffer?.length) { + output(10); + } + }, + read(stream, buffer, offset, length, pos) { + var bytesRead = 0; + for (var i = 0; i < length; i++) { + var result; + try { + result = input(); + } catch (e) { + throw new FS.ErrnoError(29); + } + if (result === undefined && bytesRead === 0) { + throw new FS.ErrnoError(6); + } + if (result === null || result === undefined) break; + bytesRead++; + buffer[offset + i] = result; + } + if (bytesRead) { + stream.node.atime = Date.now(); + } + return bytesRead; + }, + write(stream, buffer, offset, length, pos) { + for (var i = 0; i < length; i++) { + try { + output(buffer[offset + i]); + } catch (e) { + throw new FS.ErrnoError(29); + } + } + if (length) { + stream.node.mtime = stream.node.ctime = Date.now(); + } + return i; + } + }); + return FS.mkdev(path, mode, dev); + }, + forceLoadFile(obj) { + if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true; + if (globalThis.XMLHttpRequest) { + abort("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread."); + } else { + // Command-line. + try { + obj.contents = readBinary(obj.url); + } catch (e) { + throw new FS.ErrnoError(29); + } + } + }, + createLazyFile(parent, name, url, canRead, canWrite) { + // Lazy chunked Uint8Array (implements get and length from Uint8Array). + // Actual getting is abstracted away for eventual reuse. + class LazyUint8Array { + lengthKnown=false; + chunks=[]; + // Loaded chunks. Index is the chunk number + get(idx) { + if (idx > this.length - 1 || idx < 0) { + return undefined; + } + var chunkOffset = idx % this.chunkSize; + var chunkNum = (idx / this.chunkSize) | 0; + return this.getter(chunkNum)[chunkOffset]; + } + setDataGetter(getter) { + this.getter = getter; + } + cacheLength() { + // Find length + var xhr = new XMLHttpRequest; + xhr.open("HEAD", url, false); + xhr.send(null); + if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort("Couldn't load " + url + ". Status: " + xhr.status); + var datalength = Number(xhr.getResponseHeader("Content-length")); + var header; + var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; + var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip"; + var chunkSize = 1024 * 1024; + // Chunk size in bytes + if (!hasByteServing) chunkSize = datalength; + // Function to get a range from the remote URL. + var doXHR = (from, to) => { + if (from > to) abort(`invalid range (${from}, ${to}) or no bytes requested!`); + if (to > datalength - 1) abort(`only ${datalength} bytes available! programmer error!`); + // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available. + var xhr = new XMLHttpRequest; + xhr.open("GET", url, false); + if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); + // Some hints to the browser that we want binary data. + xhr.responseType = "arraybuffer"; + if (xhr.overrideMimeType) { + xhr.overrideMimeType("text/plain; charset=x-user-defined"); + } + xhr.send(null); + if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort("Couldn't load " + url + ". Status: " + xhr.status); + if (xhr.response !== undefined) { + return new Uint8Array(/** @type{Array} */ (xhr.response || [])); + } + return intArrayFromString(xhr.responseText ?? "", true); + }; + var lazyArray = this; + lazyArray.setDataGetter(chunkNum => { + var start = chunkNum * chunkSize; + var end = (chunkNum + 1) * chunkSize - 1; + // including this byte + end = Math.min(end, datalength - 1); + // if datalength-1 is selected, this is the last block + if (typeof lazyArray.chunks[chunkNum] == "undefined") { + lazyArray.chunks[chunkNum] = doXHR(start, end); + } + if (typeof lazyArray.chunks[chunkNum] == "undefined") abort("doXHR failed!"); + return lazyArray.chunks[chunkNum]; + }); + if (usesGzip || !datalength) { + // if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length + chunkSize = datalength = 1; + // this will force getter(0)/doXHR do download the whole file + datalength = this.getter(0).length; + chunkSize = datalength; + out("LazyFiles on gzip forces download of the whole file when length is accessed"); + } + this._length = datalength; + this._chunkSize = chunkSize; + this.lengthKnown = true; + } + get length() { + if (!this.lengthKnown) { + this.cacheLength(); + } + return this._length; + } + get chunkSize() { + if (!this.lengthKnown) { + this.cacheLength(); + } + return this._chunkSize; + } + } + if (globalThis.XMLHttpRequest) { + if (!ENVIRONMENT_IS_WORKER) abort("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc"); + var lazyArray = new LazyUint8Array; + var properties = { + isDevice: false, + contents: lazyArray + }; + } else { + var properties = { + isDevice: false, + url + }; + } + var node = FS.createFile(parent, name, properties, canRead, canWrite); + // This is a total hack, but I want to get this lazy file code out of the + // core of MEMFS. If we want to keep this lazy file concept I feel it should + // be its own thin LAZYFS proxying calls to MEMFS. + if (properties.contents) { + node.contents = properties.contents; + } else if (properties.url) { + node.contents = null; + node.url = properties.url; + } + // Add a function that defers querying the file size until it is asked the first time. + Object.defineProperties(node, { + usedBytes: { + get: function() { + return this.contents.length; + } + } + }); + // override each stream op with one that tries to force load the lazy file first + var stream_ops = {}; + for (const [key, fn] of Object.entries(node.stream_ops)) { + stream_ops[key] = (...args) => { + FS.forceLoadFile(node); + return fn(...args); + }; + } + function writeChunks(stream, buffer, offset, length, position) { + var contents = stream.node.contents; + if (position >= contents.length) return 0; + var size = Math.min(contents.length - position, length); + if (contents.slice) { + // normal array + for (var i = 0; i < size; i++) { + buffer[offset + i] = contents[position + i]; + } + } else { + for (var i = 0; i < size; i++) { + // LazyUint8Array from sync binary XHR + buffer[offset + i] = contents.get(position + i); + } + } + return size; + } + // use a custom read function + stream_ops.read = (stream, buffer, offset, length, position) => { + FS.forceLoadFile(node); + return writeChunks(stream, buffer, offset, length, position); + }; + // use a custom mmap function + stream_ops.mmap = (stream, length, position, prot, flags) => { + FS.forceLoadFile(node); + var ptr = mmapAlloc(length); + if (!ptr) { + throw new FS.ErrnoError(48); + } + writeChunks(stream, HEAP8, ptr, length, position); + return { + ptr, + allocated: true + }; + }; + node.stream_ops = stream_ops; + return node; + } +}; + +/** + * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the + * emscripten HEAP, returns a copy of that string as a Javascript String object. + * + * @param {number} ptr + * @param {number=} maxBytesToRead - An optional length that specifies the + * maximum number of bytes to read. You can omit this parameter to scan the + * string until the first 0 byte. If maxBytesToRead is passed, and the string + * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the + * string will cut short at that byte index. + * @param {boolean=} ignoreNul - If true, the function will not stop on a NUL character. + * @return {string} + */ var UTF8ToString = (ptr, maxBytesToRead, ignoreNul) => { + if (!ptr) return ""; + var end = findStringEnd(HEAPU8, ptr, maxBytesToRead, ignoreNul); + return UTF8Decoder.decode(HEAPU8.subarray(ptr, end)); +}; + +var SYSCALLS = { + currentUmask: 18, + calculateAt(dirfd, path, allowEmpty) { + if (PATH.isAbs(path)) { + return path; + } + // relative path + var dir; + if (dirfd === -100) { + dir = FS.cwd(); + } else { + var dirstream = SYSCALLS.getStreamFromFD(dirfd); + dir = dirstream.path; + } + if (path.length == 0) { + if (!allowEmpty) { + throw new FS.ErrnoError(44); + } + return dir; + } + return dir + "/" + path; + }, + writeStat(buf, stat) { + HEAPU32[((buf) >> 2)] = stat.dev; + HEAPU32[(((buf) + (4)) >> 2)] = stat.mode; + HEAPU32[(((buf) + (8)) >> 2)] = stat.nlink; + HEAPU32[(((buf) + (12)) >> 2)] = stat.uid; + HEAPU32[(((buf) + (16)) >> 2)] = stat.gid; + HEAPU32[(((buf) + (20)) >> 2)] = stat.rdev; + (tempI64 = [ stat.size >>> 0, (tempDouble = stat.size, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (24)) >> 2)] = tempI64[0], HEAP32[(((buf) + (28)) >> 2)] = tempI64[1]); + HEAP32[(((buf) + (32)) >> 2)] = 4096; + HEAP32[(((buf) + (36)) >> 2)] = stat.blocks; + var atime = stat.atime.getTime(); + var mtime = stat.mtime.getTime(); + var ctime = stat.ctime.getTime(); + (tempI64 = [ Math.floor(atime / 1e3) >>> 0, (tempDouble = Math.floor(atime / 1e3), + (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (40)) >> 2)] = tempI64[0], HEAP32[(((buf) + (44)) >> 2)] = tempI64[1]); + HEAPU32[(((buf) + (48)) >> 2)] = (atime % 1e3) * 1e3 * 1e3; + (tempI64 = [ Math.floor(mtime / 1e3) >>> 0, (tempDouble = Math.floor(mtime / 1e3), + (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (56)) >> 2)] = tempI64[0], HEAP32[(((buf) + (60)) >> 2)] = tempI64[1]); + HEAPU32[(((buf) + (64)) >> 2)] = (mtime % 1e3) * 1e3 * 1e3; + (tempI64 = [ Math.floor(ctime / 1e3) >>> 0, (tempDouble = Math.floor(ctime / 1e3), + (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (72)) >> 2)] = tempI64[0], HEAP32[(((buf) + (76)) >> 2)] = tempI64[1]); + HEAPU32[(((buf) + (80)) >> 2)] = (ctime % 1e3) * 1e3 * 1e3; + (tempI64 = [ stat.ino >>> 0, (tempDouble = stat.ino, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (88)) >> 2)] = tempI64[0], HEAP32[(((buf) + (92)) >> 2)] = tempI64[1]); + return 0; + }, + writeStatFs(buf, stats) { + HEAPU32[(((buf) + (4)) >> 2)] = stats.bsize; + HEAPU32[(((buf) + (60)) >> 2)] = stats.bsize; + (tempI64 = [ stats.blocks >>> 0, (tempDouble = stats.blocks, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (8)) >> 2)] = tempI64[0], HEAP32[(((buf) + (12)) >> 2)] = tempI64[1]); + (tempI64 = [ stats.bfree >>> 0, (tempDouble = stats.bfree, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (16)) >> 2)] = tempI64[0], HEAP32[(((buf) + (20)) >> 2)] = tempI64[1]); + (tempI64 = [ stats.bavail >>> 0, (tempDouble = stats.bavail, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (24)) >> 2)] = tempI64[0], HEAP32[(((buf) + (28)) >> 2)] = tempI64[1]); + (tempI64 = [ stats.files >>> 0, (tempDouble = stats.files, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (32)) >> 2)] = tempI64[0], HEAP32[(((buf) + (36)) >> 2)] = tempI64[1]); + (tempI64 = [ stats.ffree >>> 0, (tempDouble = stats.ffree, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (40)) >> 2)] = tempI64[0], HEAP32[(((buf) + (44)) >> 2)] = tempI64[1]); + HEAPU32[(((buf) + (48)) >> 2)] = stats.fsid; + HEAPU32[(((buf) + (64)) >> 2)] = stats.flags; + // ST_NOSUID + HEAPU32[(((buf) + (56)) >> 2)] = stats.namelen; + }, + doMsync(addr, stream, len, flags, offset) { + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + if (flags & 2) { + // MAP_PRIVATE calls need not to be synced back to underlying fs + return 0; + } + var buffer = HEAPU8.slice(addr, addr + len); + FS.msync(stream, buffer, offset, len, flags); + }, + getStreamFromFD(fd) { + var stream = FS.getStreamChecked(fd); + return stream; + }, + varargs: undefined, + getStr(ptr) { + var ret = UTF8ToString(ptr); + return ret; + } +}; + +function ___syscall_dup(fd) { + try { + var old = SYSCALLS.getStreamFromFD(fd); + return FS.dupStream(old).fd; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_faccessat(dirfd, path, amode, flags) { + try { + path = SYSCALLS.getStr(path); + path = SYSCALLS.calculateAt(dirfd, path); + if (amode & ~7) { + // need a valid mode + return -28; + } + var lookup = FS.lookupPath(path, { + follow: true + }); + var node = lookup.node; + if (!node) { + return -44; + } + var perms = ""; + if (amode & 4) perms += "r"; + if (amode & 2) perms += "w"; + if (amode & 1) perms += "x"; + if (perms && FS.nodePermissions(node, perms)) { + return -2; + } + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +var syscallGetVarargI = () => { + // the `+` prepended here is necessary to convince the JSCompiler that varargs is indeed a number. + var ret = HEAP32[((+SYSCALLS.varargs) >> 2)]; + SYSCALLS.varargs += 4; + return ret; +}; + +var syscallGetVarargP = syscallGetVarargI; + +function ___syscall_fcntl64(fd, cmd, varargs) { + SYSCALLS.varargs = varargs; + try { + var stream = SYSCALLS.getStreamFromFD(fd); + switch (cmd) { + case 0: + { + var arg = syscallGetVarargI(); + if (arg < 0) { + return -28; + } + while (FS.streams[arg]) { + arg++; + } + var newStream; + newStream = FS.dupStream(stream, arg); + return newStream.fd; + } + + case 1: + case 2: + return 0; + + // FD_CLOEXEC makes no sense for a single process. + case 3: + return stream.flags; + + case 4: + { + var arg = syscallGetVarargI(); + var mask = 289792; + stream.flags = (stream.flags & ~mask) | (arg & mask); + return 0; + } + + case 12: + { + var arg = syscallGetVarargP(); + var offset = 0; + // We're always unlocked. + HEAP16[(((arg) + (offset)) >> 1)] = 2; + return 0; + } + + case 13: + case 14: + // Pretend that the locking is successful. These are process-level locks, + // and Emscripten programs are a single process. If we supported linking a + // filesystem between programs, we'd need to do more here. + // See https://github.com/emscripten-core/emscripten/issues/23697 + return 0; + } + return -28; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_fstat64(fd, buf) { + try { + return SYSCALLS.writeStat(buf, FS.fstat(fd)); + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +var convertI32PairToI53Checked = (lo, hi) => ((hi + 2097152) >>> 0 < 4194305 - !!lo) ? (lo >>> 0) + hi * 4294967296 : NaN; + +function ___syscall_ftruncate64(fd, length_low, length_high) { + var length = convertI32PairToI53Checked(length_low, length_high); + try { + if (isNaN(length)) return -22; + FS.ftruncate(fd, length); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_ioctl(fd, op, varargs) { + SYSCALLS.varargs = varargs; + try { + var stream = SYSCALLS.getStreamFromFD(fd); + switch (op) { + case 21509: + { + if (!stream.tty) return -59; + return 0; + } + + case 21505: + { + if (!stream.tty) return -59; + if (stream.tty.ops.ioctl_tcgets) { + var termios = stream.tty.ops.ioctl_tcgets(stream); + var argp = syscallGetVarargP(); + HEAP32[((argp) >> 2)] = termios.c_iflag || 0; + HEAP32[(((argp) + (4)) >> 2)] = termios.c_oflag || 0; + HEAP32[(((argp) + (8)) >> 2)] = termios.c_cflag || 0; + HEAP32[(((argp) + (12)) >> 2)] = termios.c_lflag || 0; + for (var i = 0; i < 32; i++) { + HEAP8[(argp + i) + (17)] = termios.c_cc[i] || 0; + } + return 0; + } + return 0; + } + + case 21510: + case 21511: + case 21512: + { + if (!stream.tty) return -59; + return 0; + } + + case 21506: + case 21507: + case 21508: + { + if (!stream.tty) return -59; + if (stream.tty.ops.ioctl_tcsets) { + var argp = syscallGetVarargP(); + var c_iflag = HEAP32[((argp) >> 2)]; + var c_oflag = HEAP32[(((argp) + (4)) >> 2)]; + var c_cflag = HEAP32[(((argp) + (8)) >> 2)]; + var c_lflag = HEAP32[(((argp) + (12)) >> 2)]; + var c_cc = []; + for (var i = 0; i < 32; i++) { + c_cc.push(HEAP8[(argp + i) + (17)]); + } + return stream.tty.ops.ioctl_tcsets(stream.tty, op, { + c_iflag, + c_oflag, + c_cflag, + c_lflag, + c_cc + }); + } + return 0; + } + + case 21519: + { + if (!stream.tty) return -59; + var argp = syscallGetVarargP(); + HEAP32[((argp) >> 2)] = 0; + return 0; + } + + case 21520: + { + if (!stream.tty) return -59; + return -28; + } + + case 21537: + case 21531: + { + var argp = syscallGetVarargP(); + return FS.ioctl(stream, op, argp); + } + + case 21523: + { + // TODO: in theory we should write to the winsize struct that gets + // passed in, but for now musl doesn't read anything on it + if (!stream.tty) return -59; + if (stream.tty.ops.ioctl_tiocgwinsz) { + var winsize = stream.tty.ops.ioctl_tiocgwinsz(stream.tty); + var argp = syscallGetVarargP(); + HEAP16[((argp) >> 1)] = winsize[0]; + HEAP16[(((argp) + (2)) >> 1)] = winsize[1]; + } + return 0; + } + + case 21524: + { + // TODO: technically, this ioctl call should change the window size. + // but, since emscripten doesn't have any concept of a terminal window + // yet, we'll just silently throw it away as we do TIOCGWINSZ + if (!stream.tty) return -59; + return 0; + } + + case 21515: + { + if (!stream.tty) return -59; + return 0; + } + + default: + return -28; + } + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_lstat64(path, buf) { + try { + path = SYSCALLS.getStr(path); + return SYSCALLS.writeStat(buf, FS.lstat(path)); + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_newfstatat(dirfd, path, buf, flags) { + try { + path = SYSCALLS.getStr(path); + var nofollow = flags & 256; + var allowEmpty = flags & 4096; + flags = flags & (~6400); + path = SYSCALLS.calculateAt(dirfd, path, allowEmpty); + return SYSCALLS.writeStat(buf, nofollow ? FS.lstat(path) : FS.stat(path)); + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_openat(dirfd, path, flags, varargs) { + SYSCALLS.varargs = varargs; + try { + path = SYSCALLS.getStr(path); + path = SYSCALLS.calculateAt(dirfd, path); + var mode = varargs ? syscallGetVarargI() : 0; + if (flags & 64) { + mode &= ~SYSCALLS.currentUmask; + } + return FS.open(path, flags, mode).fd; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_stat64(path, buf) { + try { + path = SYSCALLS.getStr(path); + return SYSCALLS.writeStat(buf, FS.stat(path)); + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +var __abort_js = () => abort(""); + +var __embind_register_bigint = (primitiveType, name, size, minRange, maxRange) => {}; + +var AsciiToString = ptr => { + var str = ""; + while (1) { + var ch = HEAPU8[ptr++]; + if (!ch) return str; + str += String.fromCharCode(ch); + } +}; + +var awaitingDependencies = {}; + +var registeredTypes = {}; + +var typeDependencies = {}; + +var BindingError = class BindingError extends Error { + constructor(message) { + super(message); + this.name = "BindingError"; + } +}; + +var throwBindingError = message => { + throw new BindingError(message); +}; + +/** @param {Object=} options */ function sharedRegisterType(rawType, registeredInstance, options = {}) { + var name = registeredInstance.name; + if (!rawType) { + throwBindingError(`type "${name}" must have a positive integer typeid pointer`); + } + if (registeredTypes.hasOwnProperty(rawType)) { + if (options.ignoreDuplicateRegistrations) { + return; + } else { + throwBindingError(`Cannot register type '${name}' twice`); + } + } + registeredTypes[rawType] = registeredInstance; + delete typeDependencies[rawType]; + if (awaitingDependencies.hasOwnProperty(rawType)) { + var callbacks = awaitingDependencies[rawType]; + delete awaitingDependencies[rawType]; + callbacks.forEach(cb => cb()); + } +} + +/** @param {Object=} options */ function registerType(rawType, registeredInstance, options = {}) { + return sharedRegisterType(rawType, registeredInstance, options); +} + +/** @suppress {globalThis} */ var __embind_register_bool = (rawType, name, trueValue, falseValue) => { + name = AsciiToString(name); + registerType(rawType, { + name, + fromWireType: function(wt) { + // ambiguous emscripten ABI: sometimes return values are + // true or false, and sometimes integers (0 or 1) + return !!wt; + }, + toWireType: function(destructors, o) { + return o ? trueValue : falseValue; + }, + readValueFromPointer: function(pointer) { + return this.fromWireType(HEAPU8[pointer]); + }, + destructorFunction: null + }); +}; + +var emval_freelist = []; + +var emval_handles = [ 0, 1, , 1, null, 1, true, 1, false, 1 ]; + +var __emval_decref = handle => { + if (handle > 9 && 0 === --emval_handles[handle + 1]) { + var value = emval_handles[handle]; + emval_handles[handle] = undefined; + emval_freelist.push(handle); + } +}; + +var Emval = { + toValue: handle => { + if (!handle) { + throwBindingError(`Cannot use deleted val. handle = ${handle}`); + } + return emval_handles[handle]; + }, + toHandle: value => { + switch (value) { + case undefined: + return 2; + + case null: + return 4; + + case true: + return 6; + + case false: + return 8; + + default: + { + const handle = emval_freelist.pop() || emval_handles.length; + emval_handles[handle] = value; + emval_handles[handle + 1] = 1; + return handle; + } + } + } +}; + +/** @suppress {globalThis} */ function readPointer(pointer) { + return this.fromWireType(HEAPU32[((pointer) >> 2)]); +} + +var EmValType = { + name: "emscripten::val", + fromWireType: handle => { + var rv = Emval.toValue(handle); + __emval_decref(handle); + return rv; + }, + toWireType: (destructors, value) => Emval.toHandle(value), + readValueFromPointer: readPointer, + destructorFunction: null +}; + +var __embind_register_emval = rawType => registerType(rawType, EmValType); + +var floatReadValueFromPointer = (name, width) => { + switch (width) { + case 4: + return function(pointer) { + return this.fromWireType(HEAPF32[((pointer) >> 2)]); + }; + + case 8: + return function(pointer) { + return this.fromWireType(HEAPF64[((pointer) >> 3)]); + }; + + default: + throw new TypeError(`invalid float width (${width}): ${name}`); + } +}; + +var __embind_register_float = (rawType, name, size) => { + name = AsciiToString(name); + registerType(rawType, { + name, + fromWireType: value => value, + toWireType: (destructors, value) => value, + readValueFromPointer: floatReadValueFromPointer(name, size), + destructorFunction: null + }); +}; + +var integerReadValueFromPointer = (name, width, signed) => { + // integers are quite common, so generate very specialized functions + switch (width) { + case 1: + return signed ? pointer => HEAP8[pointer] : pointer => HEAPU8[pointer]; + + case 2: + return signed ? pointer => HEAP16[((pointer) >> 1)] : pointer => HEAPU16[((pointer) >> 1)]; + + case 4: + return signed ? pointer => HEAP32[((pointer) >> 2)] : pointer => HEAPU32[((pointer) >> 2)]; + + default: + throw new TypeError(`invalid integer width (${width}): ${name}`); + } +}; + +/** @suppress {globalThis} */ var __embind_register_integer = (primitiveType, name, size, minRange, maxRange) => { + name = AsciiToString(name); + const isUnsignedType = minRange === 0; + let fromWireType = value => value; + if (isUnsignedType) { + var bitshift = 32 - 8 * size; + fromWireType = value => (value << bitshift) >>> bitshift; + maxRange = fromWireType(maxRange); + } + registerType(primitiveType, { + name, + fromWireType, + toWireType: (destructors, value) => value, + readValueFromPointer: integerReadValueFromPointer(name, size, minRange !== 0), + destructorFunction: null + }); +}; + +var __embind_register_memory_view = (rawType, dataTypeIndex, name) => { + var typeMapping = [ Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array ]; + var TA = typeMapping[dataTypeIndex]; + function decodeMemoryView(handle) { + var size = HEAPU32[((handle) >> 2)]; + var data = HEAPU32[(((handle) + (4)) >> 2)]; + return new TA(HEAP8.buffer, data, size); + } + name = AsciiToString(name); + registerType(rawType, { + name, + fromWireType: decodeMemoryView, + readValueFromPointer: decodeMemoryView + }, { + ignoreDuplicateRegistrations: true + }); +}; + +var stringToUTF8 = (str, outPtr, maxBytesToWrite) => stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite); + +var __embind_register_std_string = (rawType, name) => { + name = AsciiToString(name); + var stdStringIsUTF8 = true; + registerType(rawType, { + name, + // For some method names we use string keys here since they are part of + // the public/external API and/or used by the runtime-generated code. + fromWireType(value) { + var length = HEAPU32[((value) >> 2)]; + var payload = value + 4; + var str; + if (stdStringIsUTF8) { + str = UTF8ToString(payload, length, true); + } else { + str = ""; + for (var i = 0; i < length; ++i) { + str += String.fromCharCode(HEAPU8[payload + i]); + } + } + _free(value); + return str; + }, + toWireType(destructors, value) { + if (value instanceof ArrayBuffer) { + value = new Uint8Array(value); + } + var length; + var valueIsOfTypeString = (typeof value == "string"); + // We accept `string` or array views with single byte elements + if (!(valueIsOfTypeString || (ArrayBuffer.isView(value) && value.BYTES_PER_ELEMENT == 1))) { + throwBindingError("Cannot pass non-string to std::string"); + } + if (stdStringIsUTF8 && valueIsOfTypeString) { + length = lengthBytesUTF8(value); + } else { + length = value.length; + } + // assumes POINTER_SIZE alignment + var base = _malloc(4 + length + 1); + var ptr = base + 4; + HEAPU32[((base) >> 2)] = length; + if (valueIsOfTypeString) { + if (stdStringIsUTF8) { + stringToUTF8(value, ptr, length + 1); + } else { + for (var i = 0; i < length; ++i) { + var charCode = value.charCodeAt(i); + if (charCode > 255) { + _free(base); + throwBindingError("String has UTF-16 code units that do not fit in 8 bits"); + } + HEAPU8[ptr + i] = charCode; + } + } + } else { + HEAPU8.set(value, ptr); + } + if (destructors !== null) { + destructors.push(_free, base); + } + return base; + }, + readValueFromPointer: readPointer, + destructorFunction(ptr) { + _free(ptr); + } + }); +}; + +var UTF16Decoder = new TextDecoder("utf-16le"); + +var UTF16ToString = (ptr, maxBytesToRead, ignoreNul) => { + var idx = ((ptr) >> 1); + var endIdx = findStringEnd(HEAPU16, idx, maxBytesToRead / 2, ignoreNul); + return UTF16Decoder.decode(HEAPU16.subarray(idx, endIdx)); +}; + +var stringToUTF16 = (str, outPtr, maxBytesToWrite) => { + // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. + maxBytesToWrite ??= 2147483647; + if (maxBytesToWrite < 2) return 0; + maxBytesToWrite -= 2; + // Null terminator. + var startPtr = outPtr; + var numCharsToWrite = (maxBytesToWrite < str.length * 2) ? (maxBytesToWrite / 2) : str.length; + for (var i = 0; i < numCharsToWrite; ++i) { + // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP. + var codeUnit = str.charCodeAt(i); + // possibly a lead surrogate + HEAP16[((outPtr) >> 1)] = codeUnit; + outPtr += 2; + } + // Null-terminate the pointer to the HEAP. + HEAP16[((outPtr) >> 1)] = 0; + return outPtr - startPtr; +}; + +var lengthBytesUTF16 = str => str.length * 2; + +var UTF32ToString = (ptr, maxBytesToRead, ignoreNul) => { + var str = ""; + var startIdx = ((ptr) >> 2); + // If maxBytesToRead is not passed explicitly, it will be undefined, and this + // will always evaluate to true. This saves on code size. + for (var i = 0; !(i >= maxBytesToRead / 4); i++) { + var utf32 = HEAPU32[startIdx + i]; + if (!utf32 && !ignoreNul) break; + str += String.fromCodePoint(utf32); + } + return str; +}; + +var stringToUTF32 = (str, outPtr, maxBytesToWrite) => { + // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. + maxBytesToWrite ??= 2147483647; + if (maxBytesToWrite < 4) return 0; + var startPtr = outPtr; + var endPtr = startPtr + maxBytesToWrite - 4; + for (var i = 0; i < str.length; ++i) { + var codePoint = str.codePointAt(i); + // Gotcha: if codePoint is over 0xFFFF, it is represented as a surrogate pair in UTF-16. + // We need to manually skip over the second code unit for correct iteration. + if (codePoint > 65535) { + i++; + } + HEAP32[((outPtr) >> 2)] = codePoint; + outPtr += 4; + if (outPtr + 4 > endPtr) break; + } + // Null-terminate the pointer to the HEAP. + HEAP32[((outPtr) >> 2)] = 0; + return outPtr - startPtr; +}; + +var lengthBytesUTF32 = str => { + var len = 0; + for (var i = 0; i < str.length; ++i) { + var codePoint = str.codePointAt(i); + // Gotcha: if codePoint is over 0xFFFF, it is represented as a surrogate pair in UTF-16. + // We need to manually skip over the second code unit for correct iteration. + if (codePoint > 65535) { + i++; + } + len += 4; + } + return len; +}; + +var __embind_register_std_wstring = (rawType, charSize, name) => { + name = AsciiToString(name); + var decodeString, encodeString, lengthBytesUTF; + if (charSize === 2) { + decodeString = UTF16ToString; + encodeString = stringToUTF16; + lengthBytesUTF = lengthBytesUTF16; + } else { + decodeString = UTF32ToString; + encodeString = stringToUTF32; + lengthBytesUTF = lengthBytesUTF32; + } + registerType(rawType, { + name, + fromWireType: value => { + // Code mostly taken from _embind_register_std_string fromWireType + var length = HEAPU32[((value) >> 2)]; + var str = decodeString(value + 4, length * charSize, true); + _free(value); + return str; + }, + toWireType: (destructors, value) => { + if (!(typeof value == "string")) { + throwBindingError(`Cannot pass non-string to C++ string type ${name}`); + } + // assumes POINTER_SIZE alignment + var length = lengthBytesUTF(value); + var ptr = _malloc(4 + length + charSize); + HEAPU32[((ptr) >> 2)] = length / charSize; + encodeString(value, ptr + 4, length + charSize); + if (destructors !== null) { + destructors.push(_free, ptr); + } + return ptr; + }, + readValueFromPointer: readPointer, + destructorFunction(ptr) { + _free(ptr); + } + }); +}; + +var __embind_register_void = (rawType, name) => { + name = AsciiToString(name); + registerType(rawType, { + isVoid: true, + // void return values can be optimized out sometimes + name, + fromWireType: () => undefined, + // TODO: assert if anything else is given? + toWireType: (destructors, o) => undefined + }); +}; + +var emval_methodCallers = []; + +var emval_addMethodCaller = caller => { + var id = emval_methodCallers.length; + emval_methodCallers.push(caller); + return id; +}; + +var getTypeName = type => { + var ptr = ___getTypeName(type); + var rv = AsciiToString(ptr); + _free(ptr); + return rv; +}; + +var requireRegisteredType = (rawType, humanName) => { + var impl = registeredTypes[rawType]; + if (undefined === impl) { + throwBindingError(`${humanName} has unknown type ${getTypeName(rawType)}`); + } + return impl; +}; + +var emval_lookupTypes = (argCount, argTypes) => { + var a = new Array(argCount); + for (var i = 0; i < argCount; ++i) { + a[i] = requireRegisteredType(HEAPU32[(((argTypes) + (i * 4)) >> 2)], `parameter ${i}`); + } + return a; +}; + +var createNamedFunction = (name, func) => Object.defineProperty(func, "name", { + value: name +}); + +var emval_returnValue = (toReturnWire, destructorsRef, handle) => { + var destructors = []; + var result = toReturnWire(destructors, handle); + if (destructors.length) { + // void, primitives and any other types w/o destructors don't need to allocate a handle + HEAPU32[((destructorsRef) >> 2)] = Emval.toHandle(destructors); + } + return result; +}; + +var emval_symbols = {}; + +var getStringOrSymbol = address => { + var symbol = emval_symbols[address]; + if (symbol === undefined) { + return AsciiToString(address); + } + return symbol; +}; + +var __emval_create_invoker = (argCount, argTypesPtr, kind) => { + var GenericWireTypeSize = 8; + var [retType, ...argTypes] = emval_lookupTypes(argCount, argTypesPtr); + var toReturnWire = retType.toWireType.bind(retType); + var argFromPtr = argTypes.map(type => type.readValueFromPointer.bind(type)); + argCount--; + // remove the extracted return type + var argN = new Array(argCount); + var invokerFunction = (handle, methodName, destructorsRef, args) => { + var offset = 0; + for (var i = 0; i < argCount; ++i) { + argN[i] = argFromPtr[i](args + offset); + offset += GenericWireTypeSize; + } + var rv; + switch (kind) { + case 0: + rv = Emval.toValue(handle).apply(null, argN); + break; + + case 2: + rv = Reflect.construct(Emval.toValue(handle), argN); + break; + + case 3: + // no-op, just return the argument + rv = argN[0]; + break; + + case 1: + rv = Emval.toValue(handle)[getStringOrSymbol(methodName)](...argN); + break; + } + return emval_returnValue(toReturnWire, destructorsRef, rv); + }; + var functionName = `methodCaller<(${argTypes.map(t => t.name)}) => ${retType.name}>`; + return emval_addMethodCaller(createNamedFunction(functionName, invokerFunction)); +}; + +var __emval_get_global = name => { + if (!name) { + return Emval.toHandle(globalThis); + } + name = getStringOrSymbol(name); + return Emval.toHandle(globalThis[name]); +}; + +var __emval_get_property = (handle, key) => { + handle = Emval.toValue(handle); + key = Emval.toValue(key); + return Emval.toHandle(handle[key]); +}; + +var __emval_incref = handle => { + if (handle > 9) { + emval_handles[handle + 1] += 1; + } +}; + +var __emval_instanceof = (object, constructor) => { + object = Emval.toValue(object); + constructor = Emval.toValue(constructor); + return object instanceof constructor; +}; + +var __emval_invoke = (caller, handle, methodName, destructorsRef, args) => emval_methodCallers[caller](handle, methodName, destructorsRef, args); + +var __emval_new_cstring = v => Emval.toHandle(getStringOrSymbol(v)); + +var runDestructors = destructors => { + while (destructors.length) { + var ptr = destructors.pop(); + var del = destructors.pop(); + del(ptr); + } +}; + +var __emval_run_destructors = handle => { + var destructors = Emval.toValue(handle); + runDestructors(destructors); + __emval_decref(handle); +}; + +var __emval_set_property = (handle, key, value) => { + handle = Emval.toValue(handle); + key = Emval.toValue(key); + value = Emval.toValue(value); + handle[key] = value; +}; + +var __emval_typeof = handle => { + handle = Emval.toValue(handle); + return Emval.toHandle(typeof handle); +}; + +function __gmtime_js(time_low, time_high, tmPtr) { + var time = convertI32PairToI53Checked(time_low, time_high); + var date = new Date(time * 1e3); + HEAP32[((tmPtr) >> 2)] = date.getUTCSeconds(); + HEAP32[(((tmPtr) + (4)) >> 2)] = date.getUTCMinutes(); + HEAP32[(((tmPtr) + (8)) >> 2)] = date.getUTCHours(); + HEAP32[(((tmPtr) + (12)) >> 2)] = date.getUTCDate(); + HEAP32[(((tmPtr) + (16)) >> 2)] = date.getUTCMonth(); + HEAP32[(((tmPtr) + (20)) >> 2)] = date.getUTCFullYear() - 1900; + HEAP32[(((tmPtr) + (24)) >> 2)] = date.getUTCDay(); + var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0); + var yday = ((date.getTime() - start) / (1e3 * 60 * 60 * 24)) | 0; + HEAP32[(((tmPtr) + (28)) >> 2)] = yday; +} + +var isLeapYear = year => year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0); + +var MONTH_DAYS_LEAP_CUMULATIVE = [ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 ]; + +var MONTH_DAYS_REGULAR_CUMULATIVE = [ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 ]; + +var ydayFromDate = date => { + var leap = isLeapYear(date.getFullYear()); + var monthDaysCumulative = (leap ? MONTH_DAYS_LEAP_CUMULATIVE : MONTH_DAYS_REGULAR_CUMULATIVE); + var yday = monthDaysCumulative[date.getMonth()] + date.getDate() - 1; + // -1 since it's days since Jan 1 + return yday; +}; + +function __localtime_js(time_low, time_high, tmPtr) { + var time = convertI32PairToI53Checked(time_low, time_high); + var date = new Date(time * 1e3); + HEAP32[((tmPtr) >> 2)] = date.getSeconds(); + HEAP32[(((tmPtr) + (4)) >> 2)] = date.getMinutes(); + HEAP32[(((tmPtr) + (8)) >> 2)] = date.getHours(); + HEAP32[(((tmPtr) + (12)) >> 2)] = date.getDate(); + HEAP32[(((tmPtr) + (16)) >> 2)] = date.getMonth(); + HEAP32[(((tmPtr) + (20)) >> 2)] = date.getFullYear() - 1900; + HEAP32[(((tmPtr) + (24)) >> 2)] = date.getDay(); + var yday = ydayFromDate(date) | 0; + HEAP32[(((tmPtr) + (28)) >> 2)] = yday; + HEAP32[(((tmPtr) + (36)) >> 2)] = -(date.getTimezoneOffset() * 60); + // Attention: DST is in December in South, and some regions don't have DST at all. + var start = new Date(date.getFullYear(), 0, 1); + var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset(); + var winterOffset = start.getTimezoneOffset(); + var dst = (summerOffset != winterOffset && date.getTimezoneOffset() == Math.min(winterOffset, summerOffset)) | 0; + HEAP32[(((tmPtr) + (32)) >> 2)] = dst; +} + +var setTempRet0 = val => __emscripten_tempret_set(val); + +var __mktime_js = function(tmPtr) { + var ret = (() => { + var date = new Date(HEAP32[(((tmPtr) + (20)) >> 2)] + 1900, HEAP32[(((tmPtr) + (16)) >> 2)], HEAP32[(((tmPtr) + (12)) >> 2)], HEAP32[(((tmPtr) + (8)) >> 2)], HEAP32[(((tmPtr) + (4)) >> 2)], HEAP32[((tmPtr) >> 2)], 0); + if (isNaN(date.getTime())) { + return -1; + } + // There's an ambiguous hour when the time goes back; the tm_isdst field is + // used to disambiguate it. Date() basically guesses, so we fix it up if it + // guessed wrong, or fill in tm_isdst with the guess if it's -1. + var dst = HEAP32[(((tmPtr) + (32)) >> 2)]; + var guessedOffset = date.getTimezoneOffset(); + var start = new Date(date.getFullYear(), 0, 1); + var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset(); + var winterOffset = start.getTimezoneOffset(); + var dstOffset = Math.min(winterOffset, summerOffset); + // DST is in December in South + if (dst < 0) { + // Attention: some regions don't have DST at all. + HEAP32[(((tmPtr) + (32)) >> 2)] = Number(summerOffset != winterOffset && dstOffset == guessedOffset); + } else if ((dst > 0) != (dstOffset == guessedOffset)) { + var nonDstOffset = Math.max(winterOffset, summerOffset); + var trueOffset = dst > 0 ? dstOffset : nonDstOffset; + // Don't try setMinutes(date.getMinutes() + ...) -- it's messed up. + date.setTime(date.getTime() + (trueOffset - guessedOffset) * 6e4); + } + HEAP32[(((tmPtr) + (24)) >> 2)] = date.getDay(); + var yday = ydayFromDate(date) | 0; + HEAP32[(((tmPtr) + (28)) >> 2)] = yday; + // To match expected behavior, update fields from date + HEAP32[((tmPtr) >> 2)] = date.getSeconds(); + HEAP32[(((tmPtr) + (4)) >> 2)] = date.getMinutes(); + HEAP32[(((tmPtr) + (8)) >> 2)] = date.getHours(); + HEAP32[(((tmPtr) + (12)) >> 2)] = date.getDate(); + HEAP32[(((tmPtr) + (16)) >> 2)] = date.getMonth(); + HEAP32[(((tmPtr) + (20)) >> 2)] = date.getYear(); + // Return time in seconds + return date.getTime() / 1e3; + })(); + return (setTempRet0((tempDouble = ret, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0)), + ret >>> 0); +}; + +function __mmap_js(len, prot, flags, fd, offset_low, offset_high, allocated, addr) { + var offset = convertI32PairToI53Checked(offset_low, offset_high); + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var res = FS.mmap(stream, len, offset, prot, flags); + var ptr = res.ptr; + HEAP32[((allocated) >> 2)] = res.allocated; + HEAPU32[((addr) >> 2)] = ptr; + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function __munmap_js(addr, len, prot, flags, fd, offset_low, offset_high) { + var offset = convertI32PairToI53Checked(offset_low, offset_high); + try { + var stream = SYSCALLS.getStreamFromFD(fd); + if (prot & 2) { + SYSCALLS.doMsync(addr, stream, len, flags, offset); + } + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +var __tzset_js = (timezone, daylight, std_name, dst_name) => { + // TODO: Use (malleable) environment variables instead of system settings. + var currentYear = (new Date).getFullYear(); + var winter = new Date(currentYear, 0, 1); + var summer = new Date(currentYear, 6, 1); + var winterOffset = winter.getTimezoneOffset(); + var summerOffset = summer.getTimezoneOffset(); + // Local standard timezone offset. Local standard time is not adjusted for + // daylight savings. This code uses the fact that getTimezoneOffset returns + // a greater value during Standard Time versus Daylight Saving Time (DST). + // Thus it determines the expected output during Standard Time, and it + // compares whether the output of the given date the same (Standard) or less + // (DST). + var stdTimezoneOffset = Math.max(winterOffset, summerOffset); + // timezone is specified as seconds west of UTC ("The external variable + // `timezone` shall be set to the difference, in seconds, between + // Coordinated Universal Time (UTC) and local standard time."), the same + // as returned by stdTimezoneOffset. + // See http://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html + HEAPU32[((timezone) >> 2)] = stdTimezoneOffset * 60; + HEAP32[((daylight) >> 2)] = Number(winterOffset != summerOffset); + var extractZone = timezoneOffset => { + // Why inverse sign? + // Read here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset + var sign = timezoneOffset >= 0 ? "-" : "+"; + var absOffset = Math.abs(timezoneOffset); + var hours = String(Math.floor(absOffset / 60)).padStart(2, "0"); + var minutes = String(absOffset % 60).padStart(2, "0"); + return `UTC${sign}${hours}${minutes}`; + }; + var winterName = extractZone(winterOffset); + var summerName = extractZone(summerOffset); + if (summerOffset < winterOffset) { + // Northern hemisphere + stringToUTF8(winterName, std_name, 17); + stringToUTF8(summerName, dst_name, 17); + } else { + stringToUTF8(winterName, dst_name, 17); + stringToUTF8(summerName, std_name, 17); + } +}; + +var _emscripten_get_now = () => performance.now(); + +var _emscripten_date_now = () => Date.now(); + +var nowIsMonotonic = 1; + +var checkWasiClock = clock_id => clock_id >= 0 && clock_id <= 3; + +function _clock_time_get(clk_id, ignored_precision_low, ignored_precision_high, ptime) { + var ignored_precision = convertI32PairToI53Checked(ignored_precision_low, ignored_precision_high); + if (!checkWasiClock(clk_id)) { + return 28; + } + var now; + // all wasi clocks but realtime are monotonic + if (clk_id === 0) { + now = _emscripten_date_now(); + } else if (nowIsMonotonic) { + now = _emscripten_get_now(); + } else { + return 52; + } + // "now" is in ms, and wasi times are in ns. + var nsec = Math.round(now * 1e3 * 1e3); + (tempI64 = [ nsec >>> 0, (tempDouble = nsec, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[((ptime) >> 2)] = tempI64[0], HEAP32[(((ptime) + (4)) >> 2)] = tempI64[1]); + return 0; +} + +var readEmAsmArgsArray = []; + +var readEmAsmArgs = (sigPtr, buf) => { + readEmAsmArgsArray.length = 0; + var ch; + // Most arguments are i32s, so shift the buffer pointer so it is a plain + // index into HEAP32. + while (ch = HEAPU8[sigPtr++]) { + // Floats are always passed as doubles, so all types except for 'i' + // are 8 bytes and require alignment. + var wide = (ch != 105); + wide &= (ch != 112); + buf += wide && (buf % 8) ? 4 : 0; + readEmAsmArgsArray.push(// Special case for pointers under wasm64 or CAN_ADDRESS_2GB mode. + ch == 112 ? HEAPU32[((buf) >> 2)] : ch == 105 ? HEAP32[((buf) >> 2)] : HEAPF64[((buf) >> 3)]); + buf += wide ? 8 : 4; + } + return readEmAsmArgsArray; +}; + +var runEmAsmFunction = (code, sigPtr, argbuf) => { + var args = readEmAsmArgs(sigPtr, argbuf); + return ASM_CONSTS[code](...args); +}; + +var _emscripten_asm_const_int = (code, sigPtr, argbuf) => runEmAsmFunction(code, sigPtr, argbuf); + +var _emscripten_asm_const_ptr = (code, sigPtr, argbuf) => runEmAsmFunction(code, sigPtr, argbuf); + +var _emscripten_errn = (str, len) => err(UTF8ToString(str, len)); + +var getHeapMax = () => // Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate +// full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side +// for any code that deals with heap sizes, which would require special +// casing all heap size related code to treat 0 specially. +2147483648; + +var _emscripten_get_heap_max = () => getHeapMax(); + +var _emscripten_has_asyncify = () => 0; + +var _emscripten_outn = (str, len) => out(UTF8ToString(str, len)); + +var UNWIND_CACHE = {}; + +var stringToNewUTF8 = str => { + var size = lengthBytesUTF8(str) + 1; + var ret = _malloc(size); + if (ret) stringToUTF8(str, ret, size); + return ret; +}; + +/** @returns {number} */ var convertFrameToPC = frame => { + var match; + if (match = /\bwasm-function\[\d+\]:(0x[0-9a-f]+)/.exec(frame)) { + // Wasm engines give the binary offset directly, so we use that as return address + return +match[1]; + } else if (match = /:(\d+):\d+(?:\)|$)/.exec(frame)) { + // If we are in js, we can use the js line number as the "return address". + // This should work for wasm2js. We tag the high bit to distinguish this + // from wasm addresses. + return 2147483648 | +match[1]; + } + // return 0 if we can't find any + return 0; +}; + +var saveInUnwindCache = callstack => { + for (var line of callstack) { + var pc = convertFrameToPC(line); + if (pc) { + UNWIND_CACHE[pc] = line; + } + } +}; + +var jsStackTrace = () => (new Error).stack.toString(); + +var _emscripten_stack_snapshot = () => { + var callstack = jsStackTrace().split("\n"); + if (callstack[0] == "Error") { + callstack.shift(); + } + saveInUnwindCache(callstack); + // Caches the stack snapshot so that emscripten_stack_unwind_buffer() can + // unwind from this spot. + UNWIND_CACHE.last_addr = convertFrameToPC(callstack[3]); + UNWIND_CACHE.last_stack = callstack; + return UNWIND_CACHE.last_addr; +}; + +var _emscripten_pc_get_function = pc => { + var frame = UNWIND_CACHE[pc]; + if (!frame) return 0; + var name; + var match; + // First try to match foo.wasm.sym files explcitly. e.g. + // at test_return_address.wasm.main (wasm://wasm/test_return_address.wasm-0012cc2a:wasm-function[26]:0x9f3 + // Then match JS symbols which don't include that module name: + // at invokeEntryPoint (.../test_return_address.js:1500:42) + // Finally match firefox format: + // Object._main@http://server.com:4324:12' + if (match = /^\s+at .*\.wasm\.(.*) \(.*\)$/.exec(frame)) { + name = match[1]; + } else if (match = /^\s+at (.*) \(.*\)$/.exec(frame)) { + name = match[1]; + } else if (match = /^(.+?)@/.exec(frame)) { + name = match[1]; + } else { + return 0; + } + _free(_emscripten_pc_get_function.ret ?? 0); + _emscripten_pc_get_function.ret = stringToNewUTF8(name); + return _emscripten_pc_get_function.ret; +}; + +var growMemory = size => { + var oldHeapSize = wasmMemory.buffer.byteLength; + var pages = ((size - oldHeapSize + 65535) / 65536) | 0; + try { + // round size grow request up to wasm page size (fixed 64KB per spec) + wasmMemory.grow(pages); + // .grow() takes a delta compared to the previous size + updateMemoryViews(); + return 1; + } catch (e) {} +}; + +var _emscripten_resize_heap = requestedSize => { + var oldSize = HEAPU8.length; + // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned. + requestedSize >>>= 0; + // With multithreaded builds, races can happen (another thread might increase the size + // in between), so return a failure, and let the caller retry. + // Memory resize rules: + // 1. Always increase heap size to at least the requested size, rounded up + // to next page multiple. + // 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap + // geometrically: increase the heap size according to + // MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), At most + // overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB). + // 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap + // linearly: increase the heap size by at least + // MEMORY_GROWTH_LINEAR_STEP bytes. + // 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by + // MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest + // 4. If we were unable to allocate as much memory, it may be due to + // over-eager decision to excessively reserve due to (3) above. + // Hence if an allocation fails, cut down on the amount of excess + // growth, in an attempt to succeed to perform a smaller allocation. + // A limit is set for how much we can grow. We should not exceed that + // (the wasm binary specifies it, so if we tried, we'd fail anyhow). + var maxHeapSize = getHeapMax(); + if (requestedSize > maxHeapSize) { + return false; + } + // Loop through potential heap size increases. If we attempt a too eager + // reservation that fails, cut down on the attempted size and reserve a + // smaller bump instead. (max 3 times, chosen somewhat arbitrarily) + for (var cutDown = 1; cutDown <= 4; cutDown *= 2) { + var overGrownHeapSize = oldSize * (1 + .2 / cutDown); + // ensure geometric growth + // but limit overreserving (default to capping at +96MB overgrowth at most) + overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296); + var newSize = Math.min(maxHeapSize, alignMemory(Math.max(requestedSize, overGrownHeapSize), 65536)); + var replacement = growMemory(newSize); + if (replacement) { + return true; + } + } + return false; +}; + +var _emscripten_stack_unwind_buffer = (addr, buffer, count) => { + var stack; + if (UNWIND_CACHE.last_addr == addr) { + stack = UNWIND_CACHE.last_stack; + } else { + stack = jsStackTrace().split("\n"); + if (stack[0] == "Error") { + stack.shift(); + } + saveInUnwindCache(stack); + } + var offset = 3; + while (stack[offset] && convertFrameToPC(stack[offset]) != addr) { + ++offset; + } + for (var i = 0; i < count && stack[i + offset]; ++i) { + HEAP32[(((buffer) + (i * 4)) >> 2)] = convertFrameToPC(stack[i + offset]); + } + return i; +}; + +var GLctx; + +var webgl_enable_ANGLE_instanced_arrays = ctx => { + // Extension available in WebGL 1 from Firefox 26 and Google Chrome 30 onwards. Core feature in WebGL 2. + var ext = ctx.getExtension("ANGLE_instanced_arrays"); + // Because this extension is a core function in WebGL 2, assign the extension entry points in place of + // where the core functions will reside in WebGL 2. This way the calling code can call these without + // having to dynamically branch depending if running against WebGL 1 or WebGL 2. + if (ext) { + ctx["vertexAttribDivisor"] = (index, divisor) => ext["vertexAttribDivisorANGLE"](index, divisor); + ctx["drawArraysInstanced"] = (mode, first, count, primcount) => ext["drawArraysInstancedANGLE"](mode, first, count, primcount); + ctx["drawElementsInstanced"] = (mode, count, type, indices, primcount) => ext["drawElementsInstancedANGLE"](mode, count, type, indices, primcount); + return 1; + } +}; + +var webgl_enable_OES_vertex_array_object = ctx => { + // Extension available in WebGL 1 from Firefox 25 and WebKit 536.28/desktop Safari 6.0.3 onwards. Core feature in WebGL 2. + var ext = ctx.getExtension("OES_vertex_array_object"); + if (ext) { + ctx["createVertexArray"] = () => ext["createVertexArrayOES"](); + ctx["deleteVertexArray"] = vao => ext["deleteVertexArrayOES"](vao); + ctx["bindVertexArray"] = vao => ext["bindVertexArrayOES"](vao); + ctx["isVertexArray"] = vao => ext["isVertexArrayOES"](vao); + return 1; + } +}; + +var webgl_enable_WEBGL_draw_buffers = ctx => { + // Extension available in WebGL 1 from Firefox 28 onwards. Core feature in WebGL 2. + var ext = ctx.getExtension("WEBGL_draw_buffers"); + if (ext) { + ctx["drawBuffers"] = (n, bufs) => ext["drawBuffersWEBGL"](n, bufs); + return 1; + } +}; + +var webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance = ctx => // Closure is expected to be allowed to minify the '.dibvbi' property, so not accessing it quoted. +!!(ctx.dibvbi = ctx.getExtension("WEBGL_draw_instanced_base_vertex_base_instance")); + +var webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance = ctx => !!(ctx.mdibvbi = ctx.getExtension("WEBGL_multi_draw_instanced_base_vertex_base_instance")); + +var webgl_enable_EXT_polygon_offset_clamp = ctx => !!(ctx.extPolygonOffsetClamp = ctx.getExtension("EXT_polygon_offset_clamp")); + +var webgl_enable_EXT_clip_control = ctx => !!(ctx.extClipControl = ctx.getExtension("EXT_clip_control")); + +var webgl_enable_WEBGL_polygon_mode = ctx => !!(ctx.webglPolygonMode = ctx.getExtension("WEBGL_polygon_mode")); + +var webgl_enable_WEBGL_multi_draw = ctx => // Closure is expected to be allowed to minify the '.multiDrawWebgl' property, so not accessing it quoted. +!!(ctx.multiDrawWebgl = ctx.getExtension("WEBGL_multi_draw")); + +var getEmscriptenSupportedExtensions = ctx => { + // Restrict the list of advertised extensions to those that we actually + // support. + var supportedExtensions = [ // WebGL 1 extensions + "ANGLE_instanced_arrays", "EXT_blend_minmax", "EXT_disjoint_timer_query", "EXT_frag_depth", "EXT_shader_texture_lod", "EXT_sRGB", "OES_element_index_uint", "OES_fbo_render_mipmap", "OES_standard_derivatives", "OES_texture_float", "OES_texture_half_float", "OES_texture_half_float_linear", "OES_vertex_array_object", "WEBGL_color_buffer_float", "WEBGL_depth_texture", "WEBGL_draw_buffers", // WebGL 2 extensions + "EXT_color_buffer_float", "EXT_conservative_depth", "EXT_disjoint_timer_query_webgl2", "EXT_texture_norm16", "NV_shader_noperspective_interpolation", "WEBGL_clip_cull_distance", // WebGL 1 and WebGL 2 extensions + "EXT_clip_control", "EXT_color_buffer_half_float", "EXT_depth_clamp", "EXT_float_blend", "EXT_polygon_offset_clamp", "EXT_texture_compression_bptc", "EXT_texture_compression_rgtc", "EXT_texture_filter_anisotropic", "KHR_parallel_shader_compile", "OES_texture_float_linear", "WEBGL_blend_func_extended", "WEBGL_compressed_texture_astc", "WEBGL_compressed_texture_etc", "WEBGL_compressed_texture_etc1", "WEBGL_compressed_texture_s3tc", "WEBGL_compressed_texture_s3tc_srgb", "WEBGL_debug_renderer_info", "WEBGL_debug_shaders", "WEBGL_lose_context", "WEBGL_multi_draw", "WEBGL_polygon_mode" ]; + // .getSupportedExtensions() can return null if context is lost, so coerce to empty array. + return ctx.getSupportedExtensions()?.filter(ext => supportedExtensions.includes(ext)) ?? []; +}; + +var registerPreMainLoop = f => { + // Does nothing unless $MainLoop is included/used. + typeof MainLoop != "undefined" && MainLoop.preMainLoop.push(f); +}; + +var webglBufferSubData = (target, offset, size, data, src = HEAPU8) => { + if (GL.currentContext.version >= 2) { + size && GLctx.bufferSubData(target, offset, src, data, size); + return; + } + GLctx.bufferSubData(target, offset, src.subarray(data, data + size)); +}; + +var GL = { + counter: 1, + buffers: [], + mappedBuffers: {}, + programs: [], + framebuffers: [], + renderbuffers: [], + textures: [], + shaders: [], + vaos: [], + contexts: [], + offscreenCanvases: {}, + queries: [], + samplers: [], + transformFeedbacks: [], + syncs: [], + byteSizeByTypeRoot: 5120, + byteSizeByType: [ 1, 1, 2, 2, 4, 4, 4, 2, 3, 4, 8 ], + stringCache: {}, + stringiCache: {}, + unpackAlignment: 4, + unpackRowLength: 0, + recordError: errorCode => { + if (!GL.lastError) { + GL.lastError = errorCode; + } + }, + getNewId: table => { + var ret = GL.counter++; + for (var i = table.length; i < ret; i++) { + table[i] = null; + } + // Skip over any non-null elements that might have been created by + // glBindBuffer. + while (table[ret]) { + ret = GL.counter++; + } + return ret; + }, + genObject: (n, buffers, createFunction, objectTable) => { + for (var i = 0; i < n; i++) { + var buffer = GLctx[createFunction](); + var id = buffer && GL.getNewId(objectTable); + if (buffer) { + buffer.name = id; + objectTable[id] = buffer; + } else { + GL.recordError(1282); + } + HEAP32[(((buffers) + (i * 4)) >> 2)] = id; + } + }, + MAX_TEMP_BUFFER_SIZE: 2097152, + numTempVertexBuffersPerSize: 64, + log2ceilLookup: i => 32 - Math.clz32(i === 0 ? 0 : i - 1), + generateTempBuffers: (quads, context) => { + var largestIndex = GL.log2ceilLookup(GL.MAX_TEMP_BUFFER_SIZE); + context.tempVertexBufferCounters1 = []; + context.tempVertexBufferCounters2 = []; + context.tempVertexBufferCounters1.length = context.tempVertexBufferCounters2.length = largestIndex + 1; + context.tempVertexBuffers1 = []; + context.tempVertexBuffers2 = []; + context.tempVertexBuffers1.length = context.tempVertexBuffers2.length = largestIndex + 1; + context.tempIndexBuffers = []; + context.tempIndexBuffers.length = largestIndex + 1; + for (var i = 0; i <= largestIndex; ++i) { + context.tempIndexBuffers[i] = null; + // Created on-demand + context.tempVertexBufferCounters1[i] = context.tempVertexBufferCounters2[i] = 0; + var ringbufferLength = GL.numTempVertexBuffersPerSize; + context.tempVertexBuffers1[i] = []; + context.tempVertexBuffers2[i] = []; + var ringbuffer1 = context.tempVertexBuffers1[i]; + var ringbuffer2 = context.tempVertexBuffers2[i]; + ringbuffer1.length = ringbuffer2.length = ringbufferLength; + for (var j = 0; j < ringbufferLength; ++j) { + ringbuffer1[j] = ringbuffer2[j] = null; + } + } + if (quads) { + // GL_QUAD indexes can be precalculated + context.tempQuadIndexBuffer = GLctx.createBuffer(); + context.GLctx.bindBuffer(34963, context.tempQuadIndexBuffer); + var numIndexes = GL.MAX_TEMP_BUFFER_SIZE >> 1; + var quadIndexes = new Uint16Array(numIndexes); + var i = 0, v = 0; + while (1) { + quadIndexes[i++] = v; + if (i >= numIndexes) break; + quadIndexes[i++] = v + 1; + if (i >= numIndexes) break; + quadIndexes[i++] = v + 2; + if (i >= numIndexes) break; + quadIndexes[i++] = v; + if (i >= numIndexes) break; + quadIndexes[i++] = v + 2; + if (i >= numIndexes) break; + quadIndexes[i++] = v + 3; + if (i >= numIndexes) break; + v += 4; + } + context.GLctx.bufferData(34963, quadIndexes, 35044); + context.GLctx.bindBuffer(34963, null); + } + }, + getTempVertexBuffer: sizeBytes => { + var idx = GL.log2ceilLookup(sizeBytes); + var ringbuffer = GL.currentContext.tempVertexBuffers1[idx]; + var nextFreeBufferIndex = GL.currentContext.tempVertexBufferCounters1[idx]; + GL.currentContext.tempVertexBufferCounters1[idx] = (GL.currentContext.tempVertexBufferCounters1[idx] + 1) & (GL.numTempVertexBuffersPerSize - 1); + var vbo = ringbuffer[nextFreeBufferIndex]; + if (vbo) { + return vbo; + } + var prevVBO = GLctx.getParameter(34964); + ringbuffer[nextFreeBufferIndex] = GLctx.createBuffer(); + GLctx.bindBuffer(34962, ringbuffer[nextFreeBufferIndex]); + GLctx.bufferData(34962, 1 << idx, 35048); + GLctx.bindBuffer(34962, prevVBO); + return ringbuffer[nextFreeBufferIndex]; + }, + getTempIndexBuffer: sizeBytes => { + var idx = GL.log2ceilLookup(sizeBytes); + var ibo = GL.currentContext.tempIndexBuffers[idx]; + if (ibo) { + return ibo; + } + var prevIBO = GLctx.getParameter(34965); + GL.currentContext.tempIndexBuffers[idx] = GLctx.createBuffer(); + GLctx.bindBuffer(34963, GL.currentContext.tempIndexBuffers[idx]); + GLctx.bufferData(34963, 1 << idx, 35048); + GLctx.bindBuffer(34963, prevIBO); + return GL.currentContext.tempIndexBuffers[idx]; + }, + newRenderingFrameStarted: () => { + if (!GL.currentContext) { + return; + } + var vb = GL.currentContext.tempVertexBuffers1; + GL.currentContext.tempVertexBuffers1 = GL.currentContext.tempVertexBuffers2; + GL.currentContext.tempVertexBuffers2 = vb; + vb = GL.currentContext.tempVertexBufferCounters1; + GL.currentContext.tempVertexBufferCounters1 = GL.currentContext.tempVertexBufferCounters2; + GL.currentContext.tempVertexBufferCounters2 = vb; + var largestIndex = GL.log2ceilLookup(GL.MAX_TEMP_BUFFER_SIZE); + for (var i = 0; i <= largestIndex; ++i) { + GL.currentContext.tempVertexBufferCounters1[i] = 0; + } + }, + getSource: (shader, count, string, length) => { + var source = ""; + for (var i = 0; i < count; ++i) { + var len = length ? HEAPU32[(((length) + (i * 4)) >> 2)] : undefined; + source += UTF8ToString(HEAPU32[(((string) + (i * 4)) >> 2)], len); + } + return source; + }, + calcBufLength: (size, type, stride, count) => { + if (stride > 0) { + return count * stride; + } + var typeSize = GL.byteSizeByType[type - GL.byteSizeByTypeRoot]; + return size * typeSize * count; + }, + usedTempBuffers: [], + preDrawHandleClientVertexAttribBindings: count => { + GL.resetBufferBinding = false; + // TODO: initial pass to detect ranges we need to upload, might not need + // an upload per attrib + for (var i = 0; i < GL.currentContext.maxVertexAttribs; ++i) { + var cb = GL.currentContext.clientBuffers[i]; + if (!cb.clientside || !cb.enabled) continue; + GL.resetBufferBinding = true; + var size = GL.calcBufLength(cb.size, cb.type, cb.stride, count); + var buf = GL.getTempVertexBuffer(size); + GLctx.bindBuffer(34962, buf); + webglBufferSubData(34962, 0, size, cb.ptr); + cb.vertexAttribPointerAdaptor.call(GLctx, i, cb.size, cb.type, cb.normalized, cb.stride, 0); + } + }, + postDrawHandleClientVertexAttribBindings: () => { + if (GL.resetBufferBinding) { + GLctx.bindBuffer(34962, GL.buffers[GLctx.currentArrayBufferBinding]); + } + }, + createContext: (/** @type {HTMLCanvasElement} */ canvas, webGLContextAttributes) => { + // BUG: Workaround Safari WebGL issue: After successfully acquiring WebGL + // context on a canvas, calling .getContext() will always return that + // context independent of which 'webgl' or 'webgl2' + // context version was passed. See: + // https://webkit.org/b/222758 + // and: + // https://github.com/emscripten-core/emscripten/issues/13295. + // TODO: Once the bug is fixed and shipped in Safari, adjust the Safari + // version field in above check. + if (!canvas.getContextSafariWebGL2Fixed) { + canvas.getContextSafariWebGL2Fixed = canvas.getContext; + /** @type {function(this:HTMLCanvasElement, string, (Object|null)=): (Object|null)} */ function fixedGetContext(ver, attrs) { + var gl = canvas.getContextSafariWebGL2Fixed(ver, attrs); + return ((ver == "webgl") == (gl instanceof WebGLRenderingContext)) ? gl : null; + } + canvas.getContext = fixedGetContext; + } + var ctx = (webGLContextAttributes.majorVersion > 1) ? canvas.getContext("webgl2", webGLContextAttributes) : canvas.getContext("webgl", webGLContextAttributes); + if (!ctx) return 0; + var handle = GL.registerContext(ctx, webGLContextAttributes); + return handle; + }, + registerContext: (ctx, webGLContextAttributes) => { + // without pthreads a context is just an integer ID + var handle = GL.getNewId(GL.contexts); + var context = { + handle, + attributes: webGLContextAttributes, + version: webGLContextAttributes.majorVersion, + GLctx: ctx + }; + // Store the created context object so that we can access the context + // given a canvas without having to pass the parameters again. + if (ctx.canvas) ctx.canvas.GLctxObject = context; + GL.contexts[handle] = context; + if (typeof webGLContextAttributes.enableExtensionsByDefault == "undefined" || webGLContextAttributes.enableExtensionsByDefault) { + GL.initExtensions(context); + } + context.maxVertexAttribs = context.GLctx.getParameter(34921); + context.clientBuffers = []; + for (var i = 0; i < context.maxVertexAttribs; i++) { + context.clientBuffers[i] = { + enabled: false, + clientside: false, + size: 0, + type: 0, + normalized: 0, + stride: 0, + ptr: 0, + vertexAttribPointerAdaptor: null + }; + } + GL.generateTempBuffers(false, context); + return handle; + }, + makeContextCurrent: contextHandle => { + // Active Emscripten GL layer context object. + GL.currentContext = GL.contexts[contextHandle]; + // Active WebGL context object. + Module["ctx"] = GLctx = GL.currentContext?.GLctx; + return !(contextHandle && !GLctx); + }, + getContext: contextHandle => GL.contexts[contextHandle], + deleteContext: contextHandle => { + if (GL.currentContext === GL.contexts[contextHandle]) { + GL.currentContext = null; + } + if (typeof JSEvents == "object") { + // Release all JS event handlers on the DOM element that the GL context is + // associated with since the context is now deleted. + JSEvents.removeAllHandlersOnTarget(GL.contexts[contextHandle].GLctx.canvas); + } + // Make sure the canvas object no longer refers to the context object so + // there are no GC surprises. + if (GL.contexts[contextHandle]?.GLctx.canvas) { + GL.contexts[contextHandle].GLctx.canvas.GLctxObject = undefined; + } + GL.contexts[contextHandle] = null; + }, + initExtensions: context => { + // If this function is called without a specific context object, init the + // extensions of the currently active context. + context ||= GL.currentContext; + if (context.initExtensionsDone) return; + context.initExtensionsDone = true; + var GLctx = context.GLctx; + // Detect the presence of a few extensions manually, since the GL interop + // layer itself will need to know if they exist. + // Extensions that are available in both WebGL 1 and WebGL 2 + webgl_enable_WEBGL_multi_draw(GLctx); + webgl_enable_EXT_polygon_offset_clamp(GLctx); + webgl_enable_EXT_clip_control(GLctx); + webgl_enable_WEBGL_polygon_mode(GLctx); + // Extensions that are only available in WebGL 1 (the calls will be no-ops + // if called on a WebGL 2 context active) + webgl_enable_ANGLE_instanced_arrays(GLctx); + webgl_enable_OES_vertex_array_object(GLctx); + webgl_enable_WEBGL_draw_buffers(GLctx); + // Extensions that are available from WebGL >= 2 (no-op if called on a WebGL 1 context active) + webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(GLctx); + webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(GLctx); + // On WebGL 2, EXT_disjoint_timer_query is replaced with an alternative + // that's based on core APIs, and exposes only the queryCounterEXT() + // entrypoint. + if (context.version >= 2) { + GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query_webgl2"); + } + // However, Firefox exposes the WebGL 1 version on WebGL 2 as well and + // thus we look for the WebGL 1 version again if the WebGL 2 version + // isn't present. https://bugzil.la/1328882 + if (context.version < 2 || !GLctx.disjointTimerQueryExt) { + GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query"); + } + for (var ext of getEmscriptenSupportedExtensions(GLctx)) { + // WEBGL_lose_context, WEBGL_debug_renderer_info and WEBGL_debug_shaders + // are not enabled by default. + if (!ext.includes("lose_context") && !ext.includes("debug")) { + // Call .getExtension() to enable that extension permanently. + GLctx.getExtension(ext); + } + } + } +}; + +var webglPowerPreferences = [ "default", "low-power", "high-performance" ]; + +/** @type {Object} */ var specialHTMLTargets = [ 0, globalThis.document ?? 0, globalThis.window ?? 0 ]; + +var findEventTarget = target => { + // The sensible "default" target varies between events, but use window as the default + // since DOM events mostly can default to that. Specific callback registrations + // override their own defaults. + if (!target) return window; + if (typeof target == "number") target = specialHTMLTargets[target] || UTF8ToString(target); + if (target === "#window") return window; else if (target === "#document") return document; else if (target === "#screen") return screen; else if (target === "#canvas") return Module["canvas"]; else if (typeof target == "string") return globalThis.document?.getElementById(target); + return target; +}; + +var findCanvasEventTarget = target => { + if (typeof target == "number") target = UTF8ToString(target); + if (!target || target === "#canvas") { + if (typeof GL != "undefined" && GL.offscreenCanvases["canvas"]) return GL.offscreenCanvases["canvas"]; + // TODO: Remove this line, target '#canvas' should refer only to Module['canvas'], not to GL.offscreenCanvases['canvas'] - but need stricter tests to be able to remove this line. + return Module["canvas"]; + } + if (typeof GL != "undefined" && GL.offscreenCanvases[target]) return GL.offscreenCanvases[target]; + return findEventTarget(target); +}; + +var _emscripten_webgl_do_create_context = (target, attributes) => { + var attr32 = ((attributes) >> 2); + var powerPreference = HEAP32[attr32 + (8 >> 2)]; + var contextAttributes = { + "alpha": !!HEAP8[attributes + 0], + "depth": !!HEAP8[attributes + 1], + "stencil": !!HEAP8[attributes + 2], + "antialias": !!HEAP8[attributes + 3], + "premultipliedAlpha": !!HEAP8[attributes + 4], + "preserveDrawingBuffer": !!HEAP8[attributes + 5], + "powerPreference": webglPowerPreferences[powerPreference], + "failIfMajorPerformanceCaveat": !!HEAP8[attributes + 12], + // The following are not predefined WebGL context attributes in the WebGL specification, so the property names can be minified by Closure. + majorVersion: HEAP32[attr32 + (16 >> 2)], + minorVersion: HEAP32[attr32 + (20 >> 2)], + enableExtensionsByDefault: HEAP8[attributes + 24], + explicitSwapControl: HEAP8[attributes + 25], + proxyContextToMainThread: HEAP32[attr32 + (28 >> 2)], + renderViaOffscreenBackBuffer: HEAP8[attributes + 32] + }; + var canvas = findCanvasEventTarget(target); + if (!canvas) { + return 0; + } + if (contextAttributes.explicitSwapControl) { + return 0; + } + var contextHandle = GL.createContext(canvas, contextAttributes); + return contextHandle; +}; + +var _emscripten_webgl_create_context = _emscripten_webgl_do_create_context; + +var _emscripten_webgl_destroy_context = contextHandle => { + if (GL.currentContext == contextHandle) GL.currentContext = 0; + GL.deleteContext(contextHandle); +}; + +var _emscripten_webgl_get_context_attributes = (c, a) => { + if (!a) return -5; + c = GL.contexts[c]; + if (!c) return -3; + var t = c.GLctx?.getContextAttributes(); + if (!t) return -3; + HEAP8[a] = t.alpha; + HEAP8[(a) + (1)] = t.depth; + HEAP8[(a) + (2)] = t.stencil; + HEAP8[(a) + (3)] = t.antialias; + HEAP8[(a) + (4)] = t.premultipliedAlpha; + HEAP8[(a) + (5)] = t.preserveDrawingBuffer; + var power = t["powerPreference"] && webglPowerPreferences.indexOf(t["powerPreference"]); + HEAP32[(((a) + (8)) >> 2)] = power; + HEAP8[(a) + (12)] = t.failIfMajorPerformanceCaveat; + HEAP32[(((a) + (16)) >> 2)] = c.version; + HEAP32[(((a) + (20)) >> 2)] = 0; + HEAP8[(a) + (24)] = c.attributes.enableExtensionsByDefault; + return 0; +}; + +var _emscripten_webgl_do_get_current_context = () => GL.currentContext ? GL.currentContext.handle : 0; + +var _emscripten_webgl_get_current_context = _emscripten_webgl_do_get_current_context; + +var _emscripten_webgl_make_context_current = contextHandle => { + var success = GL.makeContextCurrent(contextHandle); + return success ? 0 : -5; +}; + +var stackAlloc = sz => __emscripten_stack_alloc(sz); + +var stringToUTF8OnStack = str => { + var size = lengthBytesUTF8(str) + 1; + var ret = stackAlloc(size); + stringToUTF8(str, ret, size); + return ret; +}; + +var writeI53ToI64 = (ptr, num) => { + HEAPU32[((ptr) >> 2)] = num; + var lower = HEAPU32[((ptr) >> 2)]; + HEAPU32[(((ptr) + (4)) >> 2)] = (num - lower) / 4294967296; +}; + +var readI53FromI64 = ptr => HEAPU32[((ptr) >> 2)] + HEAP32[(((ptr) + (4)) >> 2)] * 4294967296; + +var wasmTableMirror = []; + +var getWasmTableEntry = funcPtr => { + var func = wasmTableMirror[funcPtr]; + if (!func) { + /** @suppress {checkTypes} */ wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr); + } + return func; +}; + +var WebGPU = { + Internals: { + jsObjects: [], + jsObjectInsert: (ptr, jsObject) => { + ptr >>>= 0; + WebGPU.Internals.jsObjects[ptr] = jsObject; + }, + bufferOnUnmaps: [], + futures: [], + futureInsert: (futureId, promise) => {} + }, + getJsObject: ptr => { + if (!ptr) return undefined; + ptr >>>= 0; + return WebGPU.Internals.jsObjects[ptr]; + }, + importJsAdapter: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateAdapter(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsBindGroup: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateBindGroup(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsBindGroupLayout: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateBindGroupLayout(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsBuffer: (buffer, parentPtr = 0) => { + // At the moment, we do not allow importing pending buffers. + assert(buffer.mapState === "unmapped"); + var bufferPtr = _emwgpuImportBuffer(parentPtr); + WebGPU.Internals.jsObjectInsert(bufferPtr, buffer); + return bufferPtr; + }, + importJsCommandBuffer: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateCommandBuffer(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsCommandEncoder: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateCommandEncoder(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsComputePassEncoder: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateComputePassEncoder(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsComputePipeline: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateComputePipeline(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsDevice: (device, parentPtr = 0) => { + var queuePtr = _emwgpuCreateQueue(parentPtr); + var devicePtr = _emwgpuCreateDevice(parentPtr, queuePtr); + WebGPU.Internals.jsObjectInsert(queuePtr, device.queue); + WebGPU.Internals.jsObjectInsert(devicePtr, device); + return devicePtr; + }, + importJsExternalTexture: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateExternalTexture(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsPipelineLayout: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreatePipelineLayout(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsQuerySet: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateQuerySet(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsQueue: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateQueue(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsRenderBundle: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateRenderBundle(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsRenderBundleEncoder: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateRenderBundleEncoder(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsRenderPassEncoder: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateRenderPassEncoder(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsRenderPipeline: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateRenderPipeline(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsSampler: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateSampler(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsShaderModule: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateShaderModule(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsSurface: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateSurface(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsTexture: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateTexture(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsTextureView: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateTextureView(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + errorCallback: (callback, type, message, userdata) => { + var sp = stackSave(); + var messagePtr = stringToUTF8OnStack(message); + getWasmTableEntry(callback)(type, messagePtr, userdata); + stackRestore(sp); + }, + iterateExtensions: (root, handlers) => { + for (var ptr = HEAPU32[((root) >> 2)]; ptr; ptr = HEAPU32[((ptr) >> 2)]) { + var sType = HEAP32[(((ptr) + (4)) >> 2)]; + // This will crash if there's no handler indicating either a bogus + // sType, or one we haven't implemented yet. + var handler = handlers[sType](ptr); + } + }, + setStringView: (ptr, data, length) => { + HEAPU32[((ptr) >> 2)] = data; + HEAPU32[(((ptr) + (4)) >> 2)] = length; + }, + makeStringFromStringView: stringViewPtr => { + var ptr = HEAPU32[((stringViewPtr) >> 2)]; + var length = HEAPU32[(((stringViewPtr) + (4)) >> 2)]; + // UTF8ToString stops at the first null terminator character in the + // string regardless of the length. + return UTF8ToString(ptr, length); + }, + makeStringFromOptionalStringView: stringViewPtr => { + var ptr = HEAPU32[((stringViewPtr) >> 2)]; + var length = HEAPU32[(((stringViewPtr) + (4)) >> 2)]; + // If we don't have a valid string pointer, just return undefined when + // optional. + if (!ptr) { + if (length === 0) { + return ""; + } + return undefined; + } + // UTF8ToString stops at the first null terminator character in the + // string regardless of the length. + return UTF8ToString(ptr, length); + }, + makeColor: ptr => ({ + "r": HEAPF64[((ptr) >> 3)], + "g": HEAPF64[(((ptr) + (8)) >> 3)], + "b": HEAPF64[(((ptr) + (16)) >> 3)], + "a": HEAPF64[(((ptr) + (24)) >> 3)] + }), + makeExtent3D: ptr => ({ + "width": HEAPU32[((ptr) >> 2)], + "height": HEAPU32[(((ptr) + (4)) >> 2)], + "depthOrArrayLayers": HEAPU32[(((ptr) + (8)) >> 2)] + }), + makeOrigin3D: ptr => ({ + "x": HEAPU32[((ptr) >> 2)], + "y": HEAPU32[(((ptr) + (4)) >> 2)], + "z": HEAPU32[(((ptr) + (8)) >> 2)] + }), + makeTexelCopyTextureInfo: ptr => ({ + "texture": WebGPU.getJsObject(HEAPU32[((ptr) >> 2)]), + "mipLevel": HEAPU32[(((ptr) + (4)) >> 2)], + "origin": WebGPU.makeOrigin3D(ptr + 8), + "aspect": WebGPU.TextureAspect[HEAP32[(((ptr) + (20)) >> 2)]] + }), + makeTexelCopyBufferLayout: ptr => { + var bytesPerRow = HEAPU32[(((ptr) + (8)) >> 2)]; + var rowsPerImage = HEAPU32[(((ptr) + (12)) >> 2)]; + return { + "offset": readI53FromI64(ptr), + "bytesPerRow": bytesPerRow === 4294967295 ? undefined : bytesPerRow, + "rowsPerImage": rowsPerImage === 4294967295 ? undefined : rowsPerImage + }; + }, + makeTexelCopyBufferInfo: ptr => { + var layoutPtr = ptr + 0; + var bufferCopyView = WebGPU.makeTexelCopyBufferLayout(layoutPtr); + bufferCopyView["buffer"] = WebGPU.getJsObject(HEAPU32[(((ptr) + (16)) >> 2)]); + return bufferCopyView; + }, + makePassTimestampWrites: ptr => { + if (ptr === 0) return undefined; + return { + "querySet": WebGPU.getJsObject(HEAPU32[(((ptr) + (4)) >> 2)]), + "beginningOfPassWriteIndex": HEAPU32[(((ptr) + (8)) >> 2)], + "endOfPassWriteIndex": HEAPU32[(((ptr) + (12)) >> 2)] + }; + }, + makePipelineConstants: (constantCount, constantsPtr) => { + if (!constantCount) return; + var constants = {}; + for (var i = 0; i < constantCount; ++i) { + var entryPtr = constantsPtr + 24 * i; + var key = WebGPU.makeStringFromStringView(entryPtr + 4); + constants[key] = HEAPF64[(((entryPtr) + (16)) >> 3)]; + } + return constants; + }, + makePipelineLayout: layoutPtr => { + if (!layoutPtr) return "auto"; + return WebGPU.getJsObject(layoutPtr); + }, + makeComputeState: ptr => { + if (!ptr) return undefined; + var desc = { + "module": WebGPU.getJsObject(HEAPU32[(((ptr) + (4)) >> 2)]), + "constants": WebGPU.makePipelineConstants(HEAPU32[(((ptr) + (16)) >> 2)], HEAPU32[(((ptr) + (20)) >> 2)]), + "entryPoint": WebGPU.makeStringFromOptionalStringView(ptr + 8) + }; + return desc; + }, + makeComputePipelineDesc: descriptor => { + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "layout": WebGPU.makePipelineLayout(HEAPU32[(((descriptor) + (12)) >> 2)]), + "compute": WebGPU.makeComputeState(descriptor + 16) + }; + return desc; + }, + makeRenderPipelineDesc: descriptor => { + function makePrimitiveState(psPtr) { + if (!psPtr) return undefined; + return { + "topology": WebGPU.PrimitiveTopology[HEAP32[(((psPtr) + (4)) >> 2)]], + "stripIndexFormat": WebGPU.IndexFormat[HEAP32[(((psPtr) + (8)) >> 2)]], + "frontFace": WebGPU.FrontFace[HEAP32[(((psPtr) + (12)) >> 2)]], + "cullMode": WebGPU.CullMode[HEAP32[(((psPtr) + (16)) >> 2)]], + "unclippedDepth": !!(HEAPU32[(((psPtr) + (20)) >> 2)]) + }; + } + function makeBlendComponent(bdPtr) { + if (!bdPtr) return undefined; + return { + "operation": WebGPU.BlendOperation[HEAP32[((bdPtr) >> 2)]], + "srcFactor": WebGPU.BlendFactor[HEAP32[(((bdPtr) + (4)) >> 2)]], + "dstFactor": WebGPU.BlendFactor[HEAP32[(((bdPtr) + (8)) >> 2)]] + }; + } + function makeBlendState(bsPtr) { + if (!bsPtr) return undefined; + return { + "alpha": makeBlendComponent(bsPtr + 12), + "color": makeBlendComponent(bsPtr + 0) + }; + } + function makeColorState(csPtr) { + var format = WebGPU.TextureFormat[HEAP32[(((csPtr) + (4)) >> 2)]]; + return format ? { + "format": format, + "blend": makeBlendState(HEAPU32[(((csPtr) + (8)) >> 2)]), + "writeMask": HEAPU32[(((csPtr) + (16)) >> 2)] + } : undefined; + } + function makeColorStates(count, csArrayPtr) { + var states = []; + for (var i = 0; i < count; ++i) { + states.push(makeColorState(csArrayPtr + 24 * i)); + } + return states; + } + function makeStencilStateFace(ssfPtr) { + return { + "compare": WebGPU.CompareFunction[HEAP32[((ssfPtr) >> 2)]], + "failOp": WebGPU.StencilOperation[HEAP32[(((ssfPtr) + (4)) >> 2)]], + "depthFailOp": WebGPU.StencilOperation[HEAP32[(((ssfPtr) + (8)) >> 2)]], + "passOp": WebGPU.StencilOperation[HEAP32[(((ssfPtr) + (12)) >> 2)]] + }; + } + function makeDepthStencilState(dssPtr) { + if (!dssPtr) return undefined; + return { + "format": WebGPU.TextureFormat[HEAP32[(((dssPtr) + (4)) >> 2)]], + "depthWriteEnabled": !!(HEAPU32[(((dssPtr) + (8)) >> 2)]), + "depthCompare": WebGPU.CompareFunction[HEAP32[(((dssPtr) + (12)) >> 2)]], + "stencilFront": makeStencilStateFace(dssPtr + 16), + "stencilBack": makeStencilStateFace(dssPtr + 32), + "stencilReadMask": HEAPU32[(((dssPtr) + (48)) >> 2)], + "stencilWriteMask": HEAPU32[(((dssPtr) + (52)) >> 2)], + "depthBias": HEAP32[(((dssPtr) + (56)) >> 2)], + "depthBiasSlopeScale": HEAPF32[(((dssPtr) + (60)) >> 2)], + "depthBiasClamp": HEAPF32[(((dssPtr) + (64)) >> 2)] + }; + } + function makeVertexAttribute(vaPtr) { + return { + "format": WebGPU.VertexFormat[HEAP32[(((vaPtr) + (4)) >> 2)]], + "offset": readI53FromI64((vaPtr) + (8)), + "shaderLocation": HEAPU32[(((vaPtr) + (16)) >> 2)] + }; + } + function makeVertexAttributes(count, vaArrayPtr) { + var vas = []; + for (var i = 0; i < count; ++i) { + vas.push(makeVertexAttribute(vaArrayPtr + i * 24)); + } + return vas; + } + function makeVertexBuffer(vbPtr) { + if (!vbPtr) return undefined; + var stepMode = WebGPU.VertexStepMode[HEAP32[(((vbPtr) + (4)) >> 2)]]; + var attributeCount = HEAPU32[(((vbPtr) + (16)) >> 2)]; + if (!stepMode && !attributeCount) { + return null; + } + return { + "arrayStride": readI53FromI64((vbPtr) + (8)), + "stepMode": stepMode, + "attributes": makeVertexAttributes(attributeCount, HEAPU32[(((vbPtr) + (20)) >> 2)]) + }; + } + function makeVertexBuffers(count, vbArrayPtr) { + if (!count) return undefined; + var vbs = []; + for (var i = 0; i < count; ++i) { + vbs.push(makeVertexBuffer(vbArrayPtr + i * 24)); + } + return vbs; + } + function makeVertexState(viPtr) { + if (!viPtr) return undefined; + var desc = { + "module": WebGPU.getJsObject(HEAPU32[(((viPtr) + (4)) >> 2)]), + "constants": WebGPU.makePipelineConstants(HEAPU32[(((viPtr) + (16)) >> 2)], HEAPU32[(((viPtr) + (20)) >> 2)]), + "buffers": makeVertexBuffers(HEAPU32[(((viPtr) + (24)) >> 2)], HEAPU32[(((viPtr) + (28)) >> 2)]), + "entryPoint": WebGPU.makeStringFromOptionalStringView(viPtr + 8) + }; + return desc; + } + function makeMultisampleState(msPtr) { + if (!msPtr) return undefined; + return { + "count": HEAPU32[(((msPtr) + (4)) >> 2)], + "mask": HEAPU32[(((msPtr) + (8)) >> 2)], + "alphaToCoverageEnabled": !!(HEAPU32[(((msPtr) + (12)) >> 2)]) + }; + } + function makeFragmentState(fsPtr) { + if (!fsPtr) return undefined; + var desc = { + "module": WebGPU.getJsObject(HEAPU32[(((fsPtr) + (4)) >> 2)]), + "constants": WebGPU.makePipelineConstants(HEAPU32[(((fsPtr) + (16)) >> 2)], HEAPU32[(((fsPtr) + (20)) >> 2)]), + "targets": makeColorStates(HEAPU32[(((fsPtr) + (24)) >> 2)], HEAPU32[(((fsPtr) + (28)) >> 2)]), + "entryPoint": WebGPU.makeStringFromOptionalStringView(fsPtr + 8) + }; + return desc; + } + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "layout": WebGPU.makePipelineLayout(HEAPU32[(((descriptor) + (12)) >> 2)]), + "vertex": makeVertexState(descriptor + 16), + "primitive": makePrimitiveState(descriptor + 48), + "depthStencil": makeDepthStencilState(HEAPU32[(((descriptor) + (72)) >> 2)]), + "multisample": makeMultisampleState(descriptor + 76), + "fragment": makeFragmentState(HEAPU32[(((descriptor) + (92)) >> 2)]) + }; + return desc; + }, + fillLimitStruct: (limits, limitsOutPtr) => { + var nextInChainPtr = HEAPU32[((limitsOutPtr) >> 2)]; + function setLimitValueU32(name, basePtr, limitOffset, fallbackValue = 0) { + var limitValue = limits[name] ?? fallbackValue; + HEAPU32[(((basePtr) + (limitOffset)) >> 2)] = limitValue; + } + function setLimitValueU64(name, basePtr, limitOffset, fallbackValue = 0) { + var limitValue = limits[name] ?? fallbackValue; + // Limits are integer-valued JS `Number`s, so they fit in 'i53'. + writeI53ToI64((basePtr) + (limitOffset), limitValue); + } + setLimitValueU32("maxTextureDimension1D", limitsOutPtr, 4); + setLimitValueU32("maxTextureDimension2D", limitsOutPtr, 8); + setLimitValueU32("maxTextureDimension3D", limitsOutPtr, 12); + setLimitValueU32("maxTextureArrayLayers", limitsOutPtr, 16); + setLimitValueU32("maxBindGroups", limitsOutPtr, 20); + setLimitValueU32("maxBindGroupsPlusVertexBuffers", limitsOutPtr, 24); + setLimitValueU32("maxBindingsPerBindGroup", limitsOutPtr, 28); + setLimitValueU32("maxDynamicUniformBuffersPerPipelineLayout", limitsOutPtr, 32); + setLimitValueU32("maxDynamicStorageBuffersPerPipelineLayout", limitsOutPtr, 36); + setLimitValueU32("maxSampledTexturesPerShaderStage", limitsOutPtr, 40); + setLimitValueU32("maxSamplersPerShaderStage", limitsOutPtr, 44); + setLimitValueU32("maxStorageBuffersPerShaderStage", limitsOutPtr, 48); + setLimitValueU32("maxStorageTexturesPerShaderStage", limitsOutPtr, 52); + setLimitValueU32("maxUniformBuffersPerShaderStage", limitsOutPtr, 56); + setLimitValueU32("minUniformBufferOffsetAlignment", limitsOutPtr, 80); + setLimitValueU32("minStorageBufferOffsetAlignment", limitsOutPtr, 84); + setLimitValueU64("maxUniformBufferBindingSize", limitsOutPtr, 64); + setLimitValueU64("maxStorageBufferBindingSize", limitsOutPtr, 72); + setLimitValueU32("maxVertexBuffers", limitsOutPtr, 88); + setLimitValueU64("maxBufferSize", limitsOutPtr, 96); + setLimitValueU32("maxVertexAttributes", limitsOutPtr, 104); + setLimitValueU32("maxVertexBufferArrayStride", limitsOutPtr, 108); + setLimitValueU32("maxInterStageShaderVariables", limitsOutPtr, 112); + setLimitValueU32("maxColorAttachments", limitsOutPtr, 116); + setLimitValueU32("maxColorAttachmentBytesPerSample", limitsOutPtr, 120); + setLimitValueU32("maxComputeWorkgroupStorageSize", limitsOutPtr, 124); + setLimitValueU32("maxComputeInvocationsPerWorkgroup", limitsOutPtr, 128); + setLimitValueU32("maxComputeWorkgroupSizeX", limitsOutPtr, 132); + setLimitValueU32("maxComputeWorkgroupSizeY", limitsOutPtr, 136); + setLimitValueU32("maxComputeWorkgroupSizeZ", limitsOutPtr, 140); + setLimitValueU32("maxComputeWorkgroupsPerDimension", limitsOutPtr, 144); + // Note this limit is new and won't be present in all browsers for a while. Fall back to 0. + setLimitValueU32("maxImmediateSize", limitsOutPtr, 148); + if (nextInChainPtr !== 0) { + var sType = HEAP32[(((nextInChainPtr) + (4)) >> 2)]; + var compatibilityModeLimitsPtr = nextInChainPtr; + // Note these limits are new and won't be present in all browsers for a while. Fall back to exposing the PerShaderStage limit. + setLimitValueU32("maxStorageBuffersInVertexStage", compatibilityModeLimitsPtr, 8, limits.maxStorageBuffersPerShaderStage); + setLimitValueU32("maxStorageBuffersInFragmentStage", compatibilityModeLimitsPtr, 16, limits.maxStorageBuffersPerShaderStage); + setLimitValueU32("maxStorageTexturesInVertexStage", compatibilityModeLimitsPtr, 12, limits.maxStorageTexturesPerShaderStage); + setLimitValueU32("maxStorageTexturesInFragmentStage", compatibilityModeLimitsPtr, 20, limits.maxStorageTexturesPerShaderStage); + } + }, + fillAdapterInfoStruct: (info, infoStruct) => { + // Populate subgroup limits. + HEAPU32[(((infoStruct) + (52)) >> 2)] = info.subgroupMinSize; + HEAPU32[(((infoStruct) + (56)) >> 2)] = info.subgroupMaxSize; + // Append all the strings together to condense into a single malloc. + var strs = info.vendor + info.architecture + info.device + info.description; + var strPtr = stringToNewUTF8(strs); + var vendorLen = lengthBytesUTF8(info.vendor); + WebGPU.setStringView(infoStruct + 4, strPtr, vendorLen); + strPtr += vendorLen; + var architectureLen = lengthBytesUTF8(info.architecture); + WebGPU.setStringView(infoStruct + 12, strPtr, architectureLen); + strPtr += architectureLen; + var deviceLen = lengthBytesUTF8(info.device); + WebGPU.setStringView(infoStruct + 20, strPtr, deviceLen); + strPtr += deviceLen; + var descriptionLen = lengthBytesUTF8(info.description); + WebGPU.setStringView(infoStruct + 28, strPtr, descriptionLen); + strPtr += descriptionLen; + HEAP32[(((infoStruct) + (36)) >> 2)] = 2; + var adapterType = info.isFallbackAdapter ? 3 : 4; + HEAP32[(((infoStruct) + (40)) >> 2)] = adapterType; + HEAPU32[(((infoStruct) + (44)) >> 2)] = 0; + HEAPU32[(((infoStruct) + (48)) >> 2)] = 0; + }, + AddressMode: [ , "clamp-to-edge", "repeat", "mirror-repeat" ], + BlendFactor: [ , "zero", "one", "src", "one-minus-src", "src-alpha", "one-minus-src-alpha", "dst", "one-minus-dst", "dst-alpha", "one-minus-dst-alpha", "src-alpha-saturated", "constant", "one-minus-constant", "src1", "one-minus-src1", "src1-alpha", "one-minus-src1-alpha" ], + BlendOperation: [ , "add", "subtract", "reverse-subtract", "min", "max" ], + BufferBindingType: [ , , "uniform", "storage", "read-only-storage" ], + BufferMapState: [ , "unmapped", "pending", "mapped" ], + CompareFunction: [ , "never", "less", "equal", "less-equal", "greater", "not-equal", "greater-equal", "always" ], + CompilationInfoRequestStatus: [ , "success", "callback-cancelled" ], + ComponentSwizzle: [ , "0", "1", "r", "g", "b", "a" ], + CompositeAlphaMode: [ , "opaque", "premultiplied", "unpremultiplied", "inherit" ], + CullMode: [ , "none", "front", "back" ], + ErrorFilter: [ , "validation", "out-of-memory", "internal" ], + FeatureLevel: [ , "compatibility", "core" ], + FeatureName: { + 1: "core-features-and-limits", + 2: "depth-clip-control", + 3: "depth32float-stencil8", + 4: "texture-compression-bc", + 5: "texture-compression-bc-sliced-3d", + 6: "texture-compression-etc2", + 7: "texture-compression-astc", + 8: "texture-compression-astc-sliced-3d", + 9: "timestamp-query", + 10: "indirect-first-instance", + 11: "shader-f16", + 12: "rg11b10ufloat-renderable", + 13: "bgra8unorm-storage", + 14: "float32-filterable", + 15: "float32-blendable", + 16: "clip-distances", + 17: "dual-source-blending", + 18: "subgroups", + 19: "texture-formats-tier1", + 20: "texture-formats-tier2", + 21: "primitive-index", + 22: "texture-component-swizzle", + 23: "subgroup-size-control", + 327692: "chromium-experimental-unorm16-texture-formats", + 327729: "chromium-experimental-multi-draw-indirect" + }, + FilterMode: [ , "nearest", "linear" ], + FrontFace: [ , "ccw", "cw" ], + IndexFormat: [ , "uint16", "uint32" ], + InstanceFeatureName: [ , "timed-wait-any", "shader-source-spirv", "multiple-devices-per-adapter" ], + LoadOp: [ , "load", "clear" ], + MipmapFilterMode: [ , "nearest", "linear" ], + OptionalBool: [ "false", "true" ], + PowerPreference: [ , "low-power", "high-performance" ], + PredefinedColorSpace: [ , "srgb", "display-p3" ], + PrimitiveTopology: [ , "point-list", "line-list", "line-strip", "triangle-list", "triangle-strip" ], + QueryType: [ , "occlusion", "timestamp" ], + SamplerBindingType: [ , , "filtering", "non-filtering", "comparison" ], + Status: [ , "success", "error" ], + StencilOperation: [ , "keep", "zero", "replace", "invert", "increment-clamp", "decrement-clamp", "increment-wrap", "decrement-wrap" ], + StorageTextureAccess: [ , , "write-only", "read-only", "read-write" ], + StoreOp: [ , "store", "discard" ], + SurfaceGetCurrentTextureStatus: [ , "success-optimal", "success-suboptimal", "timeout", "outdated", "lost", "error" ], + TextureAspect: [ , "all", "stencil-only", "depth-only" ], + TextureDimension: [ , "1d", "2d", "3d" ], + TextureFormat: [ , "r8unorm", "r8snorm", "r8uint", "r8sint", "r16unorm", "r16snorm", "r16uint", "r16sint", "r16float", "rg8unorm", "rg8snorm", "rg8uint", "rg8sint", "r32float", "r32uint", "r32sint", "rg16unorm", "rg16snorm", "rg16uint", "rg16sint", "rg16float", "rgba8unorm", "rgba8unorm-srgb", "rgba8snorm", "rgba8uint", "rgba8sint", "bgra8unorm", "bgra8unorm-srgb", "rgb10a2uint", "rgb10a2unorm", "rg11b10ufloat", "rgb9e5ufloat", "rg32float", "rg32uint", "rg32sint", "rgba16unorm", "rgba16snorm", "rgba16uint", "rgba16sint", "rgba16float", "rgba32float", "rgba32uint", "rgba32sint", "stencil8", "depth16unorm", "depth24plus", "depth24plus-stencil8", "depth32float", "depth32float-stencil8", "bc1-rgba-unorm", "bc1-rgba-unorm-srgb", "bc2-rgba-unorm", "bc2-rgba-unorm-srgb", "bc3-rgba-unorm", "bc3-rgba-unorm-srgb", "bc4-r-unorm", "bc4-r-snorm", "bc5-rg-unorm", "bc5-rg-snorm", "bc6h-rgb-ufloat", "bc6h-rgb-float", "bc7-rgba-unorm", "bc7-rgba-unorm-srgb", "etc2-rgb8unorm", "etc2-rgb8unorm-srgb", "etc2-rgb8a1unorm", "etc2-rgb8a1unorm-srgb", "etc2-rgba8unorm", "etc2-rgba8unorm-srgb", "eac-r11unorm", "eac-r11snorm", "eac-rg11unorm", "eac-rg11snorm", "astc-4x4-unorm", "astc-4x4-unorm-srgb", "astc-5x4-unorm", "astc-5x4-unorm-srgb", "astc-5x5-unorm", "astc-5x5-unorm-srgb", "astc-6x5-unorm", "astc-6x5-unorm-srgb", "astc-6x6-unorm", "astc-6x6-unorm-srgb", "astc-8x5-unorm", "astc-8x5-unorm-srgb", "astc-8x6-unorm", "astc-8x6-unorm-srgb", "astc-8x8-unorm", "astc-8x8-unorm-srgb", "astc-10x5-unorm", "astc-10x5-unorm-srgb", "astc-10x6-unorm", "astc-10x6-unorm-srgb", "astc-10x8-unorm", "astc-10x8-unorm-srgb", "astc-10x10-unorm", "astc-10x10-unorm-srgb", "astc-12x10-unorm", "astc-12x10-unorm-srgb", "astc-12x12-unorm", "astc-12x12-unorm-srgb" ], + TextureSampleType: [ , , "float", "unfilterable-float", "depth", "sint", "uint" ], + TextureViewDimension: [ , "1d", "2d", "2d-array", "cube", "cube-array", "3d" ], + ToneMappingMode: [ , "standard", "extended" ], + VertexFormat: [ , "uint8", "uint8x2", "uint8x4", "sint8", "sint8x2", "sint8x4", "unorm8", "unorm8x2", "unorm8x4", "snorm8", "snorm8x2", "snorm8x4", "uint16", "uint16x2", "uint16x4", "sint16", "sint16x2", "sint16x4", "unorm16", "unorm16x2", "unorm16x4", "snorm16", "snorm16x2", "snorm16x4", "float16", "float16x2", "float16x4", "float32", "float32x2", "float32x3", "float32x4", "uint32", "uint32x2", "uint32x3", "uint32x4", "sint32", "sint32x2", "sint32x3", "sint32x4", "unorm10-10-10-2", "unorm8x4-bgra", "snorm10-10-10-2" ], + VertexStepMode: [ , "vertex", "instance" ], + WGSLLanguageFeatureName: [ , "readonly_and_readwrite_storage_textures", "packed_4x8_integer_dot_product", "unrestricted_pointer_parameters", "pointer_composite_access", "uniform_buffer_standard_layout", "subgroup_id", "texture_and_sampler_let", "subgroup_uniformity", "texture_formats_tier1", "linear_indexing", "immediate_address_space", "buffer_view" ] +}; + +var _emscripten_webgpu_get_device = () => { + if (WebGPU.preinitializedDeviceId === undefined) { + WebGPU.preinitializedDeviceId = WebGPU.importJsDevice(Module["preinitializedWebGPUDevice"]); + // Some users depend on this keeping the device alive, so we add an + // additional reference when we first initialize it. + _wgpuDeviceAddRef(WebGPU.preinitializedDeviceId); + } + _wgpuDeviceAddRef(WebGPU.preinitializedDeviceId); + return WebGPU.preinitializedDeviceId; +}; + +var _emwgpuBufferDestroy = bufferPtr => { + var buffer = WebGPU.getJsObject(bufferPtr); + var onUnmap = WebGPU.Internals.bufferOnUnmaps[bufferPtr]; + if (onUnmap) { + for (var i = 0; i < onUnmap.length; ++i) { + onUnmap[i](); + } + delete WebGPU.Internals.bufferOnUnmaps[bufferPtr]; + } + buffer.destroy(); +}; + +var _emwgpuBufferGetMappedRange = (bufferPtr, offset, size) => { + var buffer = WebGPU.getJsObject(bufferPtr); + if (size == -1) size = undefined; + var mapped; + try { + mapped = buffer.getMappedRange(offset, size); + } catch (ex) { + return 0; + } + var data = _memalign(16, mapped.byteLength); + HEAPU8.fill(0, data, mapped.byteLength); + WebGPU.Internals.bufferOnUnmaps[bufferPtr].push(() => { + new Uint8Array(mapped).set(HEAPU8.subarray(data, data + mapped.byteLength)); + _free(data); + }); + return data; +}; + +var _emwgpuBufferUnmap = bufferPtr => { + var buffer = WebGPU.getJsObject(bufferPtr); + var onUnmap = WebGPU.Internals.bufferOnUnmaps[bufferPtr]; + if (!onUnmap) { + // Already unmapped + return; + } + for (var i = 0; i < onUnmap.length; ++i) { + onUnmap[i](); + } + delete WebGPU.Internals.bufferOnUnmaps[bufferPtr]; + buffer.unmap(); +}; + +var _emwgpuDelete = ptr => { + delete WebGPU.Internals.jsObjects[ptr]; +}; + +var _emwgpuDeviceCreateBuffer = (devicePtr, descriptor, bufferPtr) => { + var mappedAtCreation = !!(HEAPU32[(((descriptor) + (32)) >> 2)]); + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "usage": HEAPU32[(((descriptor) + (16)) >> 2)], + "size": readI53FromI64((descriptor) + (24)), + "mappedAtCreation": mappedAtCreation + }; + var device = WebGPU.getJsObject(devicePtr); + var buffer; + try { + buffer = device.createBuffer(desc); + } catch (ex) { + // The only exception should be RangeError if mapping at creation ran out of memory. + return false; + } + WebGPU.Internals.jsObjectInsert(bufferPtr, buffer); + if (mappedAtCreation) { + WebGPU.Internals.bufferOnUnmaps[bufferPtr] = []; + } + return true; +}; + +var _emwgpuDeviceCreateComputePipelineAsync = function(devicePtr, futureId_low, futureId_high, descriptor, pipelinePtr) { + var futureId = convertI32PairToI53Checked(futureId_low, futureId_high); + var desc = WebGPU.makeComputePipelineDesc(descriptor); + var device = WebGPU.getJsObject(devicePtr); + // createComputePipelineAsync + WebGPU.Internals.futureInsert(futureId, device.createComputePipelineAsync(desc).then(pipeline => { + // createComputePipelineAsync fulfilled + callUserCallback(() => { + WebGPU.Internals.jsObjectInsert(pipelinePtr, pipeline); + _emwgpuOnCreateComputePipelineCompleted(futureId, 1, pipelinePtr, 0); + }); + }, pipelineError => { + // createComputePipelineAsync rejected + callUserCallback(() => { + var sp = stackSave(); + var messagePtr = stringToUTF8OnStack(pipelineError.message); + var status = pipelineError.reason === "validation" ? 3 : pipelineError.reason === "internal" ? 4 : 0; + _emwgpuOnCreateComputePipelineCompleted(futureId, status, pipelinePtr, messagePtr); + stackRestore(sp); + }); + })); +}; + +var _emwgpuDeviceCreateRenderPipelineAsync = function(devicePtr, futureId_low, futureId_high, descriptor, pipelinePtr) { + var futureId = convertI32PairToI53Checked(futureId_low, futureId_high); + var desc = WebGPU.makeRenderPipelineDesc(descriptor); + var device = WebGPU.getJsObject(devicePtr); + // createRenderPipelineAsync + WebGPU.Internals.futureInsert(futureId, device.createRenderPipelineAsync(desc).then(pipeline => { + // createRenderPipelineAsync fulfilled + callUserCallback(() => { + WebGPU.Internals.jsObjectInsert(pipelinePtr, pipeline); + _emwgpuOnCreateRenderPipelineCompleted(futureId, 1, pipelinePtr, 0); + }); + }, pipelineError => { + // createRenderPipelineAsync rejected + callUserCallback(() => { + var sp = stackSave(); + var messagePtr = stringToUTF8OnStack(pipelineError.message); + var status = pipelineError.reason === "validation" ? 3 : pipelineError.reason === "internal" ? 4 : 0; + _emwgpuOnCreateRenderPipelineCompleted(futureId, status, pipelinePtr, messagePtr); + stackRestore(sp); + }); + })); +}; + +var _emwgpuDeviceCreateShaderModule = (devicePtr, descriptor, shaderModulePtr) => { + var nextInChainPtr = HEAPU32[((descriptor) >> 2)]; + var sType = HEAP32[(((nextInChainPtr) + (4)) >> 2)]; + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "code": "" + }; + switch (sType) { + case 2: + { + desc["code"] = WebGPU.makeStringFromStringView(nextInChainPtr + 8); + break; + } + } + var device = WebGPU.getJsObject(devicePtr); + WebGPU.Internals.jsObjectInsert(shaderModulePtr, device.createShaderModule(desc)); +}; + +var _emwgpuDeviceDestroy = devicePtr => { + const device = WebGPU.getJsObject(devicePtr); + // Remove the onuncapturederror handler which holds a pointer to the WGPUDevice. + device.onuncapturederror = null; + device.destroy(); +}; + +var _emwgpuWaitAny = (futurePtr, futureCount, timeoutMSPtr) => { + abort("TODO: Implement asyncify-free WaitAny for timeout=0"); +}; + +var ENV = {}; + +var getExecutableName = () => thisProgram; + +var getEnvStrings = () => { + if (!getEnvStrings.strings) { + // Default values. + var lang = (globalThis.navigator?.language ?? "C").replace("-", "_") + ".UTF-8"; + var env = { + "USER": "web_user", + "LOGNAME": "web_user", + "PATH": "/", + "PWD": "/", + "HOME": "/home/web_user", + "LANG": lang, + "_": getExecutableName() + }; + // Apply the user-provided values, if any. + for (var x in ENV) { + // x is a key in ENV; if ENV[x] is undefined, that means it was + // explicitly set to be so. We allow user code to do that to + // force variables with default values to remain unset. + if (ENV[x] === undefined) delete env[x]; else env[x] = ENV[x]; + } + var strings = []; + for (var x in env) { + strings.push(`${x}=${env[x]}`); + } + getEnvStrings.strings = strings; + } + return getEnvStrings.strings; +}; + +var _environ_get = (__environ, environ_buf) => { + var bufSize = 0; + var envp = 0; + for (var string of getEnvStrings()) { + var ptr = environ_buf + bufSize; + HEAPU32[(((__environ) + (envp)) >> 2)] = ptr; + bufSize += stringToUTF8(string, ptr, Infinity) + 1; + envp += 4; + } + return 0; +}; + +var _environ_sizes_get = (penviron_count, penviron_buf_size) => { + var strings = getEnvStrings(); + HEAPU32[((penviron_count) >> 2)] = strings.length; + var bufSize = 0; + for (var string of strings) { + bufSize += lengthBytesUTF8(string) + 1; + } + HEAPU32[((penviron_buf_size) >> 2)] = bufSize; + return 0; +}; + +function _fd_close(fd) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + FS.close(stream); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +/** @param {number=} offset */ var doReadv = (stream, iov, iovcnt, offset) => { + var ret = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = HEAPU32[((iov) >> 2)]; + var len = HEAPU32[(((iov) + (4)) >> 2)]; + iov += 8; + var curr = FS.read(stream, HEAP8, ptr, len, offset); + if (curr < 0) return -1; + ret += curr; + if (curr < len) break; + // nothing more to read + if (typeof offset != "undefined") { + offset += curr; + } + } + return ret; +}; + +function _fd_read(fd, iov, iovcnt, pnum) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var num = doReadv(stream, iov, iovcnt); + HEAPU32[((pnum) >> 2)] = num; + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +function _fd_seek(fd, offset_low, offset_high, whence, newOffset) { + var offset = convertI32PairToI53Checked(offset_low, offset_high); + try { + if (isNaN(offset)) return 22; + var stream = SYSCALLS.getStreamFromFD(fd); + FS.llseek(stream, offset, whence); + (tempI64 = [ stream.position >>> 0, (tempDouble = stream.position, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[((newOffset) >> 2)] = tempI64[0], HEAP32[(((newOffset) + (4)) >> 2)] = tempI64[1]); + if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; + // reset readdir state + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +/** @param {number=} offset */ var doWritev = (stream, iov, iovcnt, offset) => { + var ret = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = HEAPU32[((iov) >> 2)]; + var len = HEAPU32[(((iov) + (4)) >> 2)]; + iov += 8; + var curr = FS.write(stream, HEAP8, ptr, len, offset); + if (curr < 0) return -1; + ret += curr; + if (curr < len) { + // No more space to write. + break; + } + if (typeof offset != "undefined") { + offset += curr; + } + } + return ret; +}; + +function _fd_write(fd, iov, iovcnt, pnum) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var num = doWritev(stream, iov, iovcnt); + HEAPU32[((pnum) >> 2)] = num; + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +var _emscripten_glActiveTexture = x0 => GLctx.activeTexture(x0); + +var _glActiveTexture = _emscripten_glActiveTexture; + +var _emscripten_glAttachShader = (program, shader) => { + GLctx.attachShader(GL.programs[program], GL.shaders[shader]); +}; + +var _glAttachShader = _emscripten_glAttachShader; + +var _emscripten_glBindAttribLocation = (program, index, name) => { + GLctx.bindAttribLocation(GL.programs[program], index, UTF8ToString(name)); +}; + +var _glBindAttribLocation = _emscripten_glBindAttribLocation; + +var _emscripten_glBindBuffer = (target, buffer) => { + // Calling glBindBuffer with an unknown buffer will implicitly create a + // new one. Here we bypass `GL.counter` and directly using the ID passed + // in. + if (buffer && !GL.buffers[buffer]) { + var b = GLctx.createBuffer(); + b.name = buffer; + GL.buffers[buffer] = b; + } + if (target == 34962) { + GLctx.currentArrayBufferBinding = buffer; + } else if (target == 34963) { + GLctx.currentElementArrayBufferBinding = buffer; + } + if (target == 35051) { + // In WebGL 2 glReadPixels entry point, we need to use a different WebGL 2 + // API function call when a buffer is bound to + // GL_PIXEL_PACK_BUFFER_BINDING point, so must keep track whether that + // binding point is non-null to know what is the proper API function to + // call. + GLctx.currentPixelPackBufferBinding = buffer; + } else if (target == 35052) { + // In WebGL 2 gl(Compressed)Tex(Sub)Image[23]D entry points, we need to + // use a different WebGL 2 API function call when a buffer is bound to + // GL_PIXEL_UNPACK_BUFFER_BINDING point, so must keep track whether that + // binding point is non-null to know what is the proper API function to + // call. + GLctx.currentPixelUnpackBufferBinding = buffer; + } + GLctx.bindBuffer(target, GL.buffers[buffer]); +}; + +var _glBindBuffer = _emscripten_glBindBuffer; + +var _emscripten_glBindBufferBase = (target, index, buffer) => { + GLctx.bindBufferBase(target, index, GL.buffers[buffer]); +}; + +var _glBindBufferBase = _emscripten_glBindBufferBase; + +var _emscripten_glBindFramebuffer = (target, framebuffer) => { + GLctx.bindFramebuffer(target, GL.framebuffers[framebuffer]); +}; + +var _glBindFramebuffer = _emscripten_glBindFramebuffer; + +var _emscripten_glBindTexture = (target, texture) => { + GLctx.bindTexture(target, GL.textures[texture]); +}; + +var _glBindTexture = _emscripten_glBindTexture; + +var _emscripten_glBindVertexArray = vao => { + GLctx.bindVertexArray(GL.vaos[vao]); + var ibo = GLctx.getParameter(34965); + GLctx.currentElementArrayBufferBinding = ibo ? (ibo.name | 0) : 0; +}; + +var _glBindVertexArray = _emscripten_glBindVertexArray; + +var _emscripten_glBlendEquation = x0 => GLctx.blendEquation(x0); + +var _glBlendEquation = _emscripten_glBlendEquation; + +var _emscripten_glBlendFunc = (x0, x1) => GLctx.blendFunc(x0, x1); + +var _glBlendFunc = _emscripten_glBlendFunc; + +var _emscripten_glBufferData = (target, size, data, usage) => { + if (GL.currentContext.version >= 2) { + // If size is zero, WebGL would interpret uploading the whole input + // arraybuffer (starting from given offset), which would not make sense in + // WebAssembly, so avoid uploading if size is zero. However we must still + // call bufferData to establish a backing storage of zero bytes. + if (data && size) { + GLctx.bufferData(target, HEAPU8, usage, data, size); + } else { + GLctx.bufferData(target, size, usage); + } + return; + } + // N.b. here first form specifies a heap subarray, second form an integer + // size, so the ?: code here is polymorphic. It is advised to avoid + // randomly mixing both uses in calling code, to avoid any potential JS + // engine JIT issues. + GLctx.bufferData(target, data ? HEAPU8.subarray(data, data + size) : size, usage); +}; + +var _glBufferData = _emscripten_glBufferData; + +var _emscripten_glClear = x0 => GLctx.clear(x0); + +var _glClear = _emscripten_glClear; + +var _emscripten_glClearColor = (x0, x1, x2, x3) => GLctx.clearColor(x0, x1, x2, x3); + +var _glClearColor = _emscripten_glClearColor; + +var convertI32PairToI53 = (lo, hi) => (lo >>> 0) + hi * 4294967296; + +var _emscripten_glClientWaitSync = (sync, flags, timeout_low, timeout_high) => { + // WebGL2 vs GLES3 differences: in GLES3, the timeout parameter is a uint64, where 0xFFFFFFFFFFFFFFFFULL means GL_TIMEOUT_IGNORED. + // In JS, there's no 64-bit value types, so instead timeout is taken to be signed, and GL_TIMEOUT_IGNORED is given value -1. + // Inherently the value accepted in the timeout is lossy, and can't take in arbitrary u64 bit pattern (but most likely doesn't matter) + // See https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.15 + var timeout = convertI32PairToI53(timeout_low, timeout_high); + return GLctx.clientWaitSync(GL.syncs[sync], flags, timeout); +}; + +var _glClientWaitSync = _emscripten_glClientWaitSync; + +var _emscripten_glColorMask = (red, green, blue, alpha) => { + GLctx.colorMask(!!red, !!green, !!blue, !!alpha); +}; + +var _glColorMask = _emscripten_glColorMask; + +var _emscripten_glCompileShader = shader => { + GLctx.compileShader(GL.shaders[shader]); +}; + +var _glCompileShader = _emscripten_glCompileShader; + +var _emscripten_glCreateProgram = () => { + var id = GL.getNewId(GL.programs); + var program = GLctx.createProgram(); + // Store additional information needed for each shader program: + program.name = id; + // Lazy cache results of + // glGetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH/GL_ACTIVE_ATTRIBUTE_MAX_LENGTH/GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH) + program.maxUniformLength = program.maxAttributeLength = program.maxUniformBlockNameLength = 0; + program.uniformIdCounter = 1; + GL.programs[id] = program; + return id; +}; + +var _glCreateProgram = _emscripten_glCreateProgram; + +var _emscripten_glCreateShader = shaderType => { + var id = GL.getNewId(GL.shaders); + GL.shaders[id] = GLctx.createShader(shaderType); + return id; +}; + +var _glCreateShader = _emscripten_glCreateShader; + +var _emscripten_glDeleteBuffers = (n, buffers) => { + for (var i = 0; i < n; i++) { + var id = HEAP32[(((buffers) + (i * 4)) >> 2)]; + var buffer = GL.buffers[id]; + // From spec: "glDeleteBuffers silently ignores 0's and names that do not + // correspond to existing buffer objects." + if (!buffer) continue; + GLctx.deleteBuffer(buffer); + buffer.name = 0; + GL.buffers[id] = null; + if (id == GLctx.currentArrayBufferBinding) GLctx.currentArrayBufferBinding = 0; + if (id == GLctx.currentElementArrayBufferBinding) GLctx.currentElementArrayBufferBinding = 0; + if (id == GLctx.currentPixelPackBufferBinding) GLctx.currentPixelPackBufferBinding = 0; + if (id == GLctx.currentPixelUnpackBufferBinding) GLctx.currentPixelUnpackBufferBinding = 0; + } +}; + +var _glDeleteBuffers = _emscripten_glDeleteBuffers; + +var _emscripten_glDeleteFramebuffers = (n, framebuffers) => { + for (var i = 0; i < n; ++i) { + var id = HEAP32[(((framebuffers) + (i * 4)) >> 2)]; + var framebuffer = GL.framebuffers[id]; + if (!framebuffer) continue; + // GL spec: "glDeleteFramebuffers silently ignores 0s and names that do not correspond to existing framebuffer objects". + GLctx.deleteFramebuffer(framebuffer); + framebuffer.name = 0; + GL.framebuffers[id] = null; + } +}; + +var _glDeleteFramebuffers = _emscripten_glDeleteFramebuffers; + +var _emscripten_glDeleteProgram = id => { + if (!id) return; + var program = GL.programs[id]; + if (!program) { + // glDeleteProgram actually signals an error when deleting a nonexisting + // object, unlike some other GL delete functions. + GL.recordError(1281); + return; + } + GLctx.deleteProgram(program); + program.name = 0; + GL.programs[id] = null; +}; + +var _glDeleteProgram = _emscripten_glDeleteProgram; + +var _emscripten_glDeleteShader = id => { + if (!id) return; + var shader = GL.shaders[id]; + if (!shader) { + // glDeleteShader actually signals an error when deleting a nonexisting + // object, unlike some other GL delete functions. + GL.recordError(1281); + return; + } + GLctx.deleteShader(shader); + GL.shaders[id] = null; +}; + +var _glDeleteShader = _emscripten_glDeleteShader; + +var _emscripten_glDeleteSync = id => { + if (!id) return; + var sync = GL.syncs[id]; + if (!sync) { + // glDeleteSync signals an error when deleting a nonexisting object, unlike some other GL delete functions. + GL.recordError(1281); + return; + } + GLctx.deleteSync(sync); + sync.name = 0; + GL.syncs[id] = null; +}; + +var _glDeleteSync = _emscripten_glDeleteSync; + +var _emscripten_glDeleteTextures = (n, textures) => { + for (var i = 0; i < n; i++) { + var id = HEAP32[(((textures) + (i * 4)) >> 2)]; + var texture = GL.textures[id]; + // GL spec: "glDeleteTextures silently ignores 0s and names that do not + // correspond to existing textures". + if (!texture) continue; + GLctx.deleteTexture(texture); + texture.name = 0; + GL.textures[id] = null; + } +}; + +var _glDeleteTextures = _emscripten_glDeleteTextures; + +var _emscripten_glDeleteVertexArrays = (n, vaos) => { + for (var i = 0; i < n; i++) { + var id = HEAP32[(((vaos) + (i * 4)) >> 2)]; + GLctx.deleteVertexArray(GL.vaos[id]); + GL.vaos[id] = null; + } +}; + +var _glDeleteVertexArrays = _emscripten_glDeleteVertexArrays; + +var _emscripten_glDetachShader = (program, shader) => { + GLctx.detachShader(GL.programs[program], GL.shaders[shader]); +}; + +var _glDetachShader = _emscripten_glDetachShader; + +var _emscripten_glDisable = x0 => GLctx.disable(x0); + +var _glDisable = _emscripten_glDisable; + +var _emscripten_glDisableVertexAttribArray = index => { + var cb = GL.currentContext.clientBuffers[index]; + cb.enabled = false; + GLctx.disableVertexAttribArray(index); +}; + +var _glDisableVertexAttribArray = _emscripten_glDisableVertexAttribArray; + +var _emscripten_glDrawArrays = (mode, first, count) => { + // bind any client-side buffers + GL.preDrawHandleClientVertexAttribBindings(first + count); + GLctx.drawArrays(mode, first, count); + GL.postDrawHandleClientVertexAttribBindings(); +}; + +var _glDrawArrays = _emscripten_glDrawArrays; + +var tempFixedLengthArray = []; + +var _emscripten_glDrawBuffers = (n, bufs) => { + var bufArray = tempFixedLengthArray[n]; + for (var i = 0; i < n; i++) { + bufArray[i] = HEAP32[(((bufs) + (i * 4)) >> 2)]; + } + GLctx.drawBuffers(bufArray); +}; + +var _glDrawBuffers = _emscripten_glDrawBuffers; + +var _emscripten_glEnable = x0 => GLctx.enable(x0); + +var _glEnable = _emscripten_glEnable; + +var _emscripten_glEnableVertexAttribArray = index => { + var cb = GL.currentContext.clientBuffers[index]; + cb.enabled = true; + GLctx.enableVertexAttribArray(index); +}; + +var _glEnableVertexAttribArray = _emscripten_glEnableVertexAttribArray; + +var _emscripten_glFenceSync = (condition, flags) => { + var sync = GLctx.fenceSync(condition, flags); + if (sync) { + var id = GL.getNewId(GL.syncs); + sync.name = id; + GL.syncs[id] = sync; + return id; + } + return 0; +}; + +var _glFenceSync = _emscripten_glFenceSync; + +var _emscripten_glFinish = () => GLctx.finish(); + +var _glFinish = _emscripten_glFinish; + +var _emscripten_glFlush = () => GLctx.flush(); + +var _glFlush = _emscripten_glFlush; + +var _emscripten_glFramebufferTexture2D = (target, attachment, textarget, texture, level) => { + GLctx.framebufferTexture2D(target, attachment, textarget, GL.textures[texture], level); +}; + +var _glFramebufferTexture2D = _emscripten_glFramebufferTexture2D; + +var _emscripten_glFramebufferTextureLayer = (target, attachment, texture, level, layer) => { + GLctx.framebufferTextureLayer(target, attachment, GL.textures[texture], level, layer); +}; + +var _glFramebufferTextureLayer = _emscripten_glFramebufferTextureLayer; + +var _emscripten_glGenBuffers = (n, buffers) => { + GL.genObject(n, buffers, "createBuffer", GL.buffers); +}; + +var _glGenBuffers = _emscripten_glGenBuffers; + +var _emscripten_glGenFramebuffers = (n, ids) => { + GL.genObject(n, ids, "createFramebuffer", GL.framebuffers); +}; + +var _glGenFramebuffers = _emscripten_glGenFramebuffers; + +var _emscripten_glGenTextures = (n, textures) => { + GL.genObject(n, textures, "createTexture", GL.textures); +}; + +var _glGenTextures = _emscripten_glGenTextures; + +var _emscripten_glGenVertexArrays = (n, arrays) => { + GL.genObject(n, arrays, "createVertexArray", GL.vaos); +}; + +var _glGenVertexArrays = _emscripten_glGenVertexArrays; + +var _emscripten_glGetAttribLocation = (program, name) => GLctx.getAttribLocation(GL.programs[program], UTF8ToString(name)); + +var _glGetAttribLocation = _emscripten_glGetAttribLocation; + +var _emscripten_glGetError = () => { + var error = GLctx.getError() || GL.lastError; + GL.lastError = 0; + return error; +}; + +var _glGetError = _emscripten_glGetError; + +var webglGetExtensions = () => { + var exts = getEmscriptenSupportedExtensions(GLctx); + exts = exts.concat(exts.map(e => "GL_" + e)); + return exts; +}; + +var emscriptenWebGLGet = (name_, p, type) => { + // Guard against user passing a null pointer. + // Note that GLES2 spec does not say anything about how passing a null + // pointer should be treated. Testing on desktop core GL 3, the application + // crashes on glGetIntegerv to a null pointer, but better to report an error + // instead of doing anything random. + if (!p) { + GL.recordError(1281); + return; + } + var ret = undefined; + switch (name_) { + // Handle a few trivial GLES values + case 36346: + // GL_SHADER_COMPILER + ret = 1; + break; + + case 36344: + // GL_SHADER_BINARY_FORMATS + if (type != 0 && type != 1) { + GL.recordError(1280); + } + // Do not write anything to the out pointer, since no binary formats are + // supported. + return; + + case 34814: + // GL_NUM_PROGRAM_BINARY_FORMATS + case 36345: + // GL_NUM_SHADER_BINARY_FORMATS + ret = 0; + break; + + case 34466: + // GL_NUM_COMPRESSED_TEXTURE_FORMATS + // WebGL doesn't have GL_NUM_COMPRESSED_TEXTURE_FORMATS (it's obsolete + // since GL_COMPRESSED_TEXTURE_FORMATS returns a JS array that can be + // queried for length), so implement it ourselves to allow C++ GLES2 + // code to get the length. + var formats = GLctx.getParameter(34467); + ret = formats ? formats.length : 0; + break; + + case 33309: + // GL_NUM_EXTENSIONS + if (GL.currentContext.version < 2) { + // Calling GLES3/WebGL2 function with a GLES2/WebGL1 context + GL.recordError(1282); + return; + } + ret = webglGetExtensions().length; + break; + + case 33307: + // GL_MAJOR_VERSION + case 33308: + // GL_MINOR_VERSION + if (GL.currentContext.version < 2) { + GL.recordError(1280); + // GL_INVALID_ENUM + return; + } + ret = name_ == 33307 ? 3 : 0; + // return version 3.0 + break; + } + if (ret === undefined) { + var result = GLctx.getParameter(name_); + switch (typeof result) { + case "number": + ret = result; + break; + + case "boolean": + ret = result ? 1 : 0; + break; + + case "string": + GL.recordError(1280); + // GL_INVALID_ENUM + return; + + case "object": + if (result === null) { + // null is a valid result for some (e.g., which buffer is bound - + // perhaps nothing is bound), but otherwise can mean an invalid + // name_, which we need to report as an error + switch (name_) { + case 34964: + // ARRAY_BUFFER_BINDING + case 35725: + // CURRENT_PROGRAM + case 34965: + // ELEMENT_ARRAY_BUFFER_BINDING + case 36006: + // FRAMEBUFFER_BINDING or DRAW_FRAMEBUFFER_BINDING + case 36007: + // RENDERBUFFER_BINDING + case 32873: + // TEXTURE_BINDING_2D + case 34229: + // WebGL 2 GL_VERTEX_ARRAY_BINDING, or WebGL 1 extension OES_vertex_array_object GL_VERTEX_ARRAY_BINDING_OES + case 36662: + // COPY_READ_BUFFER_BINDING or COPY_READ_BUFFER + case 36663: + // COPY_WRITE_BUFFER_BINDING or COPY_WRITE_BUFFER + case 35053: + // PIXEL_PACK_BUFFER_BINDING + case 35055: + // PIXEL_UNPACK_BUFFER_BINDING + case 36010: + // READ_FRAMEBUFFER_BINDING + case 35097: + // SAMPLER_BINDING + case 35869: + // TEXTURE_BINDING_2D_ARRAY + case 32874: + // TEXTURE_BINDING_3D + case 36389: + // TRANSFORM_FEEDBACK_BINDING + case 35983: + // TRANSFORM_FEEDBACK_BUFFER_BINDING + case 35368: + // UNIFORM_BUFFER_BINDING + case 34068: + { + // TEXTURE_BINDING_CUBE_MAP + ret = 0; + break; + } + + default: + { + GL.recordError(1280); + // GL_INVALID_ENUM + return; + } + } + } else if (result instanceof Float32Array || result instanceof Uint32Array || result instanceof Int32Array || result instanceof Array) { + for (var i = 0; i < result.length; ++i) { + switch (type) { + case 0: + HEAP32[(((p) + (i * 4)) >> 2)] = result[i]; + break; + + case 2: + HEAPF32[(((p) + (i * 4)) >> 2)] = result[i]; + break; + + case 4: + HEAP8[(p) + (i)] = result[i] ? 1 : 0; + break; + } + } + return; + } else { + try { + ret = result.name | 0; + } catch (e) { + GL.recordError(1280); + // GL_INVALID_ENUM + err(`GL_INVALID_ENUM in glGet${type}v: Unknown object returned from WebGL getParameter(${name_})! (error: ${e})`); + return; + } + } + break; + + default: + GL.recordError(1280); + // GL_INVALID_ENUM + err(`GL_INVALID_ENUM in glGet${type}v: Native code calling glGet${type}v(${name_}) and it returns ${result} of type ${typeof (result)}!`); + return; + } + } + switch (type) { + case 1: + writeI53ToI64(p, ret); + break; + + case 0: + HEAP32[((p) >> 2)] = ret; + break; + + case 2: + HEAPF32[((p) >> 2)] = ret; + break; + + case 4: + HEAP8[p] = ret ? 1 : 0; + break; + } +}; + +var _emscripten_glGetFloatv = (name_, p) => emscriptenWebGLGet(name_, p, 2); + +var _glGetFloatv = _emscripten_glGetFloatv; + +var _emscripten_glGetIntegerv = (name_, p) => emscriptenWebGLGet(name_, p, 0); + +var _glGetIntegerv = _emscripten_glGetIntegerv; + +var _emscripten_glGetProgramiv = (program, pname, p) => { + if (!p) { + // GLES2 specification does not specify how to behave if p is a null + // pointer. Since calling this function does not make sense if p == null, + // issue a GL error to notify user about it. + GL.recordError(1281); + return; + } + if (program >= GL.counter) { + GL.recordError(1281); + return; + } + program = GL.programs[program]; + if (pname == 35716) { + // GL_INFO_LOG_LENGTH + var log = GLctx.getProgramInfoLog(program); + if (log === null) log = "(unknown error)"; + HEAP32[((p) >> 2)] = log.length + 1; + } else if (pname == 35719) { + if (!program.maxUniformLength) { + var numActiveUniforms = GLctx.getProgramParameter(program, 35718); + for (var i = 0; i < numActiveUniforms; ++i) { + program.maxUniformLength = Math.max(program.maxUniformLength, GLctx.getActiveUniform(program, i).name.length + 1); + } + } + HEAP32[((p) >> 2)] = program.maxUniformLength; + } else if (pname == 35722) { + if (!program.maxAttributeLength) { + var numActiveAttributes = GLctx.getProgramParameter(program, 35721); + for (var i = 0; i < numActiveAttributes; ++i) { + program.maxAttributeLength = Math.max(program.maxAttributeLength, GLctx.getActiveAttrib(program, i).name.length + 1); + } + } + HEAP32[((p) >> 2)] = program.maxAttributeLength; + } else if (pname == 35381) { + if (!program.maxUniformBlockNameLength) { + var numActiveUniformBlocks = GLctx.getProgramParameter(program, 35382); + for (var i = 0; i < numActiveUniformBlocks; ++i) { + program.maxUniformBlockNameLength = Math.max(program.maxUniformBlockNameLength, GLctx.getActiveUniformBlockName(program, i).length + 1); + } + } + HEAP32[((p) >> 2)] = program.maxUniformBlockNameLength; + } else { + HEAP32[((p) >> 2)] = GLctx.getProgramParameter(program, pname); + } +}; + +var _glGetProgramiv = _emscripten_glGetProgramiv; + +var _emscripten_glGetShaderInfoLog = (shader, maxLength, length, infoLog) => { + var log = GLctx.getShaderInfoLog(GL.shaders[shader]); + if (log === null) log = "(unknown error)"; + var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0; + if (length) HEAP32[((length) >> 2)] = numBytesWrittenExclNull; +}; + +var _glGetShaderInfoLog = _emscripten_glGetShaderInfoLog; + +var _emscripten_glGetShaderiv = (shader, pname, p) => { + if (!p) { + // GLES2 specification does not specify how to behave if p is a null + // pointer. Since calling this function does not make sense if p == null, + // issue a GL error to notify user about it. + GL.recordError(1281); + return; + } + if (pname == 35716) { + // GL_INFO_LOG_LENGTH + var log = GLctx.getShaderInfoLog(GL.shaders[shader]); + if (log === null) log = "(unknown error)"; + // The GLES2 specification says that if the shader has an empty info log, + // a value of 0 is returned. Otherwise the log has a null char appended. + // (An empty string is falsey, so we can just check that instead of + // looking at log.length.) + var logLength = log ? log.length + 1 : 0; + HEAP32[((p) >> 2)] = logLength; + } else if (pname == 35720) { + // GL_SHADER_SOURCE_LENGTH + var source = GLctx.getShaderSource(GL.shaders[shader]); + // source may be a null, or the empty string, both of which are falsey + // values that we report a 0 length for. + var sourceLength = source ? source.length + 1 : 0; + HEAP32[((p) >> 2)] = sourceLength; + } else { + HEAP32[((p) >> 2)] = GLctx.getShaderParameter(GL.shaders[shader], pname); + } +}; + +var _glGetShaderiv = _emscripten_glGetShaderiv; + +var _emscripten_glGetString = name_ => { + var ret = GL.stringCache[name_]; + if (!ret) { + switch (name_) { + case 7939: + ret = stringToNewUTF8(webglGetExtensions().join(" ")); + break; + + case 7936: + case 7937: + case 37445: + case 37446: + var s = GLctx.getParameter(name_); + if (!s) { + GL.recordError(1280); + } + ret = s ? stringToNewUTF8(s) : 0; + break; + + case 7938: + var webGLVersion = GLctx.getParameter(7938); + // return GLES version string corresponding to the version of the WebGL context + var glVersion = `OpenGL ES 2.0 (${webGLVersion})`; + if (GL.currentContext.version >= 2) glVersion = `OpenGL ES 3.0 (${webGLVersion})`; + ret = stringToNewUTF8(glVersion); + break; + + case 35724: + var glslVersion = GLctx.getParameter(35724); + // extract the version number 'N.M' from the string 'WebGL GLSL ES N.M ...' + var ver_re = /^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/; + var ver_num = glslVersion.match(ver_re); + if (ver_num !== null) { + if (ver_num[1].length == 3) ver_num[1] = ver_num[1] + "0"; + // ensure minor version has 2 digits + glslVersion = `OpenGL ES GLSL ES ${ver_num[1]} (${glslVersion})`; + } + ret = stringToNewUTF8(glslVersion); + break; + + default: + GL.recordError(1280); + } + GL.stringCache[name_] = ret; + } + return ret; +}; + +var _glGetString = _emscripten_glGetString; + +var _emscripten_glGetUniformBlockIndex = (program, uniformBlockName) => GLctx.getUniformBlockIndex(GL.programs[program], UTF8ToString(uniformBlockName)); + +var _glGetUniformBlockIndex = _emscripten_glGetUniformBlockIndex; + +/** @suppress {checkTypes} */ var jstoi_q = str => parseInt(str); + +/** @noinline */ var webglGetLeftBracePos = name => name.slice(-1) == "]" && name.lastIndexOf("["); + +var webglPrepareUniformLocationsBeforeFirstUse = program => { + var uniformLocsById = program.uniformLocsById, // Maps GLuint -> WebGLUniformLocation + uniformSizeAndIdsByName = program.uniformSizeAndIdsByName, // Maps name -> [uniform array length, GLuint] + i, j; + // On the first time invocation of glGetUniformLocation on this shader program: + // initialize cache data structures and discover which uniforms are arrays. + if (!uniformLocsById) { + // maps GLint integer locations to WebGLUniformLocations + program.uniformLocsById = uniformLocsById = {}; + // maps integer locations back to uniform name strings, so that we can lazily fetch uniform array locations + program.uniformArrayNamesById = {}; + var numActiveUniforms = GLctx.getProgramParameter(program, 35718); + for (i = 0; i < numActiveUniforms; ++i) { + var u = GLctx.getActiveUniform(program, i); + var nm = u.name; + var sz = u.size; + var lb = webglGetLeftBracePos(nm); + var arrayName = lb > 0 ? nm.slice(0, lb) : nm; + // Assign a new location. + var id = program.uniformIdCounter; + program.uniformIdCounter += sz; + // Eagerly get the location of the uniformArray[0] base element. + // The remaining indices >0 will be left for lazy evaluation to + // improve performance. Those may never be needed to fetch, if the + // application fills arrays always in full starting from the first + // element of the array. + uniformSizeAndIdsByName[arrayName] = [ sz, id ]; + // Store placeholder integers in place that highlight that these + // >0 index locations are array indices pending population. + for (j = 0; j < sz; ++j) { + uniformLocsById[id] = j; + program.uniformArrayNamesById[id++] = arrayName; + } + } + } +}; + +var _emscripten_glGetUniformLocation = (program, name) => { + name = UTF8ToString(name); + if (program = GL.programs[program]) { + webglPrepareUniformLocationsBeforeFirstUse(program); + var uniformLocsById = program.uniformLocsById; + // Maps GLuint -> WebGLUniformLocation + var arrayIndex = 0; + var uniformBaseName = name; + // Invariant: when populating integer IDs for uniform locations, we must + // maintain the precondition that arrays reside in contiguous addresses, + // i.e. for a 'vec4 colors[10];', colors[4] must be at location + // colors[0]+4. However, user might call glGetUniformLocation(program, + // "colors") for an array, so we cannot discover based on the user input + // arguments whether the uniform we are dealing with is an array. The only + // way to discover which uniforms are arrays is to enumerate over all the + // active uniforms in the program. + var leftBrace = webglGetLeftBracePos(name); + // If user passed an array accessor "[index]", parse the array index off the accessor. + if (leftBrace > 0) { + 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. + uniformBaseName = name.slice(0, leftBrace); + } + // Have we cached the location of this uniform before? + // A pair [array length, GLint of the uniform location] + var sizeAndId = program.uniformSizeAndIdsByName[uniformBaseName]; + // If a uniform with this name exists, and if its index is within the + // array limits (if it's even an array), query the WebGLlocation, or + // return an existing cached location. + if (sizeAndId && arrayIndex < sizeAndId[0]) { + arrayIndex += sizeAndId[1]; + // Add the base location of the uniform to the array index offset. + if ((uniformLocsById[arrayIndex] = uniformLocsById[arrayIndex] || GLctx.getUniformLocation(program, name))) { + return arrayIndex; + } + } + } else { + // N.b. we are currently unable to distinguish between GL program IDs that + // never existed vs GL program IDs that have been deleted, so report + // GL_INVALID_VALUE in both cases. + GL.recordError(1281); + } + return -1; +}; + +var _glGetUniformLocation = _emscripten_glGetUniformLocation; + +var _emscripten_glLineWidth = x0 => GLctx.lineWidth(x0); + +var _glLineWidth = _emscripten_glLineWidth; + +var _emscripten_glLinkProgram = program => { + program = GL.programs[program]; + GLctx.linkProgram(program); + // Invalidate earlier computed uniform->ID mappings, those have now become stale + program.uniformLocsById = 0; + // Mark as null-like so that glGetUniformLocation() knows to populate this again. + program.uniformSizeAndIdsByName = {}; +}; + +var _glLinkProgram = _emscripten_glLinkProgram; + +var _emscripten_glPixelStorei = (pname, param) => { + if (pname == 3317) { + GL.unpackAlignment = param; + } else if (pname == 3314) { + GL.unpackRowLength = param; + } + GLctx.pixelStorei(pname, param); +}; + +var _glPixelStorei = _emscripten_glPixelStorei; + +var computeUnpackAlignedImageSize = (width, height, sizePerPixel) => { + function roundedToNextMultipleOf(x, y) { + return (x + y - 1) & -y; + } + var plainRowSize = (GL.unpackRowLength || width) * sizePerPixel; + var alignedRowSize = roundedToNextMultipleOf(plainRowSize, GL.unpackAlignment); + return height * alignedRowSize; +}; + +var colorChannelsInGlTextureFormat = format => { + // Micro-optimizations for size: map format to size by subtracting smallest + // enum value (0x1902) from all values first. Also omit the most common + // size value (1) from the list, which is assumed by formats not on the + // list. + var colorChannels = { + // 0x1902 /* GL_DEPTH_COMPONENT */ - 0x1902: 1, + // 0x1906 /* GL_ALPHA */ - 0x1902: 1, + 5: 3, + 6: 4, + // 0x1909 /* GL_LUMINANCE */ - 0x1902: 1, + 8: 2, + 29502: 3, + 29504: 4, + // 0x1903 /* GL_RED */ - 0x1902: 1, + 26917: 2, + 26918: 2, + // 0x8D94 /* GL_RED_INTEGER */ - 0x1902: 1, + 29846: 3, + 29847: 4 + }; + return colorChannels[format - 6402] || 1; +}; + +var heapObjectForWebGLType = type => { + // Micro-optimization for size: Subtract lowest GL enum number (0x1400/* GL_BYTE */) from type to compare + // smaller values for the heap, for shorter generated code size. + // Also the type HEAPU16 is not tested for explicitly, but any unrecognized type will return out HEAPU16. + // (since most types are HEAPU16) + type -= 5120; + if (type == 0) return HEAP8; + if (type == 1) return HEAPU8; + if (type == 2) return HEAP16; + if (type == 4) return HEAP32; + if (type == 6) return HEAPF32; + if (type == 5 || type == 28922 || type == 28520 || type == 30779 || type == 30782) return HEAPU32; + return HEAPU16; +}; + +var toTypedArrayIndex = (pointer, heap) => pointer >>> (31 - Math.clz32(heap.BYTES_PER_ELEMENT)); + +var emscriptenWebGLGetTexPixelData = (type, format, width, height, pixels) => { + var heap = heapObjectForWebGLType(type); + var sizePerPixel = colorChannelsInGlTextureFormat(format) * heap.BYTES_PER_ELEMENT; + var bytes = computeUnpackAlignedImageSize(width, height, sizePerPixel); + return heap.subarray(toTypedArrayIndex(pixels, heap), toTypedArrayIndex(pixels + bytes, heap)); +}; + +var _emscripten_glReadPixels = (x, y, width, height, format, type, pixels) => { + if (GL.currentContext.version >= 2) { + if (GLctx.currentPixelPackBufferBinding) { + GLctx.readPixels(x, y, width, height, format, type, pixels); + return; + } + var heap = heapObjectForWebGLType(type); + var target = toTypedArrayIndex(pixels, heap); + GLctx.readPixels(x, y, width, height, format, type, heap, target); + return; + } + var pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels); + if (!pixelData) { + GL.recordError(1280); + return; + } + GLctx.readPixels(x, y, width, height, format, type, pixelData); +}; + +var _glReadPixels = _emscripten_glReadPixels; + +var _emscripten_glShaderSource = (shader, count, string, length) => { + var source = GL.getSource(shader, count, string, length); + GLctx.shaderSource(GL.shaders[shader], source); +}; + +var _glShaderSource = _emscripten_glShaderSource; + +var _emscripten_glTexImage2D = (target, level, internalFormat, width, height, border, format, type, pixels) => { + if (GL.currentContext.version >= 2) { + if (GLctx.currentPixelUnpackBufferBinding) { + GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels); + return; + } + if (pixels) { + var heap = heapObjectForWebGLType(type); + var index = toTypedArrayIndex(pixels, heap); + GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, heap, index); + return; + } + } + var pixelData = pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels) : null; + GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixelData); +}; + +var _glTexImage2D = _emscripten_glTexImage2D; + +var _emscripten_glTexParameterf = (x0, x1, x2) => GLctx.texParameterf(x0, x1, x2); + +var _glTexParameterf = _emscripten_glTexParameterf; + +var _emscripten_glTexParameterfv = (target, pname, params) => { + var param = HEAPF32[((params) >> 2)]; + GLctx.texParameterf(target, pname, param); +}; + +var _glTexParameterfv = _emscripten_glTexParameterfv; + +var _emscripten_glTexParameteri = (x0, x1, x2) => GLctx.texParameteri(x0, x1, x2); + +var _glTexParameteri = _emscripten_glTexParameteri; + +var _emscripten_glTexStorage2D = (x0, x1, x2, x3, x4) => GLctx.texStorage2D(x0, x1, x2, x3, x4); + +var _glTexStorage2D = _emscripten_glTexStorage2D; + +var _emscripten_glTexStorage3D = (x0, x1, x2, x3, x4, x5) => GLctx.texStorage3D(x0, x1, x2, x3, x4, x5); + +var _glTexStorage3D = _emscripten_glTexStorage3D; + +var _emscripten_glTexSubImage2D = (target, level, xoffset, yoffset, width, height, format, type, pixels) => { + if (GL.currentContext.version >= 2) { + if (GLctx.currentPixelUnpackBufferBinding) { + GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + return; + } + if (pixels) { + var heap = heapObjectForWebGLType(type); + GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, heap, toTypedArrayIndex(pixels, heap)); + return; + } + } + var pixelData = pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels) : null; + GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixelData); +}; + +var _glTexSubImage2D = _emscripten_glTexSubImage2D; + +var _emscripten_glTexSubImage3D = (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) => { + if (GLctx.currentPixelUnpackBufferBinding) { + GLctx.texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + } else if (pixels) { + var heap = heapObjectForWebGLType(type); + GLctx.texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, heap, toTypedArrayIndex(pixels, heap)); + } else { + GLctx.texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, null); + } +}; + +var _glTexSubImage3D = _emscripten_glTexSubImage3D; + +var webglGetProgramUniformLocation = (program, location) => { + if (program) { + var webglLoc = program.uniformLocsById[location]; + // program.uniformLocsById[location] stores either an integer, or a + // WebGLUniformLocation. + // If an integer, we have not yet bound the location, so do it now. The + // integer value specifies the array index we should bind to. + if (typeof webglLoc == "number") { + program.uniformLocsById[location] = webglLoc = GLctx.getUniformLocation(program, program.uniformArrayNamesById[location] + (webglLoc > 0 ? `[${webglLoc}]` : "")); + } + // Else an already cached WebGLUniformLocation, return it. + return webglLoc; + } else { + GL.recordError(1282); + } +}; + +var webglGetUniformLocation = location => webglGetProgramUniformLocation(GLctx.currentProgram, location); + +var _emscripten_glUniform1f = (location, v0) => { + GLctx.uniform1f(webglGetUniformLocation(location), v0); +}; + +var _glUniform1f = _emscripten_glUniform1f; + +var miniTempWebGLFloatBuffers = []; + +var _emscripten_glUniform1fv = (location, count, value) => { + if (GL.currentContext.version >= 2) { + count && GLctx.uniform1fv(webglGetUniformLocation(location), HEAPF32, ((value) >> 2), count); + return; + } + if (count <= 288) { + // avoid allocation when uploading few enough uniforms + var view = miniTempWebGLFloatBuffers[count]; + for (var i = 0; i < count; ++i) { + view[i] = HEAPF32[(((value) + (4 * i)) >> 2)]; + } + } else { + var view = HEAPF32.subarray((((value) >> 2)), ((value + count * 4) >> 2)); + } + GLctx.uniform1fv(webglGetUniformLocation(location), view); +}; + +var _glUniform1fv = _emscripten_glUniform1fv; + +var _emscripten_glUniform1i = (location, v0) => { + GLctx.uniform1i(webglGetUniformLocation(location), v0); +}; + +var _glUniform1i = _emscripten_glUniform1i; + +var _emscripten_glUniform2f = (location, v0, v1) => { + GLctx.uniform2f(webglGetUniformLocation(location), v0, v1); +}; + +var _glUniform2f = _emscripten_glUniform2f; + +var _emscripten_glUniform2fv = (location, count, value) => { + if (GL.currentContext.version >= 2) { + count && GLctx.uniform2fv(webglGetUniformLocation(location), HEAPF32, ((value) >> 2), count * 2); + return; + } + if (count <= 144) { + // avoid allocation when uploading few enough uniforms + count *= 2; + var view = miniTempWebGLFloatBuffers[count]; + for (var i = 0; i < count; i += 2) { + view[i] = HEAPF32[(((value) + (4 * i)) >> 2)]; + view[i + 1] = HEAPF32[(((value) + (4 * i + 4)) >> 2)]; + } + } else { + var view = HEAPF32.subarray((((value) >> 2)), ((value + count * 8) >> 2)); + } + GLctx.uniform2fv(webglGetUniformLocation(location), view); +}; + +var _glUniform2fv = _emscripten_glUniform2fv; + +var _emscripten_glUniform3f = (location, v0, v1, v2) => { + GLctx.uniform3f(webglGetUniformLocation(location), v0, v1, v2); +}; + +var _glUniform3f = _emscripten_glUniform3f; + +var _emscripten_glUniform4f = (location, v0, v1, v2, v3) => { + GLctx.uniform4f(webglGetUniformLocation(location), v0, v1, v2, v3); +}; + +var _glUniform4f = _emscripten_glUniform4f; + +var _emscripten_glUniform4fv = (location, count, value) => { + if (GL.currentContext.version >= 2) { + count && GLctx.uniform4fv(webglGetUniformLocation(location), HEAPF32, ((value) >> 2), count * 4); + return; + } + if (count <= 72) { + // avoid allocation when uploading few enough uniforms + var view = miniTempWebGLFloatBuffers[4 * count]; + // hoist the heap out of the loop for size and for pthreads+growth. + var heap = HEAPF32; + value = ((value) >> 2); + count *= 4; + for (var i = 0; i < count; i += 4) { + var dst = value + i; + view[i] = heap[dst]; + view[i + 1] = heap[dst + 1]; + view[i + 2] = heap[dst + 2]; + view[i + 3] = heap[dst + 3]; + } + } else { + var view = HEAPF32.subarray((((value) >> 2)), ((value + count * 16) >> 2)); + } + GLctx.uniform4fv(webglGetUniformLocation(location), view); +}; + +var _glUniform4fv = _emscripten_glUniform4fv; + +var miniTempWebGLIntBuffers = []; + +var _emscripten_glUniform4iv = (location, count, value) => { + if (GL.currentContext.version >= 2) { + count && GLctx.uniform4iv(webglGetUniformLocation(location), HEAP32, ((value) >> 2), count * 4); + return; + } + if (count <= 72) { + // avoid allocation when uploading few enough uniforms + count *= 4; + var view = miniTempWebGLIntBuffers[count]; + for (var i = 0; i < count; i += 4) { + view[i] = HEAP32[(((value) + (4 * i)) >> 2)]; + view[i + 1] = HEAP32[(((value) + (4 * i + 4)) >> 2)]; + view[i + 2] = HEAP32[(((value) + (4 * i + 8)) >> 2)]; + view[i + 3] = HEAP32[(((value) + (4 * i + 12)) >> 2)]; + } + } else { + var view = HEAP32.subarray((((value) >> 2)), ((value + count * 16) >> 2)); + } + GLctx.uniform4iv(webglGetUniformLocation(location), view); +}; + +var _glUniform4iv = _emscripten_glUniform4iv; + +var _emscripten_glUniformBlockBinding = (program, uniformBlockIndex, uniformBlockBinding) => { + program = GL.programs[program]; + GLctx.uniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); +}; + +var _glUniformBlockBinding = _emscripten_glUniformBlockBinding; + +var _emscripten_glUniformMatrix2fv = (location, count, transpose, value) => { + if (GL.currentContext.version >= 2) { + count && GLctx.uniformMatrix2fv(webglGetUniformLocation(location), !!transpose, HEAPF32, ((value) >> 2), count * 4); + return; + } + if (count <= 72) { + // avoid allocation when uploading few enough uniforms + count *= 4; + var view = miniTempWebGLFloatBuffers[count]; + for (var i = 0; i < count; i += 4) { + view[i] = HEAPF32[(((value) + (4 * i)) >> 2)]; + view[i + 1] = HEAPF32[(((value) + (4 * i + 4)) >> 2)]; + view[i + 2] = HEAPF32[(((value) + (4 * i + 8)) >> 2)]; + view[i + 3] = HEAPF32[(((value) + (4 * i + 12)) >> 2)]; + } + } else { + var view = HEAPF32.subarray((((value) >> 2)), ((value + count * 16) >> 2)); + } + GLctx.uniformMatrix2fv(webglGetUniformLocation(location), !!transpose, view); +}; + +var _glUniformMatrix2fv = _emscripten_glUniformMatrix2fv; + +var _emscripten_glUniformMatrix3fv = (location, count, transpose, value) => { + if (GL.currentContext.version >= 2) { + count && GLctx.uniformMatrix3fv(webglGetUniformLocation(location), !!transpose, HEAPF32, ((value) >> 2), count * 9); + return; + } + if (count <= 32) { + // avoid allocation when uploading few enough uniforms + count *= 9; + var view = miniTempWebGLFloatBuffers[count]; + for (var i = 0; i < count; i += 9) { + view[i] = HEAPF32[(((value) + (4 * i)) >> 2)]; + view[i + 1] = HEAPF32[(((value) + (4 * i + 4)) >> 2)]; + view[i + 2] = HEAPF32[(((value) + (4 * i + 8)) >> 2)]; + view[i + 3] = HEAPF32[(((value) + (4 * i + 12)) >> 2)]; + view[i + 4] = HEAPF32[(((value) + (4 * i + 16)) >> 2)]; + view[i + 5] = HEAPF32[(((value) + (4 * i + 20)) >> 2)]; + view[i + 6] = HEAPF32[(((value) + (4 * i + 24)) >> 2)]; + view[i + 7] = HEAPF32[(((value) + (4 * i + 28)) >> 2)]; + view[i + 8] = HEAPF32[(((value) + (4 * i + 32)) >> 2)]; + } + } else { + var view = HEAPF32.subarray((((value) >> 2)), ((value + count * 36) >> 2)); + } + GLctx.uniformMatrix3fv(webglGetUniformLocation(location), !!transpose, view); +}; + +var _glUniformMatrix3fv = _emscripten_glUniformMatrix3fv; + +var _emscripten_glUniformMatrix4fv = (location, count, transpose, value) => { + if (GL.currentContext.version >= 2) { + count && GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, HEAPF32, ((value) >> 2), count * 16); + return; + } + if (count <= 18) { + // avoid allocation when uploading few enough uniforms + var view = miniTempWebGLFloatBuffers[16 * count]; + // hoist the heap out of the loop for size and for pthreads+growth. + var heap = HEAPF32; + value = ((value) >> 2); + count *= 16; + for (var i = 0; i < count; i += 16) { + var dst = value + i; + view[i] = heap[dst]; + view[i + 1] = heap[dst + 1]; + view[i + 2] = heap[dst + 2]; + view[i + 3] = heap[dst + 3]; + view[i + 4] = heap[dst + 4]; + view[i + 5] = heap[dst + 5]; + view[i + 6] = heap[dst + 6]; + view[i + 7] = heap[dst + 7]; + view[i + 8] = heap[dst + 8]; + view[i + 9] = heap[dst + 9]; + view[i + 10] = heap[dst + 10]; + view[i + 11] = heap[dst + 11]; + view[i + 12] = heap[dst + 12]; + view[i + 13] = heap[dst + 13]; + view[i + 14] = heap[dst + 14]; + view[i + 15] = heap[dst + 15]; + } + } else { + var view = HEAPF32.subarray((((value) >> 2)), ((value + count * 64) >> 2)); + } + GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, view); +}; + +var _glUniformMatrix4fv = _emscripten_glUniformMatrix4fv; + +var _emscripten_glUseProgram = program => { + program = GL.programs[program]; + GLctx.useProgram(program); + // Record the currently active program so that we can access the uniform + // mapping table of that program. + GLctx.currentProgram = program; +}; + +var _glUseProgram = _emscripten_glUseProgram; + +var _emscripten_glVertexAttribPointer = (index, size, type, normalized, stride, ptr) => { + var cb = GL.currentContext.clientBuffers[index]; + if (!GLctx.currentArrayBufferBinding) { + cb.size = size; + cb.type = type; + cb.normalized = normalized; + cb.stride = stride; + cb.ptr = ptr; + cb.clientside = true; + cb.vertexAttribPointerAdaptor = /** @this {WebGLRenderingContext} */ function(index, size, type, normalized, stride, ptr) { + this.vertexAttribPointer(index, size, type, normalized, stride, ptr); + }; + return; + } + cb.clientside = false; + GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr); +}; + +var _glVertexAttribPointer = _emscripten_glVertexAttribPointer; + +var _emscripten_glViewport = (x0, x1, x2, x3) => GLctx.viewport(x0, x1, x2, x3); + +var _glViewport = _emscripten_glViewport; + +function _mediapipe_find_canvas_event_target(canvasSelector) { + let target = findCanvasEventTarget(canvasSelector); + // WebGPU-on-worker uses this function to try to grab the canvas, but + // doesn't have a DOM element to find. So as a quick patch, if the default + // behavior is unsuccessful here then we try a webgpu canvas property + // which is set by the user directly on the Module, much like how our old + // pipeline used the Module.canvas property. See b/265271517 for details. + if (Module && !target) { + target = Module.canvasWebGpu; + } + return Emval.toHandle(target); +} + +function _mediapipe_webgl_tex_image_drawable(drawableHandle) { + const drawable = Emval.toValue(drawableHandle); + GLctx.texImage2D(GLctx.TEXTURE_2D, 0, GLctx.RGBA, GLctx.RGBA, GLctx.UNSIGNED_BYTE, drawable); +} + +var _random_get = (buffer, size) => randomFill(HEAPU8.subarray(buffer, buffer + size)); + +var _wgpuCommandEncoderBeginComputePass = (encoderPtr, descriptor) => { + var desc; + if (descriptor) { + desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "timestampWrites": WebGPU.makePassTimestampWrites(HEAPU32[(((descriptor) + (12)) >> 2)]) + }; + } + var commandEncoder = WebGPU.getJsObject(encoderPtr); + var ptr = _emwgpuCreateComputePassEncoder(0); + WebGPU.Internals.jsObjectInsert(ptr, commandEncoder.beginComputePass(desc)); + return ptr; +}; + +var _wgpuCommandEncoderBeginRenderPass = (encoderPtr, descriptor) => { + function makeColorAttachment(caPtr) { + var viewPtr = HEAPU32[(((caPtr) + (4)) >> 2)]; + if (viewPtr === 0) { + // Null `view` means no attachment in this slot. + return undefined; + } + var depthSlice = HEAPU32[(((caPtr) + (8)) >> 2)]; + if (depthSlice == 4294967295) depthSlice = undefined; + return { + "view": WebGPU.getJsObject(viewPtr), + "depthSlice": depthSlice, + "resolveTarget": WebGPU.getJsObject(HEAPU32[(((caPtr) + (12)) >> 2)]), + "clearValue": WebGPU.makeColor(caPtr + 24), + "loadOp": WebGPU.LoadOp[HEAP32[(((caPtr) + (16)) >> 2)]], + "storeOp": WebGPU.StoreOp[HEAP32[(((caPtr) + (20)) >> 2)]] + }; + } + function makeColorAttachments(count, caPtr) { + var attachments = []; + for (var i = 0; i < count; ++i) { + attachments.push(makeColorAttachment(caPtr + 56 * i)); + } + return attachments; + } + function makeDepthStencilAttachment(dsaPtr) { + if (dsaPtr === 0) return undefined; + return { + "view": WebGPU.getJsObject(HEAPU32[(((dsaPtr) + (4)) >> 2)]), + "depthClearValue": HEAPF32[(((dsaPtr) + (16)) >> 2)], + "depthLoadOp": WebGPU.LoadOp[HEAP32[(((dsaPtr) + (8)) >> 2)]], + "depthStoreOp": WebGPU.StoreOp[HEAP32[(((dsaPtr) + (12)) >> 2)]], + "depthReadOnly": !!(HEAPU32[(((dsaPtr) + (20)) >> 2)]), + "stencilClearValue": HEAPU32[(((dsaPtr) + (32)) >> 2)], + "stencilLoadOp": WebGPU.LoadOp[HEAP32[(((dsaPtr) + (24)) >> 2)]], + "stencilStoreOp": WebGPU.StoreOp[HEAP32[(((dsaPtr) + (28)) >> 2)]], + "stencilReadOnly": !!(HEAPU32[(((dsaPtr) + (36)) >> 2)]) + }; + } + function makeRenderPassDescriptor(descriptor) { + var nextInChainPtr = HEAPU32[((descriptor) >> 2)]; + var maxDrawCount = undefined; + if (nextInChainPtr !== 0) { + var sType = HEAP32[(((nextInChainPtr) + (4)) >> 2)]; + var renderPassMaxDrawCount = nextInChainPtr; + // Note: The user could have passed a really huge value here, which is technically valid in + // C but will not be allowed by WebGPU in JS because of [EnforceRange]. We intentionally + // ignore that case because it's not useful - apps can just pick a smaller maxDrawCount. + maxDrawCount = readI53FromI64((renderPassMaxDrawCount) + (8)); + } + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "colorAttachments": makeColorAttachments(HEAPU32[(((descriptor) + (12)) >> 2)], HEAPU32[(((descriptor) + (16)) >> 2)]), + "depthStencilAttachment": makeDepthStencilAttachment(HEAPU32[(((descriptor) + (20)) >> 2)]), + "occlusionQuerySet": WebGPU.getJsObject(HEAPU32[(((descriptor) + (24)) >> 2)]), + "timestampWrites": WebGPU.makePassTimestampWrites(HEAPU32[(((descriptor) + (28)) >> 2)]), + "maxDrawCount": maxDrawCount + }; + return desc; + } + var desc = makeRenderPassDescriptor(descriptor); + var commandEncoder = WebGPU.getJsObject(encoderPtr); + var ptr = _emwgpuCreateRenderPassEncoder(0); + WebGPU.Internals.jsObjectInsert(ptr, commandEncoder.beginRenderPass(desc)); + return ptr; +}; + +var _wgpuCommandEncoderCopyBufferToTexture = (encoderPtr, srcPtr, dstPtr, copySizePtr) => { + var commandEncoder = WebGPU.getJsObject(encoderPtr); + var copySize = WebGPU.makeExtent3D(copySizePtr); + commandEncoder.copyBufferToTexture(WebGPU.makeTexelCopyBufferInfo(srcPtr), WebGPU.makeTexelCopyTextureInfo(dstPtr), copySize); +}; + +var _wgpuCommandEncoderCopyTextureToBuffer = (encoderPtr, srcPtr, dstPtr, copySizePtr) => { + var commandEncoder = WebGPU.getJsObject(encoderPtr); + var copySize = WebGPU.makeExtent3D(copySizePtr); + commandEncoder.copyTextureToBuffer(WebGPU.makeTexelCopyTextureInfo(srcPtr), WebGPU.makeTexelCopyBufferInfo(dstPtr), copySize); +}; + +var _wgpuCommandEncoderCopyTextureToTexture = (encoderPtr, srcPtr, dstPtr, copySizePtr) => { + var commandEncoder = WebGPU.getJsObject(encoderPtr); + var copySize = WebGPU.makeExtent3D(copySizePtr); + commandEncoder.copyTextureToTexture(WebGPU.makeTexelCopyTextureInfo(srcPtr), WebGPU.makeTexelCopyTextureInfo(dstPtr), copySize); +}; + +var _wgpuCommandEncoderFinish = (encoderPtr, descriptor) => { + // TODO: Use the descriptor. + var commandEncoder = WebGPU.getJsObject(encoderPtr); + var ptr = _emwgpuCreateCommandBuffer(0); + WebGPU.Internals.jsObjectInsert(ptr, commandEncoder.finish()); + return ptr; +}; + +var _wgpuComputePassEncoderDispatchWorkgroups = (passPtr, x, y, z) => { + var pass = WebGPU.getJsObject(passPtr); + pass.dispatchWorkgroups(x, y, z); +}; + +var _wgpuComputePassEncoderEnd = passPtr => { + var pass = WebGPU.getJsObject(passPtr); + pass.end(); +}; + +var _wgpuComputePassEncoderSetBindGroup = (passPtr, groupIndex, groupPtr, dynamicOffsetCount, dynamicOffsetsPtr) => { + var pass = WebGPU.getJsObject(passPtr); + var group = WebGPU.getJsObject(groupPtr); + if (dynamicOffsetCount == 0) { + pass.setBindGroup(groupIndex, group); + } else { + pass.setBindGroup(groupIndex, group, HEAPU32, ((dynamicOffsetsPtr) >> 2), dynamicOffsetCount); + } +}; + +var _wgpuComputePassEncoderSetPipeline = (passPtr, pipelinePtr) => { + var pass = WebGPU.getJsObject(passPtr); + var pipeline = WebGPU.getJsObject(pipelinePtr); + pass.setPipeline(pipeline); +}; + +var _wgpuComputePipelineGetBindGroupLayout = (pipelinePtr, groupIndex) => { + var pipeline = WebGPU.getJsObject(pipelinePtr); + var ptr = _emwgpuCreateBindGroupLayout(0); + WebGPU.Internals.jsObjectInsert(ptr, pipeline.getBindGroupLayout(groupIndex)); + return ptr; +}; + +var _wgpuDeviceCreateBindGroup = (devicePtr, descriptor) => { + function makeEntry(entryPtr) { + var bufferPtr = HEAPU32[(((entryPtr) + (8)) >> 2)]; + var samplerPtr = HEAPU32[(((entryPtr) + (32)) >> 2)]; + var textureViewPtr = HEAPU32[(((entryPtr) + (36)) >> 2)]; + var externalTexturePtr = 0; + WebGPU.iterateExtensions(entryPtr, { + 14: ptr => { + externalTexturePtr = HEAPU32[(((ptr) + (8)) >> 2)]; + } + }); + var resource; + if (bufferPtr) { + // Note the sentinel UINT64_MAX will be read as -1. + var size = readI53FromI64((entryPtr) + (24)); + if (size == -1) size = undefined; + resource = { + "buffer": WebGPU.getJsObject(bufferPtr), + "offset": readI53FromI64((entryPtr) + (16)), + "size": size + }; + } else { + resource = WebGPU.getJsObject(samplerPtr || textureViewPtr || externalTexturePtr); + } + return { + "binding": HEAPU32[(((entryPtr) + (4)) >> 2)], + "resource": resource + }; + } + function makeEntries(count, entriesPtrs) { + var entries = []; + for (var i = 0; i < count; ++i) { + entries.push(makeEntry(entriesPtrs + 40 * i)); + } + return entries; + } + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "layout": WebGPU.getJsObject(HEAPU32[(((descriptor) + (12)) >> 2)]), + "entries": makeEntries(HEAPU32[(((descriptor) + (16)) >> 2)], HEAPU32[(((descriptor) + (20)) >> 2)]) + }; + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreateBindGroup(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createBindGroup(desc)); + return ptr; +}; + +var _wgpuDeviceCreateBindGroupLayout = (devicePtr, descriptor) => { + function makeBufferEntry(substructPtr) { + var typeInt = HEAPU32[(((substructPtr) + (4)) >> 2)]; + if (!typeInt) return undefined; + return { + "type": WebGPU.BufferBindingType[typeInt], + "hasDynamicOffset": !!(HEAPU32[(((substructPtr) + (8)) >> 2)]), + "minBindingSize": readI53FromI64((substructPtr) + (16)) + }; + } + function makeSamplerEntry(substructPtr) { + var typeInt = HEAPU32[(((substructPtr) + (4)) >> 2)]; + if (!typeInt) return undefined; + return { + "type": WebGPU.SamplerBindingType[typeInt] + }; + } + function makeTextureEntry(substructPtr) { + var sampleTypeInt = HEAPU32[(((substructPtr) + (4)) >> 2)]; + if (!sampleTypeInt) return undefined; + return { + "sampleType": WebGPU.TextureSampleType[sampleTypeInt], + "viewDimension": WebGPU.TextureViewDimension[HEAP32[(((substructPtr) + (8)) >> 2)]], + "multisampled": !!(HEAPU32[(((substructPtr) + (12)) >> 2)]) + }; + } + function makeStorageTextureEntry(substructPtr) { + var accessInt = HEAPU32[(((substructPtr) + (4)) >> 2)]; + if (!accessInt) return undefined; + return { + "access": WebGPU.StorageTextureAccess[accessInt], + "format": WebGPU.TextureFormat[HEAP32[(((substructPtr) + (8)) >> 2)]], + "viewDimension": WebGPU.TextureViewDimension[HEAP32[(((substructPtr) + (12)) >> 2)]] + }; + } + function makeEntry(entryPtr) { + var entry = { + "binding": HEAPU32[(((entryPtr) + (4)) >> 2)], + "visibility": HEAPU32[(((entryPtr) + (8)) >> 2)], + "buffer": makeBufferEntry(entryPtr + 24), + "sampler": makeSamplerEntry(entryPtr + 48), + "texture": makeTextureEntry(entryPtr + 56), + "storageTexture": makeStorageTextureEntry(entryPtr + 72) + }; + WebGPU.iterateExtensions(entryPtr, { + 13: ptr => { + entry["externalTexture"] = {}; + } + }); + return entry; + } + function makeEntries(count, entriesPtrs) { + var entries = []; + for (var i = 0; i < count; ++i) { + entries.push(makeEntry(entriesPtrs + 88 * i)); + } + return entries; + } + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "entries": makeEntries(HEAPU32[(((descriptor) + (12)) >> 2)], HEAPU32[(((descriptor) + (16)) >> 2)]) + }; + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreateBindGroupLayout(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createBindGroupLayout(desc)); + return ptr; +}; + +var _wgpuDeviceCreateCommandEncoder = (devicePtr, descriptor) => { + var desc; + if (descriptor) { + desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4) + }; + } + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreateCommandEncoder(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createCommandEncoder(desc)); + return ptr; +}; + +var _wgpuDeviceCreateComputePipeline = (devicePtr, descriptor) => { + var desc = WebGPU.makeComputePipelineDesc(descriptor); + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreateComputePipeline(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createComputePipeline(desc)); + return ptr; +}; + +var _wgpuDeviceCreatePipelineLayout = (devicePtr, descriptor) => { + var bglCount = HEAPU32[(((descriptor) + (12)) >> 2)]; + var bglPtr = HEAPU32[(((descriptor) + (16)) >> 2)]; + var bgls = []; + for (var i = 0; i < bglCount; ++i) { + bgls.push(WebGPU.getJsObject(HEAPU32[(((bglPtr) + (4 * i)) >> 2)])); + } + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "bindGroupLayouts": bgls, + "immediateSize": HEAPU32[(((descriptor) + (20)) >> 2)] + }; + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreatePipelineLayout(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createPipelineLayout(desc)); + return ptr; +}; + +var _wgpuDeviceCreateRenderPipeline = (devicePtr, descriptor) => { + var desc = WebGPU.makeRenderPipelineDesc(descriptor); + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreateRenderPipeline(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createRenderPipeline(desc)); + return ptr; +}; + +var _wgpuDeviceCreateSampler = (devicePtr, descriptor) => { + var desc; + if (descriptor) { + desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "addressModeU": WebGPU.AddressMode[HEAP32[(((descriptor) + (12)) >> 2)]], + "addressModeV": WebGPU.AddressMode[HEAP32[(((descriptor) + (16)) >> 2)]], + "addressModeW": WebGPU.AddressMode[HEAP32[(((descriptor) + (20)) >> 2)]], + "magFilter": WebGPU.FilterMode[HEAP32[(((descriptor) + (24)) >> 2)]], + "minFilter": WebGPU.FilterMode[HEAP32[(((descriptor) + (28)) >> 2)]], + "mipmapFilter": WebGPU.MipmapFilterMode[HEAP32[(((descriptor) + (32)) >> 2)]], + "lodMinClamp": HEAPF32[(((descriptor) + (36)) >> 2)], + "lodMaxClamp": HEAPF32[(((descriptor) + (40)) >> 2)], + "compare": WebGPU.CompareFunction[HEAP32[(((descriptor) + (44)) >> 2)]], + "maxAnisotropy": HEAPU16[(((descriptor) + (48)) >> 1)] + }; + } + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreateSampler(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createSampler(desc)); + return ptr; +}; + +var _wgpuDeviceCreateTexture = (devicePtr, descriptor) => { + var nextInChainPtr = HEAPU32[((descriptor) >> 2)]; + var textureBindingViewDimension; + if (nextInChainPtr !== 0) { + var sType = HEAP32[(((nextInChainPtr) + (4)) >> 2)]; + var textureBindingViewDimensionDescriptor = nextInChainPtr; + textureBindingViewDimension = WebGPU.TextureViewDimension[HEAP32[(((textureBindingViewDimensionDescriptor) + (8)) >> 2)]]; + } + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "size": WebGPU.makeExtent3D(descriptor + 28), + "mipLevelCount": HEAPU32[(((descriptor) + (44)) >> 2)], + "sampleCount": HEAPU32[(((descriptor) + (48)) >> 2)], + "dimension": WebGPU.TextureDimension[HEAP32[(((descriptor) + (24)) >> 2)]], + "format": WebGPU.TextureFormat[HEAP32[(((descriptor) + (40)) >> 2)]], + "usage": HEAPU32[(((descriptor) + (16)) >> 2)], + "textureBindingViewDimension": textureBindingViewDimension + }; + var viewFormatCount = HEAPU32[(((descriptor) + (52)) >> 2)]; + if (viewFormatCount) { + var viewFormatsPtr = HEAPU32[(((descriptor) + (56)) >> 2)]; + // viewFormatsPtr pointer to an array of TextureFormat which is an enum of size uint32_t + desc["viewFormats"] = Array.from(HEAP32.subarray((((viewFormatsPtr) >> 2)), ((viewFormatsPtr + viewFormatCount * 4) >> 2)), format => WebGPU.TextureFormat[format]); + } + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreateTexture(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createTexture(desc)); + return ptr; +}; + +var _wgpuQueueSubmit = (queuePtr, commandCount, commands) => { + var queue = WebGPU.getJsObject(queuePtr); + var cmds = Array.from(HEAP32.subarray((((commands) >> 2)), ((commands + commandCount * 4) >> 2)), id => WebGPU.getJsObject(id)); + queue.submit(cmds); +}; + +function _wgpuQueueWriteBuffer(queuePtr, bufferPtr, bufferOffset_low, bufferOffset_high, data, size) { + var bufferOffset = convertI32PairToI53Checked(bufferOffset_low, bufferOffset_high); + var queue = WebGPU.getJsObject(queuePtr); + var buffer = WebGPU.getJsObject(bufferPtr); + // There is a size limitation for ArrayBufferView. Work around by passing in a subarray + // instead of the whole heap. crbug.com/1201109 + var subarray = HEAPU8.subarray(data, data + size); + queue.writeBuffer(buffer, bufferOffset, subarray, 0, size); +} + +var _wgpuQueueWriteTexture = (queuePtr, destinationPtr, data, dataSize, dataLayoutPtr, writeSizePtr) => { + var queue = WebGPU.getJsObject(queuePtr); + var destination = WebGPU.makeTexelCopyTextureInfo(destinationPtr); + var dataLayout = WebGPU.makeTexelCopyBufferLayout(dataLayoutPtr); + var writeSize = WebGPU.makeExtent3D(writeSizePtr); + // This subarray isn't strictly necessary, but helps work around an issue + // where Chromium makes a copy of the entire heap. crbug.com/1134457 + var subarray = HEAPU8.subarray(data, data + dataSize); + queue.writeTexture(destination, subarray, dataLayout, writeSize); +}; + +var _wgpuRenderPassEncoderDraw = (passPtr, vertexCount, instanceCount, firstVertex, firstInstance) => { + firstVertex >>>= 0; + firstInstance >>>= 0; + var pass = WebGPU.getJsObject(passPtr); + pass.draw(vertexCount, instanceCount, firstVertex, firstInstance); +}; + +var _wgpuRenderPassEncoderEnd = encoderPtr => { + var encoder = WebGPU.getJsObject(encoderPtr); + encoder.end(); +}; + +var _wgpuRenderPassEncoderSetBindGroup = (passPtr, groupIndex, groupPtr, dynamicOffsetCount, dynamicOffsetsPtr) => { + var pass = WebGPU.getJsObject(passPtr); + var group = WebGPU.getJsObject(groupPtr); + if (dynamicOffsetCount == 0) { + pass.setBindGroup(groupIndex, group); + } else { + pass.setBindGroup(groupIndex, group, HEAPU32, ((dynamicOffsetsPtr) >> 2), dynamicOffsetCount); + } +}; + +var _wgpuRenderPassEncoderSetPipeline = (passPtr, pipelinePtr) => { + var pass = WebGPU.getJsObject(passPtr); + var pipeline = WebGPU.getJsObject(pipelinePtr); + pass.setPipeline(pipeline); +}; + +var _wgpuRenderPipelineGetBindGroupLayout = (pipelinePtr, groupIndex) => { + var pipeline = WebGPU.getJsObject(pipelinePtr); + var ptr = _emwgpuCreateBindGroupLayout(0); + WebGPU.Internals.jsObjectInsert(ptr, pipeline.getBindGroupLayout(groupIndex)); + return ptr; +}; + +var _wgpuTextureCreateView = (texturePtr, descriptor) => { + var desc; + if (descriptor) { + var swizzle; + var nextInChainPtr = HEAPU32[((descriptor) >> 2)]; + if (nextInChainPtr !== 0) { + var sType = HEAP32[(((nextInChainPtr) + (4)) >> 2)]; + var swizzleDescriptor = nextInChainPtr; + var swizzlePtr = swizzleDescriptor + 8; + var r = WebGPU.ComponentSwizzle[HEAP32[((swizzlePtr) >> 2)]] || "r"; + var g = WebGPU.ComponentSwizzle[HEAP32[(((swizzlePtr) + (4)) >> 2)]] || "g"; + var b = WebGPU.ComponentSwizzle[HEAP32[(((swizzlePtr) + (8)) >> 2)]] || "b"; + var a = WebGPU.ComponentSwizzle[HEAP32[(((swizzlePtr) + (12)) >> 2)]] || "a"; + swizzle = `${r}${g}${b}${a}`; + } + var mipLevelCount = HEAPU32[(((descriptor) + (24)) >> 2)]; + var arrayLayerCount = HEAPU32[(((descriptor) + (32)) >> 2)]; + desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "format": WebGPU.TextureFormat[HEAP32[(((descriptor) + (12)) >> 2)]], + "dimension": WebGPU.TextureViewDimension[HEAP32[(((descriptor) + (16)) >> 2)]], + "baseMipLevel": HEAPU32[(((descriptor) + (20)) >> 2)], + "mipLevelCount": mipLevelCount === 4294967295 ? undefined : mipLevelCount, + "baseArrayLayer": HEAPU32[(((descriptor) + (28)) >> 2)], + "arrayLayerCount": arrayLayerCount === 4294967295 ? undefined : arrayLayerCount, + "aspect": WebGPU.TextureAspect[HEAP32[(((descriptor) + (36)) >> 2)]], + "usage": HEAPU32[(((descriptor) + (40)) >> 2)], + "swizzle": swizzle + }; + } + var texture = WebGPU.getJsObject(texturePtr); + var ptr = _emwgpuCreateTextureView(0); + WebGPU.Internals.jsObjectInsert(ptr, texture.createView(desc)); + return ptr; +}; + +var _wgpuTextureDestroy = texturePtr => { + WebGPU.getJsObject(texturePtr).destroy(); +}; + +var _wgpuTextureGetFormat = texturePtr => { + var texture = WebGPU.getJsObject(texturePtr); + // Should return the enum integer instead of string. + return WebGPU.TextureFormat.indexOf(texture.format); +}; + +var getCFunc = ident => { + var func = Module["_" + ident]; + // closure exported function + return func; +}; + +var writeArrayToMemory = (array, buffer) => { + HEAP8.set(array, buffer); +}; + +/** + * @param {string|null=} returnType + * @param {Array=} argTypes + * @param {Array=} args + * @param {Object=} opts + */ var ccall = (ident, returnType, argTypes, args, opts) => { + // For fast lookup of conversion functions + var toC = { + "string": str => { + var ret = 0; + if (str !== null && str !== undefined && str !== 0) { + // null string + ret = stringToUTF8OnStack(str); + } + return ret; + }, + "array": arr => { + var ret = stackAlloc(arr.length); + writeArrayToMemory(arr, ret); + return ret; + } + }; + function convertReturnValue(ret) { + if (returnType === "string") { + return UTF8ToString(ret); + } + if (returnType === "boolean") return Boolean(ret); + return ret; + } + var func = getCFunc(ident); + var cArgs = []; + var stack = 0; + if (args) { + for (var i = 0; i < args.length; i++) { + var converter = toC[argTypes[i]]; + if (converter) { + if (stack === 0) stack = stackSave(); + cArgs[i] = converter(args[i]); + } else { + cArgs[i] = args[i]; + } + } + } + var ret = func(...cArgs); + function onDone(ret) { + if (stack !== 0) stackRestore(stack); + return convertReturnValue(ret); + } + ret = onDone(ret); + return ret; +}; + +var FS_createPath = (...args) => FS.createPath(...args); + +var FS_unlink = (...args) => FS.unlink(...args); + +var FS_createLazyFile = (...args) => FS.createLazyFile(...args); + +var FS_createDevice = (...args) => FS.createDevice(...args); + +FS.createPreloadedFile = FS_createPreloadedFile; + +FS.preloadFile = FS_preloadFile; + +FS.staticInit(); + +// Signal GL rendering layer that processing of a new frame is about to +// start. This helps it optimize VBO double-buffering and reduce GPU stalls. +registerPreMainLoop(() => GL.newRenderingFrameStarted()); + +for (let i = 0; i < 32; ++i) tempFixedLengthArray.push(new Array(i)); + +var miniTempWebGLFloatBuffersStorage = new Float32Array(288); + +// Create GL_POOL_TEMP_BUFFERS_SIZE+1 temporary buffers, for uploads of size 0 through GL_POOL_TEMP_BUFFERS_SIZE inclusive +for (/**@suppress{duplicate}*/ var i = 0; i <= 288; ++i) { + miniTempWebGLFloatBuffers[i] = miniTempWebGLFloatBuffersStorage.subarray(0, i); +} + +var miniTempWebGLIntBuffersStorage = new Int32Array(288); + +// Create GL_POOL_TEMP_BUFFERS_SIZE+1 temporary buffers, for uploads of size 0 through GL_POOL_TEMP_BUFFERS_SIZE inclusive +for (/**@suppress{duplicate}*/ var i = 0; i <= 288; ++i) { + miniTempWebGLIntBuffers[i] = miniTempWebGLIntBuffersStorage.subarray(0, i); +} + +// End JS library code +// include: postlibrary.js +// This file is included after the automatically-generated JS library code +// but before the wasm module is created. +{ + // Begin ATMODULES hooks + if (Module["preloadPlugins"]) preloadPlugins = Module["preloadPlugins"]; + if (Module["noExitRuntime"]) noExitRuntime = Module["noExitRuntime"]; + if (Module["print"]) out = Module["print"]; + if (Module["printErr"]) err = Module["printErr"]; + if (Module["wasmBinary"]) wasmBinary = Module["wasmBinary"]; + // End ATMODULES hooks + if (Module["arguments"]) programArgs = Module["arguments"]; + if (Module["thisProgram"]) thisProgram = Module["thisProgram"]; + if (Module["preInit"]) { + if (typeof Module["preInit"] == "function") Module["preInit"] = [ Module["preInit"] ]; + while (Module["preInit"].length > 0) { + Module["preInit"].shift()(); + } + } +} + +// Begin runtime exports +Module["addRunDependency"] = addRunDependency; + +Module["removeRunDependency"] = removeRunDependency; + +Module["ccall"] = ccall; + +Module["stringToNewUTF8"] = stringToNewUTF8; + +Module["FS_preloadFile"] = FS_preloadFile; + +Module["FS_unlink"] = FS_unlink; + +Module["FS_createPath"] = FS_createPath; + +Module["FS_createDevice"] = FS_createDevice; + +Module["FS_createDataFile"] = FS_createDataFile; + +Module["FS_createLazyFile"] = FS_createLazyFile; + +// End runtime exports +// Begin JS library exports +// End JS library exports +// end include: postlibrary.js +var ASM_CONSTS = { + 1516932: $0 => { + const canvas = Emval.toValue($0); + const context = canvas.getContext("webgpu"); + return WebGPU.importJsTexture(context.getCurrentTexture()); + }, + 1517075: ($0, $1, $2, $3, $4) => { + const drawable = Emval.toValue($0); + const device = WebGPU.getJsObject($1); + const texture = WebGPU.getJsObject($2); + const width = $3; + const height = $4; + device.queue.copyExternalImageToTexture({ + source: drawable + }, { + texture + }, [ width, height ]); + }, + 1517334: ($0, $1, $2, $3) => { + const sourceExtTex = Emval.toValue($0); + const device = WebGPU.getJsObject($1); + const sampler = WebGPU.getJsObject($2); + const bgLayout = WebGPU.getJsObject($3); + const bindGroup = device.createBindGroup({ + layout: bgLayout, + entries: [ { + binding: 0, + resource: sampler + }, { + binding: 1, + resource: sourceExtTex + } ] + }); + return WebGPU.importJsBindGroup(bindGroup); + }, + 1517704: ($0, $1) => { + const input = Emval.toValue($0); + const output = Emval.toValue($1); + const ctx = output.getContext("2d"); + ctx.drawImage(input, 0, 0, output.width, output.height); + }, + 1517869: ($0, $1) => { + const inputArray = Emval.toValue($0); + const output = Emval.toValue($1); + const ctx = output.getContext("2d"); + const image_data = new ImageData(inputArray, output.width, output.height); + ctx.putImageData(image_data, 0, 0); + }, + 1518093: ($0, $1) => { + const input = Emval.toValue($0); + const outputArray = Emval.toValue($1); + const ctx = input.getContext("2d"); + const data = ctx.getImageData(0, 0, input.width, input.height); + outputArray.set(data.data); + }, + 1518297: () => (typeof HTMLCanvasElement !== "undefined"), + 1518352: () => !!Module["preinitializedWebGPUDevice"], + 1518403: () => { + specialHTMLTargets["#canvas"] = Module.canvas; + } +}; + +function BeginGlQueryTiming(calc_name, num_repetitions) { + const gl = Module.canvas.getContext("webgl2"); + const query = gl.createQuery(); + Module.WEBGL_SHADER_CALC_METRICS = Module.WEBGL_SHADER_CALC_METRICS || {}; + Module.WEBGL_SHADER_CALC_METRICS[UTF8ToString(calc_name)] = { + query, + repetitions: num_repetitions + }; + Module.WEBGL_QUERY_TIMER_EXT = Module.WEBGL_QUERY_TIMER_EXT || gl.getExtension("EXT_disjoint_timer_query_webgl2"); + gl.beginQuery(Module.WEBGL_QUERY_TIMER_EXT.TIME_ELAPSED_EXT, query); +} + +function EndGlQueryTiming(calc_name) { + const gl = Module.canvas.getContext("webgl2"); + gl.endQuery(Module.WEBGL_QUERY_TIMER_EXT.TIME_ELAPSED_EXT, Module.WEBGL_SHADER_CALC_METRICS[UTF8ToString(calc_name)].query); +} + +function JsWrapImageConverter() { + if (!Module._imageConverter) { + Module._imageConverter = (binaryPtr, binarySize, width, height, numChannels, makeDeepCopy, outputType) => { + const imageData = new outputType(makeDeepCopy ? Module.HEAPU8.slice(binaryPtr, binaryPtr + binarySize).buffer : Module.HEAPU8.buffer, binaryPtr, width * height * numChannels); + return { + data: imageData, + width, + height + }; + }; + } +} + +function JsOnUint8ArrayImageListener(output_stream_name, binary_ptr, binary_size, width, height, num_channels, make_deep_copy, timestamp_ms) { + const image = Module._imageConverter(binary_ptr, binary_size, width, height, num_channels, make_deep_copy, Uint8Array); + Module._wrapSimpleListenerOutput(output_stream_name, image, timestamp_ms); +} + +function JsOnFloat32ArrayImageListener(output_stream_name, binary_ptr, binary_size, width, height, num_channels, make_deep_copy, timestamp_ms) { + const image = Module._imageConverter(binary_ptr, binary_size, width, height, num_channels, make_deep_copy, Float32Array); + Module._wrapSimpleListenerOutput(output_stream_name, image, timestamp_ms); +} + +function JsOnWebGLTextureListener(output_stream_name, name, width, height, timestamp_ms) { + Module._wrapSimpleListenerOutput(output_stream_name, { + data: GL.textures[name], + width, + height + }, timestamp_ms); +} + +function JsOnUint8ArrayImageVectorListener(output_stream_name, binary_ptr, binary_size, width, height, num_channels, make_deep_copy, timestamp_ms) { + const image = Module._imageConverter(binary_ptr, binary_size, width, height, num_channels, make_deep_copy, Uint8Array); + Module._wrapSimpleListenerOutput(output_stream_name, image, false, timestamp_ms); +} + +function JsOnFloat32ArrayImageVectorListener(output_stream_name, binary_ptr, binary_size, width, height, num_channels, make_deep_copy, timestamp_ms) { + const image = Module._imageConverter(binary_ptr, binary_size, width, height, num_channels, make_deep_copy, Float32Array); + Module._wrapSimpleListenerOutput(output_stream_name, image, false, timestamp_ms); +} + +function JsOnWebGLTextureVectorListener(output_stream_name, name, width, height, timestamp_ms) { + Module._wrapSimpleListenerOutput(output_stream_name, { + data: GL.textures[name], + width, + height + }, false, timestamp_ms); +} + +function JsWrapLoggingHelpers() { + if (!Module["_decodeBase64"]) { + Module["_decodeBase64"] = function(encoded_key_ptr) { + const encodedStr = UTF8ToString(encoded_key_ptr); + return atob(encodedStr); + }; + } +} + +function JsOnEmptyPacketListener(output_stream_name, timestamp) { + Module._wrapEmptyPacketListenerOutput(output_stream_name, timestamp); +} + +function JsOnVectorFinishedListener(output_stream_name, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, undefined, true, timestamp); +} + +function JsOnSimpleListenerBool(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, timestamp); +} + +function JsOnVectorListenerBool(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, false, timestamp); +} + +function JsOnSimpleListenerInt(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, timestamp); +} + +function JsOnVectorListenerInt(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, false, timestamp); +} + +function JsOnSimpleListenerUint(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, timestamp); +} + +function JsOnVectorListenerUint(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, false, timestamp); +} + +function JsOnSimpleListenerDouble(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, timestamp); +} + +function JsOnVectorListenerDouble(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, false, timestamp); +} + +function JsOnSimpleListenerFloat(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, timestamp); +} + +function JsOnVectorListenerFloat(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, false, timestamp); +} + +function JsOnSimpleListenerString(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, UTF8ToString(out_data), timestamp); +} + +function JsOnVectorListenerString(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, UTF8ToString(out_data), false, timestamp); +} + +function JsOnVectorListenerProto(output_stream_name, proto_ptr, proto_size, make_deep_copy, timestamp) { + const newProtoArray = make_deep_copy ? Module.HEAPU8.slice(proto_ptr, proto_ptr + proto_size) : new Uint8Array(Module.HEAPU8.buffer, proto_ptr, proto_size); + Module._wrapSimpleListenerOutput(output_stream_name, newProtoArray, false, timestamp); +} + +function JsWrapSimpleListeners() { + if (!Module._wrapSimpleListenerOutput) { + Module._wrapSimpleListenerOutput = (outputStreamName, ...args) => { + if (Module.simpleListeners) { + const streamName = UTF8ToString(outputStreamName); + if (Module.simpleListeners[streamName]) { + Module.simpleListeners[streamName](...args); + } + } + }; + } + if (!Module._wrapEmptyPacketListenerOutput) { + Module._wrapEmptyPacketListenerOutput = (outputStreamName, timestamp) => { + if (Module.emptyPacketListeners) { + const streamName = UTF8ToString(outputStreamName); + if (Module.emptyPacketListeners[streamName]) { + Module.emptyPacketListeners[streamName](timestamp); + } + } + }; + } +} + +function JsOnSimpleListenerBinaryArray(output_stream_name, binary_ptr, binary_size, make_deep_copy, timestamp) { + const newProtoArray = make_deep_copy ? Module.HEAPU8.slice(binary_ptr, binary_ptr + binary_size) : new Uint8Array(Module.HEAPU8.buffer, binary_ptr, binary_size); + Module._wrapSimpleListenerOutput(output_stream_name, newProtoArray, timestamp); +} + +function mediapipe_import_external_texture(device_handle, source_handle) { + const device = WebGPU.getJsObject(device_handle); + const source = Emval.toValue(source_handle); + const externalTexture = device.importExternalTexture({ + source + }); + return Emval.toHandle(externalTexture); +} + +function mediapipe_create_utility_canvas2d() { + let canvas; + if (typeof HTMLCanvasElement !== "undefined") { + canvas = document.createElement("canvas"); + canvas.style.display = "none"; + } else { + canvas = new OffscreenCanvas(0, 0); + } + return Emval.toHandle(canvas); +} + +function GetAdapterArchitecture() { + const device = Module["preinitializedWebGPUDevice"]; + const architecture = device.adapterInfo ? device.adapterInfo.architecture : "Unknown"; + return stringToNewUTF8(architecture); +} + +function GetAdapterDescription() { + const device = Module["preinitializedWebGPUDevice"]; + const description = device.adapterInfo ? device.adapterInfo.description : "Unknown"; + return stringToNewUTF8(description); +} + +function GetAdapterDeviceName() { + const device = Module["preinitializedWebGPUDevice"]; + const deviceName = device.adapterInfo ? device.adapterInfo.device : "Unknown"; + return stringToNewUTF8(deviceName); +} + +function GetAdapterVendor() { + const device = Module["preinitializedWebGPUDevice"]; + const vendor = device.adapterInfo ? device.adapterInfo.vendor : "Unknown"; + return stringToNewUTF8(vendor); +} + +function __asyncjs__mediapipe_map_buffer_jspi(buffer_handle, data) { + return Asyncify.handleAsync(async () => { + const buffer = WebGPU.getJsObject(buffer_handle); + if ("mapSync" in buffer) { + buffer.mapSync(GPUMapMode.READ); + } else { + await buffer.mapAsync(GPUMapMode.READ); + } + const mapped = buffer.getMappedRange(); + HEAPU8.set(new Uint8Array(mapped), data); + buffer.unmap(); + }); +} + +function hardware_concurrency() { + var concurrency = 1; + try { + concurrency = self.navigator.hardwareConcurrency; + } catch (e) {} + return concurrency; +} + +function UseBottomLeftGpuOrigin() { + return (Module && Module.gpuOriginForWebTexturesIsBottomLeft); +} + +function custom_emscripten_dbgn(str, len) { + if (typeof (dbg) !== "undefined") { + dbg(UTF8ToString(str, len)); + } else { + if (typeof (custom_dbg) === "undefined") { + function custom_dbg(text) { + console.warn.apply(console, arguments); + } + } + custom_dbg(UTF8ToString(str, len)); + } +} + +function JsWrapErrorListenerInternal(code, message) { + if (Module.errorListener) { + const stringMessage = UTF8ToString(message); + Module.errorListener(code, stringMessage); + } +} + +// Imports from the Wasm binary. +var _free, _malloc, _interactive_segmenter_create, _interactive_segmenter_set_image, _interactive_segmenter_segment, _interactive_segmenter_close, _wgpuDeviceAddRef, _addBoundTextureAsImageToStream, _attachImageListener, _attachImageVectorListener, _mediapipeLoggerGetEncodedApiKey, _registerModelResourcesGraphService, _bindTextureToStream, _addBoundTextureToStream, _addDoubleToInputStream, _addFloatToInputStream, _addBoolToInputStream, _addIntToInputStream, _addUintToInputStream, _addStringToInputStream, _addRawDataSpanToInputStream, _allocateBoolVector, _allocateFloatVector, _allocateDoubleVector, _allocateIntVector, _allocateUintVector, _allocateStringVector, _addBoolVectorEntry, _addFloatVectorEntry, _addDoubleVectorEntry, _addIntVectorEntry, _addUintVectorEntry, _addStringVectorEntry, _addBoolVectorToInputStream, _addFloatVectorToInputStream, _addDoubleVectorToInputStream, _addIntVectorToInputStream, _addUintVectorToInputStream, _addStringVectorToInputStream, _addFlatHashMapToInputStream, _addProtoToInputStream, _addEmptyPacketToInputStream, _addBoolToInputSidePacket, _addDoubleToInputSidePacket, _addFloatToInputSidePacket, _addIntToInputSidePacket, _addUintToInputSidePacket, _addStringToInputSidePacket, _addRawDataSpanToInputSidePacket, _addProtoToInputSidePacket, _addBoolVectorToInputSidePacket, _addDoubleVectorToInputSidePacket, _addFloatVectorToInputSidePacket, _addIntVectorToInputSidePacket, _addUintVectorToInputSidePacket, _addStringVectorToInputSidePacket, _attachBoolListener, _attachBoolVectorListener, _attachDoubleListener, _attachDoubleVectorListener, _attachFloatListener, _attachFloatVectorListener, _attachIntListener, _attachIntVectorListener, _attachUintListener, _attachUintVectorListener, _attachStringListener, _attachStringVectorListener, _attachProtoListener, _attachProtoVectorListener, _getGraphConfig, ___getTypeName, _emwgpuCreateBindGroup, _emwgpuCreateBindGroupLayout, _emwgpuCreateCommandBuffer, _emwgpuCreateCommandEncoder, _emwgpuCreateComputePassEncoder, _emwgpuCreateComputePipeline, _emwgpuCreateExternalTexture, _emwgpuCreatePipelineLayout, _emwgpuCreateQuerySet, _emwgpuCreateRenderBundle, _emwgpuCreateRenderBundleEncoder, _emwgpuCreateRenderPassEncoder, _emwgpuCreateRenderPipeline, _emwgpuCreateSampler, _emwgpuCreateSurface, _emwgpuCreateTexture, _emwgpuCreateTextureView, _emwgpuCreateAdapter, _emwgpuImportBuffer, _emwgpuCreateDevice, _emwgpuCreateQueue, _emwgpuCreateShaderModule, _emwgpuOnCreateComputePipelineCompleted, _emwgpuOnCreateRenderPipelineCompleted, _clearSubgraphs, _pushBinarySubgraph, _pushTextSubgraph, _changeBinaryGraph, _changeTextGraph, _processGl, _process, _bindTextureToCanvas, _requestShaderRefreshOnGraphChange, _waitUntilIdle, _closeGraph, _setAutoRenderToScreen, _emscripten_builtin_memalign, _memalign, __emscripten_tempret_set, __emscripten_stack_restore, __emscripten_stack_alloc, _emscripten_stack_get_current, dynCall_ji, dynCall_jii, dynCall_iiiijij, dynCall_vij, dynCall_viiji, dynCall_viji, dynCall_iiiji, dynCall_ijj, dynCall_jjj, dynCall_iiiijj, dynCall_viijj, dynCall_viiijjj, dynCall_viijii, dynCall_vijjj, dynCall_vj, dynCall_viij, dynCall_jiji, dynCall_iiiiij, dynCall_iiiiijj, dynCall_iiiiiijj, memory, _kVersionStampBuildChangelistStr, _kVersionStampCitcSnapshotStr, _kVersionStampCitcWorkspaceIdStr, _kVersionStampSourceUriStr, _kVersionStampBuildClientStr, _kVersionStampBuildClientMintStatusStr, _kVersionStampBuildCompilerStr, _kVersionStampBuildDateTimePstStr, _kVersionStampBuildDepotPathStr, _kVersionStampBuildIdStr, _kVersionStampBuildInfoStr, _kVersionStampBuildLabelStr, _kVersionStampBuildTargetStr, _kVersionStampBuildTimestampStr, _kVersionStampBuildToolStr, _kVersionStampG3BuildTargetStr, _kVersionStampVerifiableStr, _kVersionStampBuildFdoTypeStr, _kVersionStampBuildBaselineChangelistStr, _kVersionStampBuildLtoTypeStr, _kVersionStampBuildPropellerTypeStr, _kVersionStampBuildPghoTypeStr, _kVersionStampBuildFdoProfileChangelistStr, _kVersionStampBuildMemprofProfileChangelistStr, _kVersionStampBuildUsernameStr, _kVersionStampBuildHostnameStr, _kVersionStampBuildDirectoryStr, _kVersionStampBuildChangelistInt, _kVersionStampCitcSnapshotInt, _kVersionStampBuildClientMintStatusInt, _kVersionStampBuildTimestampInt, _kVersionStampVerifiableInt, _kVersionStampBuildCoverageEnabledInt, _kVersionStampBuildBaselineChangelistInt, _kVersionStampPrecookedTimestampStr, _kVersionStampPrecookedClientInfoStr, __indirect_function_table, _kVersionStampBuildHasHardeningProtobuf, wasmMemory, wasmTable; + +function assignWasmExports(wasmExports) { + _free = Module["_free"] = wasmExports["Wd"]; + _malloc = Module["_malloc"] = wasmExports["Xd"]; + _interactive_segmenter_create = Module["_interactive_segmenter_create"] = wasmExports["Yd"]; + _interactive_segmenter_set_image = Module["_interactive_segmenter_set_image"] = wasmExports["Zd"]; + _interactive_segmenter_segment = Module["_interactive_segmenter_segment"] = wasmExports["_d"]; + _interactive_segmenter_close = Module["_interactive_segmenter_close"] = wasmExports["$d"]; + _wgpuDeviceAddRef = wasmExports["ae"]; + _addBoundTextureAsImageToStream = Module["_addBoundTextureAsImageToStream"] = wasmExports["be"]; + _attachImageListener = Module["_attachImageListener"] = wasmExports["ce"]; + _attachImageVectorListener = Module["_attachImageVectorListener"] = wasmExports["de"]; + _mediapipeLoggerGetEncodedApiKey = Module["_mediapipeLoggerGetEncodedApiKey"] = wasmExports["ee"]; + _registerModelResourcesGraphService = Module["_registerModelResourcesGraphService"] = wasmExports["fe"]; + _bindTextureToStream = Module["_bindTextureToStream"] = wasmExports["ge"]; + _addBoundTextureToStream = Module["_addBoundTextureToStream"] = wasmExports["he"]; + _addDoubleToInputStream = Module["_addDoubleToInputStream"] = wasmExports["ie"]; + _addFloatToInputStream = Module["_addFloatToInputStream"] = wasmExports["je"]; + _addBoolToInputStream = Module["_addBoolToInputStream"] = wasmExports["ke"]; + _addIntToInputStream = Module["_addIntToInputStream"] = wasmExports["le"]; + _addUintToInputStream = Module["_addUintToInputStream"] = wasmExports["me"]; + _addStringToInputStream = Module["_addStringToInputStream"] = wasmExports["ne"]; + _addRawDataSpanToInputStream = Module["_addRawDataSpanToInputStream"] = wasmExports["oe"]; + _allocateBoolVector = Module["_allocateBoolVector"] = wasmExports["pe"]; + _allocateFloatVector = Module["_allocateFloatVector"] = wasmExports["qe"]; + _allocateDoubleVector = Module["_allocateDoubleVector"] = wasmExports["re"]; + _allocateIntVector = Module["_allocateIntVector"] = wasmExports["se"]; + _allocateUintVector = Module["_allocateUintVector"] = wasmExports["te"]; + _allocateStringVector = Module["_allocateStringVector"] = wasmExports["ue"]; + _addBoolVectorEntry = Module["_addBoolVectorEntry"] = wasmExports["ve"]; + _addFloatVectorEntry = Module["_addFloatVectorEntry"] = wasmExports["we"]; + _addDoubleVectorEntry = Module["_addDoubleVectorEntry"] = wasmExports["xe"]; + _addIntVectorEntry = Module["_addIntVectorEntry"] = wasmExports["ye"]; + _addUintVectorEntry = Module["_addUintVectorEntry"] = wasmExports["ze"]; + _addStringVectorEntry = Module["_addStringVectorEntry"] = wasmExports["Ae"]; + _addBoolVectorToInputStream = Module["_addBoolVectorToInputStream"] = wasmExports["Be"]; + _addFloatVectorToInputStream = Module["_addFloatVectorToInputStream"] = wasmExports["Ce"]; + _addDoubleVectorToInputStream = Module["_addDoubleVectorToInputStream"] = wasmExports["De"]; + _addIntVectorToInputStream = Module["_addIntVectorToInputStream"] = wasmExports["Ee"]; + _addUintVectorToInputStream = Module["_addUintVectorToInputStream"] = wasmExports["Fe"]; + _addStringVectorToInputStream = Module["_addStringVectorToInputStream"] = wasmExports["Ge"]; + _addFlatHashMapToInputStream = Module["_addFlatHashMapToInputStream"] = wasmExports["He"]; + _addProtoToInputStream = Module["_addProtoToInputStream"] = wasmExports["Ie"]; + _addEmptyPacketToInputStream = Module["_addEmptyPacketToInputStream"] = wasmExports["Je"]; + _addBoolToInputSidePacket = Module["_addBoolToInputSidePacket"] = wasmExports["Ke"]; + _addDoubleToInputSidePacket = Module["_addDoubleToInputSidePacket"] = wasmExports["Le"]; + _addFloatToInputSidePacket = Module["_addFloatToInputSidePacket"] = wasmExports["Me"]; + _addIntToInputSidePacket = Module["_addIntToInputSidePacket"] = wasmExports["Ne"]; + _addUintToInputSidePacket = Module["_addUintToInputSidePacket"] = wasmExports["Oe"]; + _addStringToInputSidePacket = Module["_addStringToInputSidePacket"] = wasmExports["Pe"]; + _addRawDataSpanToInputSidePacket = Module["_addRawDataSpanToInputSidePacket"] = wasmExports["Qe"]; + _addProtoToInputSidePacket = Module["_addProtoToInputSidePacket"] = wasmExports["Re"]; + _addBoolVectorToInputSidePacket = Module["_addBoolVectorToInputSidePacket"] = wasmExports["Se"]; + _addDoubleVectorToInputSidePacket = Module["_addDoubleVectorToInputSidePacket"] = wasmExports["Te"]; + _addFloatVectorToInputSidePacket = Module["_addFloatVectorToInputSidePacket"] = wasmExports["Ue"]; + _addIntVectorToInputSidePacket = Module["_addIntVectorToInputSidePacket"] = wasmExports["Ve"]; + _addUintVectorToInputSidePacket = Module["_addUintVectorToInputSidePacket"] = wasmExports["We"]; + _addStringVectorToInputSidePacket = Module["_addStringVectorToInputSidePacket"] = wasmExports["Xe"]; + _attachBoolListener = Module["_attachBoolListener"] = wasmExports["Ye"]; + _attachBoolVectorListener = Module["_attachBoolVectorListener"] = wasmExports["Ze"]; + _attachDoubleListener = Module["_attachDoubleListener"] = wasmExports["_e"]; + _attachDoubleVectorListener = Module["_attachDoubleVectorListener"] = wasmExports["$e"]; + _attachFloatListener = Module["_attachFloatListener"] = wasmExports["af"]; + _attachFloatVectorListener = Module["_attachFloatVectorListener"] = wasmExports["bf"]; + _attachIntListener = Module["_attachIntListener"] = wasmExports["cf"]; + _attachIntVectorListener = Module["_attachIntVectorListener"] = wasmExports["df"]; + _attachUintListener = Module["_attachUintListener"] = wasmExports["ef"]; + _attachUintVectorListener = Module["_attachUintVectorListener"] = wasmExports["ff"]; + _attachStringListener = Module["_attachStringListener"] = wasmExports["gf"]; + _attachStringVectorListener = Module["_attachStringVectorListener"] = wasmExports["hf"]; + _attachProtoListener = Module["_attachProtoListener"] = wasmExports["jf"]; + _attachProtoVectorListener = Module["_attachProtoVectorListener"] = wasmExports["kf"]; + _getGraphConfig = Module["_getGraphConfig"] = wasmExports["lf"]; + ___getTypeName = wasmExports["mf"]; + _emwgpuCreateBindGroup = wasmExports["nf"]; + _emwgpuCreateBindGroupLayout = wasmExports["of"]; + _emwgpuCreateCommandBuffer = wasmExports["pf"]; + _emwgpuCreateCommandEncoder = wasmExports["qf"]; + _emwgpuCreateComputePassEncoder = wasmExports["rf"]; + _emwgpuCreateComputePipeline = wasmExports["sf"]; + _emwgpuCreateExternalTexture = wasmExports["tf"]; + _emwgpuCreatePipelineLayout = wasmExports["uf"]; + _emwgpuCreateQuerySet = wasmExports["vf"]; + _emwgpuCreateRenderBundle = wasmExports["wf"]; + _emwgpuCreateRenderBundleEncoder = wasmExports["xf"]; + _emwgpuCreateRenderPassEncoder = wasmExports["yf"]; + _emwgpuCreateRenderPipeline = wasmExports["zf"]; + _emwgpuCreateSampler = wasmExports["Af"]; + _emwgpuCreateSurface = wasmExports["Bf"]; + _emwgpuCreateTexture = wasmExports["Cf"]; + _emwgpuCreateTextureView = wasmExports["Df"]; + _emwgpuCreateAdapter = wasmExports["Ef"]; + _emwgpuImportBuffer = wasmExports["Ff"]; + _emwgpuCreateDevice = wasmExports["Gf"]; + _emwgpuCreateQueue = wasmExports["Hf"]; + _emwgpuCreateShaderModule = wasmExports["If"]; + _emwgpuOnCreateComputePipelineCompleted = wasmExports["Jf"]; + _emwgpuOnCreateRenderPipelineCompleted = wasmExports["Kf"]; + _clearSubgraphs = Module["_clearSubgraphs"] = wasmExports["Lf"]; + _pushBinarySubgraph = Module["_pushBinarySubgraph"] = wasmExports["Mf"]; + _pushTextSubgraph = Module["_pushTextSubgraph"] = wasmExports["Nf"]; + _changeBinaryGraph = Module["_changeBinaryGraph"] = wasmExports["Of"]; + _changeTextGraph = Module["_changeTextGraph"] = wasmExports["Pf"]; + _processGl = Module["_processGl"] = wasmExports["Qf"]; + _process = Module["_process"] = wasmExports["Rf"]; + _bindTextureToCanvas = Module["_bindTextureToCanvas"] = wasmExports["Sf"]; + _requestShaderRefreshOnGraphChange = Module["_requestShaderRefreshOnGraphChange"] = wasmExports["Tf"]; + _waitUntilIdle = Module["_waitUntilIdle"] = wasmExports["Uf"]; + _closeGraph = Module["_closeGraph"] = wasmExports["Vf"]; + _setAutoRenderToScreen = Module["_setAutoRenderToScreen"] = wasmExports["Wf"]; + _emscripten_builtin_memalign = wasmExports["Yf"]; + _memalign = wasmExports["Zf"]; + __emscripten_tempret_set = wasmExports["_f"]; + __emscripten_stack_restore = wasmExports["$f"]; + __emscripten_stack_alloc = wasmExports["ag"]; + _emscripten_stack_get_current = wasmExports["bg"]; + dynCall_ji = wasmExports["dynCall_ji"]; + dynCall_jii = wasmExports["dynCall_jii"]; + dynCall_iiiijij = wasmExports["dynCall_iiiijij"]; + dynCall_vij = wasmExports["dynCall_vij"]; + dynCall_viiji = wasmExports["dynCall_viiji"]; + dynCall_viji = wasmExports["dynCall_viji"]; + dynCall_iiiji = wasmExports["dynCall_iiiji"]; + dynCall_ijj = wasmExports["dynCall_ijj"]; + dynCall_jjj = wasmExports["dynCall_jjj"]; + dynCall_iiiijj = wasmExports["dynCall_iiiijj"]; + dynCall_viijj = wasmExports["dynCall_viijj"]; + dynCall_viiijjj = wasmExports["dynCall_viiijjj"]; + dynCall_viijii = wasmExports["dynCall_viijii"]; + dynCall_vijjj = wasmExports["dynCall_vijjj"]; + dynCall_vj = wasmExports["dynCall_vj"]; + dynCall_viij = wasmExports["dynCall_viij"]; + dynCall_jiji = wasmExports["dynCall_jiji"]; + dynCall_iiiiij = wasmExports["dynCall_iiiiij"]; + dynCall_iiiiijj = wasmExports["dynCall_iiiiijj"]; + dynCall_iiiiiijj = wasmExports["dynCall_iiiiiijj"]; + memory = wasmMemory = wasmExports["jd"]; + _kVersionStampBuildChangelistStr = Module["_kVersionStampBuildChangelistStr"] = wasmExports["ld"].value; + _kVersionStampCitcSnapshotStr = Module["_kVersionStampCitcSnapshotStr"] = wasmExports["md"].value; + _kVersionStampCitcWorkspaceIdStr = Module["_kVersionStampCitcWorkspaceIdStr"] = wasmExports["nd"].value; + _kVersionStampSourceUriStr = Module["_kVersionStampSourceUriStr"] = wasmExports["od"].value; + _kVersionStampBuildClientStr = Module["_kVersionStampBuildClientStr"] = wasmExports["pd"].value; + _kVersionStampBuildClientMintStatusStr = Module["_kVersionStampBuildClientMintStatusStr"] = wasmExports["qd"].value; + _kVersionStampBuildCompilerStr = Module["_kVersionStampBuildCompilerStr"] = wasmExports["rd"].value; + _kVersionStampBuildDateTimePstStr = Module["_kVersionStampBuildDateTimePstStr"] = wasmExports["sd"].value; + _kVersionStampBuildDepotPathStr = Module["_kVersionStampBuildDepotPathStr"] = wasmExports["td"].value; + _kVersionStampBuildIdStr = Module["_kVersionStampBuildIdStr"] = wasmExports["ud"].value; + _kVersionStampBuildInfoStr = Module["_kVersionStampBuildInfoStr"] = wasmExports["vd"].value; + _kVersionStampBuildLabelStr = Module["_kVersionStampBuildLabelStr"] = wasmExports["wd"].value; + _kVersionStampBuildTargetStr = Module["_kVersionStampBuildTargetStr"] = wasmExports["xd"].value; + _kVersionStampBuildTimestampStr = Module["_kVersionStampBuildTimestampStr"] = wasmExports["yd"].value; + _kVersionStampBuildToolStr = Module["_kVersionStampBuildToolStr"] = wasmExports["zd"].value; + _kVersionStampG3BuildTargetStr = Module["_kVersionStampG3BuildTargetStr"] = wasmExports["Ad"].value; + _kVersionStampVerifiableStr = Module["_kVersionStampVerifiableStr"] = wasmExports["Bd"].value; + _kVersionStampBuildFdoTypeStr = Module["_kVersionStampBuildFdoTypeStr"] = wasmExports["Cd"].value; + _kVersionStampBuildBaselineChangelistStr = Module["_kVersionStampBuildBaselineChangelistStr"] = wasmExports["Dd"].value; + _kVersionStampBuildLtoTypeStr = Module["_kVersionStampBuildLtoTypeStr"] = wasmExports["Ed"].value; + _kVersionStampBuildPropellerTypeStr = Module["_kVersionStampBuildPropellerTypeStr"] = wasmExports["Fd"].value; + _kVersionStampBuildPghoTypeStr = Module["_kVersionStampBuildPghoTypeStr"] = wasmExports["Gd"].value; + _kVersionStampBuildFdoProfileChangelistStr = Module["_kVersionStampBuildFdoProfileChangelistStr"] = wasmExports["Hd"].value; + _kVersionStampBuildMemprofProfileChangelistStr = Module["_kVersionStampBuildMemprofProfileChangelistStr"] = wasmExports["Id"].value; + _kVersionStampBuildUsernameStr = Module["_kVersionStampBuildUsernameStr"] = wasmExports["Jd"].value; + _kVersionStampBuildHostnameStr = Module["_kVersionStampBuildHostnameStr"] = wasmExports["Kd"].value; + _kVersionStampBuildDirectoryStr = Module["_kVersionStampBuildDirectoryStr"] = wasmExports["Ld"].value; + _kVersionStampBuildChangelistInt = Module["_kVersionStampBuildChangelistInt"] = wasmExports["Md"].value; + _kVersionStampCitcSnapshotInt = Module["_kVersionStampCitcSnapshotInt"] = wasmExports["Nd"].value; + _kVersionStampBuildClientMintStatusInt = Module["_kVersionStampBuildClientMintStatusInt"] = wasmExports["Od"].value; + _kVersionStampBuildTimestampInt = Module["_kVersionStampBuildTimestampInt"] = wasmExports["Pd"].value; + _kVersionStampVerifiableInt = Module["_kVersionStampVerifiableInt"] = wasmExports["Qd"].value; + _kVersionStampBuildCoverageEnabledInt = Module["_kVersionStampBuildCoverageEnabledInt"] = wasmExports["Rd"].value; + _kVersionStampBuildBaselineChangelistInt = Module["_kVersionStampBuildBaselineChangelistInt"] = wasmExports["Sd"].value; + _kVersionStampPrecookedTimestampStr = Module["_kVersionStampPrecookedTimestampStr"] = wasmExports["Td"].value; + _kVersionStampPrecookedClientInfoStr = Module["_kVersionStampPrecookedClientInfoStr"] = wasmExports["Ud"].value; + __indirect_function_table = wasmTable = wasmExports["Vd"]; + _kVersionStampBuildHasHardeningProtobuf = Module["_kVersionStampBuildHasHardeningProtobuf"] = wasmExports["Xf"].value; +} + +var wasmImports = { + /** @export */ id: BeginGlQueryTiming, + /** @export */ hd: EndGlQueryTiming, + /** @export */ gd: GetAdapterArchitecture, + /** @export */ fd: GetAdapterDescription, + /** @export */ ed: GetAdapterDeviceName, + /** @export */ dd: GetAdapterVendor, + /** @export */ cd: JsOnEmptyPacketListener, + /** @export */ bd: JsOnFloat32ArrayImageListener, + /** @export */ ad: JsOnFloat32ArrayImageVectorListener, + /** @export */ ob: JsOnSimpleListenerBinaryArray, + /** @export */ $c: JsOnSimpleListenerBool, + /** @export */ _c: JsOnSimpleListenerDouble, + /** @export */ Zc: JsOnSimpleListenerFloat, + /** @export */ Yc: JsOnSimpleListenerInt, + /** @export */ Xc: JsOnSimpleListenerString, + /** @export */ Wc: JsOnSimpleListenerUint, + /** @export */ Vc: JsOnUint8ArrayImageListener, + /** @export */ Uc: JsOnUint8ArrayImageVectorListener, + /** @export */ Q: JsOnVectorFinishedListener, + /** @export */ Tc: JsOnVectorListenerBool, + /** @export */ Sc: JsOnVectorListenerDouble, + /** @export */ Rc: JsOnVectorListenerFloat, + /** @export */ Qc: JsOnVectorListenerInt, + /** @export */ Pc: JsOnVectorListenerProto, + /** @export */ Oc: JsOnVectorListenerString, + /** @export */ Nc: JsOnVectorListenerUint, + /** @export */ Mc: JsOnWebGLTextureListener, + /** @export */ Lc: JsOnWebGLTextureVectorListener, + /** @export */ Kc: JsWrapErrorListenerInternal, + /** @export */ nb: JsWrapImageConverter, + /** @export */ Jc: JsWrapLoggingHelpers, + /** @export */ v: JsWrapSimpleListeners, + /** @export */ mb: UseBottomLeftGpuOrigin, + /** @export */ xb: __asyncjs__mediapipe_map_buffer_jspi, + /** @export */ u: ___cxa_throw, + /** @export */ Ic: ___syscall_dup, + /** @export */ Hc: ___syscall_faccessat, + /** @export */ lb: ___syscall_fcntl64, + /** @export */ Gc: ___syscall_fstat64, + /** @export */ Lb: ___syscall_ftruncate64, + /** @export */ Fc: ___syscall_ioctl, + /** @export */ Ec: ___syscall_lstat64, + /** @export */ Dc: ___syscall_newfstatat, + /** @export */ kb: ___syscall_openat, + /** @export */ Cc: ___syscall_stat64, + /** @export */ xc: __abort_js, + /** @export */ Ib: __embind_register_bigint, + /** @export */ wc: __embind_register_bool, + /** @export */ vc: __embind_register_emval, + /** @export */ ib: __embind_register_float, + /** @export */ J: __embind_register_integer, + /** @export */ q: __embind_register_memory_view, + /** @export */ uc: __embind_register_std_string, + /** @export */ Ma: __embind_register_std_wstring, + /** @export */ tc: __embind_register_void, + /** @export */ aa: __emval_create_invoker, + /** @export */ p: __emval_decref, + /** @export */ La: __emval_get_global, + /** @export */ hb: __emval_get_property, + /** @export */ ja: __emval_incref, + /** @export */ Ka: __emval_instanceof, + /** @export */ $: __emval_invoke, + /** @export */ ua: __emval_new_cstring, + /** @export */ _: __emval_run_destructors, + /** @export */ gb: __emval_set_property, + /** @export */ sc: __emval_typeof, + /** @export */ Hb: __gmtime_js, + /** @export */ Gb: __localtime_js, + /** @export */ Fb: __mktime_js, + /** @export */ Eb: __mmap_js, + /** @export */ Db: __munmap_js, + /** @export */ rc: __tzset_js, + /** @export */ Kb: _clock_time_get, + /** @export */ qc: custom_emscripten_dbgn, + /** @export */ Z: _emscripten_asm_const_int, + /** @export */ fb: _emscripten_asm_const_ptr, + /** @export */ Ja: _emscripten_errn, + /** @export */ pc: _emscripten_get_heap_max, + /** @export */ y: _emscripten_get_now, + /** @export */ S: _emscripten_has_asyncify, + /** @export */ oc: _emscripten_outn, + /** @export */ nc: _emscripten_pc_get_function, + /** @export */ mc: _emscripten_resize_heap, + /** @export */ eb: _emscripten_stack_snapshot, + /** @export */ lc: _emscripten_stack_unwind_buffer, + /** @export */ kc: _emscripten_webgl_create_context, + /** @export */ jc: _emscripten_webgl_destroy_context, + /** @export */ ic: _emscripten_webgl_get_context_attributes, + /** @export */ ia: _emscripten_webgl_get_current_context, + /** @export */ hc: _emscripten_webgl_make_context_current, + /** @export */ P: _emscripten_webgpu_get_device, + /** @export */ gc: _emwgpuBufferDestroy, + /** @export */ fc: _emwgpuBufferGetMappedRange, + /** @export */ ec: _emwgpuBufferUnmap, + /** @export */ t: _emwgpuDelete, + /** @export */ dc: _emwgpuDeviceCreateBuffer, + /** @export */ Cb: _emwgpuDeviceCreateComputePipelineAsync, + /** @export */ Bb: _emwgpuDeviceCreateRenderPipelineAsync, + /** @export */ cc: _emwgpuDeviceCreateShaderModule, + /** @export */ bc: _emwgpuDeviceDestroy, + /** @export */ ac: _emwgpuWaitAny, + /** @export */ Bc: _environ_get, + /** @export */ Ac: _environ_sizes_get, + /** @export */ db: _exit, + /** @export */ Oa: _fd_close, + /** @export */ jb: _fd_read, + /** @export */ Jb: _fd_seek, + /** @export */ Na: _fd_write, + /** @export */ b: _glActiveTexture, + /** @export */ ta: _glAttachShader, + /** @export */ $b: _glBindAttribLocation, + /** @export */ c: _glBindBuffer, + /** @export */ cb: _glBindBufferBase, + /** @export */ s: _glBindFramebuffer, + /** @export */ a: _glBindTexture, + /** @export */ m: _glBindVertexArray, + /** @export */ bb: _glBlendEquation, + /** @export */ _b: _glBlendFunc, + /** @export */ j: _glBufferData, + /** @export */ I: _glClear, + /** @export */ H: _glClearColor, + /** @export */ ea: _glClientWaitSync, + /** @export */ ha: _glColorMask, + /** @export */ ab: _glCompileShader, + /** @export */ $a: _glCreateProgram, + /** @export */ _a: _glCreateShader, + /** @export */ o: _glDeleteBuffers, + /** @export */ R: _glDeleteFramebuffers, + /** @export */ h: _glDeleteProgram, + /** @export */ sa: _glDeleteShader, + /** @export */ ra: _glDeleteSync, + /** @export */ D: _glDeleteTextures, + /** @export */ A: _glDeleteVertexArrays, + /** @export */ Za: _glDetachShader, + /** @export */ G: _glDisable, + /** @export */ n: _glDisableVertexAttribArray, + /** @export */ i: _glDrawArrays, + /** @export */ ga: _glDrawBuffers, + /** @export */ Zb: _glEnable, + /** @export */ l: _glEnableVertexAttribArray, + /** @export */ Ya: _glFenceSync, + /** @export */ qa: _glFinish, + /** @export */ w: _glFlush, + /** @export */ C: _glFramebufferTexture2D, + /** @export */ Xa: _glFramebufferTextureLayer, + /** @export */ r: _glGenBuffers, + /** @export */ Y: _glGenFramebuffers, + /** @export */ F: _glGenTextures, + /** @export */ B: _glGenVertexArrays, + /** @export */ Wa: _glGetAttribLocation, + /** @export */ fa: _glGetError, + /** @export */ Yb: _glGetFloatv, + /** @export */ x: _glGetIntegerv, + /** @export */ Xb: _glGetProgramiv, + /** @export */ Wb: _glGetShaderInfoLog, + /** @export */ Vb: _glGetShaderiv, + /** @export */ O: _glGetString, + /** @export */ Ub: _glGetUniformBlockIndex, + /** @export */ d: _glGetUniformLocation, + /** @export */ Tb: _glLineWidth, + /** @export */ Va: _glLinkProgram, + /** @export */ pa: _glPixelStorei, + /** @export */ oa: _glReadPixels, + /** @export */ Ua: _glShaderSource, + /** @export */ E: _glTexImage2D, + /** @export */ na: _glTexParameterf, + /** @export */ Ta: _glTexParameterfv, + /** @export */ f: _glTexParameteri, + /** @export */ ma: _glTexStorage2D, + /** @export */ Sb: _glTexStorage3D, + /** @export */ X: _glTexSubImage2D, + /** @export */ Rb: _glTexSubImage3D, + /** @export */ N: _glUniform1f, + /** @export */ la: _glUniform1fv, + /** @export */ e: _glUniform1i, + /** @export */ W: _glUniform2f, + /** @export */ Qb: _glUniform2fv, + /** @export */ Ia: _glUniform3f, + /** @export */ Sa: _glUniform4f, + /** @export */ V: _glUniform4fv, + /** @export */ Pb: _glUniform4iv, + /** @export */ Ob: _glUniformBlockBinding, + /** @export */ Nb: _glUniformMatrix2fv, + /** @export */ Mb: _glUniformMatrix3fv, + /** @export */ Ha: _glUniformMatrix4fv, + /** @export */ g: _glUseProgram, + /** @export */ k: _glVertexAttribPointer, + /** @export */ U: _glViewport, + /** @export */ Ga: hardware_concurrency, + /** @export */ Ab: mediapipe_create_utility_canvas2d, + /** @export */ zb: _mediapipe_find_canvas_event_target, + /** @export */ yb: mediapipe_import_external_texture, + /** @export */ wb: _mediapipe_webgl_tex_image_drawable, + /** @export */ zc: _proc_exit, + /** @export */ yc: _random_get, + /** @export */ Fa: _wgpuCommandEncoderBeginComputePass, + /** @export */ Ea: _wgpuCommandEncoderBeginRenderPass, + /** @export */ vb: _wgpuCommandEncoderCopyBufferToTexture, + /** @export */ ub: _wgpuCommandEncoderCopyTextureToBuffer, + /** @export */ tb: _wgpuCommandEncoderCopyTextureToTexture, + /** @export */ M: _wgpuCommandEncoderFinish, + /** @export */ Da: _wgpuComputePassEncoderDispatchWorkgroups, + /** @export */ Ca: _wgpuComputePassEncoderEnd, + /** @export */ Ba: _wgpuComputePassEncoderSetBindGroup, + /** @export */ Aa: _wgpuComputePassEncoderSetPipeline, + /** @export */ za: _wgpuComputePipelineGetBindGroupLayout, + /** @export */ da: _wgpuDeviceCreateBindGroup, + /** @export */ sb: _wgpuDeviceCreateBindGroupLayout, + /** @export */ L: _wgpuDeviceCreateCommandEncoder, + /** @export */ rb: _wgpuDeviceCreateComputePipeline, + /** @export */ qb: _wgpuDeviceCreatePipelineLayout, + /** @export */ Ra: _wgpuDeviceCreateRenderPipeline, + /** @export */ T: _wgpuDeviceCreateSampler, + /** @export */ ca: _wgpuDeviceCreateTexture, + /** @export */ K: _wgpuQueueSubmit, + /** @export */ ka: _wgpuQueueWriteBuffer, + /** @export */ pb: _wgpuQueueWriteTexture, + /** @export */ ya: _wgpuRenderPassEncoderDraw, + /** @export */ xa: _wgpuRenderPassEncoderEnd, + /** @export */ wa: _wgpuRenderPassEncoderSetBindGroup, + /** @export */ va: _wgpuRenderPassEncoderSetPipeline, + /** @export */ Qa: _wgpuRenderPipelineGetBindGroupLayout, + /** @export */ z: _wgpuTextureCreateView, + /** @export */ Pa: _wgpuTextureDestroy, + /** @export */ ba: _wgpuTextureGetFormat +}; + +// include: postamble.js +// === Auto-generated postamble setup entry stuff === +async function run() { + if (runDependencies > 0) { + await new Promise(resolve => dependenciesFulfilled = resolve); + } + preRun(); + // a preRun added a dependency, run will be called later + if (runDependencies > 0) { + await new Promise(resolve => dependenciesFulfilled = resolve); + } + function doRun() { + // run may have just been called through dependencies being fulfilled just in this very frame, + // or while the async setStatus time below was happening + Module["calledRun"] = true; + if (ABORT) return; + initRuntime(); + Module["onRuntimeInitialized"]?.(); + postRun(); + } + if (Module["setStatus"]) { + Module["setStatus"]("Running..."); + // Yield the main thread to allow the browser to paint "Running...", then clear + // the status text after the synchronous doRun() completes. + await new Promise(resolve => { + setTimeout(() => { + setTimeout(() => Module["setStatus"](""), 1); + doRun(); + resolve(); + }, 1); + }); + } else { + doRun(); + } +} + +var wasmExports; + +// In modularize mode the generated code is within a factory function so we +// can use await here (since it's not top-level-await). +wasmExports = await createWasm(); + +await run(); + + + return Module; + }; +})(); + +// Export using a UMD style export, or ES6 exports if selected +if (typeof exports === 'object' && typeof module === 'object') { + module.exports = ModuleFactory; + // This default export looks redundant, but it allows TS to import this + // commonjs style module. + module.exports.default = ModuleFactory; +} else if (typeof define === 'function' && define['amd']) + define([], () => ModuleFactory); diff --git a/frontend/public/mediapipe/wasm/vision_wasm_internal.wasm b/frontend/public/mediapipe/wasm/vision_wasm_internal.wasm new file mode 100644 index 0000000..831b0c5 Binary files /dev/null and b/frontend/public/mediapipe/wasm/vision_wasm_internal.wasm differ diff --git a/frontend/public/mediapipe/wasm/vision_wasm_nosimd_internal.js b/frontend/public/mediapipe/wasm/vision_wasm_nosimd_internal.js new file mode 100644 index 0000000..4818d16 --- /dev/null +++ b/frontend/public/mediapipe/wasm/vision_wasm_nosimd_internal.js @@ -0,0 +1,8831 @@ +// This code implements the `-sMODULARIZE` settings by taking the generated +// JS program code (INNER_JS_CODE) and wrapping it in a factory function. + +// Single threaded MINIMAL_RUNTIME programs do not need access to +// document.currentScript, so a simple export declaration is enough. +var ModuleFactory = (() => { + // When MODULARIZE this JS may be executed later, + // after document.currentScript is gone, so we save it. + // In EXPORT_ES6 mode we can just use 'import.meta.url'. + var _scriptName = globalThis.document?.currentScript?.src; + return async function(moduleArg = {}) { + var Module = moduleArg; +// include: shell.js +// include: minimum_runtime_check.js +// end include: minimum_runtime_check.js +// The Module object: Our interface to the outside world. We import +// and export values on it. There are various ways Module can be used: +// 1. Not defined. We create it here +// 2. A function parameter, function(moduleArg) => Promise +// 3. pre-run appended it, var Module = {}; ..generated code.. +// 4. External script tag defines var Module. +// We need to check if Module already exists (e.g. case 3 above). +// Substitution will be replaced with actual code on later stage of the build, +// this way Closure Compiler will not mangle it (e.g. case 4. above). +// Note that if you want to run closure, and also to use Module +// after the generated code, you will need to define var Module = {}; +// before the code. Then that object will be used in the code, and you +// can continue to use Module afterwards as well. +// Determine the runtime environment we are in. You can customize this by +// setting the ENVIRONMENT setting at compile time (see settings.js). +// Attempt to auto-detect the environment +var ENVIRONMENT_IS_WEB = !!globalThis.window; + +var ENVIRONMENT_IS_WORKER = !!globalThis.WorkerGlobalScope; + +// N.b. Electron.js environment is simultaneously a NODE-environment, but +// also a web environment. +var ENVIRONMENT_IS_NODE = globalThis.process?.versions?.node && globalThis.process?.type != "renderer"; + +// --pre-jses are emitted after the Module integration code, so that they can +// refer to Module (if they choose; they can also define Module) +var programArgs = []; + +var thisProgram = "./this.program"; + +var quit_ = (status, toThrow) => { + throw toThrow; +}; + +if (typeof __filename != "undefined") { + // Node + _scriptName = __filename; +} else if (ENVIRONMENT_IS_WORKER) { + _scriptName = self.location.href; +} + +// `/` should be present at the end if `scriptDirectory` is not empty +var scriptDirectory = ""; + +function locateFile(path) { + if (Module["locateFile"]) { + return Module["locateFile"](path, scriptDirectory); + } + return scriptDirectory + path; +} + +// Hooks that are implemented differently in different runtime environments. +var readAsync, readBinary; + +if (ENVIRONMENT_IS_NODE) { + // These modules will usually be used on Node.js. Load them eagerly to avoid + // the complexity of lazy-loading. + var fs = require("node:fs"); + scriptDirectory = __dirname + "/"; + // include: node_shell_read.js + readBinary = filename => { + // We need to re-wrap `file://` strings to URLs. + filename = isFileURI(filename) ? new URL(filename) : filename; + var ret = fs.readFileSync(filename); + return ret; + }; + readAsync = async (filename, binary = true) => { + // See the comment in the `readBinary` function. + filename = isFileURI(filename) ? new URL(filename) : filename; + var ret = fs.readFileSync(filename, binary ? undefined : "utf8"); + return ret; + }; + // end include: node_shell_read.js + if (process.argv.length > 1) { + thisProgram = process.argv[1].replace(/\\/g, "/"); + } + programArgs = process.argv.slice(2); + quit_ = (status, toThrow) => { + process.exitCode = status; + throw toThrow; + }; +} else // Note that this includes Node.js workers when relevant (pthreads is enabled). +// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and +// ENVIRONMENT_IS_NODE. +if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { + try { + scriptDirectory = new URL(".", _scriptName).href; + } catch {} + { + // include: web_or_worker_shell_read.js + if (ENVIRONMENT_IS_WORKER) { + readBinary = url => { + var xhr = new XMLHttpRequest; + xhr.open("GET", url, false); + xhr.responseType = "arraybuffer"; + xhr.send(null); + return new Uint8Array(/** @type{!ArrayBuffer} */ (xhr.response)); + }; + } + readAsync = async url => { + // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url. + // See https://github.com/github/fetch/pull/92#issuecomment-140665932 + // Cordova or Electron apps are typically loaded from a file:// url. + // So use XHR on webview if URL is a file URL. + if (isFileURI(url)) { + return new Promise((resolve, reject) => { + var xhr = new XMLHttpRequest; + xhr.open("GET", url, true); + xhr.responseType = "arraybuffer"; + xhr.onload = () => { + if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { + // file URLs can return 0 + resolve(xhr.response); + return; + } + reject(xhr.status); + }; + xhr.onerror = reject; + xhr.send(null); + }); + } + var response = await fetch(url, { + credentials: "same-origin" + }); + if (response.ok) { + return response.arrayBuffer(); + } + throw new Error(response.status + " : " + response.url); + }; + } +} else {} + +var out = console.log.bind(console); + +var err = console.error.bind(console); + +// end include: shell.js +// include: preamble.js +// === Preamble library stuff === +// Documentation for the public APIs defined in this file must be updated in: +// site/source/docs/api_reference/preamble.js.rst +// A prebuilt local version of the documentation is available at: +// site/build/text/docs/api_reference/preamble.js.txt +// You can also build docs locally as HTML or other formats in site/ +// An online HTML version (which may be of a different version of Emscripten) +// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html +var wasmBinary; + +// Wasm globals +//======================================== +// Runtime essentials +//======================================== +// whether we are quitting the application. no code should run after this. +// set in exit() and abort() +var ABORT = false; + +// set by exit() and abort(). Passed to 'onExit' handler. +// NOTE: This is also used as the process return code in shell environments +// but only when noExitRuntime is false. +var EXITSTATUS; + +// In STRICT mode, we only define assert() when ASSERTIONS is set. i.e. we +// don't define it at all in release modes. This matches the behaviour of +// MINIMAL_RUNTIME. +// TODO(sbc): Make this the default even without STRICT enabled. +/** @type {function(*, string=)} */ function assert(condition, text) { + if (!condition) { + // This build was created without ASSERTIONS defined. `assert()` should not + // ever be called in this configuration but in case there are callers in + // the wild leave this simple abort() implementation here for now. + abort(text); + } +} + +/** + * Indicates whether filename is delivered via file protocol (as opposed to http/https) + * @noinline + */ var isFileURI = filename => filename.startsWith("file://"); + +// include: runtime_common.js +// include: runtime_stack_check.js +// end include: runtime_stack_check.js +// include: runtime_exceptions.js +// Base Emscripten EH error class +class EmscriptenEH {} + +class EmscriptenSjLj extends EmscriptenEH {} + +// end include: runtime_exceptions.js +// include: runtime_debug.js +// end include: runtime_debug.js +// Memory management +var runtimeInitialized = false; + +function updateMemoryViews() { + var b = wasmMemory.buffer; + HEAP8 = new Int8Array(b); + HEAP16 = new Int16Array(b); + Module["HEAPU8"] = HEAPU8 = new Uint8Array(b); + HEAPU16 = new Uint16Array(b); + HEAP32 = new Int32Array(b); + Module["HEAPU32"] = HEAPU32 = new Uint32Array(b); + Module["HEAPF32"] = HEAPF32 = new Float32Array(b); + Module["HEAPF64"] = HEAPF64 = new Float64Array(b); +} + +// include: memoryprofiler.js +// end include: memoryprofiler.js +// end include: runtime_common.js +function preRun() { + if (Module["preRun"]) { + if (typeof Module["preRun"] == "function") Module["preRun"] = [ Module["preRun"] ]; + while (Module["preRun"].length) { + addOnPreRun(Module["preRun"].shift()); + } + } + // Begin ATPRERUNS hooks + callRuntimeCallbacks(onPreRuns); +} + +function initRuntime() { + runtimeInitialized = true; + // Begin ATINITS hooks + if (!Module["noFSInit"] && !FS.initialized) FS.init(); + TTY.init(); + // End ATINITS hooks + wasmExports["jd"](); + // Begin ATPOSTCTORS hooks + FS.ignorePermissions = false; +} + +function postRun() { + // PThreads reuse the runtime from the main thread. + if (Module["postRun"]) { + if (typeof Module["postRun"] == "function") Module["postRun"] = [ Module["postRun"] ]; + while (Module["postRun"].length) { + addOnPostRun(Module["postRun"].shift()); + } + } + // Begin ATPOSTRUNS hooks + callRuntimeCallbacks(onPostRuns); +} + +/** + * @param {string|number=} what + */ function abort(what) { + Module["onAbort"]?.(what); + what = `Aborted(${what})`; + // TODO(sbc): Should we remove printing and leave it up to whoever + // catches the exception? + err(what); + ABORT = true; + what += ". Build with -sASSERTIONS for more info."; + // Use a wasm runtime error, because a JS error might be seen as a foreign + // exception, which means we'd run destructors on it. We need the error to + // simply make the program stop. + // FIXME This approach does not work in Wasm EH because it currently does not assume + // all RuntimeErrors are from traps; it decides whether a RuntimeError is from + // a trap or not based on a hidden field within the object. So at the moment + // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that + // allows this in the wasm spec. + // Suppress closure compiler warning here. Closure compiler's builtin extern + // definition for WebAssembly.RuntimeError claims it takes no arguments even + // though it can. + // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed. + /** @suppress {checkTypes} */ var e = new WebAssembly.RuntimeError(what); + // Throw the error whether or not MODULARIZE is set because abort is used + // in code paths apart from instantiation where an exception is expected + // to be thrown when abort is called. + throw e; +} + +var wasmBinaryFile; + +function findWasmBinary() { + return locateFile("vision_wasm_nosimd_internal.wasm"); +} + +function getBinarySync(file) { + if (file == wasmBinaryFile && wasmBinary) { + return new Uint8Array(wasmBinary); + } + if (readBinary) { + return readBinary(file); + } + // Throwing a plain string here, even though it not normally advisable since + // this gets turning into an `abort` in instantiateArrayBuffer. + throw "both async and sync fetching of the wasm failed"; +} + +async function getWasmBinary(binaryFile) { + // If we don't have the binary yet, load it asynchronously using readAsync. + if (!wasmBinary) { + // Fetch the binary using readAsync + try { + var response = await readAsync(binaryFile); + return new Uint8Array(response); + } catch {} + } + // Otherwise, getBinarySync should be able to get it synchronously + return getBinarySync(binaryFile); +} + +async function instantiateArrayBuffer(binaryFile, imports) { + try { + var binary = await getWasmBinary(binaryFile); + var instance = await WebAssembly.instantiate(binary, imports); + return instance; + } catch (reason) { + err(`failed to asynchronously prepare wasm: ${reason}`); + abort(reason); + } +} + +async function instantiateAsync(binary, binaryFile, imports) { + if (!binary && !isFileURI(binaryFile) && !ENVIRONMENT_IS_NODE) { + try { + var response = fetch(binaryFile, { + credentials: "same-origin" + }); + var instantiationResult = await WebAssembly.instantiateStreaming(response, imports); + return instantiationResult; + } catch (reason) { + // We expect the most common failure cause to be a bad MIME type for the binary, + // in which case falling back to ArrayBuffer instantiation should work. + err(`wasm streaming compile failed: ${reason}`); + err("falling back to ArrayBuffer instantiation"); + } + } + return instantiateArrayBuffer(binaryFile, imports); +} + +function getWasmImports() { + // prepare imports + var imports = { + "a": wasmImports + }; + return imports; +} + +// Create the wasm instance. +// Receives the wasm imports, returns the exports. +async function createWasm() { + // Load the wasm module and create an instance of using native support in the JS engine. + // handle a generated wasm instance, receiving its exports and + // performing other necessary setup + /** @param {WebAssembly.Module=} module*/ function receiveInstance(instance, module) { + wasmExports = instance.exports; + assignWasmExports(wasmExports); + updateMemoryViews(); + return wasmExports; + } + // Prefer streaming instantiation if available. + function receiveInstantiationResult(result) { + // 'result' is a ResultObject object which has both the module and instance. + // receiveInstance() will swap in the exports (to Module.asm) so they can be called + // 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. + // When the regression is fixed, can restore the above PTHREADS-enabled path. + return receiveInstance(result["instance"]); + } + var info = getWasmImports(); + // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback + // to manually instantiate the Wasm module themselves. This allows pages to + // run the instantiation parallel to any other async startup actions they are + // performing. + // Also pthreads and wasm workers initialize the wasm instance through this + // path. + if (Module["instantiateWasm"]) { + return new Promise((resolve, reject) => { + Module["instantiateWasm"](info, (inst, mod) => { + resolve(receiveInstance(inst, mod)); + }); + }); + } + wasmBinaryFile ??= findWasmBinary(); + var result = await instantiateAsync(wasmBinary, wasmBinaryFile, info); + var exports = receiveInstantiationResult(result); + return exports; +} + +// Globals used by JS i64 conversions (see makeSetValue) +var tempDouble; + +var tempI64; + +// end include: preamble.js +// Begin JS library code +var handleException = e => { + // Certain exception types we do not treat as errors since they are used for + // internal control flow. + // 1. ExitStatus, which is thrown by exit() + // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others + // that wish to return to JS event loop. + if (e instanceof ExitStatus || e == "unwind") { + return EXITSTATUS; + } + quit_(1, e); +}; + +class ExitStatus { + name="ExitStatus"; + constructor(status) { + this.message = `Program terminated with exit(${status})`; + this.status = status; + } +} + +var runtimeKeepaliveCounter = 0; + +var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0; + +var _proc_exit = code => { + EXITSTATUS = code; + if (!keepRuntimeAlive()) { + Module["onExit"]?.(code); + ABORT = true; + } + quit_(code, new ExitStatus(code)); +}; + +/** @param {boolean|number=} implicit */ var exitJS = (status, implicit) => { + EXITSTATUS = status; + _proc_exit(status); +}; + +var _exit = exitJS; + +var maybeExit = () => { + if (!keepRuntimeAlive()) { + try { + _exit(EXITSTATUS); + } catch (e) { + handleException(e); + } + } +}; + +var callUserCallback = func => { + if (ABORT) { + return; + } + try { + return func(); + } catch (e) { + handleException(e); + } finally { + maybeExit(); + } +}; + +function getFullscreenElement() { + return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.webkitCurrentFullScreenElement || document.msFullscreenElement; +} + +/** @param {number=} timeout */ var safeSetTimeout = (func, timeout) => setTimeout(() => { + callUserCallback(func); +}, timeout); + +var warnOnce = text => { + warnOnce.shown ||= {}; + if (!warnOnce.shown[text]) { + warnOnce.shown[text] = 1; + if (ENVIRONMENT_IS_NODE) text = "warning: " + text; + err(text); + } +}; + +var preloadPlugins = []; + +var Browser = { + useWebGL: false, + isFullscreen: false, + pointerLock: false, + moduleContextCreatedCallbacks: [], + workers: [], + preloadedImages: {}, + preloadedAudios: {}, + getCanvas: () => Module["canvas"], + init() { + if (Browser.initted) return; + Browser.initted = true; + // Support for plugins that can process preloaded files. You can add more of these to + // your app by creating and appending to preloadPlugins. + // Each plugin is asked if it can handle a file based on the file's name. If it can, + // it is given the file's raw data. When it is done, it calls a callback with the file's + // (possibly modified) data. For example, a plugin might decompress a file, or it + // might create some side data structure for use later (like an Image element, etc.). + var imagePlugin = {}; + imagePlugin["canHandle"] = name => !Module["noImageDecoding"] && /\.(jpg|jpeg|png|bmp|webp)$/i.test(name); + imagePlugin["handle"] = async (byteArray, name) => { + var b = new Blob([ byteArray ], { + type: Browser.getMimetype(name) + }); + if (b.size !== byteArray.length) { + // Safari bug #118630 + // Safari's Blob can only take an ArrayBuffer + b = new Blob([ (new Uint8Array(byteArray)).buffer ], { + type: Browser.getMimetype(name) + }); + } + var url = URL.createObjectURL(b); + return new Promise((resolve, reject) => { + var img = new Image; + img.onload = () => { + var canvas = /** @type {!HTMLCanvasElement} */ (document.createElement("canvas")); + canvas.width = img.width; + canvas.height = img.height; + var ctx = canvas.getContext("2d"); + ctx.drawImage(img, 0, 0); + Browser.preloadedImages[name] = canvas; + URL.revokeObjectURL(url); + resolve(byteArray); + }; + img.onerror = event => { + err(`Image ${url} could not be decoded`); + reject(); + }; + img.src = url; + }); + }; + preloadPlugins.push(imagePlugin); + var audioPlugin = {}; + audioPlugin["canHandle"] = name => !Module["noAudioDecoding"] && name.slice(-4) in { + ".ogg": 1, + ".wav": 1, + ".mp3": 1 + }; + audioPlugin["handle"] = async (byteArray, name) => new Promise((resolve, reject) => { + var done = false; + function finish(audio) { + if (done) return; + done = true; + Browser.preloadedAudios[name] = audio; + resolve(byteArray); + } + var b = new Blob([ byteArray ], { + type: Browser.getMimetype(name) + }); + var url = URL.createObjectURL(b); + // XXX we never revoke this! + var audio = new Audio; + audio.addEventListener("canplaythrough", () => finish(audio), false); + // use addEventListener due to chromium bug 124926 + audio.onerror = event => { + if (done) return; + err(`warning: browser could not fully decode audio ${name}, trying slower base64 approach`); + function encode64(data) { + var BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var PAD = "="; + var ret = ""; + var leftchar = 0; + var leftbits = 0; + for (var i = 0; i < data.length; i++) { + leftchar = (leftchar << 8) | data[i]; + leftbits += 8; + while (leftbits >= 6) { + var curr = (leftchar >> (leftbits - 6)) & 63; + leftbits -= 6; + ret += BASE[curr]; + } + } + if (leftbits == 2) { + ret += BASE[(leftchar & 3) << 4]; + ret += PAD + PAD; + } else if (leftbits == 4) { + ret += BASE[(leftchar & 15) << 2]; + ret += PAD; + } + return ret; + } + audio.src = "data:audio/x-" + name.slice(-3) + ";base64," + encode64(byteArray); + finish(audio); + }; + audio.src = url; + // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror + safeSetTimeout(() => { + finish(audio); + }, 1e4); + }); + preloadPlugins.push(audioPlugin); + // Canvas event setup + function pointerLockChange() { + var canvas = Browser.getCanvas(); + Browser.pointerLock = document.pointerLockElement === canvas; + } + var canvas = Browser.getCanvas(); + if (canvas) { + // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module + // Module['forcedAspectRatio'] = 4 / 3; + document.addEventListener("pointerlockchange", pointerLockChange, false); + if (Module["elementPointerLock"]) { + canvas.addEventListener("click", ev => { + if (!Browser.pointerLock && Browser.getCanvas().requestPointerLock) { + Browser.getCanvas().requestPointerLock(); + ev.preventDefault(); + } + }, false); + } + } + }, + createContext(/** @type {HTMLCanvasElement} */ canvas, useWebGL, setInModule, webGLContextAttributes) { + if (useWebGL && Module["ctx"] && canvas == Browser.getCanvas()) return Module["ctx"]; + // no need to recreate GL context if it's already been created for this canvas. + var ctx; + var contextHandle; + if (useWebGL) { + // For GLES2/desktop GL compatibility, adjust a few defaults to be different to WebGL defaults, so that they align better with the desktop defaults. + var contextAttributes = { + antialias: false, + alpha: false, + majorVersion: (typeof WebGL2RenderingContext != "undefined") ? 2 : 1 + }; + if (webGLContextAttributes) { + for (var attribute in webGLContextAttributes) { + contextAttributes[attribute] = webGLContextAttributes[attribute]; + } + } + // 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 + // actually compiled in because application is not doing any GL operations. TODO: Ideally if GL is not being used, this function + // Browser.createContext() should not even be emitted. + if (typeof GL != "undefined") { + contextHandle = GL.createContext(canvas, contextAttributes); + if (contextHandle) { + ctx = GL.getContext(contextHandle).GLctx; + } + } + } else { + ctx = canvas.getContext("2d"); + } + if (!ctx) return null; + if (setInModule) { + Module["ctx"] = ctx; + if (useWebGL) GL.makeContextCurrent(contextHandle); + Browser.useWebGL = useWebGL; + Browser.moduleContextCreatedCallbacks.forEach(callback => callback()); + Browser.init(); + } + return ctx; + }, + fullscreenHandlersInstalled: false, + lockPointer: undefined, + resizeCanvas: undefined, + requestFullscreen(lockPointer, resizeCanvas) { + Browser.lockPointer = lockPointer; + Browser.resizeCanvas = resizeCanvas; + if (typeof Browser.lockPointer == "undefined") Browser.lockPointer = true; + if (typeof Browser.resizeCanvas == "undefined") Browser.resizeCanvas = false; + var canvas = Browser.getCanvas(); + function fullscreenChange() { + Browser.isFullscreen = false; + var canvasContainer = canvas.parentNode; + if (getFullscreenElement() === canvasContainer) { + canvas.exitFullscreen = Browser.exitFullscreen; + if (Browser.lockPointer) canvas.requestPointerLock(); + Browser.isFullscreen = true; + if (Browser.resizeCanvas) { + Browser.setFullscreenCanvasSize(); + } else { + Browser.updateCanvasDimensions(canvas); + } + } else { + // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen + canvasContainer.parentNode.insertBefore(canvas, canvasContainer); + canvasContainer.parentNode.removeChild(canvasContainer); + if (Browser.resizeCanvas) { + Browser.setWindowedCanvasSize(); + } else { + Browser.updateCanvasDimensions(canvas); + } + } + Module["onFullScreen"]?.(Browser.isFullscreen); + Module["onFullscreen"]?.(Browser.isFullscreen); + } + if (!Browser.fullscreenHandlersInstalled) { + Browser.fullscreenHandlersInstalled = true; + document.addEventListener("fullscreenchange", fullscreenChange, false); + document.addEventListener("mozfullscreenchange", fullscreenChange, false); + document.addEventListener("webkitfullscreenchange", fullscreenChange, false); + document.addEventListener("MSFullscreenChange", fullscreenChange, false); + } + // 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 + var canvasContainer = document.createElement("div"); + canvas.parentNode.insertBefore(canvasContainer, canvas); + canvasContainer.appendChild(canvas); + // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size) + canvasContainer.requestFullscreen = canvasContainer["requestFullscreen"] || canvasContainer["mozRequestFullScreen"] || canvasContainer["msRequestFullscreen"] || (canvasContainer["webkitRequestFullscreen"] ? () => canvasContainer["webkitRequestFullscreen"](Element["ALLOW_KEYBOARD_INPUT"]) : null) || (canvasContainer["webkitRequestFullScreen"] ? () => canvasContainer["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"]) : null); + canvasContainer.requestFullscreen(); + }, + exitFullscreen() { + // This is workaround for chrome. Trying to exit from fullscreen + // not in fullscreen state will cause "TypeError: Document not active" + // in chrome. See https://github.com/emscripten-core/emscripten/pull/8236 + if (!Browser.isFullscreen) { + return false; + } + var CFS = document["exitFullscreen"] || document["cancelFullScreen"] || document["mozCancelFullScreen"] || document["msExitFullscreen"] || document["webkitCancelFullScreen"] || (() => {}); + CFS.apply(document, []); + return true; + }, + safeSetTimeout(func, timeout) { + // Legacy function, this is used by the SDL2 port so we need to keep it + // around at least until that is updated. + // See https://github.com/libsdl-org/SDL/pull/6304 + return safeSetTimeout(func, timeout); + }, + getMimetype(name) { + return { + "jpg": "image/jpeg", + "jpeg": "image/jpeg", + "png": "image/png", + "bmp": "image/bmp", + "ogg": "audio/ogg", + "wav": "audio/wav", + "mp3": "audio/mpeg" + }[name.slice(name.lastIndexOf(".") + 1)]; + }, + getUserMedia(func) { + window.getUserMedia ||= navigator["getUserMedia"] || navigator["mozGetUserMedia"]; + window.getUserMedia(func); + }, + getMovementX(event) { + return event["movementX"] || event["mozMovementX"] || event["webkitMovementX"] || 0; + }, + getMovementY(event) { + return event["movementY"] || event["mozMovementY"] || event["webkitMovementY"] || 0; + }, + getMouseWheelDelta(event) { + var delta = 0; + switch (event.type) { + case "DOMMouseScroll": + // 3 lines make up a step + delta = event.detail / 3; + break; + + case "mousewheel": + // 120 units make up a step + delta = event.wheelDelta / 120; + break; + + case "wheel": + delta = event.deltaY; + switch (event.deltaMode) { + case 0: + // DOM_DELTA_PIXEL: 100 pixels make up a step + delta /= 100; + break; + + case 1: + // DOM_DELTA_LINE: 3 lines make up a step + delta /= 3; + break; + + case 2: + // DOM_DELTA_PAGE: A page makes up 80 steps + delta *= 80; + break; + + default: + abort("unrecognized mouse wheel delta mode: " + event.deltaMode); + } + break; + + default: + abort("unrecognized mouse wheel event: " + event.type); + } + return delta; + }, + mouseX: 0, + mouseY: 0, + mouseMovementX: 0, + mouseMovementY: 0, + touches: {}, + lastTouches: {}, + calculateMouseCoords(pageX, pageY) { + // Calculate the movement based on the changes + // in the coordinates. + var canvas = Browser.getCanvas(); + var rect = canvas.getBoundingClientRect(); + var adjustedX = pageX - (window.scrollX + rect.left); + var adjustedY = pageY - (window.scrollY + rect.top); + // the canvas might be CSS-scaled compared to its backbuffer; + // SDL-using content will want mouse coordinates in terms + // of backbuffer units. + adjustedX = adjustedX * (canvas.width / rect.width); + adjustedY = adjustedY * (canvas.height / rect.height); + return { + x: adjustedX, + y: adjustedY + }; + }, + setMouseCoords(pageX, pageY) { + const {x, y} = Browser.calculateMouseCoords(pageX, pageY); + Browser.mouseMovementX = x - Browser.mouseX; + Browser.mouseMovementY = y - Browser.mouseY; + Browser.mouseX = x; + Browser.mouseY = y; + }, + calculateMouseEvent(event) { + // event should be mousemove, mousedown or mouseup + if (Browser.pointerLock) { + // When the pointer is locked, calculate the coordinates + // based on the movement of the mouse. + // Workaround for Firefox bug 764498 + if (event.type != "mousemove" && ("mozMovementX" in event)) { + Browser.mouseMovementX = Browser.mouseMovementY = 0; + } else { + Browser.mouseMovementX = Browser.getMovementX(event); + Browser.mouseMovementY = Browser.getMovementY(event); + } + // add the mouse delta to the current absolute mouse position + Browser.mouseX += Browser.mouseMovementX; + Browser.mouseY += Browser.mouseMovementY; + } else { + if (event.type === "touchstart" || event.type === "touchend" || event.type === "touchmove") { + var touch = event.touch; + if (touch === undefined) { + return; + } + var coords = Browser.calculateMouseCoords(touch.pageX, touch.pageY); + if (event.type === "touchstart") { + Browser.lastTouches[touch.identifier] = coords; + Browser.touches[touch.identifier] = coords; + } else if (event.type === "touchend" || event.type === "touchmove") { + var last = Browser.touches[touch.identifier]; + last ||= coords; + Browser.lastTouches[touch.identifier] = last; + Browser.touches[touch.identifier] = coords; + } + return; + } + Browser.setMouseCoords(event.pageX, event.pageY); + } + }, + resizeListeners: [], + updateResizeListeners() { + var canvas = Browser.getCanvas(); + Browser.resizeListeners.forEach(listener => listener(canvas.width, canvas.height)); + }, + setCanvasSize(width, height, noUpdates) { + var canvas = Browser.getCanvas(); + Browser.updateCanvasDimensions(canvas, width, height); + if (!noUpdates) Browser.updateResizeListeners(); + }, + windowedWidth: 0, + windowedHeight: 0, + setFullscreenCanvasSize() { + // check if SDL is available + if (typeof SDL != "undefined") { + var flags = HEAPU32[((SDL.screen) >> 2)]; + flags = flags | 8388608; + // set SDL_FULLSCREEN flag + HEAP32[((SDL.screen) >> 2)] = flags; + } + Browser.updateCanvasDimensions(Browser.getCanvas()); + Browser.updateResizeListeners(); + }, + setWindowedCanvasSize() { + // check if SDL is available + if (typeof SDL != "undefined") { + var flags = HEAPU32[((SDL.screen) >> 2)]; + flags = flags & ~8388608; + // clear SDL_FULLSCREEN flag + HEAP32[((SDL.screen) >> 2)] = flags; + } + Browser.updateCanvasDimensions(Browser.getCanvas()); + Browser.updateResizeListeners(); + }, + updateCanvasDimensions(canvas, wNative, hNative) { + if (wNative && hNative) { + canvas.widthNative = wNative; + canvas.heightNative = hNative; + } else { + wNative = canvas.widthNative; + hNative = canvas.heightNative; + } + var w = wNative; + var h = hNative; + if (Module["forcedAspectRatio"] > 0) { + if (w / h < Module["forcedAspectRatio"]) { + w = Math.round(h * Module["forcedAspectRatio"]); + } else { + h = Math.round(w / Module["forcedAspectRatio"]); + } + } + if ((getFullscreenElement() === canvas.parentNode) && (typeof screen != "undefined")) { + var factor = Math.min(screen.width / w, screen.height / h); + w = Math.round(w * factor); + h = Math.round(h * factor); + } + if (Browser.resizeCanvas) { + if (canvas.width != w) canvas.width = w; + if (canvas.height != h) canvas.height = h; + if (typeof canvas.style != "undefined") { + canvas.style.removeProperty("width"); + canvas.style.removeProperty("height"); + } + } else { + if (canvas.width != wNative) canvas.width = wNative; + if (canvas.height != hNative) canvas.height = hNative; + if (typeof canvas.style != "undefined") { + if (w != wNative || h != hNative) { + canvas.style.setProperty("width", w + "px", "important"); + canvas.style.setProperty("height", h + "px", "important"); + } else { + canvas.style.removeProperty("width"); + canvas.style.removeProperty("height"); + } + } + } + } +}; + +/** @type {!Int16Array} */ var HEAP16; + +/** @type {!Int32Array} */ var HEAP32; + +/** @type {!Int8Array} */ var HEAP8; + +/** @type {!Float32Array} */ var HEAPF32; + +/** @type {!Float64Array} */ var HEAPF64; + +/** @type {!Uint16Array} */ var HEAPU16; + +/** @type {!Uint32Array} */ var HEAPU32; + +/** @type {!Uint8Array} */ var HEAPU8; + +var callRuntimeCallbacks = callbacks => { + while (callbacks.length > 0) { + // Pass the module as the first argument. + callbacks.shift()(Module); + } +}; + +var onPostRuns = []; + +var addOnPostRun = cb => onPostRuns.push(cb); + +var onPreRuns = []; + +var addOnPreRun = cb => onPreRuns.push(cb); + +var noExitRuntime = true; + +var stackRestore = val => __emscripten_stack_restore(val); + +var stackSave = () => _emscripten_stack_get_current(); + +class ExceptionInfo { + // excPtr - Thrown object pointer to wrap. Metadata pointer is calculated from it. + constructor(excPtr) { + this.excPtr = excPtr; + this.ptr = excPtr - 24; + } + set_type(type) { + HEAPU32[(((this.ptr) + (4)) >> 2)] = type; + } + get_type() { + return HEAPU32[(((this.ptr) + (4)) >> 2)]; + } + set_destructor(destructor) { + HEAPU32[(((this.ptr) + (8)) >> 2)] = destructor; + } + get_destructor() { + return HEAPU32[(((this.ptr) + (8)) >> 2)]; + } + set_caught(caught) { + caught = caught ? 1 : 0; + HEAP8[(this.ptr) + (12)] = caught; + } + get_caught() { + return HEAP8[(this.ptr) + (12)] != 0; + } + set_rethrown(rethrown) { + rethrown = rethrown ? 1 : 0; + HEAP8[(this.ptr) + (13)] = rethrown; + } + get_rethrown() { + return HEAP8[(this.ptr) + (13)] != 0; + } + // Initialize native structure fields. Should be called once after allocated. + init(type, destructor) { + this.set_adjusted_ptr(0); + this.set_type(type); + this.set_destructor(destructor); + } + set_adjusted_ptr(adjustedPtr) { + HEAPU32[(((this.ptr) + (16)) >> 2)] = adjustedPtr; + } + get_adjusted_ptr() { + return HEAPU32[(((this.ptr) + (16)) >> 2)]; + } +} + +var uncaughtExceptionCount = 0; + +var ___cxa_throw = (ptr, type, destructor) => { + var info = new ExceptionInfo(ptr); + // Initialize ExceptionInfo content after it was allocated in __cxa_allocate_exception. + info.init(type, destructor); + uncaughtExceptionCount++; + abort(); +}; + +var PATH = { + isAbs: path => path.charAt(0) === "/", + splitPath: filename => { + var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; + return splitPathRe.exec(filename).slice(1); + }, + normalizeArray: (parts, allowAboveRoot) => { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === ".") { + parts.splice(i, 1); + } else if (last === "..") { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (;up; up--) { + parts.unshift(".."); + } + } + return parts; + }, + normalize: path => { + var isAbsolute = PATH.isAbs(path), trailingSlash = path.slice(-1) === "/"; + // Normalize the path + path = PATH.normalizeArray(path.split("/").filter(p => !!p), !isAbsolute).join("/"); + if (!path && !isAbsolute) { + path = "."; + } + if (path && trailingSlash) { + path += "/"; + } + return (isAbsolute ? "/" : "") + path; + }, + dirname: path => { + var result = PATH.splitPath(path), root = result[0], dir = result[1]; + if (!root && !dir) { + // No dirname whatsoever + return "."; + } + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.slice(0, -1); + } + return root + dir; + }, + basename: path => path && path.match(/([^\/]+|\/)\/*$/)[1], + join: (...paths) => PATH.normalize(paths.join("/")), + join2: (l, r) => PATH.normalize(l + "/" + r) +}; + +var initRandomFill = () => { + // This block is not needed on v19+ since crypto.getRandomValues is builtin + if (ENVIRONMENT_IS_NODE) { + var nodeCrypto = require("node:crypto"); + return view => nodeCrypto.randomFillSync(view); + } + return view => (crypto.getRandomValues(view), 0); +}; + +var randomFill = view => (randomFill = initRandomFill())(view); + +var PATH_FS = { + resolve: (...args) => { + var resolvedPath = "", resolvedAbsolute = false; + for (var i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? args[i] : FS.cwd(); + // Skip empty and invalid entries + if (typeof path != "string") { + throw new TypeError("Arguments to path.resolve must be strings"); + } else if (!path) { + return ""; + } + resolvedPath = path + "/" + resolvedPath; + resolvedAbsolute = PATH.isAbs(path); + } + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + resolvedPath = PATH.normalizeArray(resolvedPath.split("/").filter(p => !!p), !resolvedAbsolute).join("/"); + return ((resolvedAbsolute ? "/" : "") + resolvedPath) || "."; + }, + relative: (from, to) => { + from = PATH_FS.resolve(from).slice(1); + to = PATH_FS.resolve(to).slice(1); + function trim(arr) { + var start = 0; + for (;start < arr.length; start++) { + if (arr[start] !== "") break; + } + var end = arr.length - 1; + for (;end >= 0; end--) { + if (arr[end] !== "") break; + } + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + var fromParts = trim(from.split("/")); + var toParts = trim(to.split("/")); + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push(".."); + } + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + return outputParts.join("/"); + } +}; + +var UTF8Decoder = new TextDecoder; + +var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => { + var maxIdx = idx + maxBytesToRead; + if (ignoreNul) return maxIdx; + // TextDecoder needs to know the byte length in advance, it doesn't stop on + // null terminator by itself. + // As a tiny code save trick, compare idx against maxIdx using a negation, + // so that maxBytesToRead=undefined/NaN means Infinity. + while (heapOrArray[idx] && !(idx >= maxIdx)) ++idx; + return idx; +}; + +/** + * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given + * array that contains uint8 values, returns a copy of that string as a + * Javascript String object. + * heapOrArray is either a regular array, or a JavaScript typed array view. + * @param {number=} idx + * @param {number=} maxBytesToRead + * @param {boolean=} ignoreNul - If true, the function will not stop on a NUL character. + * @return {string} + */ var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead, ignoreNul) => { + var endPtr = findStringEnd(heapOrArray, idx, maxBytesToRead, ignoreNul); + return UTF8Decoder.decode(heapOrArray.buffer ? heapOrArray.subarray(idx, endPtr) : new Uint8Array(heapOrArray.slice(idx, endPtr))); +}; + +var FS_stdin_getChar_buffer = []; + +var lengthBytesUTF8 = str => { + var len = 0; + for (var i = 0; i < str.length; ++i) { + // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code + // unit, not a Unicode code point of the character! So decode + // UTF16->UTF32->UTF8. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var c = str.charCodeAt(i); + // possibly a lead surrogate + if (c <= 127) { + len++; + } else if (c <= 2047) { + len += 2; + } else if (c >= 55296 && c <= 57343) { + len += 4; + ++i; + } else { + len += 3; + } + } + return len; +}; + +var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => { + // Parameter maxBytesToWrite is not optional. Negative values, 0, null, + // undefined and false each don't write out any bytes. + if (!(maxBytesToWrite > 0)) return 0; + var startIdx = outIdx; + var endIdx = outIdx + maxBytesToWrite - 1; + // -1 for string null terminator. + for (var i = 0; i < str.length; ++i) { + // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description + // and https://www.ietf.org/rfc/rfc2279.txt + // and https://tools.ietf.org/html/rfc3629 + var u = str.codePointAt(i); + if (u <= 127) { + if (outIdx >= endIdx) break; + heap[outIdx++] = u; + } else if (u <= 2047) { + if (outIdx + 1 >= endIdx) break; + heap[outIdx++] = 192 | (u >> 6); + heap[outIdx++] = 128 | (u & 63); + } else if (u <= 65535) { + if (outIdx + 2 >= endIdx) break; + heap[outIdx++] = 224 | (u >> 12); + heap[outIdx++] = 128 | ((u >> 6) & 63); + heap[outIdx++] = 128 | (u & 63); + } else { + if (outIdx + 3 >= endIdx) break; + heap[outIdx++] = 240 | (u >> 18); + heap[outIdx++] = 128 | ((u >> 12) & 63); + heap[outIdx++] = 128 | ((u >> 6) & 63); + heap[outIdx++] = 128 | (u & 63); + // Gotcha: if codePoint is over 0xFFFF, it is represented as a surrogate pair in UTF-16. + // We need to manually skip over the second code unit for correct iteration. + i++; + } + } + // Null-terminate the pointer to the buffer. + heap[outIdx] = 0; + return outIdx - startIdx; +}; + +/** @type {function(string, boolean=, number=)} */ var intArrayFromString = (stringy, dontAddNull, length) => { + var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1; + var u8array = new Array(len); + var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length); + if (dontAddNull) u8array.length = numBytesWritten; + return u8array; +}; + +var FS_stdin_getChar = () => { + if (!FS_stdin_getChar_buffer.length) { + var result = null; + if (ENVIRONMENT_IS_NODE) { + // we will read data by chunks of BUFSIZE + var BUFSIZE = 256; + var buf = Buffer.alloc(BUFSIZE); + var bytesRead = 0; + // For some reason we must suppress a closure warning here, even though + // fd definitely exists on process.stdin, and is even the proper way to + // get the fd of stdin, + // https://github.com/nodejs/help/issues/2136#issuecomment-523649904 + // This started to happen after moving this logic out of library_tty.js, + // so it is related to the surrounding code in some unclear manner. + /** @suppress {missingProperties} */ var fd = process.stdin.fd; + try { + bytesRead = fs.readSync(fd, buf, 0, BUFSIZE); + } catch (e) { + // Cross-platform differences: on Windows, reading EOF throws an + // exception, but on other OSes, reading EOF returns 0. Uniformize + // behavior by treating the EOF exception to return 0. + if (e.toString().includes("EOF")) bytesRead = 0; else throw e; + } + if (bytesRead > 0) { + result = buf.slice(0, bytesRead).toString("utf-8"); + } + } else if (globalThis.window?.prompt) { + // Browser. + result = window.prompt("Input: "); + // returns null on cancel + if (result !== null) { + result += "\n"; + } + } else {} + if (!result) { + return null; + } + FS_stdin_getChar_buffer = intArrayFromString(result, true); + } + return FS_stdin_getChar_buffer.shift(); +}; + +var TTY = { + ttys: [], + init() {}, + shutdown() {}, + register(dev, ops) { + TTY.ttys[dev] = { + input: [], + output: [], + ops + }; + FS.registerDevice(dev, TTY.stream_ops); + }, + stream_ops: { + open(stream) { + var tty = TTY.ttys[stream.node.rdev]; + if (!tty) { + throw new FS.ErrnoError(43); + } + stream.tty = tty; + stream.seekable = false; + }, + close(stream) { + // flush any pending line data + stream.tty.ops.fsync(stream.tty); + }, + fsync(stream) { + stream.tty.ops.fsync(stream.tty); + }, + read(stream, buffer, offset, length, pos) { + if (!stream.tty || !stream.tty.ops.get_char) { + throw new FS.ErrnoError(60); + } + var bytesRead = 0; + for (var i = 0; i < length; i++) { + var result; + try { + result = stream.tty.ops.get_char(stream.tty); + } catch (e) { + throw new FS.ErrnoError(29); + } + if (result === undefined && bytesRead === 0) { + throw new FS.ErrnoError(6); + } + if (result === null || result === undefined) break; + bytesRead++; + buffer[offset + i] = result; + } + if (bytesRead) { + stream.node.atime = Date.now(); + } + return bytesRead; + }, + write(stream, buffer, offset, length, pos) { + if (!stream.tty || !stream.tty.ops.put_char) { + throw new FS.ErrnoError(60); + } + try { + for (var i = 0; i < length; i++) { + stream.tty.ops.put_char(stream.tty, buffer[offset + i]); + } + } catch (e) { + throw new FS.ErrnoError(29); + } + if (length) { + stream.node.mtime = stream.node.ctime = Date.now(); + } + return i; + } + }, + default_tty_ops: { + get_char(tty) { + return FS_stdin_getChar(); + }, + put_char(tty, val) { + if (val === null || val === 10) { + out(UTF8ArrayToString(tty.output)); + tty.output = []; + } else { + if (val != 0) tty.output.push(val); + } + }, + fsync(tty) { + if (tty.output?.length > 0) { + out(UTF8ArrayToString(tty.output)); + tty.output = []; + } + }, + ioctl_tcgets(tty) { + // typical setting + return { + c_iflag: 25856, + c_oflag: 5, + c_cflag: 191, + c_lflag: 35387, + c_cc: [ 3, 28, 127, 21, 4, 0, 1, 0, 17, 19, 26, 0, 18, 15, 23, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + }; + }, + ioctl_tcsets(tty, optional_actions, data) { + // currently just ignore + return 0; + }, + ioctl_tiocgwinsz(tty) { + return [ 24, 80 ]; + } + }, + default_tty1_ops: { + put_char(tty, val) { + if (val === null || val === 10) { + err(UTF8ArrayToString(tty.output)); + tty.output = []; + } else { + if (val != 0) tty.output.push(val); + } + }, + fsync(tty) { + if (tty.output?.length > 0) { + err(UTF8ArrayToString(tty.output)); + tty.output = []; + } + } + } +}; + +var zeroMemory = (ptr, size) => HEAPU8.fill(0, ptr, ptr + size); + +var alignMemory = (size, alignment) => Math.ceil(size / alignment) * alignment; + +var mmapAlloc = size => { + size = alignMemory(size, 65536); + var ptr = _emscripten_builtin_memalign(65536, size); + if (ptr) zeroMemory(ptr, size); + return ptr; +}; + +var MEMFS = { + ops_table: null, + mount(mount) { + return MEMFS.createNode(null, "/", 16895, 0); + }, + createNode(parent, name, mode, dev) { + if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { + // not supported + throw new FS.ErrnoError(63); + } + MEMFS.ops_table ||= { + dir: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + lookup: MEMFS.node_ops.lookup, + mknod: MEMFS.node_ops.mknod, + rename: MEMFS.node_ops.rename, + unlink: MEMFS.node_ops.unlink, + rmdir: MEMFS.node_ops.rmdir, + readdir: MEMFS.node_ops.readdir, + symlink: MEMFS.node_ops.symlink + }, + stream: { + llseek: MEMFS.stream_ops.llseek + } + }, + file: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr + }, + stream: { + llseek: MEMFS.stream_ops.llseek, + read: MEMFS.stream_ops.read, + write: MEMFS.stream_ops.write, + mmap: MEMFS.stream_ops.mmap, + msync: MEMFS.stream_ops.msync + } + }, + link: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + readlink: MEMFS.node_ops.readlink + }, + stream: {} + }, + chrdev: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr + }, + stream: FS.chrdev_stream_ops + } + }; + var node = FS.createNode(parent, name, mode, dev); + if (FS.isDir(node.mode)) { + node.node_ops = MEMFS.ops_table.dir.node; + node.stream_ops = MEMFS.ops_table.dir.stream; + node.contents = {}; + } else if (FS.isFile(node.mode)) { + node.node_ops = MEMFS.ops_table.file.node; + node.stream_ops = MEMFS.ops_table.file.stream; + // The actual number of bytes used in the typed array, as opposed to + // contents.length which gives the whole capacity. + node.usedBytes = 0; + // The byte data of the file is stored in a typed array. + // Note: typed arrays are not resizable like normal JS arrays are, so + // there is a small penalty involved for appending file writes that + // continuously grow a file similar to std::vector capacity vs used. + node.contents = MEMFS.emptyFileContents ??= new Uint8Array(0); + } else if (FS.isLink(node.mode)) { + node.node_ops = MEMFS.ops_table.link.node; + node.stream_ops = MEMFS.ops_table.link.stream; + } else if (FS.isChrdev(node.mode)) { + node.node_ops = MEMFS.ops_table.chrdev.node; + node.stream_ops = MEMFS.ops_table.chrdev.stream; + } + node.atime = node.mtime = node.ctime = Date.now(); + // add the new node to the parent + if (parent) { + parent.contents[name] = node; + parent.atime = parent.mtime = parent.ctime = node.atime; + } + return node; + }, + getFileDataAsTypedArray(node) { + return node.contents.subarray(0, node.usedBytes); + }, + expandFileStorage(node, newCapacity) { + var prevCapacity = node.contents.length; + if (prevCapacity >= newCapacity) return; + // No need to expand, the storage was already large enough. + // Don't expand strictly to the given requested limit if it's only a very + // small increase, but instead geometrically grow capacity. + // For small filesizes (<1MB), perform size*2 geometric increase, but for + // large sizes, do a much more conservative size*1.125 increase to avoid + // overshooting the allocation cap by a very large margin. + var CAPACITY_DOUBLING_MAX = 1024 * 1024; + newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125)) >>> 0); + if (prevCapacity) newCapacity = Math.max(newCapacity, 256); + // At minimum allocate 256b for each file when expanding. + var oldContents = MEMFS.getFileDataAsTypedArray(node); + node.contents = new Uint8Array(newCapacity); + // Allocate new storage. + node.contents.set(oldContents); + }, + resizeFileStorage(node, newSize) { + if (node.usedBytes == newSize) return; + var oldContents = node.contents; + node.contents = new Uint8Array(newSize); + // Allocate new storage. + node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); + // Copy old data over to the new storage. + node.usedBytes = newSize; + }, + node_ops: { + getattr(node) { + var attr = {}; + // device numbers reuse inode numbers. + attr.dev = FS.isChrdev(node.mode) ? node.id : 1; + attr.ino = node.id; + attr.mode = node.mode; + attr.nlink = 1; + attr.uid = 0; + attr.gid = 0; + attr.rdev = node.rdev; + if (FS.isDir(node.mode)) { + attr.size = 4096; + } else if (FS.isFile(node.mode)) { + attr.size = node.usedBytes; + } else if (FS.isLink(node.mode)) { + attr.size = node.link.length; + } else { + attr.size = 0; + } + attr.atime = new Date(node.atime); + attr.mtime = new Date(node.mtime); + attr.ctime = new Date(node.ctime); + // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize), + // but this is not required by the standard. + attr.blksize = 4096; + attr.blocks = Math.ceil(attr.size / attr.blksize); + return attr; + }, + setattr(node, attr) { + for (const key of [ "mode", "atime", "mtime", "ctime" ]) { + if (attr[key] != null) { + node[key] = attr[key]; + } + } + if (attr.size !== undefined) { + MEMFS.resizeFileStorage(node, attr.size); + } + }, + lookup(parent, name) { + // This error may happen quite a bit. To avoid overhead we reuse it (and + // suffer a lack of stack info). + if (!MEMFS.doesNotExistError) { + MEMFS.doesNotExistError = new FS.ErrnoError(44); + /** @suppress {checkTypes} */ MEMFS.doesNotExistError.stack = ""; + } + throw MEMFS.doesNotExistError; + }, + mknod(parent, name, mode, dev) { + return MEMFS.createNode(parent, name, mode, dev); + }, + rename(old_node, new_dir, new_name) { + var new_node; + try { + new_node = FS.lookupNode(new_dir, new_name); + } catch (e) {} + if (new_node) { + if (FS.isDir(old_node.mode)) { + // if we're overwriting a directory at new_name, make sure it's empty. + for (var i in new_node.contents) { + throw new FS.ErrnoError(55); + } + } + FS.hashRemoveNode(new_node); + } + // do the internal rewiring + delete old_node.parent.contents[old_node.name]; + new_dir.contents[new_name] = old_node; + old_node.name = new_name; + new_dir.ctime = new_dir.mtime = old_node.parent.ctime = old_node.parent.mtime = Date.now(); + }, + unlink(parent, name) { + delete parent.contents[name]; + parent.ctime = parent.mtime = Date.now(); + }, + rmdir(parent, name) { + var node = FS.lookupNode(parent, name); + for (var i in node.contents) { + throw new FS.ErrnoError(55); + } + delete parent.contents[name]; + parent.ctime = parent.mtime = Date.now(); + }, + readdir(node) { + return [ ".", "..", ...Object.keys(node.contents) ]; + }, + symlink(parent, newname, oldpath) { + var node = MEMFS.createNode(parent, newname, 511 | 40960, 0); + node.link = oldpath; + return node; + }, + readlink(node) { + if (!FS.isLink(node.mode)) { + throw new FS.ErrnoError(28); + } + return node.link; + } + }, + stream_ops: { + read(stream, buffer, offset, length, position) { + var contents = stream.node.contents; + if (position >= stream.node.usedBytes) return 0; + var size = Math.min(stream.node.usedBytes - position, length); + buffer.set(contents.subarray(position, position + size), offset); + return size; + }, + write(stream, buffer, offset, length, position, canOwn) { + // If the buffer is located in main memory (HEAP), and if + // memory can grow, we can't hold on to references of the + // memory buffer, as they may get invalidated. That means we + // need to copy its contents. + if (buffer.buffer === HEAP8.buffer) { + canOwn = false; + } + if (!length) return 0; + var node = stream.node; + node.mtime = node.ctime = Date.now(); + if (canOwn) { + node.contents = buffer.subarray(offset, offset + length); + node.usedBytes = length; + } 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. + node.contents = buffer.slice(offset, offset + length); + node.usedBytes = length; + } else { + MEMFS.expandFileStorage(node, position + length); + // Use typed array write which is available. + node.contents.set(buffer.subarray(offset, offset + length), position); + node.usedBytes = Math.max(node.usedBytes, position + length); + } + return length; + }, + llseek(stream, offset, whence) { + var position = offset; + if (whence === 1) { + position += stream.position; + } else if (whence === 2) { + if (FS.isFile(stream.node.mode)) { + position += stream.node.usedBytes; + } + } + if (position < 0) { + throw new FS.ErrnoError(28); + } + return position; + }, + mmap(stream, length, position, prot, flags) { + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + var ptr; + var allocated; + var contents = stream.node.contents; + // Only make a new copy when MAP_PRIVATE is specified. + if (!(flags & 2) && contents.buffer === HEAP8.buffer) { + // We can't emulate MAP_SHARED when the file is not backed by the + // buffer we're mapping to (e.g. the HEAP buffer). + allocated = false; + ptr = contents.byteOffset; + } else { + allocated = true; + ptr = mmapAlloc(length); + if (!ptr) { + throw new FS.ErrnoError(48); + } + if (contents) { + // Try to avoid unnecessary slices. + if (position > 0 || position + length < contents.length) { + if (contents.subarray) { + contents = contents.subarray(position, position + length); + } else { + contents = Array.prototype.slice.call(contents, position, position + length); + } + } + HEAP8.set(contents, ptr); + } + } + return { + ptr, + allocated + }; + }, + msync(stream, buffer, offset, length, mmapFlags) { + MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false); + // should we check if bytesWritten and length are the same? + return 0; + } + } +}; + +var FS_modeStringToFlags = str => { + if (typeof str != "string") return str; + var flagModes = { + "r": 0, + "r+": 2, + "w": 512 | 64 | 1, + "w+": 512 | 64 | 2, + "a": 1024 | 64 | 1, + "a+": 1024 | 64 | 2 + }; + var flags = flagModes[str]; + if (typeof flags == "undefined") { + throw new Error(`Unknown file open mode: ${str}`); + } + return flags; +}; + +var FS_fileDataToTypedArray = data => { + if (typeof data == "string") { + data = intArrayFromString(data, true); + } + if (!data.subarray) { + data = new Uint8Array(data); + } + return data; +}; + +var FS_getMode = (canRead, canWrite) => { + var mode = 0; + if (canRead) mode |= 292 | 73; + if (canWrite) mode |= 146; + return mode; +}; + +var asyncLoad = async url => { + var arrayBuffer = await readAsync(url); + return new Uint8Array(arrayBuffer); +}; + +var FS_createDataFile = (...args) => FS.createDataFile(...args); + +var getUniqueRunDependency = id => id; + +var runDependencies = 0; + +var dependenciesFulfilled = null; + +var removeRunDependency = id => { + runDependencies--; + Module["monitorRunDependencies"]?.(runDependencies); + if (runDependencies == 0) { + if (dependenciesFulfilled) { + var callback = dependenciesFulfilled; + dependenciesFulfilled = null; + callback(); + } + } +}; + +var addRunDependency = id => { + runDependencies++; + Module["monitorRunDependencies"]?.(runDependencies); +}; + +var FS_handledByPreloadPlugin = async (byteArray, fullname) => { + // Ensure plugins are ready. + if (typeof Browser != "undefined") Browser.init(); + for (var plugin of preloadPlugins) { + if (plugin["canHandle"](fullname)) { + return plugin["handle"](byteArray, fullname); + } + } + // If no plugin handled this file then return the original/unmodified + // byteArray. + return byteArray; +}; + +var FS_preloadFile = async (parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish) => { + // TODO we should allow people to just pass in a complete filename instead + // of parent and name being that we just join them anyways + var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent; + var dep = getUniqueRunDependency(`cp ${fullname}`); + // might have several active requests for the same fullname + addRunDependency(dep); + try { + var byteArray = url; + if (typeof url == "string") { + byteArray = await asyncLoad(url); + } + byteArray = await FS_handledByPreloadPlugin(byteArray, fullname); + preFinish?.(); + if (!dontCreateFile) { + FS_createDataFile(parent, name, byteArray, canRead, canWrite, canOwn); + } + } finally { + removeRunDependency(dep); + } +}; + +var FS_createPreloadedFile = (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => { + FS_preloadFile(parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish).then(onload).catch(onerror); +}; + +var FS = { + root: null, + mounts: [], + devices: {}, + streams: [], + nextInode: 1, + nameTable: null, + currentPath: "/", + initialized: false, + ignorePermissions: true, + filesystems: null, + syncFSRequests: 0, + ErrnoError: class { + name="ErrnoError"; + // We set the `name` property to be able to identify `FS.ErrnoError` + // - the `name` is a standard ECMA-262 property of error objects. Kind of good to have it anyway. + // - when using PROXYFS, an error can come from an underlying FS + // as different FS objects have their own FS.ErrnoError each, + // the test `err instanceof FS.ErrnoError` won't detect an error coming from another filesystem, causing bugs. + // we'll use the reliable test `err.name == "ErrnoError"` instead + constructor(errno) { + this.errno = errno; + } + }, + FSStream: class { + shared={}; + get object() { + return this.node; + } + set object(val) { + this.node = val; + } + get isRead() { + return (this.flags & 2097155) !== 1; + } + get isWrite() { + return (this.flags & 2097155) !== 0; + } + get isAppend() { + return (this.flags & 1024); + } + get flags() { + return this.shared.flags; + } + set flags(val) { + this.shared.flags = val; + } + get position() { + return this.shared.position; + } + set position(val) { + this.shared.position = val; + } + }, + FSNode: class { + node_ops={}; + stream_ops={}; + readMode=292 | 73; + writeMode=146; + mounted=null; + constructor(parent, name, mode, rdev) { + if (!parent) { + parent = this; + } + this.parent = parent; + this.mount = parent.mount; + this.id = FS.nextInode++; + this.name = name; + this.mode = mode; + this.rdev = rdev; + this.atime = this.mtime = this.ctime = Date.now(); + } + get read() { + return (this.mode & this.readMode) === this.readMode; + } + set read(val) { + val ? this.mode |= this.readMode : this.mode &= ~this.readMode; + } + get write() { + return (this.mode & this.writeMode) === this.writeMode; + } + set write(val) { + val ? this.mode |= this.writeMode : this.mode &= ~this.writeMode; + } + get isFolder() { + return FS.isDir(this.mode); + } + get isDevice() { + return FS.isChrdev(this.mode); + } + }, + lookupPath(path, opts = {}) { + if (!path) { + throw new FS.ErrnoError(44); + } + opts.follow_mount ??= true; + if (!PATH.isAbs(path)) { + path = FS.cwd() + "/" + path; + } + // limit max consecutive symlinks to SYMLOOP_MAX. + linkloop: for (var nlinks = 0; nlinks < 40; nlinks++) { + // split the absolute path + var parts = path.split("/").filter(p => !!p); + // start at the root + var current = FS.root; + var current_path = "/"; + for (var i = 0; i < parts.length; i++) { + var islast = (i === parts.length - 1); + if (islast && opts.parent) { + // stop resolving + break; + } + if (parts[i] === ".") { + continue; + } + if (parts[i] === "..") { + current_path = PATH.dirname(current_path); + if (FS.isRoot(current)) { + path = current_path + "/" + parts.slice(i + 1).join("/"); + // We're making progress here, don't let many consecutive ..'s + // lead to ELOOP + nlinks--; + continue linkloop; + } else { + current = current.parent; + } + continue; + } + current_path = PATH.join2(current_path, parts[i]); + try { + current = FS.lookupNode(current, parts[i]); + } catch (e) { + // if noent_okay is true, suppress a ENOENT in the last component + // and return an object with an undefined node. This is needed for + // resolving symlinks in the path when creating a file. + if ((e?.errno === 44) && islast && opts.noent_okay) { + return { + path: current_path + }; + } + throw e; + } + // jump to the mount's root node if this is a mountpoint + if (FS.isMountpoint(current) && (!islast || opts.follow_mount)) { + current = current.mounted.root; + } + // by default, lookupPath will not follow a symlink if it is the final path component. + // setting opts.follow = true will override this behavior. + if (FS.isLink(current.mode) && (!islast || opts.follow)) { + if (!current.node_ops.readlink) { + throw new FS.ErrnoError(52); + } + var link = current.node_ops.readlink(current); + if (!PATH.isAbs(link)) { + link = PATH.dirname(current_path) + "/" + link; + } + path = link + "/" + parts.slice(i + 1).join("/"); + continue linkloop; + } + } + return { + path: current_path, + node: current + }; + } + throw new FS.ErrnoError(32); + }, + getPath(node) { + var path; + while (true) { + if (FS.isRoot(node)) { + var mount = node.mount.mountpoint; + if (!path) return mount; + return mount[mount.length - 1] !== "/" ? `${mount}/${path}` : mount + path; + } + path = path ? `${node.name}/${path}` : node.name; + node = node.parent; + } + }, + hashName(parentid, name) { + var hash = 0; + for (var i = 0; i < name.length; i++) { + hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0; + } + return ((parentid + hash) >>> 0) % FS.nameTable.length; + }, + hashAddNode(node) { + var hash = FS.hashName(node.parent.id, node.name); + node.name_next = FS.nameTable[hash]; + FS.nameTable[hash] = node; + }, + hashRemoveNode(node) { + var hash = FS.hashName(node.parent.id, node.name); + if (FS.nameTable[hash] === node) { + FS.nameTable[hash] = node.name_next; + } else { + var current = FS.nameTable[hash]; + while (current) { + if (current.name_next === node) { + current.name_next = node.name_next; + break; + } + current = current.name_next; + } + } + }, + lookupNode(parent, name) { + var errCode = FS.mayLookup(parent); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + var hash = FS.hashName(parent.id, name); + for (var node = FS.nameTable[hash]; node; node = node.name_next) { + var nodeName = node.name; + if (node.parent.id === parent.id && nodeName === name) { + return node; + } + } + // if we failed to find it in the cache, call into the VFS + return FS.lookup(parent, name); + }, + createNode(parent, name, mode, rdev) { + var node = new FS.FSNode(parent, name, mode, rdev); + FS.hashAddNode(node); + return node; + }, + destroyNode(node) { + FS.hashRemoveNode(node); + }, + isRoot(node) { + return node === node.parent; + }, + isMountpoint(node) { + return !!node.mounted; + }, + isFile(mode) { + return (mode & 61440) === 32768; + }, + isDir(mode) { + return (mode & 61440) === 16384; + }, + isLink(mode) { + return (mode & 61440) === 40960; + }, + isChrdev(mode) { + return (mode & 61440) === 8192; + }, + isBlkdev(mode) { + return (mode & 61440) === 24576; + }, + isFIFO(mode) { + return (mode & 61440) === 4096; + }, + isSocket(mode) { + return (mode & 49152) === 49152; + }, + flagsToPermissionString(flag) { + var perms = [ "r", "w", "rw" ][flag & 3]; + if ((flag & 512)) { + perms += "w"; + } + return perms; + }, + nodePermissions(node, perms) { + if (FS.ignorePermissions) { + return 0; + } + // return 0 if any user, group or owner bits are set. + if (perms.includes("r") && !(node.mode & 292)) { + return 2; + } + if (perms.includes("w") && !(node.mode & 146)) { + return 2; + } + if (perms.includes("x") && !(node.mode & 73)) { + return 2; + } + return 0; + }, + mayLookup(dir) { + if (!FS.isDir(dir.mode)) return 54; + var errCode = FS.nodePermissions(dir, "x"); + if (errCode) return errCode; + if (!dir.node_ops.lookup) return 2; + return 0; + }, + mayCreate(dir, name) { + if (!FS.isDir(dir.mode)) { + return 54; + } + try { + var node = FS.lookupNode(dir, name); + return 20; + } catch (e) {} + return FS.nodePermissions(dir, "wx"); + }, + mayDelete(dir, name, isdir) { + var node; + try { + node = FS.lookupNode(dir, name); + } catch (e) { + return e.errno; + } + var errCode = FS.nodePermissions(dir, "wx"); + if (errCode) { + return errCode; + } + if (isdir) { + if (!FS.isDir(node.mode)) { + return 54; + } + if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) { + return 10; + } + } else if (FS.isDir(node.mode)) { + return 31; + } + return 0; + }, + mayOpen(node, flags) { + if (!node) { + return 44; + } + if (FS.isLink(node.mode)) { + return 32; + } + var mode = FS.flagsToPermissionString(flags); + if (FS.isDir(node.mode)) { + // opening for write + // TODO: check for O_SEARCH? (== search for dir only) + if (mode !== "r" || (flags & (512 | 64))) { + return 31; + } + } + return FS.nodePermissions(node, mode); + }, + checkOpExists(op, err) { + if (!op) { + throw new FS.ErrnoError(err); + } + return op; + }, + MAX_OPEN_FDS: 4096, + nextfd() { + for (var fd = 0; fd <= FS.MAX_OPEN_FDS; fd++) { + if (!FS.streams[fd]) { + return fd; + } + } + throw new FS.ErrnoError(33); + }, + getStreamChecked(fd) { + var stream = FS.getStream(fd); + if (!stream) { + throw new FS.ErrnoError(8); + } + return stream; + }, + getStream: fd => FS.streams[fd], + createStream(stream, fd = -1) { + // clone it, so we can return an instance of FSStream + stream = Object.assign(new FS.FSStream, stream); + if (fd == -1) { + fd = FS.nextfd(); + } + stream.fd = fd; + FS.streams[fd] = stream; + return stream; + }, + closeStream(fd) { + FS.streams[fd] = null; + }, + dupStream(origStream, fd = -1) { + var stream = FS.createStream(origStream, fd); + stream.stream_ops?.dup?.(stream); + return stream; + }, + doSetAttr(stream, node, attr) { + var setattr = stream?.stream_ops.setattr; + var arg = setattr ? stream : node; + setattr ??= node.node_ops.setattr; + FS.checkOpExists(setattr, 63); + try { + setattr(arg, attr); + } catch (e) { + if (e instanceof RangeError) { + throw new FS.ErrnoError(22); + } + throw e; + } + }, + chrdev_stream_ops: { + open(stream) { + var device = FS.getDevice(stream.node.rdev); + // override node's stream ops with the device's + stream.stream_ops = device.stream_ops; + // forward the open call + stream.stream_ops.open?.(stream); + }, + llseek() { + throw new FS.ErrnoError(70); + } + }, + major: dev => ((dev) >> 8), + minor: dev => ((dev) & 255), + makedev: (ma, mi) => ((ma) << 8 | (mi)), + registerDevice(dev, ops) { + FS.devices[dev] = { + stream_ops: ops + }; + }, + getDevice: dev => FS.devices[dev], + getMounts(mount) { + var mounts = []; + var check = [ mount ]; + while (check.length) { + var m = check.pop(); + mounts.push(m); + check.push(...m.mounts); + } + return mounts; + }, + syncfs(populate, callback) { + if (typeof populate == "function") { + callback = populate; + populate = false; + } + FS.syncFSRequests++; + if (FS.syncFSRequests > 1) { + err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`); + } + var mounts = FS.getMounts(FS.root.mount); + var completed = 0; + function doCallback(errCode) { + FS.syncFSRequests--; + return callback(errCode); + } + function done(errCode) { + if (errCode) { + if (!done.errored) { + done.errored = true; + return doCallback(errCode); + } + return; + } + if (++completed >= mounts.length) { + doCallback(null); + } + } + // sync all mounts + for (var mount of mounts) { + if (mount.type.syncfs) { + mount.type.syncfs(mount, populate, done); + } else { + done(null); + } + } + }, + mount(type, opts, mountpoint) { + var root = mountpoint === "/"; + var pseudo = !mountpoint; + var node; + if (root && FS.root) { + throw new FS.ErrnoError(10); + } else if (!root && !pseudo) { + var lookup = FS.lookupPath(mountpoint, { + follow_mount: false + }); + mountpoint = lookup.path; + // use the absolute path + node = lookup.node; + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + if (!FS.isDir(node.mode)) { + throw new FS.ErrnoError(54); + } + } + var mount = { + type, + opts, + mountpoint, + mounts: [] + }; + // create a root node for the fs + var mountRoot = type.mount(mount); + mountRoot.mount = mount; + mount.root = mountRoot; + if (root) { + FS.root = mountRoot; + } else if (node) { + // set as a mountpoint + node.mounted = mount; + // add the new mount to the current mount's children + if (node.mount) { + node.mount.mounts.push(mount); + } + } + return mountRoot; + }, + unmount(mountpoint) { + var lookup = FS.lookupPath(mountpoint, { + follow_mount: false + }); + if (!FS.isMountpoint(lookup.node)) { + throw new FS.ErrnoError(28); + } + // destroy the nodes for this mount, and all its child mounts + var node = lookup.node; + var mount = node.mounted; + var mounts = FS.getMounts(mount); + for (var [hash, current] of Object.entries(FS.nameTable)) { + while (current) { + var next = current.name_next; + if (mounts.includes(current.mount)) { + FS.destroyNode(current); + } + current = next; + } + } + // no longer a mountpoint + node.mounted = null; + // remove this mount from the child mounts + var idx = node.mount.mounts.indexOf(mount); + node.mount.mounts.splice(idx, 1); + }, + lookup(parent, name) { + return parent.node_ops.lookup(parent, name); + }, + mknod(path, mode, dev) { + var lookup = FS.lookupPath(path, { + parent: true + }); + var parent = lookup.node; + var name = PATH.basename(path); + if (!name) { + throw new FS.ErrnoError(28); + } + if (name === "." || name === "..") { + throw new FS.ErrnoError(20); + } + var errCode = FS.mayCreate(parent, name); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.mknod) { + throw new FS.ErrnoError(63); + } + return parent.node_ops.mknod(parent, name, mode, dev); + }, + statfs(path) { + return FS.statfsNode(FS.lookupPath(path, { + follow: true + }).node); + }, + statfsStream(stream) { + // We keep a separate statfsStream function because noderawfs overrides + // it. In noderawfs, stream.node is sometimes null. Instead, we need to + // look at stream.path. + return FS.statfsNode(stream.node); + }, + statfsNode(node) { + // NOTE: None of the defaults here are true. We're just returning safe and + // sane values. Currently nodefs and rawfs replace these defaults, + // other file systems leave them alone. + var rtn = { + bsize: 4096, + frsize: 4096, + blocks: 1e6, + bfree: 5e5, + bavail: 5e5, + files: FS.nextInode, + ffree: FS.nextInode - 1, + fsid: 42, + flags: 2, + namelen: 255 + }; + if (node.node_ops.statfs) { + Object.assign(rtn, node.node_ops.statfs(node.mount.opts.root)); + } + return rtn; + }, + create(path, mode = 438) { + mode &= 4095; + mode |= 32768; + return FS.mknod(path, mode, 0); + }, + mkdir(path, mode = 511) { + mode &= 511 | 512; + mode |= 16384; + return FS.mknod(path, mode, 0); + }, + mkdirTree(path, mode) { + var dirs = path.split("/"); + var d = ""; + for (var dir of dirs) { + if (!dir) continue; + if (d || PATH.isAbs(path)) d += "/"; + d += dir; + try { + FS.mkdir(d, mode); + } catch (e) { + if (e.errno != 20) throw e; + } + } + }, + mkdev(path, mode, dev) { + if (typeof dev == "undefined") { + dev = mode; + mode = 438; + } + mode |= 8192; + return FS.mknod(path, mode, dev); + }, + symlink(oldpath, newpath) { + if (!PATH_FS.resolve(oldpath)) { + throw new FS.ErrnoError(44); + } + var lookup = FS.lookupPath(newpath, { + parent: true + }); + var parent = lookup.node; + if (!parent) { + throw new FS.ErrnoError(44); + } + var newname = PATH.basename(newpath); + var errCode = FS.mayCreate(parent, newname); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.symlink) { + throw new FS.ErrnoError(63); + } + return parent.node_ops.symlink(parent, newname, oldpath); + }, + rename(old_path, new_path) { + var old_dirname = PATH.dirname(old_path); + var new_dirname = PATH.dirname(new_path); + var old_name = PATH.basename(old_path); + var new_name = PATH.basename(new_path); + // parents must exist + var lookup, old_dir, new_dir; + // let the errors from non existent directories percolate up + lookup = FS.lookupPath(old_path, { + parent: true + }); + old_dir = lookup.node; + lookup = FS.lookupPath(new_path, { + parent: true + }); + new_dir = lookup.node; + if (!old_dir || !new_dir) throw new FS.ErrnoError(44); + // need to be part of the same mount + if (old_dir.mount !== new_dir.mount) { + throw new FS.ErrnoError(75); + } + // source must exist + var old_node = FS.lookupNode(old_dir, old_name); + // old path should not be an ancestor of the new path + var relative = PATH_FS.relative(old_path, new_dirname); + if (relative.charAt(0) !== ".") { + throw new FS.ErrnoError(28); + } + // new path should not be an ancestor of the old path + relative = PATH_FS.relative(new_path, old_dirname); + if (relative.charAt(0) !== ".") { + throw new FS.ErrnoError(55); + } + // see if the new path already exists + var new_node; + try { + new_node = FS.lookupNode(new_dir, new_name); + } catch (e) {} + // early out if nothing needs to change + if (old_node === new_node) { + return; + } + // we'll need to delete the old entry + var isdir = FS.isDir(old_node.mode); + var errCode = FS.mayDelete(old_dir, old_name, isdir); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + // need delete permissions if we'll be overwriting. + // need create permissions if new doesn't already exist. + errCode = new_node ? FS.mayDelete(new_dir, new_name, isdir) : FS.mayCreate(new_dir, new_name); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!old_dir.node_ops.rename) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) { + throw new FS.ErrnoError(10); + } + // if we are going to change the parent, check write permissions + if (new_dir !== old_dir) { + errCode = FS.nodePermissions(old_dir, "w"); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + } + // remove the node from the lookup hash + FS.hashRemoveNode(old_node); + // do the underlying fs rename + try { + old_dir.node_ops.rename(old_node, new_dir, new_name); + // update old node (we do this here to avoid each backend + // needing to) + old_node.parent = new_dir; + } catch (e) { + throw e; + } finally { + // add the node back to the hash (in case node_ops.rename + // changed its name) + FS.hashAddNode(old_node); + } + }, + rmdir(path) { + var lookup = FS.lookupPath(path, { + parent: true + }); + var parent = lookup.node; + var name = PATH.basename(path); + var node = FS.lookupNode(parent, name); + var errCode = FS.mayDelete(parent, name, true); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.rmdir) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + parent.node_ops.rmdir(parent, name); + FS.destroyNode(node); + }, + readdir(path) { + var lookup = FS.lookupPath(path, { + follow: true + }); + var node = lookup.node; + var readdir = FS.checkOpExists(node.node_ops.readdir, 54); + return readdir(node); + }, + unlink(path) { + var lookup = FS.lookupPath(path, { + parent: true + }); + var parent = lookup.node; + if (!parent) { + throw new FS.ErrnoError(44); + } + var name = PATH.basename(path); + var node = FS.lookupNode(parent, name); + var errCode = FS.mayDelete(parent, name, false); + if (errCode) { + // According to POSIX, we should map EISDIR to EPERM, but + // we instead do what Linux does (and we must, as we use + // the musl linux libc). + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.unlink) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + parent.node_ops.unlink(parent, name); + FS.destroyNode(node); + }, + readlink(path) { + var lookup = FS.lookupPath(path); + var link = lookup.node; + if (!link) { + throw new FS.ErrnoError(44); + } + if (!link.node_ops.readlink) { + throw new FS.ErrnoError(28); + } + return link.node_ops.readlink(link); + }, + stat(path, dontFollow) { + var lookup = FS.lookupPath(path, { + follow: !dontFollow + }); + var node = lookup.node; + var getattr = FS.checkOpExists(node.node_ops.getattr, 63); + return getattr(node); + }, + fstat(fd) { + var stream = FS.getStreamChecked(fd); + var node = stream.node; + var getattr = stream.stream_ops.getattr; + var arg = getattr ? stream : node; + getattr ??= node.node_ops.getattr; + FS.checkOpExists(getattr, 63); + return getattr(arg); + }, + lstat(path) { + return FS.stat(path, true); + }, + doChmod(stream, node, mode, dontFollow) { + FS.doSetAttr(stream, node, { + mode: (mode & 4095) | (node.mode & ~4095), + ctime: Date.now(), + dontFollow + }); + }, + chmod(path, mode, dontFollow) { + var node; + if (typeof path == "string") { + var lookup = FS.lookupPath(path, { + follow: !dontFollow + }); + node = lookup.node; + } else { + node = path; + } + FS.doChmod(null, node, mode, dontFollow); + }, + lchmod(path, mode) { + FS.chmod(path, mode, true); + }, + fchmod(fd, mode) { + var stream = FS.getStreamChecked(fd); + FS.doChmod(stream, stream.node, mode, false); + }, + doChown(stream, node, dontFollow) { + FS.doSetAttr(stream, node, { + timestamp: Date.now(), + dontFollow + }); + }, + chown(path, uid, gid, dontFollow) { + var node; + if (typeof path == "string") { + var lookup = FS.lookupPath(path, { + follow: !dontFollow + }); + node = lookup.node; + } else { + node = path; + } + FS.doChown(null, node, dontFollow); + }, + lchown(path, uid, gid) { + FS.chown(path, uid, gid, true); + }, + fchown(fd, uid, gid) { + var stream = FS.getStreamChecked(fd); + FS.doChown(stream, stream.node, false); + }, + doTruncate(stream, node, len) { + if (FS.isDir(node.mode)) { + throw new FS.ErrnoError(31); + } + if (!FS.isFile(node.mode)) { + throw new FS.ErrnoError(28); + } + var errCode = FS.nodePermissions(node, "w"); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + FS.doSetAttr(stream, node, { + size: len, + timestamp: Date.now() + }); + }, + truncate(path, len) { + if (len < 0) { + throw new FS.ErrnoError(28); + } + var node; + if (typeof path == "string") { + var lookup = FS.lookupPath(path, { + follow: true + }); + node = lookup.node; + } else { + node = path; + } + FS.doTruncate(null, node, len); + }, + ftruncate(fd, len) { + var stream = FS.getStreamChecked(fd); + if (len < 0 || (stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(28); + } + FS.doTruncate(stream, stream.node, len); + }, + utime(path, atime, mtime) { + var lookup = FS.lookupPath(path, { + follow: true + }); + var node = lookup.node; + var setattr = FS.checkOpExists(node.node_ops.setattr, 63); + setattr(node, { + atime, + mtime + }); + }, + open(path, flags, mode = 438) { + if (path === "") { + throw new FS.ErrnoError(44); + } + flags = FS_modeStringToFlags(flags); + if ((flags & 64)) { + mode = (mode & 4095) | 32768; + } else { + mode = 0; + } + var node; + var isDirPath; + if (typeof path == "object") { + node = path; + } else { + isDirPath = path.endsWith("/"); + // noent_okay makes it so that if the final component of the path + // doesn't exist, lookupPath returns `node: undefined`. `path` will be + // updated to point to the target of all symlinks. + var lookup = FS.lookupPath(path, { + follow: !(flags & 131072), + noent_okay: true + }); + node = lookup.node; + path = lookup.path; + } + // perhaps we need to create the node + var created = false; + if ((flags & 64)) { + if (node) { + // if O_CREAT and O_EXCL are set, error out if the node already exists + if ((flags & 128)) { + throw new FS.ErrnoError(20); + } + } else if (isDirPath) { + throw new FS.ErrnoError(31); + } else { + // node doesn't exist, try to create it + // Ignore the permission bits here to ensure we can `open` this new + // file below. We use chmod below to apply the permissions once the + // file is open. + node = FS.mknod(path, mode | 511, 0); + created = true; + } + } + if (!node) { + throw new FS.ErrnoError(44); + } + // can't truncate a device + if (FS.isChrdev(node.mode)) { + flags &= ~512; + } + // if asked only for a directory, then this must be one + if ((flags & 65536) && !FS.isDir(node.mode)) { + throw new FS.ErrnoError(54); + } + // check permissions, if this is not a file we just created now (it is ok to + // create and write to a file with read-only permissions; it is read-only + // for later use) + if (!created) { + var errCode = FS.mayOpen(node, flags); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + } + // do truncation if necessary + if ((flags & 512) && !created) { + FS.truncate(node, 0); + } + // we've already handled these, don't pass down to the underlying vfs + flags &= ~(128 | 512 | 131072); + // register the stream with the filesystem + var stream = FS.createStream({ + node, + path: FS.getPath(node), + // we want the absolute path to the node + flags, + seekable: true, + position: 0, + stream_ops: node.stream_ops, + // used by the file family libc calls (fopen, fwrite, ferror, etc.) + ungotten: [], + error: false + }); + // call the new stream's open function + if (stream.stream_ops.open) { + stream.stream_ops.open(stream); + } + if (created) { + FS.chmod(node, mode & 511); + } + return stream; + }, + close(stream) { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (stream.getdents) stream.getdents = null; + // free readdir state + try { + if (stream.stream_ops.close) { + stream.stream_ops.close(stream); + } + } catch (e) { + throw e; + } finally { + FS.closeStream(stream.fd); + } + stream.fd = null; + }, + isClosed(stream) { + return stream.fd === null; + }, + llseek(stream, offset, whence) { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (!stream.seekable || !stream.stream_ops.llseek) { + throw new FS.ErrnoError(70); + } + if (whence != 0 && whence != 1 && whence != 2) { + throw new FS.ErrnoError(28); + } + stream.position = stream.stream_ops.llseek(stream, offset, whence); + stream.ungotten = []; + return stream.position; + }, + read(stream, buffer, offset, length, position) { + if (length < 0 || position < 0) { + throw new FS.ErrnoError(28); + } + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 1) { + throw new FS.ErrnoError(8); + } + if (FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(31); + } + if (!stream.stream_ops.read) { + throw new FS.ErrnoError(28); + } + var seeking = typeof position != "undefined"; + if (!seeking) { + position = stream.position; + } else if (!stream.seekable) { + throw new FS.ErrnoError(70); + } + var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position); + if (!seeking) stream.position += bytesRead; + return bytesRead; + }, + write(stream, buffer, offset, length, position, canOwn) { + if (length < 0 || position < 0) { + throw new FS.ErrnoError(28); + } + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(8); + } + if (FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(31); + } + if (!stream.stream_ops.write) { + throw new FS.ErrnoError(28); + } + if (stream.seekable && stream.flags & 1024) { + // seek to the end before writing in append mode + FS.llseek(stream, 0, 2); + } + var seeking = typeof position != "undefined"; + if (!seeking) { + position = stream.position; + } else if (!stream.seekable) { + throw new FS.ErrnoError(70); + } + var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn); + if (!seeking) stream.position += bytesWritten; + return bytesWritten; + }, + mmap(stream, length, position, prot, flags) { + // User requests writing to file (prot & PROT_WRITE != 0). + // Checking if we have permissions to write to the file unless + // MAP_PRIVATE flag is set. According to POSIX spec it is possible + // to write to file opened in read-only mode with MAP_PRIVATE flag, + // as all modifications will be visible only in the memory of + // the current process. + if ((prot & 2) !== 0 && (flags & 2) === 0 && (stream.flags & 2097155) !== 2) { + throw new FS.ErrnoError(2); + } + if ((stream.flags & 2097155) === 1) { + throw new FS.ErrnoError(2); + } + if (!stream.stream_ops.mmap) { + throw new FS.ErrnoError(43); + } + if (!length) { + throw new FS.ErrnoError(28); + } + return stream.stream_ops.mmap(stream, length, position, prot, flags); + }, + msync(stream, buffer, offset, length, mmapFlags) { + if (!stream.stream_ops.msync) { + return 0; + } + return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags); + }, + ioctl(stream, cmd, arg) { + if (!stream.stream_ops.ioctl) { + throw new FS.ErrnoError(59); + } + return stream.stream_ops.ioctl(stream, cmd, arg); + }, + readFile(path, opts = {}) { + opts.flags = opts.flags ?? 0; + opts.encoding = opts.encoding ?? "binary"; + if (opts.encoding !== "utf8" && opts.encoding !== "binary") { + abort(`Invalid encoding type "${opts.encoding}"`); + } + var stream = FS.open(path, opts.flags); + var stat = FS.stat(path); + var length = stat.size; + var buf = new Uint8Array(length); + FS.read(stream, buf, 0, length, 0); + if (opts.encoding === "utf8") { + buf = UTF8ArrayToString(buf); + } + FS.close(stream); + return buf; + }, + writeFile(path, data, opts = {}) { + opts.flags = opts.flags ?? 577; + var stream = FS.open(path, opts.flags, opts.mode); + data = FS_fileDataToTypedArray(data); + FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn); + FS.close(stream); + }, + cwd: () => FS.currentPath, + chdir(path) { + var lookup = FS.lookupPath(path, { + follow: true + }); + if (lookup.node === null) { + throw new FS.ErrnoError(44); + } + if (!FS.isDir(lookup.node.mode)) { + throw new FS.ErrnoError(54); + } + var errCode = FS.nodePermissions(lookup.node, "x"); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + FS.currentPath = lookup.path; + }, + createDefaultDirectories() { + FS.mkdir("/tmp"); + FS.mkdir("/home"); + FS.mkdir("/home/web_user"); + }, + createDefaultDevices() { + // create /dev + FS.mkdir("/dev"); + // setup /dev/null + FS.registerDevice(FS.makedev(1, 3), { + read: () => 0, + write: (stream, buffer, offset, length, pos) => length, + llseek: () => 0 + }); + FS.mkdev("/dev/null", FS.makedev(1, 3)); + // setup /dev/tty and /dev/tty1 + // stderr needs to print output using err() rather than out() + // so we register a second tty just for it. + TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); + TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); + FS.mkdev("/dev/tty", FS.makedev(5, 0)); + FS.mkdev("/dev/tty1", FS.makedev(6, 0)); + // setup /dev/[u]random + // use a buffer to avoid overhead of individual crypto calls per byte + var randomBuffer = new Uint8Array(1024), randomLeft = 0; + var randomByte = () => { + if (randomLeft === 0) { + randomFill(randomBuffer); + randomLeft = randomBuffer.byteLength; + } + return randomBuffer[--randomLeft]; + }; + FS.createDevice("/dev", "random", randomByte); + FS.createDevice("/dev", "urandom", randomByte); + // we're not going to emulate the actual shm device, + // just create the tmp dirs that reside in it commonly + FS.mkdir("/dev/shm"); + FS.mkdir("/dev/shm/tmp"); + }, + createSpecialDirectories() { + // create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the + // name of the stream for fd 6 (see test_unistd_ttyname) + FS.mkdir("/proc"); + var proc_self = FS.mkdir("/proc/self"); + FS.mkdir("/proc/self/fd"); + FS.mount({ + mount() { + var node = FS.createNode(proc_self, "fd", 16895, 73); + node.stream_ops = { + llseek: MEMFS.stream_ops.llseek + }; + node.node_ops = { + lookup(parent, name) { + var fd = +name; + var stream = FS.getStreamChecked(fd); + var ret = { + parent: null, + mount: { + mountpoint: "fake" + }, + node_ops: { + readlink: () => stream.path + }, + id: fd + 1 + }; + ret.parent = ret; + // make it look like a simple root node + return ret; + }, + readdir() { + return Array.from(FS.streams.entries()).filter(([k, v]) => v).map(([k, v]) => k.toString()); + } + }; + return node; + } + }, {}, "/proc/self/fd"); + }, + createStandardStreams(input, output, error) { + // TODO deprecate the old functionality of a single + // input / output callback and that utilizes FS.createDevice + // and instead require a unique set of stream ops + // by default, we symlink the standard streams to the + // default tty devices. however, if the standard streams + // have been overwritten we create a unique device for + // them instead. + if (input) { + FS.createDevice("/dev", "stdin", input); + } else { + FS.symlink("/dev/tty", "/dev/stdin"); + } + if (output) { + FS.createDevice("/dev", "stdout", null, output); + } else { + FS.symlink("/dev/tty", "/dev/stdout"); + } + if (error) { + FS.createDevice("/dev", "stderr", null, error); + } else { + FS.symlink("/dev/tty1", "/dev/stderr"); + } + // open default streams for the stdin, stdout and stderr devices + var stdin = FS.open("/dev/stdin", 0); + var stdout = FS.open("/dev/stdout", 1); + var stderr = FS.open("/dev/stderr", 1); + }, + staticInit() { + FS.nameTable = new Array(4096); + FS.mount(MEMFS, {}, "/"); + FS.createDefaultDirectories(); + FS.createDefaultDevices(); + FS.createSpecialDirectories(); + FS.filesystems = { + "MEMFS": MEMFS + }; + }, + init(input, output, error) { + FS.initialized = true; + // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here + input ??= Module["stdin"]; + output ??= Module["stdout"]; + error ??= Module["stderr"]; + FS.createStandardStreams(input, output, error); + }, + quit() { + FS.initialized = false; + // force-flush all streams, so we get musl std streams printed out + // close all of our streams + for (var stream of FS.streams) { + if (stream) { + FS.close(stream); + } + } + }, + findObject(path, dontResolveLastLink) { + var ret = FS.analyzePath(path, dontResolveLastLink); + if (!ret.exists) { + return null; + } + return ret.object; + }, + analyzePath(path, dontResolveLastLink) { + // operate from within the context of the symlink's target + try { + var lookup = FS.lookupPath(path, { + follow: !dontResolveLastLink + }); + path = lookup.path; + } catch (e) {} + var ret = { + isRoot: false, + exists: false, + error: 0, + name: null, + path: null, + object: null, + parentExists: false, + parentPath: null, + parentObject: null + }; + try { + var lookup = FS.lookupPath(path, { + parent: true + }); + ret.parentExists = true; + ret.parentPath = lookup.path; + ret.parentObject = lookup.node; + ret.name = PATH.basename(path); + lookup = FS.lookupPath(path, { + follow: !dontResolveLastLink + }); + ret.exists = true; + ret.path = lookup.path; + ret.object = lookup.node; + ret.name = lookup.node.name; + ret.isRoot = lookup.path === "/"; + } catch (e) { + ret.error = e.errno; + } + return ret; + }, + createPath(parent, path, canRead, canWrite) { + parent = typeof parent == "string" ? parent : FS.getPath(parent); + var parts = path.split("/").reverse(); + while (parts.length) { + var part = parts.pop(); + if (!part) continue; + var current = PATH.join2(parent, part); + try { + FS.mkdir(current); + } catch (e) { + if (e.errno != 20) throw e; + } + parent = current; + } + return current; + }, + createFile(parent, name, properties, canRead, canWrite) { + var path = PATH.join2(typeof parent == "string" ? parent : FS.getPath(parent), name); + var mode = FS_getMode(canRead, canWrite); + return FS.create(path, mode); + }, + createDataFile(parent, name, data, canRead, canWrite, canOwn) { + var path = name; + if (parent) { + parent = typeof parent == "string" ? parent : FS.getPath(parent); + path = name ? PATH.join2(parent, name) : parent; + } + var mode = FS_getMode(canRead, canWrite); + var node = FS.create(path, mode); + if (data) { + data = FS_fileDataToTypedArray(data); + // make sure we can write to the file + FS.chmod(node, mode | 146); + var stream = FS.open(node, 577); + FS.write(stream, data, 0, data.length, 0, canOwn); + FS.close(stream); + FS.chmod(node, mode); + } + }, + createDevice(parent, name, input, output) { + var path = PATH.join2(typeof parent == "string" ? parent : FS.getPath(parent), name); + var mode = FS_getMode(!!input, !!output); + FS.createDevice.major ??= 64; + var dev = FS.makedev(FS.createDevice.major++, 0); + // Create a fake device that a set of stream ops to emulate + // the old behavior. + FS.registerDevice(dev, { + open(stream) { + stream.seekable = false; + }, + close(stream) { + // flush any pending line data + if (output?.buffer?.length) { + output(10); + } + }, + read(stream, buffer, offset, length, pos) { + var bytesRead = 0; + for (var i = 0; i < length; i++) { + var result; + try { + result = input(); + } catch (e) { + throw new FS.ErrnoError(29); + } + if (result === undefined && bytesRead === 0) { + throw new FS.ErrnoError(6); + } + if (result === null || result === undefined) break; + bytesRead++; + buffer[offset + i] = result; + } + if (bytesRead) { + stream.node.atime = Date.now(); + } + return bytesRead; + }, + write(stream, buffer, offset, length, pos) { + for (var i = 0; i < length; i++) { + try { + output(buffer[offset + i]); + } catch (e) { + throw new FS.ErrnoError(29); + } + } + if (length) { + stream.node.mtime = stream.node.ctime = Date.now(); + } + return i; + } + }); + return FS.mkdev(path, mode, dev); + }, + forceLoadFile(obj) { + if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true; + if (globalThis.XMLHttpRequest) { + abort("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread."); + } else { + // Command-line. + try { + obj.contents = readBinary(obj.url); + } catch (e) { + throw new FS.ErrnoError(29); + } + } + }, + createLazyFile(parent, name, url, canRead, canWrite) { + // Lazy chunked Uint8Array (implements get and length from Uint8Array). + // Actual getting is abstracted away for eventual reuse. + class LazyUint8Array { + lengthKnown=false; + chunks=[]; + // Loaded chunks. Index is the chunk number + get(idx) { + if (idx > this.length - 1 || idx < 0) { + return undefined; + } + var chunkOffset = idx % this.chunkSize; + var chunkNum = (idx / this.chunkSize) | 0; + return this.getter(chunkNum)[chunkOffset]; + } + setDataGetter(getter) { + this.getter = getter; + } + cacheLength() { + // Find length + var xhr = new XMLHttpRequest; + xhr.open("HEAD", url, false); + xhr.send(null); + if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort("Couldn't load " + url + ". Status: " + xhr.status); + var datalength = Number(xhr.getResponseHeader("Content-length")); + var header; + var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; + var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip"; + var chunkSize = 1024 * 1024; + // Chunk size in bytes + if (!hasByteServing) chunkSize = datalength; + // Function to get a range from the remote URL. + var doXHR = (from, to) => { + if (from > to) abort(`invalid range (${from}, ${to}) or no bytes requested!`); + if (to > datalength - 1) abort(`only ${datalength} bytes available! programmer error!`); + // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available. + var xhr = new XMLHttpRequest; + xhr.open("GET", url, false); + if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); + // Some hints to the browser that we want binary data. + xhr.responseType = "arraybuffer"; + if (xhr.overrideMimeType) { + xhr.overrideMimeType("text/plain; charset=x-user-defined"); + } + xhr.send(null); + if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort("Couldn't load " + url + ". Status: " + xhr.status); + if (xhr.response !== undefined) { + return new Uint8Array(/** @type{Array} */ (xhr.response || [])); + } + return intArrayFromString(xhr.responseText ?? "", true); + }; + var lazyArray = this; + lazyArray.setDataGetter(chunkNum => { + var start = chunkNum * chunkSize; + var end = (chunkNum + 1) * chunkSize - 1; + // including this byte + end = Math.min(end, datalength - 1); + // if datalength-1 is selected, this is the last block + if (typeof lazyArray.chunks[chunkNum] == "undefined") { + lazyArray.chunks[chunkNum] = doXHR(start, end); + } + if (typeof lazyArray.chunks[chunkNum] == "undefined") abort("doXHR failed!"); + return lazyArray.chunks[chunkNum]; + }); + if (usesGzip || !datalength) { + // if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length + chunkSize = datalength = 1; + // this will force getter(0)/doXHR do download the whole file + datalength = this.getter(0).length; + chunkSize = datalength; + out("LazyFiles on gzip forces download of the whole file when length is accessed"); + } + this._length = datalength; + this._chunkSize = chunkSize; + this.lengthKnown = true; + } + get length() { + if (!this.lengthKnown) { + this.cacheLength(); + } + return this._length; + } + get chunkSize() { + if (!this.lengthKnown) { + this.cacheLength(); + } + return this._chunkSize; + } + } + if (globalThis.XMLHttpRequest) { + if (!ENVIRONMENT_IS_WORKER) abort("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc"); + var lazyArray = new LazyUint8Array; + var properties = { + isDevice: false, + contents: lazyArray + }; + } else { + var properties = { + isDevice: false, + url + }; + } + var node = FS.createFile(parent, name, properties, canRead, canWrite); + // This is a total hack, but I want to get this lazy file code out of the + // core of MEMFS. If we want to keep this lazy file concept I feel it should + // be its own thin LAZYFS proxying calls to MEMFS. + if (properties.contents) { + node.contents = properties.contents; + } else if (properties.url) { + node.contents = null; + node.url = properties.url; + } + // Add a function that defers querying the file size until it is asked the first time. + Object.defineProperties(node, { + usedBytes: { + get: function() { + return this.contents.length; + } + } + }); + // override each stream op with one that tries to force load the lazy file first + var stream_ops = {}; + for (const [key, fn] of Object.entries(node.stream_ops)) { + stream_ops[key] = (...args) => { + FS.forceLoadFile(node); + return fn(...args); + }; + } + function writeChunks(stream, buffer, offset, length, position) { + var contents = stream.node.contents; + if (position >= contents.length) return 0; + var size = Math.min(contents.length - position, length); + if (contents.slice) { + // normal array + for (var i = 0; i < size; i++) { + buffer[offset + i] = contents[position + i]; + } + } else { + for (var i = 0; i < size; i++) { + // LazyUint8Array from sync binary XHR + buffer[offset + i] = contents.get(position + i); + } + } + return size; + } + // use a custom read function + stream_ops.read = (stream, buffer, offset, length, position) => { + FS.forceLoadFile(node); + return writeChunks(stream, buffer, offset, length, position); + }; + // use a custom mmap function + stream_ops.mmap = (stream, length, position, prot, flags) => { + FS.forceLoadFile(node); + var ptr = mmapAlloc(length); + if (!ptr) { + throw new FS.ErrnoError(48); + } + writeChunks(stream, HEAP8, ptr, length, position); + return { + ptr, + allocated: true + }; + }; + node.stream_ops = stream_ops; + return node; + } +}; + +/** + * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the + * emscripten HEAP, returns a copy of that string as a Javascript String object. + * + * @param {number} ptr + * @param {number=} maxBytesToRead - An optional length that specifies the + * maximum number of bytes to read. You can omit this parameter to scan the + * string until the first 0 byte. If maxBytesToRead is passed, and the string + * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the + * string will cut short at that byte index. + * @param {boolean=} ignoreNul - If true, the function will not stop on a NUL character. + * @return {string} + */ var UTF8ToString = (ptr, maxBytesToRead, ignoreNul) => { + if (!ptr) return ""; + var end = findStringEnd(HEAPU8, ptr, maxBytesToRead, ignoreNul); + return UTF8Decoder.decode(HEAPU8.subarray(ptr, end)); +}; + +var SYSCALLS = { + currentUmask: 18, + calculateAt(dirfd, path, allowEmpty) { + if (PATH.isAbs(path)) { + return path; + } + // relative path + var dir; + if (dirfd === -100) { + dir = FS.cwd(); + } else { + var dirstream = SYSCALLS.getStreamFromFD(dirfd); + dir = dirstream.path; + } + if (path.length == 0) { + if (!allowEmpty) { + throw new FS.ErrnoError(44); + } + return dir; + } + return dir + "/" + path; + }, + writeStat(buf, stat) { + HEAPU32[((buf) >> 2)] = stat.dev; + HEAPU32[(((buf) + (4)) >> 2)] = stat.mode; + HEAPU32[(((buf) + (8)) >> 2)] = stat.nlink; + HEAPU32[(((buf) + (12)) >> 2)] = stat.uid; + HEAPU32[(((buf) + (16)) >> 2)] = stat.gid; + HEAPU32[(((buf) + (20)) >> 2)] = stat.rdev; + (tempI64 = [ stat.size >>> 0, (tempDouble = stat.size, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (24)) >> 2)] = tempI64[0], HEAP32[(((buf) + (28)) >> 2)] = tempI64[1]); + HEAP32[(((buf) + (32)) >> 2)] = 4096; + HEAP32[(((buf) + (36)) >> 2)] = stat.blocks; + var atime = stat.atime.getTime(); + var mtime = stat.mtime.getTime(); + var ctime = stat.ctime.getTime(); + (tempI64 = [ Math.floor(atime / 1e3) >>> 0, (tempDouble = Math.floor(atime / 1e3), + (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (40)) >> 2)] = tempI64[0], HEAP32[(((buf) + (44)) >> 2)] = tempI64[1]); + HEAPU32[(((buf) + (48)) >> 2)] = (atime % 1e3) * 1e3 * 1e3; + (tempI64 = [ Math.floor(mtime / 1e3) >>> 0, (tempDouble = Math.floor(mtime / 1e3), + (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (56)) >> 2)] = tempI64[0], HEAP32[(((buf) + (60)) >> 2)] = tempI64[1]); + HEAPU32[(((buf) + (64)) >> 2)] = (mtime % 1e3) * 1e3 * 1e3; + (tempI64 = [ Math.floor(ctime / 1e3) >>> 0, (tempDouble = Math.floor(ctime / 1e3), + (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (72)) >> 2)] = tempI64[0], HEAP32[(((buf) + (76)) >> 2)] = tempI64[1]); + HEAPU32[(((buf) + (80)) >> 2)] = (ctime % 1e3) * 1e3 * 1e3; + (tempI64 = [ stat.ino >>> 0, (tempDouble = stat.ino, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (88)) >> 2)] = tempI64[0], HEAP32[(((buf) + (92)) >> 2)] = tempI64[1]); + return 0; + }, + writeStatFs(buf, stats) { + HEAPU32[(((buf) + (4)) >> 2)] = stats.bsize; + HEAPU32[(((buf) + (60)) >> 2)] = stats.bsize; + (tempI64 = [ stats.blocks >>> 0, (tempDouble = stats.blocks, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (8)) >> 2)] = tempI64[0], HEAP32[(((buf) + (12)) >> 2)] = tempI64[1]); + (tempI64 = [ stats.bfree >>> 0, (tempDouble = stats.bfree, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (16)) >> 2)] = tempI64[0], HEAP32[(((buf) + (20)) >> 2)] = tempI64[1]); + (tempI64 = [ stats.bavail >>> 0, (tempDouble = stats.bavail, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (24)) >> 2)] = tempI64[0], HEAP32[(((buf) + (28)) >> 2)] = tempI64[1]); + (tempI64 = [ stats.files >>> 0, (tempDouble = stats.files, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (32)) >> 2)] = tempI64[0], HEAP32[(((buf) + (36)) >> 2)] = tempI64[1]); + (tempI64 = [ stats.ffree >>> 0, (tempDouble = stats.ffree, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[(((buf) + (40)) >> 2)] = tempI64[0], HEAP32[(((buf) + (44)) >> 2)] = tempI64[1]); + HEAPU32[(((buf) + (48)) >> 2)] = stats.fsid; + HEAPU32[(((buf) + (64)) >> 2)] = stats.flags; + // ST_NOSUID + HEAPU32[(((buf) + (56)) >> 2)] = stats.namelen; + }, + doMsync(addr, stream, len, flags, offset) { + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + if (flags & 2) { + // MAP_PRIVATE calls need not to be synced back to underlying fs + return 0; + } + var buffer = HEAPU8.slice(addr, addr + len); + FS.msync(stream, buffer, offset, len, flags); + }, + getStreamFromFD(fd) { + var stream = FS.getStreamChecked(fd); + return stream; + }, + varargs: undefined, + getStr(ptr) { + var ret = UTF8ToString(ptr); + return ret; + } +}; + +function ___syscall_dup(fd) { + try { + var old = SYSCALLS.getStreamFromFD(fd); + return FS.dupStream(old).fd; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_faccessat(dirfd, path, amode, flags) { + try { + path = SYSCALLS.getStr(path); + path = SYSCALLS.calculateAt(dirfd, path); + if (amode & ~7) { + // need a valid mode + return -28; + } + var lookup = FS.lookupPath(path, { + follow: true + }); + var node = lookup.node; + if (!node) { + return -44; + } + var perms = ""; + if (amode & 4) perms += "r"; + if (amode & 2) perms += "w"; + if (amode & 1) perms += "x"; + if (perms && FS.nodePermissions(node, perms)) { + return -2; + } + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +var syscallGetVarargI = () => { + // the `+` prepended here is necessary to convince the JSCompiler that varargs is indeed a number. + var ret = HEAP32[((+SYSCALLS.varargs) >> 2)]; + SYSCALLS.varargs += 4; + return ret; +}; + +var syscallGetVarargP = syscallGetVarargI; + +function ___syscall_fcntl64(fd, cmd, varargs) { + SYSCALLS.varargs = varargs; + try { + var stream = SYSCALLS.getStreamFromFD(fd); + switch (cmd) { + case 0: + { + var arg = syscallGetVarargI(); + if (arg < 0) { + return -28; + } + while (FS.streams[arg]) { + arg++; + } + var newStream; + newStream = FS.dupStream(stream, arg); + return newStream.fd; + } + + case 1: + case 2: + return 0; + + // FD_CLOEXEC makes no sense for a single process. + case 3: + return stream.flags; + + case 4: + { + var arg = syscallGetVarargI(); + var mask = 289792; + stream.flags = (stream.flags & ~mask) | (arg & mask); + return 0; + } + + case 12: + { + var arg = syscallGetVarargP(); + var offset = 0; + // We're always unlocked. + HEAP16[(((arg) + (offset)) >> 1)] = 2; + return 0; + } + + case 13: + case 14: + // Pretend that the locking is successful. These are process-level locks, + // and Emscripten programs are a single process. If we supported linking a + // filesystem between programs, we'd need to do more here. + // See https://github.com/emscripten-core/emscripten/issues/23697 + return 0; + } + return -28; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_fstat64(fd, buf) { + try { + return SYSCALLS.writeStat(buf, FS.fstat(fd)); + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +var convertI32PairToI53Checked = (lo, hi) => ((hi + 2097152) >>> 0 < 4194305 - !!lo) ? (lo >>> 0) + hi * 4294967296 : NaN; + +function ___syscall_ftruncate64(fd, length_low, length_high) { + var length = convertI32PairToI53Checked(length_low, length_high); + try { + if (isNaN(length)) return -22; + FS.ftruncate(fd, length); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_ioctl(fd, op, varargs) { + SYSCALLS.varargs = varargs; + try { + var stream = SYSCALLS.getStreamFromFD(fd); + switch (op) { + case 21509: + { + if (!stream.tty) return -59; + return 0; + } + + case 21505: + { + if (!stream.tty) return -59; + if (stream.tty.ops.ioctl_tcgets) { + var termios = stream.tty.ops.ioctl_tcgets(stream); + var argp = syscallGetVarargP(); + HEAP32[((argp) >> 2)] = termios.c_iflag || 0; + HEAP32[(((argp) + (4)) >> 2)] = termios.c_oflag || 0; + HEAP32[(((argp) + (8)) >> 2)] = termios.c_cflag || 0; + HEAP32[(((argp) + (12)) >> 2)] = termios.c_lflag || 0; + for (var i = 0; i < 32; i++) { + HEAP8[(argp + i) + (17)] = termios.c_cc[i] || 0; + } + return 0; + } + return 0; + } + + case 21510: + case 21511: + case 21512: + { + if (!stream.tty) return -59; + return 0; + } + + case 21506: + case 21507: + case 21508: + { + if (!stream.tty) return -59; + if (stream.tty.ops.ioctl_tcsets) { + var argp = syscallGetVarargP(); + var c_iflag = HEAP32[((argp) >> 2)]; + var c_oflag = HEAP32[(((argp) + (4)) >> 2)]; + var c_cflag = HEAP32[(((argp) + (8)) >> 2)]; + var c_lflag = HEAP32[(((argp) + (12)) >> 2)]; + var c_cc = []; + for (var i = 0; i < 32; i++) { + c_cc.push(HEAP8[(argp + i) + (17)]); + } + return stream.tty.ops.ioctl_tcsets(stream.tty, op, { + c_iflag, + c_oflag, + c_cflag, + c_lflag, + c_cc + }); + } + return 0; + } + + case 21519: + { + if (!stream.tty) return -59; + var argp = syscallGetVarargP(); + HEAP32[((argp) >> 2)] = 0; + return 0; + } + + case 21520: + { + if (!stream.tty) return -59; + return -28; + } + + case 21537: + case 21531: + { + var argp = syscallGetVarargP(); + return FS.ioctl(stream, op, argp); + } + + case 21523: + { + // TODO: in theory we should write to the winsize struct that gets + // passed in, but for now musl doesn't read anything on it + if (!stream.tty) return -59; + if (stream.tty.ops.ioctl_tiocgwinsz) { + var winsize = stream.tty.ops.ioctl_tiocgwinsz(stream.tty); + var argp = syscallGetVarargP(); + HEAP16[((argp) >> 1)] = winsize[0]; + HEAP16[(((argp) + (2)) >> 1)] = winsize[1]; + } + return 0; + } + + case 21524: + { + // TODO: technically, this ioctl call should change the window size. + // but, since emscripten doesn't have any concept of a terminal window + // yet, we'll just silently throw it away as we do TIOCGWINSZ + if (!stream.tty) return -59; + return 0; + } + + case 21515: + { + if (!stream.tty) return -59; + return 0; + } + + default: + return -28; + } + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_lstat64(path, buf) { + try { + path = SYSCALLS.getStr(path); + return SYSCALLS.writeStat(buf, FS.lstat(path)); + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_newfstatat(dirfd, path, buf, flags) { + try { + path = SYSCALLS.getStr(path); + var nofollow = flags & 256; + var allowEmpty = flags & 4096; + flags = flags & (~6400); + path = SYSCALLS.calculateAt(dirfd, path, allowEmpty); + return SYSCALLS.writeStat(buf, nofollow ? FS.lstat(path) : FS.stat(path)); + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_openat(dirfd, path, flags, varargs) { + SYSCALLS.varargs = varargs; + try { + path = SYSCALLS.getStr(path); + path = SYSCALLS.calculateAt(dirfd, path); + var mode = varargs ? syscallGetVarargI() : 0; + if (flags & 64) { + mode &= ~SYSCALLS.currentUmask; + } + return FS.open(path, flags, mode).fd; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function ___syscall_stat64(path, buf) { + try { + path = SYSCALLS.getStr(path); + return SYSCALLS.writeStat(buf, FS.stat(path)); + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +var __abort_js = () => abort(""); + +var __embind_register_bigint = (primitiveType, name, size, minRange, maxRange) => {}; + +var AsciiToString = ptr => { + var str = ""; + while (1) { + var ch = HEAPU8[ptr++]; + if (!ch) return str; + str += String.fromCharCode(ch); + } +}; + +var awaitingDependencies = {}; + +var registeredTypes = {}; + +var typeDependencies = {}; + +var BindingError = class BindingError extends Error { + constructor(message) { + super(message); + this.name = "BindingError"; + } +}; + +var throwBindingError = message => { + throw new BindingError(message); +}; + +/** @param {Object=} options */ function sharedRegisterType(rawType, registeredInstance, options = {}) { + var name = registeredInstance.name; + if (!rawType) { + throwBindingError(`type "${name}" must have a positive integer typeid pointer`); + } + if (registeredTypes.hasOwnProperty(rawType)) { + if (options.ignoreDuplicateRegistrations) { + return; + } else { + throwBindingError(`Cannot register type '${name}' twice`); + } + } + registeredTypes[rawType] = registeredInstance; + delete typeDependencies[rawType]; + if (awaitingDependencies.hasOwnProperty(rawType)) { + var callbacks = awaitingDependencies[rawType]; + delete awaitingDependencies[rawType]; + callbacks.forEach(cb => cb()); + } +} + +/** @param {Object=} options */ function registerType(rawType, registeredInstance, options = {}) { + return sharedRegisterType(rawType, registeredInstance, options); +} + +/** @suppress {globalThis} */ var __embind_register_bool = (rawType, name, trueValue, falseValue) => { + name = AsciiToString(name); + registerType(rawType, { + name, + fromWireType: function(wt) { + // ambiguous emscripten ABI: sometimes return values are + // true or false, and sometimes integers (0 or 1) + return !!wt; + }, + toWireType: function(destructors, o) { + return o ? trueValue : falseValue; + }, + readValueFromPointer: function(pointer) { + return this.fromWireType(HEAPU8[pointer]); + }, + destructorFunction: null + }); +}; + +var emval_freelist = []; + +var emval_handles = [ 0, 1, , 1, null, 1, true, 1, false, 1 ]; + +var __emval_decref = handle => { + if (handle > 9 && 0 === --emval_handles[handle + 1]) { + var value = emval_handles[handle]; + emval_handles[handle] = undefined; + emval_freelist.push(handle); + } +}; + +var Emval = { + toValue: handle => { + if (!handle) { + throwBindingError(`Cannot use deleted val. handle = ${handle}`); + } + return emval_handles[handle]; + }, + toHandle: value => { + switch (value) { + case undefined: + return 2; + + case null: + return 4; + + case true: + return 6; + + case false: + return 8; + + default: + { + const handle = emval_freelist.pop() || emval_handles.length; + emval_handles[handle] = value; + emval_handles[handle + 1] = 1; + return handle; + } + } + } +}; + +/** @suppress {globalThis} */ function readPointer(pointer) { + return this.fromWireType(HEAPU32[((pointer) >> 2)]); +} + +var EmValType = { + name: "emscripten::val", + fromWireType: handle => { + var rv = Emval.toValue(handle); + __emval_decref(handle); + return rv; + }, + toWireType: (destructors, value) => Emval.toHandle(value), + readValueFromPointer: readPointer, + destructorFunction: null +}; + +var __embind_register_emval = rawType => registerType(rawType, EmValType); + +var floatReadValueFromPointer = (name, width) => { + switch (width) { + case 4: + return function(pointer) { + return this.fromWireType(HEAPF32[((pointer) >> 2)]); + }; + + case 8: + return function(pointer) { + return this.fromWireType(HEAPF64[((pointer) >> 3)]); + }; + + default: + throw new TypeError(`invalid float width (${width}): ${name}`); + } +}; + +var __embind_register_float = (rawType, name, size) => { + name = AsciiToString(name); + registerType(rawType, { + name, + fromWireType: value => value, + toWireType: (destructors, value) => value, + readValueFromPointer: floatReadValueFromPointer(name, size), + destructorFunction: null + }); +}; + +var integerReadValueFromPointer = (name, width, signed) => { + // integers are quite common, so generate very specialized functions + switch (width) { + case 1: + return signed ? pointer => HEAP8[pointer] : pointer => HEAPU8[pointer]; + + case 2: + return signed ? pointer => HEAP16[((pointer) >> 1)] : pointer => HEAPU16[((pointer) >> 1)]; + + case 4: + return signed ? pointer => HEAP32[((pointer) >> 2)] : pointer => HEAPU32[((pointer) >> 2)]; + + default: + throw new TypeError(`invalid integer width (${width}): ${name}`); + } +}; + +/** @suppress {globalThis} */ var __embind_register_integer = (primitiveType, name, size, minRange, maxRange) => { + name = AsciiToString(name); + const isUnsignedType = minRange === 0; + let fromWireType = value => value; + if (isUnsignedType) { + var bitshift = 32 - 8 * size; + fromWireType = value => (value << bitshift) >>> bitshift; + maxRange = fromWireType(maxRange); + } + registerType(primitiveType, { + name, + fromWireType, + toWireType: (destructors, value) => value, + readValueFromPointer: integerReadValueFromPointer(name, size, minRange !== 0), + destructorFunction: null + }); +}; + +var __embind_register_memory_view = (rawType, dataTypeIndex, name) => { + var typeMapping = [ Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array ]; + var TA = typeMapping[dataTypeIndex]; + function decodeMemoryView(handle) { + var size = HEAPU32[((handle) >> 2)]; + var data = HEAPU32[(((handle) + (4)) >> 2)]; + return new TA(HEAP8.buffer, data, size); + } + name = AsciiToString(name); + registerType(rawType, { + name, + fromWireType: decodeMemoryView, + readValueFromPointer: decodeMemoryView + }, { + ignoreDuplicateRegistrations: true + }); +}; + +var stringToUTF8 = (str, outPtr, maxBytesToWrite) => stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite); + +var __embind_register_std_string = (rawType, name) => { + name = AsciiToString(name); + var stdStringIsUTF8 = true; + registerType(rawType, { + name, + // For some method names we use string keys here since they are part of + // the public/external API and/or used by the runtime-generated code. + fromWireType(value) { + var length = HEAPU32[((value) >> 2)]; + var payload = value + 4; + var str; + if (stdStringIsUTF8) { + str = UTF8ToString(payload, length, true); + } else { + str = ""; + for (var i = 0; i < length; ++i) { + str += String.fromCharCode(HEAPU8[payload + i]); + } + } + _free(value); + return str; + }, + toWireType(destructors, value) { + if (value instanceof ArrayBuffer) { + value = new Uint8Array(value); + } + var length; + var valueIsOfTypeString = (typeof value == "string"); + // We accept `string` or array views with single byte elements + if (!(valueIsOfTypeString || (ArrayBuffer.isView(value) && value.BYTES_PER_ELEMENT == 1))) { + throwBindingError("Cannot pass non-string to std::string"); + } + if (stdStringIsUTF8 && valueIsOfTypeString) { + length = lengthBytesUTF8(value); + } else { + length = value.length; + } + // assumes POINTER_SIZE alignment + var base = _malloc(4 + length + 1); + var ptr = base + 4; + HEAPU32[((base) >> 2)] = length; + if (valueIsOfTypeString) { + if (stdStringIsUTF8) { + stringToUTF8(value, ptr, length + 1); + } else { + for (var i = 0; i < length; ++i) { + var charCode = value.charCodeAt(i); + if (charCode > 255) { + _free(base); + throwBindingError("String has UTF-16 code units that do not fit in 8 bits"); + } + HEAPU8[ptr + i] = charCode; + } + } + } else { + HEAPU8.set(value, ptr); + } + if (destructors !== null) { + destructors.push(_free, base); + } + return base; + }, + readValueFromPointer: readPointer, + destructorFunction(ptr) { + _free(ptr); + } + }); +}; + +var UTF16Decoder = new TextDecoder("utf-16le"); + +var UTF16ToString = (ptr, maxBytesToRead, ignoreNul) => { + var idx = ((ptr) >> 1); + var endIdx = findStringEnd(HEAPU16, idx, maxBytesToRead / 2, ignoreNul); + return UTF16Decoder.decode(HEAPU16.subarray(idx, endIdx)); +}; + +var stringToUTF16 = (str, outPtr, maxBytesToWrite) => { + // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. + maxBytesToWrite ??= 2147483647; + if (maxBytesToWrite < 2) return 0; + maxBytesToWrite -= 2; + // Null terminator. + var startPtr = outPtr; + var numCharsToWrite = (maxBytesToWrite < str.length * 2) ? (maxBytesToWrite / 2) : str.length; + for (var i = 0; i < numCharsToWrite; ++i) { + // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP. + var codeUnit = str.charCodeAt(i); + // possibly a lead surrogate + HEAP16[((outPtr) >> 1)] = codeUnit; + outPtr += 2; + } + // Null-terminate the pointer to the HEAP. + HEAP16[((outPtr) >> 1)] = 0; + return outPtr - startPtr; +}; + +var lengthBytesUTF16 = str => str.length * 2; + +var UTF32ToString = (ptr, maxBytesToRead, ignoreNul) => { + var str = ""; + var startIdx = ((ptr) >> 2); + // If maxBytesToRead is not passed explicitly, it will be undefined, and this + // will always evaluate to true. This saves on code size. + for (var i = 0; !(i >= maxBytesToRead / 4); i++) { + var utf32 = HEAPU32[startIdx + i]; + if (!utf32 && !ignoreNul) break; + str += String.fromCodePoint(utf32); + } + return str; +}; + +var stringToUTF32 = (str, outPtr, maxBytesToWrite) => { + // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. + maxBytesToWrite ??= 2147483647; + if (maxBytesToWrite < 4) return 0; + var startPtr = outPtr; + var endPtr = startPtr + maxBytesToWrite - 4; + for (var i = 0; i < str.length; ++i) { + var codePoint = str.codePointAt(i); + // Gotcha: if codePoint is over 0xFFFF, it is represented as a surrogate pair in UTF-16. + // We need to manually skip over the second code unit for correct iteration. + if (codePoint > 65535) { + i++; + } + HEAP32[((outPtr) >> 2)] = codePoint; + outPtr += 4; + if (outPtr + 4 > endPtr) break; + } + // Null-terminate the pointer to the HEAP. + HEAP32[((outPtr) >> 2)] = 0; + return outPtr - startPtr; +}; + +var lengthBytesUTF32 = str => { + var len = 0; + for (var i = 0; i < str.length; ++i) { + var codePoint = str.codePointAt(i); + // Gotcha: if codePoint is over 0xFFFF, it is represented as a surrogate pair in UTF-16. + // We need to manually skip over the second code unit for correct iteration. + if (codePoint > 65535) { + i++; + } + len += 4; + } + return len; +}; + +var __embind_register_std_wstring = (rawType, charSize, name) => { + name = AsciiToString(name); + var decodeString, encodeString, lengthBytesUTF; + if (charSize === 2) { + decodeString = UTF16ToString; + encodeString = stringToUTF16; + lengthBytesUTF = lengthBytesUTF16; + } else { + decodeString = UTF32ToString; + encodeString = stringToUTF32; + lengthBytesUTF = lengthBytesUTF32; + } + registerType(rawType, { + name, + fromWireType: value => { + // Code mostly taken from _embind_register_std_string fromWireType + var length = HEAPU32[((value) >> 2)]; + var str = decodeString(value + 4, length * charSize, true); + _free(value); + return str; + }, + toWireType: (destructors, value) => { + if (!(typeof value == "string")) { + throwBindingError(`Cannot pass non-string to C++ string type ${name}`); + } + // assumes POINTER_SIZE alignment + var length = lengthBytesUTF(value); + var ptr = _malloc(4 + length + charSize); + HEAPU32[((ptr) >> 2)] = length / charSize; + encodeString(value, ptr + 4, length + charSize); + if (destructors !== null) { + destructors.push(_free, ptr); + } + return ptr; + }, + readValueFromPointer: readPointer, + destructorFunction(ptr) { + _free(ptr); + } + }); +}; + +var __embind_register_void = (rawType, name) => { + name = AsciiToString(name); + registerType(rawType, { + isVoid: true, + // void return values can be optimized out sometimes + name, + fromWireType: () => undefined, + // TODO: assert if anything else is given? + toWireType: (destructors, o) => undefined + }); +}; + +var emval_methodCallers = []; + +var emval_addMethodCaller = caller => { + var id = emval_methodCallers.length; + emval_methodCallers.push(caller); + return id; +}; + +var getTypeName = type => { + var ptr = ___getTypeName(type); + var rv = AsciiToString(ptr); + _free(ptr); + return rv; +}; + +var requireRegisteredType = (rawType, humanName) => { + var impl = registeredTypes[rawType]; + if (undefined === impl) { + throwBindingError(`${humanName} has unknown type ${getTypeName(rawType)}`); + } + return impl; +}; + +var emval_lookupTypes = (argCount, argTypes) => { + var a = new Array(argCount); + for (var i = 0; i < argCount; ++i) { + a[i] = requireRegisteredType(HEAPU32[(((argTypes) + (i * 4)) >> 2)], `parameter ${i}`); + } + return a; +}; + +var createNamedFunction = (name, func) => Object.defineProperty(func, "name", { + value: name +}); + +var emval_returnValue = (toReturnWire, destructorsRef, handle) => { + var destructors = []; + var result = toReturnWire(destructors, handle); + if (destructors.length) { + // void, primitives and any other types w/o destructors don't need to allocate a handle + HEAPU32[((destructorsRef) >> 2)] = Emval.toHandle(destructors); + } + return result; +}; + +var emval_symbols = {}; + +var getStringOrSymbol = address => { + var symbol = emval_symbols[address]; + if (symbol === undefined) { + return AsciiToString(address); + } + return symbol; +}; + +var __emval_create_invoker = (argCount, argTypesPtr, kind) => { + var GenericWireTypeSize = 8; + var [retType, ...argTypes] = emval_lookupTypes(argCount, argTypesPtr); + var toReturnWire = retType.toWireType.bind(retType); + var argFromPtr = argTypes.map(type => type.readValueFromPointer.bind(type)); + argCount--; + // remove the extracted return type + var argN = new Array(argCount); + var invokerFunction = (handle, methodName, destructorsRef, args) => { + var offset = 0; + for (var i = 0; i < argCount; ++i) { + argN[i] = argFromPtr[i](args + offset); + offset += GenericWireTypeSize; + } + var rv; + switch (kind) { + case 0: + rv = Emval.toValue(handle).apply(null, argN); + break; + + case 2: + rv = Reflect.construct(Emval.toValue(handle), argN); + break; + + case 3: + // no-op, just return the argument + rv = argN[0]; + break; + + case 1: + rv = Emval.toValue(handle)[getStringOrSymbol(methodName)](...argN); + break; + } + return emval_returnValue(toReturnWire, destructorsRef, rv); + }; + var functionName = `methodCaller<(${argTypes.map(t => t.name)}) => ${retType.name}>`; + return emval_addMethodCaller(createNamedFunction(functionName, invokerFunction)); +}; + +var __emval_get_global = name => { + if (!name) { + return Emval.toHandle(globalThis); + } + name = getStringOrSymbol(name); + return Emval.toHandle(globalThis[name]); +}; + +var __emval_get_property = (handle, key) => { + handle = Emval.toValue(handle); + key = Emval.toValue(key); + return Emval.toHandle(handle[key]); +}; + +var __emval_incref = handle => { + if (handle > 9) { + emval_handles[handle + 1] += 1; + } +}; + +var __emval_instanceof = (object, constructor) => { + object = Emval.toValue(object); + constructor = Emval.toValue(constructor); + return object instanceof constructor; +}; + +var __emval_invoke = (caller, handle, methodName, destructorsRef, args) => emval_methodCallers[caller](handle, methodName, destructorsRef, args); + +var __emval_new_cstring = v => Emval.toHandle(getStringOrSymbol(v)); + +var runDestructors = destructors => { + while (destructors.length) { + var ptr = destructors.pop(); + var del = destructors.pop(); + del(ptr); + } +}; + +var __emval_run_destructors = handle => { + var destructors = Emval.toValue(handle); + runDestructors(destructors); + __emval_decref(handle); +}; + +var __emval_set_property = (handle, key, value) => { + handle = Emval.toValue(handle); + key = Emval.toValue(key); + value = Emval.toValue(value); + handle[key] = value; +}; + +var __emval_typeof = handle => { + handle = Emval.toValue(handle); + return Emval.toHandle(typeof handle); +}; + +function __gmtime_js(time_low, time_high, tmPtr) { + var time = convertI32PairToI53Checked(time_low, time_high); + var date = new Date(time * 1e3); + HEAP32[((tmPtr) >> 2)] = date.getUTCSeconds(); + HEAP32[(((tmPtr) + (4)) >> 2)] = date.getUTCMinutes(); + HEAP32[(((tmPtr) + (8)) >> 2)] = date.getUTCHours(); + HEAP32[(((tmPtr) + (12)) >> 2)] = date.getUTCDate(); + HEAP32[(((tmPtr) + (16)) >> 2)] = date.getUTCMonth(); + HEAP32[(((tmPtr) + (20)) >> 2)] = date.getUTCFullYear() - 1900; + HEAP32[(((tmPtr) + (24)) >> 2)] = date.getUTCDay(); + var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0); + var yday = ((date.getTime() - start) / (1e3 * 60 * 60 * 24)) | 0; + HEAP32[(((tmPtr) + (28)) >> 2)] = yday; +} + +var isLeapYear = year => year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0); + +var MONTH_DAYS_LEAP_CUMULATIVE = [ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 ]; + +var MONTH_DAYS_REGULAR_CUMULATIVE = [ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 ]; + +var ydayFromDate = date => { + var leap = isLeapYear(date.getFullYear()); + var monthDaysCumulative = (leap ? MONTH_DAYS_LEAP_CUMULATIVE : MONTH_DAYS_REGULAR_CUMULATIVE); + var yday = monthDaysCumulative[date.getMonth()] + date.getDate() - 1; + // -1 since it's days since Jan 1 + return yday; +}; + +function __localtime_js(time_low, time_high, tmPtr) { + var time = convertI32PairToI53Checked(time_low, time_high); + var date = new Date(time * 1e3); + HEAP32[((tmPtr) >> 2)] = date.getSeconds(); + HEAP32[(((tmPtr) + (4)) >> 2)] = date.getMinutes(); + HEAP32[(((tmPtr) + (8)) >> 2)] = date.getHours(); + HEAP32[(((tmPtr) + (12)) >> 2)] = date.getDate(); + HEAP32[(((tmPtr) + (16)) >> 2)] = date.getMonth(); + HEAP32[(((tmPtr) + (20)) >> 2)] = date.getFullYear() - 1900; + HEAP32[(((tmPtr) + (24)) >> 2)] = date.getDay(); + var yday = ydayFromDate(date) | 0; + HEAP32[(((tmPtr) + (28)) >> 2)] = yday; + HEAP32[(((tmPtr) + (36)) >> 2)] = -(date.getTimezoneOffset() * 60); + // Attention: DST is in December in South, and some regions don't have DST at all. + var start = new Date(date.getFullYear(), 0, 1); + var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset(); + var winterOffset = start.getTimezoneOffset(); + var dst = (summerOffset != winterOffset && date.getTimezoneOffset() == Math.min(winterOffset, summerOffset)) | 0; + HEAP32[(((tmPtr) + (32)) >> 2)] = dst; +} + +var setTempRet0 = val => __emscripten_tempret_set(val); + +var __mktime_js = function(tmPtr) { + var ret = (() => { + var date = new Date(HEAP32[(((tmPtr) + (20)) >> 2)] + 1900, HEAP32[(((tmPtr) + (16)) >> 2)], HEAP32[(((tmPtr) + (12)) >> 2)], HEAP32[(((tmPtr) + (8)) >> 2)], HEAP32[(((tmPtr) + (4)) >> 2)], HEAP32[((tmPtr) >> 2)], 0); + if (isNaN(date.getTime())) { + return -1; + } + // There's an ambiguous hour when the time goes back; the tm_isdst field is + // used to disambiguate it. Date() basically guesses, so we fix it up if it + // guessed wrong, or fill in tm_isdst with the guess if it's -1. + var dst = HEAP32[(((tmPtr) + (32)) >> 2)]; + var guessedOffset = date.getTimezoneOffset(); + var start = new Date(date.getFullYear(), 0, 1); + var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset(); + var winterOffset = start.getTimezoneOffset(); + var dstOffset = Math.min(winterOffset, summerOffset); + // DST is in December in South + if (dst < 0) { + // Attention: some regions don't have DST at all. + HEAP32[(((tmPtr) + (32)) >> 2)] = Number(summerOffset != winterOffset && dstOffset == guessedOffset); + } else if ((dst > 0) != (dstOffset == guessedOffset)) { + var nonDstOffset = Math.max(winterOffset, summerOffset); + var trueOffset = dst > 0 ? dstOffset : nonDstOffset; + // Don't try setMinutes(date.getMinutes() + ...) -- it's messed up. + date.setTime(date.getTime() + (trueOffset - guessedOffset) * 6e4); + } + HEAP32[(((tmPtr) + (24)) >> 2)] = date.getDay(); + var yday = ydayFromDate(date) | 0; + HEAP32[(((tmPtr) + (28)) >> 2)] = yday; + // To match expected behavior, update fields from date + HEAP32[((tmPtr) >> 2)] = date.getSeconds(); + HEAP32[(((tmPtr) + (4)) >> 2)] = date.getMinutes(); + HEAP32[(((tmPtr) + (8)) >> 2)] = date.getHours(); + HEAP32[(((tmPtr) + (12)) >> 2)] = date.getDate(); + HEAP32[(((tmPtr) + (16)) >> 2)] = date.getMonth(); + HEAP32[(((tmPtr) + (20)) >> 2)] = date.getYear(); + // Return time in seconds + return date.getTime() / 1e3; + })(); + return (setTempRet0((tempDouble = ret, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0)), + ret >>> 0); +}; + +function __mmap_js(len, prot, flags, fd, offset_low, offset_high, allocated, addr) { + var offset = convertI32PairToI53Checked(offset_low, offset_high); + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var res = FS.mmap(stream, len, offset, prot, flags); + var ptr = res.ptr; + HEAP32[((allocated) >> 2)] = res.allocated; + HEAPU32[((addr) >> 2)] = ptr; + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +function __munmap_js(addr, len, prot, flags, fd, offset_low, offset_high) { + var offset = convertI32PairToI53Checked(offset_low, offset_high); + try { + var stream = SYSCALLS.getStreamFromFD(fd); + if (prot & 2) { + SYSCALLS.doMsync(addr, stream, len, flags, offset); + } + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +var __tzset_js = (timezone, daylight, std_name, dst_name) => { + // TODO: Use (malleable) environment variables instead of system settings. + var currentYear = (new Date).getFullYear(); + var winter = new Date(currentYear, 0, 1); + var summer = new Date(currentYear, 6, 1); + var winterOffset = winter.getTimezoneOffset(); + var summerOffset = summer.getTimezoneOffset(); + // Local standard timezone offset. Local standard time is not adjusted for + // daylight savings. This code uses the fact that getTimezoneOffset returns + // a greater value during Standard Time versus Daylight Saving Time (DST). + // Thus it determines the expected output during Standard Time, and it + // compares whether the output of the given date the same (Standard) or less + // (DST). + var stdTimezoneOffset = Math.max(winterOffset, summerOffset); + // timezone is specified as seconds west of UTC ("The external variable + // `timezone` shall be set to the difference, in seconds, between + // Coordinated Universal Time (UTC) and local standard time."), the same + // as returned by stdTimezoneOffset. + // See http://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html + HEAPU32[((timezone) >> 2)] = stdTimezoneOffset * 60; + HEAP32[((daylight) >> 2)] = Number(winterOffset != summerOffset); + var extractZone = timezoneOffset => { + // Why inverse sign? + // Read here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset + var sign = timezoneOffset >= 0 ? "-" : "+"; + var absOffset = Math.abs(timezoneOffset); + var hours = String(Math.floor(absOffset / 60)).padStart(2, "0"); + var minutes = String(absOffset % 60).padStart(2, "0"); + return `UTC${sign}${hours}${minutes}`; + }; + var winterName = extractZone(winterOffset); + var summerName = extractZone(summerOffset); + if (summerOffset < winterOffset) { + // Northern hemisphere + stringToUTF8(winterName, std_name, 17); + stringToUTF8(summerName, dst_name, 17); + } else { + stringToUTF8(winterName, dst_name, 17); + stringToUTF8(summerName, std_name, 17); + } +}; + +var _emscripten_get_now = () => performance.now(); + +var _emscripten_date_now = () => Date.now(); + +var nowIsMonotonic = 1; + +var checkWasiClock = clock_id => clock_id >= 0 && clock_id <= 3; + +function _clock_time_get(clk_id, ignored_precision_low, ignored_precision_high, ptime) { + var ignored_precision = convertI32PairToI53Checked(ignored_precision_low, ignored_precision_high); + if (!checkWasiClock(clk_id)) { + return 28; + } + var now; + // all wasi clocks but realtime are monotonic + if (clk_id === 0) { + now = _emscripten_date_now(); + } else if (nowIsMonotonic) { + now = _emscripten_get_now(); + } else { + return 52; + } + // "now" is in ms, and wasi times are in ns. + var nsec = Math.round(now * 1e3 * 1e3); + (tempI64 = [ nsec >>> 0, (tempDouble = nsec, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[((ptime) >> 2)] = tempI64[0], HEAP32[(((ptime) + (4)) >> 2)] = tempI64[1]); + return 0; +} + +var readEmAsmArgsArray = []; + +var readEmAsmArgs = (sigPtr, buf) => { + readEmAsmArgsArray.length = 0; + var ch; + // Most arguments are i32s, so shift the buffer pointer so it is a plain + // index into HEAP32. + while (ch = HEAPU8[sigPtr++]) { + // Floats are always passed as doubles, so all types except for 'i' + // are 8 bytes and require alignment. + var wide = (ch != 105); + wide &= (ch != 112); + buf += wide && (buf % 8) ? 4 : 0; + readEmAsmArgsArray.push(// Special case for pointers under wasm64 or CAN_ADDRESS_2GB mode. + ch == 112 ? HEAPU32[((buf) >> 2)] : ch == 105 ? HEAP32[((buf) >> 2)] : HEAPF64[((buf) >> 3)]); + buf += wide ? 8 : 4; + } + return readEmAsmArgsArray; +}; + +var runEmAsmFunction = (code, sigPtr, argbuf) => { + var args = readEmAsmArgs(sigPtr, argbuf); + return ASM_CONSTS[code](...args); +}; + +var _emscripten_asm_const_int = (code, sigPtr, argbuf) => runEmAsmFunction(code, sigPtr, argbuf); + +var _emscripten_asm_const_ptr = (code, sigPtr, argbuf) => runEmAsmFunction(code, sigPtr, argbuf); + +var _emscripten_errn = (str, len) => err(UTF8ToString(str, len)); + +var getHeapMax = () => // Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate +// full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side +// for any code that deals with heap sizes, which would require special +// casing all heap size related code to treat 0 specially. +2147483648; + +var _emscripten_get_heap_max = () => getHeapMax(); + +var _emscripten_has_asyncify = () => 0; + +var _emscripten_outn = (str, len) => out(UTF8ToString(str, len)); + +var UNWIND_CACHE = {}; + +var stringToNewUTF8 = str => { + var size = lengthBytesUTF8(str) + 1; + var ret = _malloc(size); + if (ret) stringToUTF8(str, ret, size); + return ret; +}; + +/** @returns {number} */ var convertFrameToPC = frame => { + var match; + if (match = /\bwasm-function\[\d+\]:(0x[0-9a-f]+)/.exec(frame)) { + // Wasm engines give the binary offset directly, so we use that as return address + return +match[1]; + } else if (match = /:(\d+):\d+(?:\)|$)/.exec(frame)) { + // If we are in js, we can use the js line number as the "return address". + // This should work for wasm2js. We tag the high bit to distinguish this + // from wasm addresses. + return 2147483648 | +match[1]; + } + // return 0 if we can't find any + return 0; +}; + +var saveInUnwindCache = callstack => { + for (var line of callstack) { + var pc = convertFrameToPC(line); + if (pc) { + UNWIND_CACHE[pc] = line; + } + } +}; + +var jsStackTrace = () => (new Error).stack.toString(); + +var _emscripten_stack_snapshot = () => { + var callstack = jsStackTrace().split("\n"); + if (callstack[0] == "Error") { + callstack.shift(); + } + saveInUnwindCache(callstack); + // Caches the stack snapshot so that emscripten_stack_unwind_buffer() can + // unwind from this spot. + UNWIND_CACHE.last_addr = convertFrameToPC(callstack[3]); + UNWIND_CACHE.last_stack = callstack; + return UNWIND_CACHE.last_addr; +}; + +var _emscripten_pc_get_function = pc => { + var frame = UNWIND_CACHE[pc]; + if (!frame) return 0; + var name; + var match; + // First try to match foo.wasm.sym files explcitly. e.g. + // at test_return_address.wasm.main (wasm://wasm/test_return_address.wasm-0012cc2a:wasm-function[26]:0x9f3 + // Then match JS symbols which don't include that module name: + // at invokeEntryPoint (.../test_return_address.js:1500:42) + // Finally match firefox format: + // Object._main@http://server.com:4324:12' + if (match = /^\s+at .*\.wasm\.(.*) \(.*\)$/.exec(frame)) { + name = match[1]; + } else if (match = /^\s+at (.*) \(.*\)$/.exec(frame)) { + name = match[1]; + } else if (match = /^(.+?)@/.exec(frame)) { + name = match[1]; + } else { + return 0; + } + _free(_emscripten_pc_get_function.ret ?? 0); + _emscripten_pc_get_function.ret = stringToNewUTF8(name); + return _emscripten_pc_get_function.ret; +}; + +var growMemory = size => { + var oldHeapSize = wasmMemory.buffer.byteLength; + var pages = ((size - oldHeapSize + 65535) / 65536) | 0; + try { + // round size grow request up to wasm page size (fixed 64KB per spec) + wasmMemory.grow(pages); + // .grow() takes a delta compared to the previous size + updateMemoryViews(); + return 1; + } catch (e) {} +}; + +var _emscripten_resize_heap = requestedSize => { + var oldSize = HEAPU8.length; + // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned. + requestedSize >>>= 0; + // With multithreaded builds, races can happen (another thread might increase the size + // in between), so return a failure, and let the caller retry. + // Memory resize rules: + // 1. Always increase heap size to at least the requested size, rounded up + // to next page multiple. + // 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap + // geometrically: increase the heap size according to + // MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), At most + // overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB). + // 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap + // linearly: increase the heap size by at least + // MEMORY_GROWTH_LINEAR_STEP bytes. + // 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by + // MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest + // 4. If we were unable to allocate as much memory, it may be due to + // over-eager decision to excessively reserve due to (3) above. + // Hence if an allocation fails, cut down on the amount of excess + // growth, in an attempt to succeed to perform a smaller allocation. + // A limit is set for how much we can grow. We should not exceed that + // (the wasm binary specifies it, so if we tried, we'd fail anyhow). + var maxHeapSize = getHeapMax(); + if (requestedSize > maxHeapSize) { + return false; + } + // Loop through potential heap size increases. If we attempt a too eager + // reservation that fails, cut down on the attempted size and reserve a + // smaller bump instead. (max 3 times, chosen somewhat arbitrarily) + for (var cutDown = 1; cutDown <= 4; cutDown *= 2) { + var overGrownHeapSize = oldSize * (1 + .2 / cutDown); + // ensure geometric growth + // but limit overreserving (default to capping at +96MB overgrowth at most) + overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296); + var newSize = Math.min(maxHeapSize, alignMemory(Math.max(requestedSize, overGrownHeapSize), 65536)); + var replacement = growMemory(newSize); + if (replacement) { + return true; + } + } + return false; +}; + +var _emscripten_stack_unwind_buffer = (addr, buffer, count) => { + var stack; + if (UNWIND_CACHE.last_addr == addr) { + stack = UNWIND_CACHE.last_stack; + } else { + stack = jsStackTrace().split("\n"); + if (stack[0] == "Error") { + stack.shift(); + } + saveInUnwindCache(stack); + } + var offset = 3; + while (stack[offset] && convertFrameToPC(stack[offset]) != addr) { + ++offset; + } + for (var i = 0; i < count && stack[i + offset]; ++i) { + HEAP32[(((buffer) + (i * 4)) >> 2)] = convertFrameToPC(stack[i + offset]); + } + return i; +}; + +var GLctx; + +var webgl_enable_ANGLE_instanced_arrays = ctx => { + // Extension available in WebGL 1 from Firefox 26 and Google Chrome 30 onwards. Core feature in WebGL 2. + var ext = ctx.getExtension("ANGLE_instanced_arrays"); + // Because this extension is a core function in WebGL 2, assign the extension entry points in place of + // where the core functions will reside in WebGL 2. This way the calling code can call these without + // having to dynamically branch depending if running against WebGL 1 or WebGL 2. + if (ext) { + ctx["vertexAttribDivisor"] = (index, divisor) => ext["vertexAttribDivisorANGLE"](index, divisor); + ctx["drawArraysInstanced"] = (mode, first, count, primcount) => ext["drawArraysInstancedANGLE"](mode, first, count, primcount); + ctx["drawElementsInstanced"] = (mode, count, type, indices, primcount) => ext["drawElementsInstancedANGLE"](mode, count, type, indices, primcount); + return 1; + } +}; + +var webgl_enable_OES_vertex_array_object = ctx => { + // Extension available in WebGL 1 from Firefox 25 and WebKit 536.28/desktop Safari 6.0.3 onwards. Core feature in WebGL 2. + var ext = ctx.getExtension("OES_vertex_array_object"); + if (ext) { + ctx["createVertexArray"] = () => ext["createVertexArrayOES"](); + ctx["deleteVertexArray"] = vao => ext["deleteVertexArrayOES"](vao); + ctx["bindVertexArray"] = vao => ext["bindVertexArrayOES"](vao); + ctx["isVertexArray"] = vao => ext["isVertexArrayOES"](vao); + return 1; + } +}; + +var webgl_enable_WEBGL_draw_buffers = ctx => { + // Extension available in WebGL 1 from Firefox 28 onwards. Core feature in WebGL 2. + var ext = ctx.getExtension("WEBGL_draw_buffers"); + if (ext) { + ctx["drawBuffers"] = (n, bufs) => ext["drawBuffersWEBGL"](n, bufs); + return 1; + } +}; + +var webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance = ctx => // Closure is expected to be allowed to minify the '.dibvbi' property, so not accessing it quoted. +!!(ctx.dibvbi = ctx.getExtension("WEBGL_draw_instanced_base_vertex_base_instance")); + +var webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance = ctx => !!(ctx.mdibvbi = ctx.getExtension("WEBGL_multi_draw_instanced_base_vertex_base_instance")); + +var webgl_enable_EXT_polygon_offset_clamp = ctx => !!(ctx.extPolygonOffsetClamp = ctx.getExtension("EXT_polygon_offset_clamp")); + +var webgl_enable_EXT_clip_control = ctx => !!(ctx.extClipControl = ctx.getExtension("EXT_clip_control")); + +var webgl_enable_WEBGL_polygon_mode = ctx => !!(ctx.webglPolygonMode = ctx.getExtension("WEBGL_polygon_mode")); + +var webgl_enable_WEBGL_multi_draw = ctx => // Closure is expected to be allowed to minify the '.multiDrawWebgl' property, so not accessing it quoted. +!!(ctx.multiDrawWebgl = ctx.getExtension("WEBGL_multi_draw")); + +var getEmscriptenSupportedExtensions = ctx => { + // Restrict the list of advertised extensions to those that we actually + // support. + var supportedExtensions = [ // WebGL 1 extensions + "ANGLE_instanced_arrays", "EXT_blend_minmax", "EXT_disjoint_timer_query", "EXT_frag_depth", "EXT_shader_texture_lod", "EXT_sRGB", "OES_element_index_uint", "OES_fbo_render_mipmap", "OES_standard_derivatives", "OES_texture_float", "OES_texture_half_float", "OES_texture_half_float_linear", "OES_vertex_array_object", "WEBGL_color_buffer_float", "WEBGL_depth_texture", "WEBGL_draw_buffers", // WebGL 2 extensions + "EXT_color_buffer_float", "EXT_conservative_depth", "EXT_disjoint_timer_query_webgl2", "EXT_texture_norm16", "NV_shader_noperspective_interpolation", "WEBGL_clip_cull_distance", // WebGL 1 and WebGL 2 extensions + "EXT_clip_control", "EXT_color_buffer_half_float", "EXT_depth_clamp", "EXT_float_blend", "EXT_polygon_offset_clamp", "EXT_texture_compression_bptc", "EXT_texture_compression_rgtc", "EXT_texture_filter_anisotropic", "KHR_parallel_shader_compile", "OES_texture_float_linear", "WEBGL_blend_func_extended", "WEBGL_compressed_texture_astc", "WEBGL_compressed_texture_etc", "WEBGL_compressed_texture_etc1", "WEBGL_compressed_texture_s3tc", "WEBGL_compressed_texture_s3tc_srgb", "WEBGL_debug_renderer_info", "WEBGL_debug_shaders", "WEBGL_lose_context", "WEBGL_multi_draw", "WEBGL_polygon_mode" ]; + // .getSupportedExtensions() can return null if context is lost, so coerce to empty array. + return ctx.getSupportedExtensions()?.filter(ext => supportedExtensions.includes(ext)) ?? []; +}; + +var registerPreMainLoop = f => { + // Does nothing unless $MainLoop is included/used. + typeof MainLoop != "undefined" && MainLoop.preMainLoop.push(f); +}; + +var webglBufferSubData = (target, offset, size, data, src = HEAPU8) => { + if (GL.currentContext.version >= 2) { + size && GLctx.bufferSubData(target, offset, src, data, size); + return; + } + GLctx.bufferSubData(target, offset, src.subarray(data, data + size)); +}; + +var GL = { + counter: 1, + buffers: [], + mappedBuffers: {}, + programs: [], + framebuffers: [], + renderbuffers: [], + textures: [], + shaders: [], + vaos: [], + contexts: [], + offscreenCanvases: {}, + queries: [], + samplers: [], + transformFeedbacks: [], + syncs: [], + byteSizeByTypeRoot: 5120, + byteSizeByType: [ 1, 1, 2, 2, 4, 4, 4, 2, 3, 4, 8 ], + stringCache: {}, + stringiCache: {}, + unpackAlignment: 4, + unpackRowLength: 0, + recordError: errorCode => { + if (!GL.lastError) { + GL.lastError = errorCode; + } + }, + getNewId: table => { + var ret = GL.counter++; + for (var i = table.length; i < ret; i++) { + table[i] = null; + } + // Skip over any non-null elements that might have been created by + // glBindBuffer. + while (table[ret]) { + ret = GL.counter++; + } + return ret; + }, + genObject: (n, buffers, createFunction, objectTable) => { + for (var i = 0; i < n; i++) { + var buffer = GLctx[createFunction](); + var id = buffer && GL.getNewId(objectTable); + if (buffer) { + buffer.name = id; + objectTable[id] = buffer; + } else { + GL.recordError(1282); + } + HEAP32[(((buffers) + (i * 4)) >> 2)] = id; + } + }, + MAX_TEMP_BUFFER_SIZE: 2097152, + numTempVertexBuffersPerSize: 64, + log2ceilLookup: i => 32 - Math.clz32(i === 0 ? 0 : i - 1), + generateTempBuffers: (quads, context) => { + var largestIndex = GL.log2ceilLookup(GL.MAX_TEMP_BUFFER_SIZE); + context.tempVertexBufferCounters1 = []; + context.tempVertexBufferCounters2 = []; + context.tempVertexBufferCounters1.length = context.tempVertexBufferCounters2.length = largestIndex + 1; + context.tempVertexBuffers1 = []; + context.tempVertexBuffers2 = []; + context.tempVertexBuffers1.length = context.tempVertexBuffers2.length = largestIndex + 1; + context.tempIndexBuffers = []; + context.tempIndexBuffers.length = largestIndex + 1; + for (var i = 0; i <= largestIndex; ++i) { + context.tempIndexBuffers[i] = null; + // Created on-demand + context.tempVertexBufferCounters1[i] = context.tempVertexBufferCounters2[i] = 0; + var ringbufferLength = GL.numTempVertexBuffersPerSize; + context.tempVertexBuffers1[i] = []; + context.tempVertexBuffers2[i] = []; + var ringbuffer1 = context.tempVertexBuffers1[i]; + var ringbuffer2 = context.tempVertexBuffers2[i]; + ringbuffer1.length = ringbuffer2.length = ringbufferLength; + for (var j = 0; j < ringbufferLength; ++j) { + ringbuffer1[j] = ringbuffer2[j] = null; + } + } + if (quads) { + // GL_QUAD indexes can be precalculated + context.tempQuadIndexBuffer = GLctx.createBuffer(); + context.GLctx.bindBuffer(34963, context.tempQuadIndexBuffer); + var numIndexes = GL.MAX_TEMP_BUFFER_SIZE >> 1; + var quadIndexes = new Uint16Array(numIndexes); + var i = 0, v = 0; + while (1) { + quadIndexes[i++] = v; + if (i >= numIndexes) break; + quadIndexes[i++] = v + 1; + if (i >= numIndexes) break; + quadIndexes[i++] = v + 2; + if (i >= numIndexes) break; + quadIndexes[i++] = v; + if (i >= numIndexes) break; + quadIndexes[i++] = v + 2; + if (i >= numIndexes) break; + quadIndexes[i++] = v + 3; + if (i >= numIndexes) break; + v += 4; + } + context.GLctx.bufferData(34963, quadIndexes, 35044); + context.GLctx.bindBuffer(34963, null); + } + }, + getTempVertexBuffer: sizeBytes => { + var idx = GL.log2ceilLookup(sizeBytes); + var ringbuffer = GL.currentContext.tempVertexBuffers1[idx]; + var nextFreeBufferIndex = GL.currentContext.tempVertexBufferCounters1[idx]; + GL.currentContext.tempVertexBufferCounters1[idx] = (GL.currentContext.tempVertexBufferCounters1[idx] + 1) & (GL.numTempVertexBuffersPerSize - 1); + var vbo = ringbuffer[nextFreeBufferIndex]; + if (vbo) { + return vbo; + } + var prevVBO = GLctx.getParameter(34964); + ringbuffer[nextFreeBufferIndex] = GLctx.createBuffer(); + GLctx.bindBuffer(34962, ringbuffer[nextFreeBufferIndex]); + GLctx.bufferData(34962, 1 << idx, 35048); + GLctx.bindBuffer(34962, prevVBO); + return ringbuffer[nextFreeBufferIndex]; + }, + getTempIndexBuffer: sizeBytes => { + var idx = GL.log2ceilLookup(sizeBytes); + var ibo = GL.currentContext.tempIndexBuffers[idx]; + if (ibo) { + return ibo; + } + var prevIBO = GLctx.getParameter(34965); + GL.currentContext.tempIndexBuffers[idx] = GLctx.createBuffer(); + GLctx.bindBuffer(34963, GL.currentContext.tempIndexBuffers[idx]); + GLctx.bufferData(34963, 1 << idx, 35048); + GLctx.bindBuffer(34963, prevIBO); + return GL.currentContext.tempIndexBuffers[idx]; + }, + newRenderingFrameStarted: () => { + if (!GL.currentContext) { + return; + } + var vb = GL.currentContext.tempVertexBuffers1; + GL.currentContext.tempVertexBuffers1 = GL.currentContext.tempVertexBuffers2; + GL.currentContext.tempVertexBuffers2 = vb; + vb = GL.currentContext.tempVertexBufferCounters1; + GL.currentContext.tempVertexBufferCounters1 = GL.currentContext.tempVertexBufferCounters2; + GL.currentContext.tempVertexBufferCounters2 = vb; + var largestIndex = GL.log2ceilLookup(GL.MAX_TEMP_BUFFER_SIZE); + for (var i = 0; i <= largestIndex; ++i) { + GL.currentContext.tempVertexBufferCounters1[i] = 0; + } + }, + getSource: (shader, count, string, length) => { + var source = ""; + for (var i = 0; i < count; ++i) { + var len = length ? HEAPU32[(((length) + (i * 4)) >> 2)] : undefined; + source += UTF8ToString(HEAPU32[(((string) + (i * 4)) >> 2)], len); + } + return source; + }, + calcBufLength: (size, type, stride, count) => { + if (stride > 0) { + return count * stride; + } + var typeSize = GL.byteSizeByType[type - GL.byteSizeByTypeRoot]; + return size * typeSize * count; + }, + usedTempBuffers: [], + preDrawHandleClientVertexAttribBindings: count => { + GL.resetBufferBinding = false; + // TODO: initial pass to detect ranges we need to upload, might not need + // an upload per attrib + for (var i = 0; i < GL.currentContext.maxVertexAttribs; ++i) { + var cb = GL.currentContext.clientBuffers[i]; + if (!cb.clientside || !cb.enabled) continue; + GL.resetBufferBinding = true; + var size = GL.calcBufLength(cb.size, cb.type, cb.stride, count); + var buf = GL.getTempVertexBuffer(size); + GLctx.bindBuffer(34962, buf); + webglBufferSubData(34962, 0, size, cb.ptr); + cb.vertexAttribPointerAdaptor.call(GLctx, i, cb.size, cb.type, cb.normalized, cb.stride, 0); + } + }, + postDrawHandleClientVertexAttribBindings: () => { + if (GL.resetBufferBinding) { + GLctx.bindBuffer(34962, GL.buffers[GLctx.currentArrayBufferBinding]); + } + }, + createContext: (/** @type {HTMLCanvasElement} */ canvas, webGLContextAttributes) => { + // BUG: Workaround Safari WebGL issue: After successfully acquiring WebGL + // context on a canvas, calling .getContext() will always return that + // context independent of which 'webgl' or 'webgl2' + // context version was passed. See: + // https://webkit.org/b/222758 + // and: + // https://github.com/emscripten-core/emscripten/issues/13295. + // TODO: Once the bug is fixed and shipped in Safari, adjust the Safari + // version field in above check. + if (!canvas.getContextSafariWebGL2Fixed) { + canvas.getContextSafariWebGL2Fixed = canvas.getContext; + /** @type {function(this:HTMLCanvasElement, string, (Object|null)=): (Object|null)} */ function fixedGetContext(ver, attrs) { + var gl = canvas.getContextSafariWebGL2Fixed(ver, attrs); + return ((ver == "webgl") == (gl instanceof WebGLRenderingContext)) ? gl : null; + } + canvas.getContext = fixedGetContext; + } + var ctx = (webGLContextAttributes.majorVersion > 1) ? canvas.getContext("webgl2", webGLContextAttributes) : canvas.getContext("webgl", webGLContextAttributes); + if (!ctx) return 0; + var handle = GL.registerContext(ctx, webGLContextAttributes); + return handle; + }, + registerContext: (ctx, webGLContextAttributes) => { + // without pthreads a context is just an integer ID + var handle = GL.getNewId(GL.contexts); + var context = { + handle, + attributes: webGLContextAttributes, + version: webGLContextAttributes.majorVersion, + GLctx: ctx + }; + // Store the created context object so that we can access the context + // given a canvas without having to pass the parameters again. + if (ctx.canvas) ctx.canvas.GLctxObject = context; + GL.contexts[handle] = context; + if (typeof webGLContextAttributes.enableExtensionsByDefault == "undefined" || webGLContextAttributes.enableExtensionsByDefault) { + GL.initExtensions(context); + } + context.maxVertexAttribs = context.GLctx.getParameter(34921); + context.clientBuffers = []; + for (var i = 0; i < context.maxVertexAttribs; i++) { + context.clientBuffers[i] = { + enabled: false, + clientside: false, + size: 0, + type: 0, + normalized: 0, + stride: 0, + ptr: 0, + vertexAttribPointerAdaptor: null + }; + } + GL.generateTempBuffers(false, context); + return handle; + }, + makeContextCurrent: contextHandle => { + // Active Emscripten GL layer context object. + GL.currentContext = GL.contexts[contextHandle]; + // Active WebGL context object. + Module["ctx"] = GLctx = GL.currentContext?.GLctx; + return !(contextHandle && !GLctx); + }, + getContext: contextHandle => GL.contexts[contextHandle], + deleteContext: contextHandle => { + if (GL.currentContext === GL.contexts[contextHandle]) { + GL.currentContext = null; + } + if (typeof JSEvents == "object") { + // Release all JS event handlers on the DOM element that the GL context is + // associated with since the context is now deleted. + JSEvents.removeAllHandlersOnTarget(GL.contexts[contextHandle].GLctx.canvas); + } + // Make sure the canvas object no longer refers to the context object so + // there are no GC surprises. + if (GL.contexts[contextHandle]?.GLctx.canvas) { + GL.contexts[contextHandle].GLctx.canvas.GLctxObject = undefined; + } + GL.contexts[contextHandle] = null; + }, + initExtensions: context => { + // If this function is called without a specific context object, init the + // extensions of the currently active context. + context ||= GL.currentContext; + if (context.initExtensionsDone) return; + context.initExtensionsDone = true; + var GLctx = context.GLctx; + // Detect the presence of a few extensions manually, since the GL interop + // layer itself will need to know if they exist. + // Extensions that are available in both WebGL 1 and WebGL 2 + webgl_enable_WEBGL_multi_draw(GLctx); + webgl_enable_EXT_polygon_offset_clamp(GLctx); + webgl_enable_EXT_clip_control(GLctx); + webgl_enable_WEBGL_polygon_mode(GLctx); + // Extensions that are only available in WebGL 1 (the calls will be no-ops + // if called on a WebGL 2 context active) + webgl_enable_ANGLE_instanced_arrays(GLctx); + webgl_enable_OES_vertex_array_object(GLctx); + webgl_enable_WEBGL_draw_buffers(GLctx); + // Extensions that are available from WebGL >= 2 (no-op if called on a WebGL 1 context active) + webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(GLctx); + webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(GLctx); + // On WebGL 2, EXT_disjoint_timer_query is replaced with an alternative + // that's based on core APIs, and exposes only the queryCounterEXT() + // entrypoint. + if (context.version >= 2) { + GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query_webgl2"); + } + // However, Firefox exposes the WebGL 1 version on WebGL 2 as well and + // thus we look for the WebGL 1 version again if the WebGL 2 version + // isn't present. https://bugzil.la/1328882 + if (context.version < 2 || !GLctx.disjointTimerQueryExt) { + GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query"); + } + for (var ext of getEmscriptenSupportedExtensions(GLctx)) { + // WEBGL_lose_context, WEBGL_debug_renderer_info and WEBGL_debug_shaders + // are not enabled by default. + if (!ext.includes("lose_context") && !ext.includes("debug")) { + // Call .getExtension() to enable that extension permanently. + GLctx.getExtension(ext); + } + } + } +}; + +var webglPowerPreferences = [ "default", "low-power", "high-performance" ]; + +/** @type {Object} */ var specialHTMLTargets = [ 0, globalThis.document ?? 0, globalThis.window ?? 0 ]; + +var findEventTarget = target => { + // The sensible "default" target varies between events, but use window as the default + // since DOM events mostly can default to that. Specific callback registrations + // override their own defaults. + if (!target) return window; + if (typeof target == "number") target = specialHTMLTargets[target] || UTF8ToString(target); + if (target === "#window") return window; else if (target === "#document") return document; else if (target === "#screen") return screen; else if (target === "#canvas") return Module["canvas"]; else if (typeof target == "string") return globalThis.document?.getElementById(target); + return target; +}; + +var findCanvasEventTarget = target => { + if (typeof target == "number") target = UTF8ToString(target); + if (!target || target === "#canvas") { + if (typeof GL != "undefined" && GL.offscreenCanvases["canvas"]) return GL.offscreenCanvases["canvas"]; + // TODO: Remove this line, target '#canvas' should refer only to Module['canvas'], not to GL.offscreenCanvases['canvas'] - but need stricter tests to be able to remove this line. + return Module["canvas"]; + } + if (typeof GL != "undefined" && GL.offscreenCanvases[target]) return GL.offscreenCanvases[target]; + return findEventTarget(target); +}; + +var _emscripten_webgl_do_create_context = (target, attributes) => { + var attr32 = ((attributes) >> 2); + var powerPreference = HEAP32[attr32 + (8 >> 2)]; + var contextAttributes = { + "alpha": !!HEAP8[attributes + 0], + "depth": !!HEAP8[attributes + 1], + "stencil": !!HEAP8[attributes + 2], + "antialias": !!HEAP8[attributes + 3], + "premultipliedAlpha": !!HEAP8[attributes + 4], + "preserveDrawingBuffer": !!HEAP8[attributes + 5], + "powerPreference": webglPowerPreferences[powerPreference], + "failIfMajorPerformanceCaveat": !!HEAP8[attributes + 12], + // The following are not predefined WebGL context attributes in the WebGL specification, so the property names can be minified by Closure. + majorVersion: HEAP32[attr32 + (16 >> 2)], + minorVersion: HEAP32[attr32 + (20 >> 2)], + enableExtensionsByDefault: HEAP8[attributes + 24], + explicitSwapControl: HEAP8[attributes + 25], + proxyContextToMainThread: HEAP32[attr32 + (28 >> 2)], + renderViaOffscreenBackBuffer: HEAP8[attributes + 32] + }; + var canvas = findCanvasEventTarget(target); + if (!canvas) { + return 0; + } + if (contextAttributes.explicitSwapControl) { + return 0; + } + var contextHandle = GL.createContext(canvas, contextAttributes); + return contextHandle; +}; + +var _emscripten_webgl_create_context = _emscripten_webgl_do_create_context; + +var _emscripten_webgl_destroy_context = contextHandle => { + if (GL.currentContext == contextHandle) GL.currentContext = 0; + GL.deleteContext(contextHandle); +}; + +var _emscripten_webgl_get_context_attributes = (c, a) => { + if (!a) return -5; + c = GL.contexts[c]; + if (!c) return -3; + var t = c.GLctx?.getContextAttributes(); + if (!t) return -3; + HEAP8[a] = t.alpha; + HEAP8[(a) + (1)] = t.depth; + HEAP8[(a) + (2)] = t.stencil; + HEAP8[(a) + (3)] = t.antialias; + HEAP8[(a) + (4)] = t.premultipliedAlpha; + HEAP8[(a) + (5)] = t.preserveDrawingBuffer; + var power = t["powerPreference"] && webglPowerPreferences.indexOf(t["powerPreference"]); + HEAP32[(((a) + (8)) >> 2)] = power; + HEAP8[(a) + (12)] = t.failIfMajorPerformanceCaveat; + HEAP32[(((a) + (16)) >> 2)] = c.version; + HEAP32[(((a) + (20)) >> 2)] = 0; + HEAP8[(a) + (24)] = c.attributes.enableExtensionsByDefault; + return 0; +}; + +var _emscripten_webgl_do_get_current_context = () => GL.currentContext ? GL.currentContext.handle : 0; + +var _emscripten_webgl_get_current_context = _emscripten_webgl_do_get_current_context; + +var _emscripten_webgl_make_context_current = contextHandle => { + var success = GL.makeContextCurrent(contextHandle); + return success ? 0 : -5; +}; + +var stackAlloc = sz => __emscripten_stack_alloc(sz); + +var stringToUTF8OnStack = str => { + var size = lengthBytesUTF8(str) + 1; + var ret = stackAlloc(size); + stringToUTF8(str, ret, size); + return ret; +}; + +var writeI53ToI64 = (ptr, num) => { + HEAPU32[((ptr) >> 2)] = num; + var lower = HEAPU32[((ptr) >> 2)]; + HEAPU32[(((ptr) + (4)) >> 2)] = (num - lower) / 4294967296; +}; + +var readI53FromI64 = ptr => HEAPU32[((ptr) >> 2)] + HEAP32[(((ptr) + (4)) >> 2)] * 4294967296; + +var wasmTableMirror = []; + +var getWasmTableEntry = funcPtr => { + var func = wasmTableMirror[funcPtr]; + if (!func) { + /** @suppress {checkTypes} */ wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr); + } + return func; +}; + +var WebGPU = { + Internals: { + jsObjects: [], + jsObjectInsert: (ptr, jsObject) => { + ptr >>>= 0; + WebGPU.Internals.jsObjects[ptr] = jsObject; + }, + bufferOnUnmaps: [], + futures: [], + futureInsert: (futureId, promise) => {} + }, + getJsObject: ptr => { + if (!ptr) return undefined; + ptr >>>= 0; + return WebGPU.Internals.jsObjects[ptr]; + }, + importJsAdapter: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateAdapter(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsBindGroup: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateBindGroup(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsBindGroupLayout: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateBindGroupLayout(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsBuffer: (buffer, parentPtr = 0) => { + // At the moment, we do not allow importing pending buffers. + assert(buffer.mapState === "unmapped"); + var bufferPtr = _emwgpuImportBuffer(parentPtr); + WebGPU.Internals.jsObjectInsert(bufferPtr, buffer); + return bufferPtr; + }, + importJsCommandBuffer: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateCommandBuffer(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsCommandEncoder: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateCommandEncoder(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsComputePassEncoder: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateComputePassEncoder(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsComputePipeline: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateComputePipeline(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsDevice: (device, parentPtr = 0) => { + var queuePtr = _emwgpuCreateQueue(parentPtr); + var devicePtr = _emwgpuCreateDevice(parentPtr, queuePtr); + WebGPU.Internals.jsObjectInsert(queuePtr, device.queue); + WebGPU.Internals.jsObjectInsert(devicePtr, device); + return devicePtr; + }, + importJsExternalTexture: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateExternalTexture(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsPipelineLayout: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreatePipelineLayout(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsQuerySet: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateQuerySet(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsQueue: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateQueue(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsRenderBundle: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateRenderBundle(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsRenderBundleEncoder: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateRenderBundleEncoder(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsRenderPassEncoder: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateRenderPassEncoder(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsRenderPipeline: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateRenderPipeline(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsSampler: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateSampler(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsShaderModule: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateShaderModule(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsSurface: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateSurface(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsTexture: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateTexture(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + importJsTextureView: (obj, parentPtr = 0) => { + var ptr = _emwgpuCreateTextureView(parentPtr); + WebGPU.Internals.jsObjects[ptr] = obj; + return ptr; + }, + errorCallback: (callback, type, message, userdata) => { + var sp = stackSave(); + var messagePtr = stringToUTF8OnStack(message); + getWasmTableEntry(callback)(type, messagePtr, userdata); + stackRestore(sp); + }, + iterateExtensions: (root, handlers) => { + for (var ptr = HEAPU32[((root) >> 2)]; ptr; ptr = HEAPU32[((ptr) >> 2)]) { + var sType = HEAP32[(((ptr) + (4)) >> 2)]; + // This will crash if there's no handler indicating either a bogus + // sType, or one we haven't implemented yet. + var handler = handlers[sType](ptr); + } + }, + setStringView: (ptr, data, length) => { + HEAPU32[((ptr) >> 2)] = data; + HEAPU32[(((ptr) + (4)) >> 2)] = length; + }, + makeStringFromStringView: stringViewPtr => { + var ptr = HEAPU32[((stringViewPtr) >> 2)]; + var length = HEAPU32[(((stringViewPtr) + (4)) >> 2)]; + // UTF8ToString stops at the first null terminator character in the + // string regardless of the length. + return UTF8ToString(ptr, length); + }, + makeStringFromOptionalStringView: stringViewPtr => { + var ptr = HEAPU32[((stringViewPtr) >> 2)]; + var length = HEAPU32[(((stringViewPtr) + (4)) >> 2)]; + // If we don't have a valid string pointer, just return undefined when + // optional. + if (!ptr) { + if (length === 0) { + return ""; + } + return undefined; + } + // UTF8ToString stops at the first null terminator character in the + // string regardless of the length. + return UTF8ToString(ptr, length); + }, + makeColor: ptr => ({ + "r": HEAPF64[((ptr) >> 3)], + "g": HEAPF64[(((ptr) + (8)) >> 3)], + "b": HEAPF64[(((ptr) + (16)) >> 3)], + "a": HEAPF64[(((ptr) + (24)) >> 3)] + }), + makeExtent3D: ptr => ({ + "width": HEAPU32[((ptr) >> 2)], + "height": HEAPU32[(((ptr) + (4)) >> 2)], + "depthOrArrayLayers": HEAPU32[(((ptr) + (8)) >> 2)] + }), + makeOrigin3D: ptr => ({ + "x": HEAPU32[((ptr) >> 2)], + "y": HEAPU32[(((ptr) + (4)) >> 2)], + "z": HEAPU32[(((ptr) + (8)) >> 2)] + }), + makeTexelCopyTextureInfo: ptr => ({ + "texture": WebGPU.getJsObject(HEAPU32[((ptr) >> 2)]), + "mipLevel": HEAPU32[(((ptr) + (4)) >> 2)], + "origin": WebGPU.makeOrigin3D(ptr + 8), + "aspect": WebGPU.TextureAspect[HEAP32[(((ptr) + (20)) >> 2)]] + }), + makeTexelCopyBufferLayout: ptr => { + var bytesPerRow = HEAPU32[(((ptr) + (8)) >> 2)]; + var rowsPerImage = HEAPU32[(((ptr) + (12)) >> 2)]; + return { + "offset": readI53FromI64(ptr), + "bytesPerRow": bytesPerRow === 4294967295 ? undefined : bytesPerRow, + "rowsPerImage": rowsPerImage === 4294967295 ? undefined : rowsPerImage + }; + }, + makeTexelCopyBufferInfo: ptr => { + var layoutPtr = ptr + 0; + var bufferCopyView = WebGPU.makeTexelCopyBufferLayout(layoutPtr); + bufferCopyView["buffer"] = WebGPU.getJsObject(HEAPU32[(((ptr) + (16)) >> 2)]); + return bufferCopyView; + }, + makePassTimestampWrites: ptr => { + if (ptr === 0) return undefined; + return { + "querySet": WebGPU.getJsObject(HEAPU32[(((ptr) + (4)) >> 2)]), + "beginningOfPassWriteIndex": HEAPU32[(((ptr) + (8)) >> 2)], + "endOfPassWriteIndex": HEAPU32[(((ptr) + (12)) >> 2)] + }; + }, + makePipelineConstants: (constantCount, constantsPtr) => { + if (!constantCount) return; + var constants = {}; + for (var i = 0; i < constantCount; ++i) { + var entryPtr = constantsPtr + 24 * i; + var key = WebGPU.makeStringFromStringView(entryPtr + 4); + constants[key] = HEAPF64[(((entryPtr) + (16)) >> 3)]; + } + return constants; + }, + makePipelineLayout: layoutPtr => { + if (!layoutPtr) return "auto"; + return WebGPU.getJsObject(layoutPtr); + }, + makeComputeState: ptr => { + if (!ptr) return undefined; + var desc = { + "module": WebGPU.getJsObject(HEAPU32[(((ptr) + (4)) >> 2)]), + "constants": WebGPU.makePipelineConstants(HEAPU32[(((ptr) + (16)) >> 2)], HEAPU32[(((ptr) + (20)) >> 2)]), + "entryPoint": WebGPU.makeStringFromOptionalStringView(ptr + 8) + }; + return desc; + }, + makeComputePipelineDesc: descriptor => { + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "layout": WebGPU.makePipelineLayout(HEAPU32[(((descriptor) + (12)) >> 2)]), + "compute": WebGPU.makeComputeState(descriptor + 16) + }; + return desc; + }, + makeRenderPipelineDesc: descriptor => { + function makePrimitiveState(psPtr) { + if (!psPtr) return undefined; + return { + "topology": WebGPU.PrimitiveTopology[HEAP32[(((psPtr) + (4)) >> 2)]], + "stripIndexFormat": WebGPU.IndexFormat[HEAP32[(((psPtr) + (8)) >> 2)]], + "frontFace": WebGPU.FrontFace[HEAP32[(((psPtr) + (12)) >> 2)]], + "cullMode": WebGPU.CullMode[HEAP32[(((psPtr) + (16)) >> 2)]], + "unclippedDepth": !!(HEAPU32[(((psPtr) + (20)) >> 2)]) + }; + } + function makeBlendComponent(bdPtr) { + if (!bdPtr) return undefined; + return { + "operation": WebGPU.BlendOperation[HEAP32[((bdPtr) >> 2)]], + "srcFactor": WebGPU.BlendFactor[HEAP32[(((bdPtr) + (4)) >> 2)]], + "dstFactor": WebGPU.BlendFactor[HEAP32[(((bdPtr) + (8)) >> 2)]] + }; + } + function makeBlendState(bsPtr) { + if (!bsPtr) return undefined; + return { + "alpha": makeBlendComponent(bsPtr + 12), + "color": makeBlendComponent(bsPtr + 0) + }; + } + function makeColorState(csPtr) { + var format = WebGPU.TextureFormat[HEAP32[(((csPtr) + (4)) >> 2)]]; + return format ? { + "format": format, + "blend": makeBlendState(HEAPU32[(((csPtr) + (8)) >> 2)]), + "writeMask": HEAPU32[(((csPtr) + (16)) >> 2)] + } : undefined; + } + function makeColorStates(count, csArrayPtr) { + var states = []; + for (var i = 0; i < count; ++i) { + states.push(makeColorState(csArrayPtr + 24 * i)); + } + return states; + } + function makeStencilStateFace(ssfPtr) { + return { + "compare": WebGPU.CompareFunction[HEAP32[((ssfPtr) >> 2)]], + "failOp": WebGPU.StencilOperation[HEAP32[(((ssfPtr) + (4)) >> 2)]], + "depthFailOp": WebGPU.StencilOperation[HEAP32[(((ssfPtr) + (8)) >> 2)]], + "passOp": WebGPU.StencilOperation[HEAP32[(((ssfPtr) + (12)) >> 2)]] + }; + } + function makeDepthStencilState(dssPtr) { + if (!dssPtr) return undefined; + return { + "format": WebGPU.TextureFormat[HEAP32[(((dssPtr) + (4)) >> 2)]], + "depthWriteEnabled": !!(HEAPU32[(((dssPtr) + (8)) >> 2)]), + "depthCompare": WebGPU.CompareFunction[HEAP32[(((dssPtr) + (12)) >> 2)]], + "stencilFront": makeStencilStateFace(dssPtr + 16), + "stencilBack": makeStencilStateFace(dssPtr + 32), + "stencilReadMask": HEAPU32[(((dssPtr) + (48)) >> 2)], + "stencilWriteMask": HEAPU32[(((dssPtr) + (52)) >> 2)], + "depthBias": HEAP32[(((dssPtr) + (56)) >> 2)], + "depthBiasSlopeScale": HEAPF32[(((dssPtr) + (60)) >> 2)], + "depthBiasClamp": HEAPF32[(((dssPtr) + (64)) >> 2)] + }; + } + function makeVertexAttribute(vaPtr) { + return { + "format": WebGPU.VertexFormat[HEAP32[(((vaPtr) + (4)) >> 2)]], + "offset": readI53FromI64((vaPtr) + (8)), + "shaderLocation": HEAPU32[(((vaPtr) + (16)) >> 2)] + }; + } + function makeVertexAttributes(count, vaArrayPtr) { + var vas = []; + for (var i = 0; i < count; ++i) { + vas.push(makeVertexAttribute(vaArrayPtr + i * 24)); + } + return vas; + } + function makeVertexBuffer(vbPtr) { + if (!vbPtr) return undefined; + var stepMode = WebGPU.VertexStepMode[HEAP32[(((vbPtr) + (4)) >> 2)]]; + var attributeCount = HEAPU32[(((vbPtr) + (16)) >> 2)]; + if (!stepMode && !attributeCount) { + return null; + } + return { + "arrayStride": readI53FromI64((vbPtr) + (8)), + "stepMode": stepMode, + "attributes": makeVertexAttributes(attributeCount, HEAPU32[(((vbPtr) + (20)) >> 2)]) + }; + } + function makeVertexBuffers(count, vbArrayPtr) { + if (!count) return undefined; + var vbs = []; + for (var i = 0; i < count; ++i) { + vbs.push(makeVertexBuffer(vbArrayPtr + i * 24)); + } + return vbs; + } + function makeVertexState(viPtr) { + if (!viPtr) return undefined; + var desc = { + "module": WebGPU.getJsObject(HEAPU32[(((viPtr) + (4)) >> 2)]), + "constants": WebGPU.makePipelineConstants(HEAPU32[(((viPtr) + (16)) >> 2)], HEAPU32[(((viPtr) + (20)) >> 2)]), + "buffers": makeVertexBuffers(HEAPU32[(((viPtr) + (24)) >> 2)], HEAPU32[(((viPtr) + (28)) >> 2)]), + "entryPoint": WebGPU.makeStringFromOptionalStringView(viPtr + 8) + }; + return desc; + } + function makeMultisampleState(msPtr) { + if (!msPtr) return undefined; + return { + "count": HEAPU32[(((msPtr) + (4)) >> 2)], + "mask": HEAPU32[(((msPtr) + (8)) >> 2)], + "alphaToCoverageEnabled": !!(HEAPU32[(((msPtr) + (12)) >> 2)]) + }; + } + function makeFragmentState(fsPtr) { + if (!fsPtr) return undefined; + var desc = { + "module": WebGPU.getJsObject(HEAPU32[(((fsPtr) + (4)) >> 2)]), + "constants": WebGPU.makePipelineConstants(HEAPU32[(((fsPtr) + (16)) >> 2)], HEAPU32[(((fsPtr) + (20)) >> 2)]), + "targets": makeColorStates(HEAPU32[(((fsPtr) + (24)) >> 2)], HEAPU32[(((fsPtr) + (28)) >> 2)]), + "entryPoint": WebGPU.makeStringFromOptionalStringView(fsPtr + 8) + }; + return desc; + } + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "layout": WebGPU.makePipelineLayout(HEAPU32[(((descriptor) + (12)) >> 2)]), + "vertex": makeVertexState(descriptor + 16), + "primitive": makePrimitiveState(descriptor + 48), + "depthStencil": makeDepthStencilState(HEAPU32[(((descriptor) + (72)) >> 2)]), + "multisample": makeMultisampleState(descriptor + 76), + "fragment": makeFragmentState(HEAPU32[(((descriptor) + (92)) >> 2)]) + }; + return desc; + }, + fillLimitStruct: (limits, limitsOutPtr) => { + var nextInChainPtr = HEAPU32[((limitsOutPtr) >> 2)]; + function setLimitValueU32(name, basePtr, limitOffset, fallbackValue = 0) { + var limitValue = limits[name] ?? fallbackValue; + HEAPU32[(((basePtr) + (limitOffset)) >> 2)] = limitValue; + } + function setLimitValueU64(name, basePtr, limitOffset, fallbackValue = 0) { + var limitValue = limits[name] ?? fallbackValue; + // Limits are integer-valued JS `Number`s, so they fit in 'i53'. + writeI53ToI64((basePtr) + (limitOffset), limitValue); + } + setLimitValueU32("maxTextureDimension1D", limitsOutPtr, 4); + setLimitValueU32("maxTextureDimension2D", limitsOutPtr, 8); + setLimitValueU32("maxTextureDimension3D", limitsOutPtr, 12); + setLimitValueU32("maxTextureArrayLayers", limitsOutPtr, 16); + setLimitValueU32("maxBindGroups", limitsOutPtr, 20); + setLimitValueU32("maxBindGroupsPlusVertexBuffers", limitsOutPtr, 24); + setLimitValueU32("maxBindingsPerBindGroup", limitsOutPtr, 28); + setLimitValueU32("maxDynamicUniformBuffersPerPipelineLayout", limitsOutPtr, 32); + setLimitValueU32("maxDynamicStorageBuffersPerPipelineLayout", limitsOutPtr, 36); + setLimitValueU32("maxSampledTexturesPerShaderStage", limitsOutPtr, 40); + setLimitValueU32("maxSamplersPerShaderStage", limitsOutPtr, 44); + setLimitValueU32("maxStorageBuffersPerShaderStage", limitsOutPtr, 48); + setLimitValueU32("maxStorageTexturesPerShaderStage", limitsOutPtr, 52); + setLimitValueU32("maxUniformBuffersPerShaderStage", limitsOutPtr, 56); + setLimitValueU32("minUniformBufferOffsetAlignment", limitsOutPtr, 80); + setLimitValueU32("minStorageBufferOffsetAlignment", limitsOutPtr, 84); + setLimitValueU64("maxUniformBufferBindingSize", limitsOutPtr, 64); + setLimitValueU64("maxStorageBufferBindingSize", limitsOutPtr, 72); + setLimitValueU32("maxVertexBuffers", limitsOutPtr, 88); + setLimitValueU64("maxBufferSize", limitsOutPtr, 96); + setLimitValueU32("maxVertexAttributes", limitsOutPtr, 104); + setLimitValueU32("maxVertexBufferArrayStride", limitsOutPtr, 108); + setLimitValueU32("maxInterStageShaderVariables", limitsOutPtr, 112); + setLimitValueU32("maxColorAttachments", limitsOutPtr, 116); + setLimitValueU32("maxColorAttachmentBytesPerSample", limitsOutPtr, 120); + setLimitValueU32("maxComputeWorkgroupStorageSize", limitsOutPtr, 124); + setLimitValueU32("maxComputeInvocationsPerWorkgroup", limitsOutPtr, 128); + setLimitValueU32("maxComputeWorkgroupSizeX", limitsOutPtr, 132); + setLimitValueU32("maxComputeWorkgroupSizeY", limitsOutPtr, 136); + setLimitValueU32("maxComputeWorkgroupSizeZ", limitsOutPtr, 140); + setLimitValueU32("maxComputeWorkgroupsPerDimension", limitsOutPtr, 144); + // Note this limit is new and won't be present in all browsers for a while. Fall back to 0. + setLimitValueU32("maxImmediateSize", limitsOutPtr, 148); + if (nextInChainPtr !== 0) { + var sType = HEAP32[(((nextInChainPtr) + (4)) >> 2)]; + var compatibilityModeLimitsPtr = nextInChainPtr; + // Note these limits are new and won't be present in all browsers for a while. Fall back to exposing the PerShaderStage limit. + setLimitValueU32("maxStorageBuffersInVertexStage", compatibilityModeLimitsPtr, 8, limits.maxStorageBuffersPerShaderStage); + setLimitValueU32("maxStorageBuffersInFragmentStage", compatibilityModeLimitsPtr, 16, limits.maxStorageBuffersPerShaderStage); + setLimitValueU32("maxStorageTexturesInVertexStage", compatibilityModeLimitsPtr, 12, limits.maxStorageTexturesPerShaderStage); + setLimitValueU32("maxStorageTexturesInFragmentStage", compatibilityModeLimitsPtr, 20, limits.maxStorageTexturesPerShaderStage); + } + }, + fillAdapterInfoStruct: (info, infoStruct) => { + // Populate subgroup limits. + HEAPU32[(((infoStruct) + (52)) >> 2)] = info.subgroupMinSize; + HEAPU32[(((infoStruct) + (56)) >> 2)] = info.subgroupMaxSize; + // Append all the strings together to condense into a single malloc. + var strs = info.vendor + info.architecture + info.device + info.description; + var strPtr = stringToNewUTF8(strs); + var vendorLen = lengthBytesUTF8(info.vendor); + WebGPU.setStringView(infoStruct + 4, strPtr, vendorLen); + strPtr += vendorLen; + var architectureLen = lengthBytesUTF8(info.architecture); + WebGPU.setStringView(infoStruct + 12, strPtr, architectureLen); + strPtr += architectureLen; + var deviceLen = lengthBytesUTF8(info.device); + WebGPU.setStringView(infoStruct + 20, strPtr, deviceLen); + strPtr += deviceLen; + var descriptionLen = lengthBytesUTF8(info.description); + WebGPU.setStringView(infoStruct + 28, strPtr, descriptionLen); + strPtr += descriptionLen; + HEAP32[(((infoStruct) + (36)) >> 2)] = 2; + var adapterType = info.isFallbackAdapter ? 3 : 4; + HEAP32[(((infoStruct) + (40)) >> 2)] = adapterType; + HEAPU32[(((infoStruct) + (44)) >> 2)] = 0; + HEAPU32[(((infoStruct) + (48)) >> 2)] = 0; + }, + AddressMode: [ , "clamp-to-edge", "repeat", "mirror-repeat" ], + BlendFactor: [ , "zero", "one", "src", "one-minus-src", "src-alpha", "one-minus-src-alpha", "dst", "one-minus-dst", "dst-alpha", "one-minus-dst-alpha", "src-alpha-saturated", "constant", "one-minus-constant", "src1", "one-minus-src1", "src1-alpha", "one-minus-src1-alpha" ], + BlendOperation: [ , "add", "subtract", "reverse-subtract", "min", "max" ], + BufferBindingType: [ , , "uniform", "storage", "read-only-storage" ], + BufferMapState: [ , "unmapped", "pending", "mapped" ], + CompareFunction: [ , "never", "less", "equal", "less-equal", "greater", "not-equal", "greater-equal", "always" ], + CompilationInfoRequestStatus: [ , "success", "callback-cancelled" ], + ComponentSwizzle: [ , "0", "1", "r", "g", "b", "a" ], + CompositeAlphaMode: [ , "opaque", "premultiplied", "unpremultiplied", "inherit" ], + CullMode: [ , "none", "front", "back" ], + ErrorFilter: [ , "validation", "out-of-memory", "internal" ], + FeatureLevel: [ , "compatibility", "core" ], + FeatureName: { + 1: "core-features-and-limits", + 2: "depth-clip-control", + 3: "depth32float-stencil8", + 4: "texture-compression-bc", + 5: "texture-compression-bc-sliced-3d", + 6: "texture-compression-etc2", + 7: "texture-compression-astc", + 8: "texture-compression-astc-sliced-3d", + 9: "timestamp-query", + 10: "indirect-first-instance", + 11: "shader-f16", + 12: "rg11b10ufloat-renderable", + 13: "bgra8unorm-storage", + 14: "float32-filterable", + 15: "float32-blendable", + 16: "clip-distances", + 17: "dual-source-blending", + 18: "subgroups", + 19: "texture-formats-tier1", + 20: "texture-formats-tier2", + 21: "primitive-index", + 22: "texture-component-swizzle", + 23: "subgroup-size-control", + 327692: "chromium-experimental-unorm16-texture-formats", + 327729: "chromium-experimental-multi-draw-indirect" + }, + FilterMode: [ , "nearest", "linear" ], + FrontFace: [ , "ccw", "cw" ], + IndexFormat: [ , "uint16", "uint32" ], + InstanceFeatureName: [ , "timed-wait-any", "shader-source-spirv", "multiple-devices-per-adapter" ], + LoadOp: [ , "load", "clear" ], + MipmapFilterMode: [ , "nearest", "linear" ], + OptionalBool: [ "false", "true" ], + PowerPreference: [ , "low-power", "high-performance" ], + PredefinedColorSpace: [ , "srgb", "display-p3" ], + PrimitiveTopology: [ , "point-list", "line-list", "line-strip", "triangle-list", "triangle-strip" ], + QueryType: [ , "occlusion", "timestamp" ], + SamplerBindingType: [ , , "filtering", "non-filtering", "comparison" ], + Status: [ , "success", "error" ], + StencilOperation: [ , "keep", "zero", "replace", "invert", "increment-clamp", "decrement-clamp", "increment-wrap", "decrement-wrap" ], + StorageTextureAccess: [ , , "write-only", "read-only", "read-write" ], + StoreOp: [ , "store", "discard" ], + SurfaceGetCurrentTextureStatus: [ , "success-optimal", "success-suboptimal", "timeout", "outdated", "lost", "error" ], + TextureAspect: [ , "all", "stencil-only", "depth-only" ], + TextureDimension: [ , "1d", "2d", "3d" ], + TextureFormat: [ , "r8unorm", "r8snorm", "r8uint", "r8sint", "r16unorm", "r16snorm", "r16uint", "r16sint", "r16float", "rg8unorm", "rg8snorm", "rg8uint", "rg8sint", "r32float", "r32uint", "r32sint", "rg16unorm", "rg16snorm", "rg16uint", "rg16sint", "rg16float", "rgba8unorm", "rgba8unorm-srgb", "rgba8snorm", "rgba8uint", "rgba8sint", "bgra8unorm", "bgra8unorm-srgb", "rgb10a2uint", "rgb10a2unorm", "rg11b10ufloat", "rgb9e5ufloat", "rg32float", "rg32uint", "rg32sint", "rgba16unorm", "rgba16snorm", "rgba16uint", "rgba16sint", "rgba16float", "rgba32float", "rgba32uint", "rgba32sint", "stencil8", "depth16unorm", "depth24plus", "depth24plus-stencil8", "depth32float", "depth32float-stencil8", "bc1-rgba-unorm", "bc1-rgba-unorm-srgb", "bc2-rgba-unorm", "bc2-rgba-unorm-srgb", "bc3-rgba-unorm", "bc3-rgba-unorm-srgb", "bc4-r-unorm", "bc4-r-snorm", "bc5-rg-unorm", "bc5-rg-snorm", "bc6h-rgb-ufloat", "bc6h-rgb-float", "bc7-rgba-unorm", "bc7-rgba-unorm-srgb", "etc2-rgb8unorm", "etc2-rgb8unorm-srgb", "etc2-rgb8a1unorm", "etc2-rgb8a1unorm-srgb", "etc2-rgba8unorm", "etc2-rgba8unorm-srgb", "eac-r11unorm", "eac-r11snorm", "eac-rg11unorm", "eac-rg11snorm", "astc-4x4-unorm", "astc-4x4-unorm-srgb", "astc-5x4-unorm", "astc-5x4-unorm-srgb", "astc-5x5-unorm", "astc-5x5-unorm-srgb", "astc-6x5-unorm", "astc-6x5-unorm-srgb", "astc-6x6-unorm", "astc-6x6-unorm-srgb", "astc-8x5-unorm", "astc-8x5-unorm-srgb", "astc-8x6-unorm", "astc-8x6-unorm-srgb", "astc-8x8-unorm", "astc-8x8-unorm-srgb", "astc-10x5-unorm", "astc-10x5-unorm-srgb", "astc-10x6-unorm", "astc-10x6-unorm-srgb", "astc-10x8-unorm", "astc-10x8-unorm-srgb", "astc-10x10-unorm", "astc-10x10-unorm-srgb", "astc-12x10-unorm", "astc-12x10-unorm-srgb", "astc-12x12-unorm", "astc-12x12-unorm-srgb" ], + TextureSampleType: [ , , "float", "unfilterable-float", "depth", "sint", "uint" ], + TextureViewDimension: [ , "1d", "2d", "2d-array", "cube", "cube-array", "3d" ], + ToneMappingMode: [ , "standard", "extended" ], + VertexFormat: [ , "uint8", "uint8x2", "uint8x4", "sint8", "sint8x2", "sint8x4", "unorm8", "unorm8x2", "unorm8x4", "snorm8", "snorm8x2", "snorm8x4", "uint16", "uint16x2", "uint16x4", "sint16", "sint16x2", "sint16x4", "unorm16", "unorm16x2", "unorm16x4", "snorm16", "snorm16x2", "snorm16x4", "float16", "float16x2", "float16x4", "float32", "float32x2", "float32x3", "float32x4", "uint32", "uint32x2", "uint32x3", "uint32x4", "sint32", "sint32x2", "sint32x3", "sint32x4", "unorm10-10-10-2", "unorm8x4-bgra", "snorm10-10-10-2" ], + VertexStepMode: [ , "vertex", "instance" ], + WGSLLanguageFeatureName: [ , "readonly_and_readwrite_storage_textures", "packed_4x8_integer_dot_product", "unrestricted_pointer_parameters", "pointer_composite_access", "uniform_buffer_standard_layout", "subgroup_id", "texture_and_sampler_let", "subgroup_uniformity", "texture_formats_tier1", "linear_indexing", "immediate_address_space", "buffer_view" ] +}; + +var _emscripten_webgpu_get_device = () => { + if (WebGPU.preinitializedDeviceId === undefined) { + WebGPU.preinitializedDeviceId = WebGPU.importJsDevice(Module["preinitializedWebGPUDevice"]); + // Some users depend on this keeping the device alive, so we add an + // additional reference when we first initialize it. + _wgpuDeviceAddRef(WebGPU.preinitializedDeviceId); + } + _wgpuDeviceAddRef(WebGPU.preinitializedDeviceId); + return WebGPU.preinitializedDeviceId; +}; + +var _emwgpuBufferDestroy = bufferPtr => { + var buffer = WebGPU.getJsObject(bufferPtr); + var onUnmap = WebGPU.Internals.bufferOnUnmaps[bufferPtr]; + if (onUnmap) { + for (var i = 0; i < onUnmap.length; ++i) { + onUnmap[i](); + } + delete WebGPU.Internals.bufferOnUnmaps[bufferPtr]; + } + buffer.destroy(); +}; + +var _emwgpuBufferGetMappedRange = (bufferPtr, offset, size) => { + var buffer = WebGPU.getJsObject(bufferPtr); + if (size == -1) size = undefined; + var mapped; + try { + mapped = buffer.getMappedRange(offset, size); + } catch (ex) { + return 0; + } + var data = _memalign(16, mapped.byteLength); + HEAPU8.fill(0, data, mapped.byteLength); + WebGPU.Internals.bufferOnUnmaps[bufferPtr].push(() => { + new Uint8Array(mapped).set(HEAPU8.subarray(data, data + mapped.byteLength)); + _free(data); + }); + return data; +}; + +var _emwgpuBufferUnmap = bufferPtr => { + var buffer = WebGPU.getJsObject(bufferPtr); + var onUnmap = WebGPU.Internals.bufferOnUnmaps[bufferPtr]; + if (!onUnmap) { + // Already unmapped + return; + } + for (var i = 0; i < onUnmap.length; ++i) { + onUnmap[i](); + } + delete WebGPU.Internals.bufferOnUnmaps[bufferPtr]; + buffer.unmap(); +}; + +var _emwgpuDelete = ptr => { + delete WebGPU.Internals.jsObjects[ptr]; +}; + +var _emwgpuDeviceCreateBuffer = (devicePtr, descriptor, bufferPtr) => { + var mappedAtCreation = !!(HEAPU32[(((descriptor) + (32)) >> 2)]); + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "usage": HEAPU32[(((descriptor) + (16)) >> 2)], + "size": readI53FromI64((descriptor) + (24)), + "mappedAtCreation": mappedAtCreation + }; + var device = WebGPU.getJsObject(devicePtr); + var buffer; + try { + buffer = device.createBuffer(desc); + } catch (ex) { + // The only exception should be RangeError if mapping at creation ran out of memory. + return false; + } + WebGPU.Internals.jsObjectInsert(bufferPtr, buffer); + if (mappedAtCreation) { + WebGPU.Internals.bufferOnUnmaps[bufferPtr] = []; + } + return true; +}; + +var _emwgpuDeviceCreateComputePipelineAsync = function(devicePtr, futureId_low, futureId_high, descriptor, pipelinePtr) { + var futureId = convertI32PairToI53Checked(futureId_low, futureId_high); + var desc = WebGPU.makeComputePipelineDesc(descriptor); + var device = WebGPU.getJsObject(devicePtr); + // createComputePipelineAsync + WebGPU.Internals.futureInsert(futureId, device.createComputePipelineAsync(desc).then(pipeline => { + // createComputePipelineAsync fulfilled + callUserCallback(() => { + WebGPU.Internals.jsObjectInsert(pipelinePtr, pipeline); + _emwgpuOnCreateComputePipelineCompleted(futureId, 1, pipelinePtr, 0); + }); + }, pipelineError => { + // createComputePipelineAsync rejected + callUserCallback(() => { + var sp = stackSave(); + var messagePtr = stringToUTF8OnStack(pipelineError.message); + var status = pipelineError.reason === "validation" ? 3 : pipelineError.reason === "internal" ? 4 : 0; + _emwgpuOnCreateComputePipelineCompleted(futureId, status, pipelinePtr, messagePtr); + stackRestore(sp); + }); + })); +}; + +var _emwgpuDeviceCreateRenderPipelineAsync = function(devicePtr, futureId_low, futureId_high, descriptor, pipelinePtr) { + var futureId = convertI32PairToI53Checked(futureId_low, futureId_high); + var desc = WebGPU.makeRenderPipelineDesc(descriptor); + var device = WebGPU.getJsObject(devicePtr); + // createRenderPipelineAsync + WebGPU.Internals.futureInsert(futureId, device.createRenderPipelineAsync(desc).then(pipeline => { + // createRenderPipelineAsync fulfilled + callUserCallback(() => { + WebGPU.Internals.jsObjectInsert(pipelinePtr, pipeline); + _emwgpuOnCreateRenderPipelineCompleted(futureId, 1, pipelinePtr, 0); + }); + }, pipelineError => { + // createRenderPipelineAsync rejected + callUserCallback(() => { + var sp = stackSave(); + var messagePtr = stringToUTF8OnStack(pipelineError.message); + var status = pipelineError.reason === "validation" ? 3 : pipelineError.reason === "internal" ? 4 : 0; + _emwgpuOnCreateRenderPipelineCompleted(futureId, status, pipelinePtr, messagePtr); + stackRestore(sp); + }); + })); +}; + +var _emwgpuDeviceCreateShaderModule = (devicePtr, descriptor, shaderModulePtr) => { + var nextInChainPtr = HEAPU32[((descriptor) >> 2)]; + var sType = HEAP32[(((nextInChainPtr) + (4)) >> 2)]; + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "code": "" + }; + switch (sType) { + case 2: + { + desc["code"] = WebGPU.makeStringFromStringView(nextInChainPtr + 8); + break; + } + } + var device = WebGPU.getJsObject(devicePtr); + WebGPU.Internals.jsObjectInsert(shaderModulePtr, device.createShaderModule(desc)); +}; + +var _emwgpuDeviceDestroy = devicePtr => { + const device = WebGPU.getJsObject(devicePtr); + // Remove the onuncapturederror handler which holds a pointer to the WGPUDevice. + device.onuncapturederror = null; + device.destroy(); +}; + +var _emwgpuWaitAny = (futurePtr, futureCount, timeoutMSPtr) => { + abort("TODO: Implement asyncify-free WaitAny for timeout=0"); +}; + +var ENV = {}; + +var getExecutableName = () => thisProgram; + +var getEnvStrings = () => { + if (!getEnvStrings.strings) { + // Default values. + var lang = (globalThis.navigator?.language ?? "C").replace("-", "_") + ".UTF-8"; + var env = { + "USER": "web_user", + "LOGNAME": "web_user", + "PATH": "/", + "PWD": "/", + "HOME": "/home/web_user", + "LANG": lang, + "_": getExecutableName() + }; + // Apply the user-provided values, if any. + for (var x in ENV) { + // x is a key in ENV; if ENV[x] is undefined, that means it was + // explicitly set to be so. We allow user code to do that to + // force variables with default values to remain unset. + if (ENV[x] === undefined) delete env[x]; else env[x] = ENV[x]; + } + var strings = []; + for (var x in env) { + strings.push(`${x}=${env[x]}`); + } + getEnvStrings.strings = strings; + } + return getEnvStrings.strings; +}; + +var _environ_get = (__environ, environ_buf) => { + var bufSize = 0; + var envp = 0; + for (var string of getEnvStrings()) { + var ptr = environ_buf + bufSize; + HEAPU32[(((__environ) + (envp)) >> 2)] = ptr; + bufSize += stringToUTF8(string, ptr, Infinity) + 1; + envp += 4; + } + return 0; +}; + +var _environ_sizes_get = (penviron_count, penviron_buf_size) => { + var strings = getEnvStrings(); + HEAPU32[((penviron_count) >> 2)] = strings.length; + var bufSize = 0; + for (var string of strings) { + bufSize += lengthBytesUTF8(string) + 1; + } + HEAPU32[((penviron_buf_size) >> 2)] = bufSize; + return 0; +}; + +function _fd_close(fd) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + FS.close(stream); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +/** @param {number=} offset */ var doReadv = (stream, iov, iovcnt, offset) => { + var ret = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = HEAPU32[((iov) >> 2)]; + var len = HEAPU32[(((iov) + (4)) >> 2)]; + iov += 8; + var curr = FS.read(stream, HEAP8, ptr, len, offset); + if (curr < 0) return -1; + ret += curr; + if (curr < len) break; + // nothing more to read + if (typeof offset != "undefined") { + offset += curr; + } + } + return ret; +}; + +function _fd_read(fd, iov, iovcnt, pnum) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var num = doReadv(stream, iov, iovcnt); + HEAPU32[((pnum) >> 2)] = num; + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +function _fd_seek(fd, offset_low, offset_high, whence, newOffset) { + var offset = convertI32PairToI53Checked(offset_low, offset_high); + try { + if (isNaN(offset)) return 22; + var stream = SYSCALLS.getStreamFromFD(fd); + FS.llseek(stream, offset, whence); + (tempI64 = [ stream.position >>> 0, (tempDouble = stream.position, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + HEAP32[((newOffset) >> 2)] = tempI64[0], HEAP32[(((newOffset) + (4)) >> 2)] = tempI64[1]); + if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; + // reset readdir state + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +/** @param {number=} offset */ var doWritev = (stream, iov, iovcnt, offset) => { + var ret = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = HEAPU32[((iov) >> 2)]; + var len = HEAPU32[(((iov) + (4)) >> 2)]; + iov += 8; + var curr = FS.write(stream, HEAP8, ptr, len, offset); + if (curr < 0) return -1; + ret += curr; + if (curr < len) { + // No more space to write. + break; + } + if (typeof offset != "undefined") { + offset += curr; + } + } + return ret; +}; + +function _fd_write(fd, iov, iovcnt, pnum) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var num = doWritev(stream, iov, iovcnt); + HEAPU32[((pnum) >> 2)] = num; + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +var _emscripten_glActiveTexture = x0 => GLctx.activeTexture(x0); + +var _glActiveTexture = _emscripten_glActiveTexture; + +var _emscripten_glAttachShader = (program, shader) => { + GLctx.attachShader(GL.programs[program], GL.shaders[shader]); +}; + +var _glAttachShader = _emscripten_glAttachShader; + +var _emscripten_glBindAttribLocation = (program, index, name) => { + GLctx.bindAttribLocation(GL.programs[program], index, UTF8ToString(name)); +}; + +var _glBindAttribLocation = _emscripten_glBindAttribLocation; + +var _emscripten_glBindBuffer = (target, buffer) => { + // Calling glBindBuffer with an unknown buffer will implicitly create a + // new one. Here we bypass `GL.counter` and directly using the ID passed + // in. + if (buffer && !GL.buffers[buffer]) { + var b = GLctx.createBuffer(); + b.name = buffer; + GL.buffers[buffer] = b; + } + if (target == 34962) { + GLctx.currentArrayBufferBinding = buffer; + } else if (target == 34963) { + GLctx.currentElementArrayBufferBinding = buffer; + } + if (target == 35051) { + // In WebGL 2 glReadPixels entry point, we need to use a different WebGL 2 + // API function call when a buffer is bound to + // GL_PIXEL_PACK_BUFFER_BINDING point, so must keep track whether that + // binding point is non-null to know what is the proper API function to + // call. + GLctx.currentPixelPackBufferBinding = buffer; + } else if (target == 35052) { + // In WebGL 2 gl(Compressed)Tex(Sub)Image[23]D entry points, we need to + // use a different WebGL 2 API function call when a buffer is bound to + // GL_PIXEL_UNPACK_BUFFER_BINDING point, so must keep track whether that + // binding point is non-null to know what is the proper API function to + // call. + GLctx.currentPixelUnpackBufferBinding = buffer; + } + GLctx.bindBuffer(target, GL.buffers[buffer]); +}; + +var _glBindBuffer = _emscripten_glBindBuffer; + +var _emscripten_glBindBufferBase = (target, index, buffer) => { + GLctx.bindBufferBase(target, index, GL.buffers[buffer]); +}; + +var _glBindBufferBase = _emscripten_glBindBufferBase; + +var _emscripten_glBindFramebuffer = (target, framebuffer) => { + GLctx.bindFramebuffer(target, GL.framebuffers[framebuffer]); +}; + +var _glBindFramebuffer = _emscripten_glBindFramebuffer; + +var _emscripten_glBindTexture = (target, texture) => { + GLctx.bindTexture(target, GL.textures[texture]); +}; + +var _glBindTexture = _emscripten_glBindTexture; + +var _emscripten_glBindVertexArray = vao => { + GLctx.bindVertexArray(GL.vaos[vao]); + var ibo = GLctx.getParameter(34965); + GLctx.currentElementArrayBufferBinding = ibo ? (ibo.name | 0) : 0; +}; + +var _glBindVertexArray = _emscripten_glBindVertexArray; + +var _emscripten_glBlendEquation = x0 => GLctx.blendEquation(x0); + +var _glBlendEquation = _emscripten_glBlendEquation; + +var _emscripten_glBlendFunc = (x0, x1) => GLctx.blendFunc(x0, x1); + +var _glBlendFunc = _emscripten_glBlendFunc; + +var _emscripten_glBufferData = (target, size, data, usage) => { + if (GL.currentContext.version >= 2) { + // If size is zero, WebGL would interpret uploading the whole input + // arraybuffer (starting from given offset), which would not make sense in + // WebAssembly, so avoid uploading if size is zero. However we must still + // call bufferData to establish a backing storage of zero bytes. + if (data && size) { + GLctx.bufferData(target, HEAPU8, usage, data, size); + } else { + GLctx.bufferData(target, size, usage); + } + return; + } + // N.b. here first form specifies a heap subarray, second form an integer + // size, so the ?: code here is polymorphic. It is advised to avoid + // randomly mixing both uses in calling code, to avoid any potential JS + // engine JIT issues. + GLctx.bufferData(target, data ? HEAPU8.subarray(data, data + size) : size, usage); +}; + +var _glBufferData = _emscripten_glBufferData; + +var _emscripten_glClear = x0 => GLctx.clear(x0); + +var _glClear = _emscripten_glClear; + +var _emscripten_glClearColor = (x0, x1, x2, x3) => GLctx.clearColor(x0, x1, x2, x3); + +var _glClearColor = _emscripten_glClearColor; + +var convertI32PairToI53 = (lo, hi) => (lo >>> 0) + hi * 4294967296; + +var _emscripten_glClientWaitSync = (sync, flags, timeout_low, timeout_high) => { + // WebGL2 vs GLES3 differences: in GLES3, the timeout parameter is a uint64, where 0xFFFFFFFFFFFFFFFFULL means GL_TIMEOUT_IGNORED. + // In JS, there's no 64-bit value types, so instead timeout is taken to be signed, and GL_TIMEOUT_IGNORED is given value -1. + // Inherently the value accepted in the timeout is lossy, and can't take in arbitrary u64 bit pattern (but most likely doesn't matter) + // See https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.15 + var timeout = convertI32PairToI53(timeout_low, timeout_high); + return GLctx.clientWaitSync(GL.syncs[sync], flags, timeout); +}; + +var _glClientWaitSync = _emscripten_glClientWaitSync; + +var _emscripten_glColorMask = (red, green, blue, alpha) => { + GLctx.colorMask(!!red, !!green, !!blue, !!alpha); +}; + +var _glColorMask = _emscripten_glColorMask; + +var _emscripten_glCompileShader = shader => { + GLctx.compileShader(GL.shaders[shader]); +}; + +var _glCompileShader = _emscripten_glCompileShader; + +var _emscripten_glCreateProgram = () => { + var id = GL.getNewId(GL.programs); + var program = GLctx.createProgram(); + // Store additional information needed for each shader program: + program.name = id; + // Lazy cache results of + // glGetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH/GL_ACTIVE_ATTRIBUTE_MAX_LENGTH/GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH) + program.maxUniformLength = program.maxAttributeLength = program.maxUniformBlockNameLength = 0; + program.uniformIdCounter = 1; + GL.programs[id] = program; + return id; +}; + +var _glCreateProgram = _emscripten_glCreateProgram; + +var _emscripten_glCreateShader = shaderType => { + var id = GL.getNewId(GL.shaders); + GL.shaders[id] = GLctx.createShader(shaderType); + return id; +}; + +var _glCreateShader = _emscripten_glCreateShader; + +var _emscripten_glDeleteBuffers = (n, buffers) => { + for (var i = 0; i < n; i++) { + var id = HEAP32[(((buffers) + (i * 4)) >> 2)]; + var buffer = GL.buffers[id]; + // From spec: "glDeleteBuffers silently ignores 0's and names that do not + // correspond to existing buffer objects." + if (!buffer) continue; + GLctx.deleteBuffer(buffer); + buffer.name = 0; + GL.buffers[id] = null; + if (id == GLctx.currentArrayBufferBinding) GLctx.currentArrayBufferBinding = 0; + if (id == GLctx.currentElementArrayBufferBinding) GLctx.currentElementArrayBufferBinding = 0; + if (id == GLctx.currentPixelPackBufferBinding) GLctx.currentPixelPackBufferBinding = 0; + if (id == GLctx.currentPixelUnpackBufferBinding) GLctx.currentPixelUnpackBufferBinding = 0; + } +}; + +var _glDeleteBuffers = _emscripten_glDeleteBuffers; + +var _emscripten_glDeleteFramebuffers = (n, framebuffers) => { + for (var i = 0; i < n; ++i) { + var id = HEAP32[(((framebuffers) + (i * 4)) >> 2)]; + var framebuffer = GL.framebuffers[id]; + if (!framebuffer) continue; + // GL spec: "glDeleteFramebuffers silently ignores 0s and names that do not correspond to existing framebuffer objects". + GLctx.deleteFramebuffer(framebuffer); + framebuffer.name = 0; + GL.framebuffers[id] = null; + } +}; + +var _glDeleteFramebuffers = _emscripten_glDeleteFramebuffers; + +var _emscripten_glDeleteProgram = id => { + if (!id) return; + var program = GL.programs[id]; + if (!program) { + // glDeleteProgram actually signals an error when deleting a nonexisting + // object, unlike some other GL delete functions. + GL.recordError(1281); + return; + } + GLctx.deleteProgram(program); + program.name = 0; + GL.programs[id] = null; +}; + +var _glDeleteProgram = _emscripten_glDeleteProgram; + +var _emscripten_glDeleteShader = id => { + if (!id) return; + var shader = GL.shaders[id]; + if (!shader) { + // glDeleteShader actually signals an error when deleting a nonexisting + // object, unlike some other GL delete functions. + GL.recordError(1281); + return; + } + GLctx.deleteShader(shader); + GL.shaders[id] = null; +}; + +var _glDeleteShader = _emscripten_glDeleteShader; + +var _emscripten_glDeleteSync = id => { + if (!id) return; + var sync = GL.syncs[id]; + if (!sync) { + // glDeleteSync signals an error when deleting a nonexisting object, unlike some other GL delete functions. + GL.recordError(1281); + return; + } + GLctx.deleteSync(sync); + sync.name = 0; + GL.syncs[id] = null; +}; + +var _glDeleteSync = _emscripten_glDeleteSync; + +var _emscripten_glDeleteTextures = (n, textures) => { + for (var i = 0; i < n; i++) { + var id = HEAP32[(((textures) + (i * 4)) >> 2)]; + var texture = GL.textures[id]; + // GL spec: "glDeleteTextures silently ignores 0s and names that do not + // correspond to existing textures". + if (!texture) continue; + GLctx.deleteTexture(texture); + texture.name = 0; + GL.textures[id] = null; + } +}; + +var _glDeleteTextures = _emscripten_glDeleteTextures; + +var _emscripten_glDeleteVertexArrays = (n, vaos) => { + for (var i = 0; i < n; i++) { + var id = HEAP32[(((vaos) + (i * 4)) >> 2)]; + GLctx.deleteVertexArray(GL.vaos[id]); + GL.vaos[id] = null; + } +}; + +var _glDeleteVertexArrays = _emscripten_glDeleteVertexArrays; + +var _emscripten_glDetachShader = (program, shader) => { + GLctx.detachShader(GL.programs[program], GL.shaders[shader]); +}; + +var _glDetachShader = _emscripten_glDetachShader; + +var _emscripten_glDisable = x0 => GLctx.disable(x0); + +var _glDisable = _emscripten_glDisable; + +var _emscripten_glDisableVertexAttribArray = index => { + var cb = GL.currentContext.clientBuffers[index]; + cb.enabled = false; + GLctx.disableVertexAttribArray(index); +}; + +var _glDisableVertexAttribArray = _emscripten_glDisableVertexAttribArray; + +var _emscripten_glDrawArrays = (mode, first, count) => { + // bind any client-side buffers + GL.preDrawHandleClientVertexAttribBindings(first + count); + GLctx.drawArrays(mode, first, count); + GL.postDrawHandleClientVertexAttribBindings(); +}; + +var _glDrawArrays = _emscripten_glDrawArrays; + +var tempFixedLengthArray = []; + +var _emscripten_glDrawBuffers = (n, bufs) => { + var bufArray = tempFixedLengthArray[n]; + for (var i = 0; i < n; i++) { + bufArray[i] = HEAP32[(((bufs) + (i * 4)) >> 2)]; + } + GLctx.drawBuffers(bufArray); +}; + +var _glDrawBuffers = _emscripten_glDrawBuffers; + +var _emscripten_glEnable = x0 => GLctx.enable(x0); + +var _glEnable = _emscripten_glEnable; + +var _emscripten_glEnableVertexAttribArray = index => { + var cb = GL.currentContext.clientBuffers[index]; + cb.enabled = true; + GLctx.enableVertexAttribArray(index); +}; + +var _glEnableVertexAttribArray = _emscripten_glEnableVertexAttribArray; + +var _emscripten_glFenceSync = (condition, flags) => { + var sync = GLctx.fenceSync(condition, flags); + if (sync) { + var id = GL.getNewId(GL.syncs); + sync.name = id; + GL.syncs[id] = sync; + return id; + } + return 0; +}; + +var _glFenceSync = _emscripten_glFenceSync; + +var _emscripten_glFinish = () => GLctx.finish(); + +var _glFinish = _emscripten_glFinish; + +var _emscripten_glFlush = () => GLctx.flush(); + +var _glFlush = _emscripten_glFlush; + +var _emscripten_glFramebufferTexture2D = (target, attachment, textarget, texture, level) => { + GLctx.framebufferTexture2D(target, attachment, textarget, GL.textures[texture], level); +}; + +var _glFramebufferTexture2D = _emscripten_glFramebufferTexture2D; + +var _emscripten_glFramebufferTextureLayer = (target, attachment, texture, level, layer) => { + GLctx.framebufferTextureLayer(target, attachment, GL.textures[texture], level, layer); +}; + +var _glFramebufferTextureLayer = _emscripten_glFramebufferTextureLayer; + +var _emscripten_glGenBuffers = (n, buffers) => { + GL.genObject(n, buffers, "createBuffer", GL.buffers); +}; + +var _glGenBuffers = _emscripten_glGenBuffers; + +var _emscripten_glGenFramebuffers = (n, ids) => { + GL.genObject(n, ids, "createFramebuffer", GL.framebuffers); +}; + +var _glGenFramebuffers = _emscripten_glGenFramebuffers; + +var _emscripten_glGenTextures = (n, textures) => { + GL.genObject(n, textures, "createTexture", GL.textures); +}; + +var _glGenTextures = _emscripten_glGenTextures; + +var _emscripten_glGenVertexArrays = (n, arrays) => { + GL.genObject(n, arrays, "createVertexArray", GL.vaos); +}; + +var _glGenVertexArrays = _emscripten_glGenVertexArrays; + +var _emscripten_glGetAttribLocation = (program, name) => GLctx.getAttribLocation(GL.programs[program], UTF8ToString(name)); + +var _glGetAttribLocation = _emscripten_glGetAttribLocation; + +var _emscripten_glGetError = () => { + var error = GLctx.getError() || GL.lastError; + GL.lastError = 0; + return error; +}; + +var _glGetError = _emscripten_glGetError; + +var webglGetExtensions = () => { + var exts = getEmscriptenSupportedExtensions(GLctx); + exts = exts.concat(exts.map(e => "GL_" + e)); + return exts; +}; + +var emscriptenWebGLGet = (name_, p, type) => { + // Guard against user passing a null pointer. + // Note that GLES2 spec does not say anything about how passing a null + // pointer should be treated. Testing on desktop core GL 3, the application + // crashes on glGetIntegerv to a null pointer, but better to report an error + // instead of doing anything random. + if (!p) { + GL.recordError(1281); + return; + } + var ret = undefined; + switch (name_) { + // Handle a few trivial GLES values + case 36346: + // GL_SHADER_COMPILER + ret = 1; + break; + + case 36344: + // GL_SHADER_BINARY_FORMATS + if (type != 0 && type != 1) { + GL.recordError(1280); + } + // Do not write anything to the out pointer, since no binary formats are + // supported. + return; + + case 34814: + // GL_NUM_PROGRAM_BINARY_FORMATS + case 36345: + // GL_NUM_SHADER_BINARY_FORMATS + ret = 0; + break; + + case 34466: + // GL_NUM_COMPRESSED_TEXTURE_FORMATS + // WebGL doesn't have GL_NUM_COMPRESSED_TEXTURE_FORMATS (it's obsolete + // since GL_COMPRESSED_TEXTURE_FORMATS returns a JS array that can be + // queried for length), so implement it ourselves to allow C++ GLES2 + // code to get the length. + var formats = GLctx.getParameter(34467); + ret = formats ? formats.length : 0; + break; + + case 33309: + // GL_NUM_EXTENSIONS + if (GL.currentContext.version < 2) { + // Calling GLES3/WebGL2 function with a GLES2/WebGL1 context + GL.recordError(1282); + return; + } + ret = webglGetExtensions().length; + break; + + case 33307: + // GL_MAJOR_VERSION + case 33308: + // GL_MINOR_VERSION + if (GL.currentContext.version < 2) { + GL.recordError(1280); + // GL_INVALID_ENUM + return; + } + ret = name_ == 33307 ? 3 : 0; + // return version 3.0 + break; + } + if (ret === undefined) { + var result = GLctx.getParameter(name_); + switch (typeof result) { + case "number": + ret = result; + break; + + case "boolean": + ret = result ? 1 : 0; + break; + + case "string": + GL.recordError(1280); + // GL_INVALID_ENUM + return; + + case "object": + if (result === null) { + // null is a valid result for some (e.g., which buffer is bound - + // perhaps nothing is bound), but otherwise can mean an invalid + // name_, which we need to report as an error + switch (name_) { + case 34964: + // ARRAY_BUFFER_BINDING + case 35725: + // CURRENT_PROGRAM + case 34965: + // ELEMENT_ARRAY_BUFFER_BINDING + case 36006: + // FRAMEBUFFER_BINDING or DRAW_FRAMEBUFFER_BINDING + case 36007: + // RENDERBUFFER_BINDING + case 32873: + // TEXTURE_BINDING_2D + case 34229: + // WebGL 2 GL_VERTEX_ARRAY_BINDING, or WebGL 1 extension OES_vertex_array_object GL_VERTEX_ARRAY_BINDING_OES + case 36662: + // COPY_READ_BUFFER_BINDING or COPY_READ_BUFFER + case 36663: + // COPY_WRITE_BUFFER_BINDING or COPY_WRITE_BUFFER + case 35053: + // PIXEL_PACK_BUFFER_BINDING + case 35055: + // PIXEL_UNPACK_BUFFER_BINDING + case 36010: + // READ_FRAMEBUFFER_BINDING + case 35097: + // SAMPLER_BINDING + case 35869: + // TEXTURE_BINDING_2D_ARRAY + case 32874: + // TEXTURE_BINDING_3D + case 36389: + // TRANSFORM_FEEDBACK_BINDING + case 35983: + // TRANSFORM_FEEDBACK_BUFFER_BINDING + case 35368: + // UNIFORM_BUFFER_BINDING + case 34068: + { + // TEXTURE_BINDING_CUBE_MAP + ret = 0; + break; + } + + default: + { + GL.recordError(1280); + // GL_INVALID_ENUM + return; + } + } + } else if (result instanceof Float32Array || result instanceof Uint32Array || result instanceof Int32Array || result instanceof Array) { + for (var i = 0; i < result.length; ++i) { + switch (type) { + case 0: + HEAP32[(((p) + (i * 4)) >> 2)] = result[i]; + break; + + case 2: + HEAPF32[(((p) + (i * 4)) >> 2)] = result[i]; + break; + + case 4: + HEAP8[(p) + (i)] = result[i] ? 1 : 0; + break; + } + } + return; + } else { + try { + ret = result.name | 0; + } catch (e) { + GL.recordError(1280); + // GL_INVALID_ENUM + err(`GL_INVALID_ENUM in glGet${type}v: Unknown object returned from WebGL getParameter(${name_})! (error: ${e})`); + return; + } + } + break; + + default: + GL.recordError(1280); + // GL_INVALID_ENUM + err(`GL_INVALID_ENUM in glGet${type}v: Native code calling glGet${type}v(${name_}) and it returns ${result} of type ${typeof (result)}!`); + return; + } + } + switch (type) { + case 1: + writeI53ToI64(p, ret); + break; + + case 0: + HEAP32[((p) >> 2)] = ret; + break; + + case 2: + HEAPF32[((p) >> 2)] = ret; + break; + + case 4: + HEAP8[p] = ret ? 1 : 0; + break; + } +}; + +var _emscripten_glGetFloatv = (name_, p) => emscriptenWebGLGet(name_, p, 2); + +var _glGetFloatv = _emscripten_glGetFloatv; + +var _emscripten_glGetIntegerv = (name_, p) => emscriptenWebGLGet(name_, p, 0); + +var _glGetIntegerv = _emscripten_glGetIntegerv; + +var _emscripten_glGetProgramiv = (program, pname, p) => { + if (!p) { + // GLES2 specification does not specify how to behave if p is a null + // pointer. Since calling this function does not make sense if p == null, + // issue a GL error to notify user about it. + GL.recordError(1281); + return; + } + if (program >= GL.counter) { + GL.recordError(1281); + return; + } + program = GL.programs[program]; + if (pname == 35716) { + // GL_INFO_LOG_LENGTH + var log = GLctx.getProgramInfoLog(program); + if (log === null) log = "(unknown error)"; + HEAP32[((p) >> 2)] = log.length + 1; + } else if (pname == 35719) { + if (!program.maxUniformLength) { + var numActiveUniforms = GLctx.getProgramParameter(program, 35718); + for (var i = 0; i < numActiveUniforms; ++i) { + program.maxUniformLength = Math.max(program.maxUniformLength, GLctx.getActiveUniform(program, i).name.length + 1); + } + } + HEAP32[((p) >> 2)] = program.maxUniformLength; + } else if (pname == 35722) { + if (!program.maxAttributeLength) { + var numActiveAttributes = GLctx.getProgramParameter(program, 35721); + for (var i = 0; i < numActiveAttributes; ++i) { + program.maxAttributeLength = Math.max(program.maxAttributeLength, GLctx.getActiveAttrib(program, i).name.length + 1); + } + } + HEAP32[((p) >> 2)] = program.maxAttributeLength; + } else if (pname == 35381) { + if (!program.maxUniformBlockNameLength) { + var numActiveUniformBlocks = GLctx.getProgramParameter(program, 35382); + for (var i = 0; i < numActiveUniformBlocks; ++i) { + program.maxUniformBlockNameLength = Math.max(program.maxUniformBlockNameLength, GLctx.getActiveUniformBlockName(program, i).length + 1); + } + } + HEAP32[((p) >> 2)] = program.maxUniformBlockNameLength; + } else { + HEAP32[((p) >> 2)] = GLctx.getProgramParameter(program, pname); + } +}; + +var _glGetProgramiv = _emscripten_glGetProgramiv; + +var _emscripten_glGetShaderInfoLog = (shader, maxLength, length, infoLog) => { + var log = GLctx.getShaderInfoLog(GL.shaders[shader]); + if (log === null) log = "(unknown error)"; + var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0; + if (length) HEAP32[((length) >> 2)] = numBytesWrittenExclNull; +}; + +var _glGetShaderInfoLog = _emscripten_glGetShaderInfoLog; + +var _emscripten_glGetShaderiv = (shader, pname, p) => { + if (!p) { + // GLES2 specification does not specify how to behave if p is a null + // pointer. Since calling this function does not make sense if p == null, + // issue a GL error to notify user about it. + GL.recordError(1281); + return; + } + if (pname == 35716) { + // GL_INFO_LOG_LENGTH + var log = GLctx.getShaderInfoLog(GL.shaders[shader]); + if (log === null) log = "(unknown error)"; + // The GLES2 specification says that if the shader has an empty info log, + // a value of 0 is returned. Otherwise the log has a null char appended. + // (An empty string is falsey, so we can just check that instead of + // looking at log.length.) + var logLength = log ? log.length + 1 : 0; + HEAP32[((p) >> 2)] = logLength; + } else if (pname == 35720) { + // GL_SHADER_SOURCE_LENGTH + var source = GLctx.getShaderSource(GL.shaders[shader]); + // source may be a null, or the empty string, both of which are falsey + // values that we report a 0 length for. + var sourceLength = source ? source.length + 1 : 0; + HEAP32[((p) >> 2)] = sourceLength; + } else { + HEAP32[((p) >> 2)] = GLctx.getShaderParameter(GL.shaders[shader], pname); + } +}; + +var _glGetShaderiv = _emscripten_glGetShaderiv; + +var _emscripten_glGetString = name_ => { + var ret = GL.stringCache[name_]; + if (!ret) { + switch (name_) { + case 7939: + ret = stringToNewUTF8(webglGetExtensions().join(" ")); + break; + + case 7936: + case 7937: + case 37445: + case 37446: + var s = GLctx.getParameter(name_); + if (!s) { + GL.recordError(1280); + } + ret = s ? stringToNewUTF8(s) : 0; + break; + + case 7938: + var webGLVersion = GLctx.getParameter(7938); + // return GLES version string corresponding to the version of the WebGL context + var glVersion = `OpenGL ES 2.0 (${webGLVersion})`; + if (GL.currentContext.version >= 2) glVersion = `OpenGL ES 3.0 (${webGLVersion})`; + ret = stringToNewUTF8(glVersion); + break; + + case 35724: + var glslVersion = GLctx.getParameter(35724); + // extract the version number 'N.M' from the string 'WebGL GLSL ES N.M ...' + var ver_re = /^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/; + var ver_num = glslVersion.match(ver_re); + if (ver_num !== null) { + if (ver_num[1].length == 3) ver_num[1] = ver_num[1] + "0"; + // ensure minor version has 2 digits + glslVersion = `OpenGL ES GLSL ES ${ver_num[1]} (${glslVersion})`; + } + ret = stringToNewUTF8(glslVersion); + break; + + default: + GL.recordError(1280); + } + GL.stringCache[name_] = ret; + } + return ret; +}; + +var _glGetString = _emscripten_glGetString; + +var _emscripten_glGetUniformBlockIndex = (program, uniformBlockName) => GLctx.getUniformBlockIndex(GL.programs[program], UTF8ToString(uniformBlockName)); + +var _glGetUniformBlockIndex = _emscripten_glGetUniformBlockIndex; + +/** @suppress {checkTypes} */ var jstoi_q = str => parseInt(str); + +/** @noinline */ var webglGetLeftBracePos = name => name.slice(-1) == "]" && name.lastIndexOf("["); + +var webglPrepareUniformLocationsBeforeFirstUse = program => { + var uniformLocsById = program.uniformLocsById, // Maps GLuint -> WebGLUniformLocation + uniformSizeAndIdsByName = program.uniformSizeAndIdsByName, // Maps name -> [uniform array length, GLuint] + i, j; + // On the first time invocation of glGetUniformLocation on this shader program: + // initialize cache data structures and discover which uniforms are arrays. + if (!uniformLocsById) { + // maps GLint integer locations to WebGLUniformLocations + program.uniformLocsById = uniformLocsById = {}; + // maps integer locations back to uniform name strings, so that we can lazily fetch uniform array locations + program.uniformArrayNamesById = {}; + var numActiveUniforms = GLctx.getProgramParameter(program, 35718); + for (i = 0; i < numActiveUniforms; ++i) { + var u = GLctx.getActiveUniform(program, i); + var nm = u.name; + var sz = u.size; + var lb = webglGetLeftBracePos(nm); + var arrayName = lb > 0 ? nm.slice(0, lb) : nm; + // Assign a new location. + var id = program.uniformIdCounter; + program.uniformIdCounter += sz; + // Eagerly get the location of the uniformArray[0] base element. + // The remaining indices >0 will be left for lazy evaluation to + // improve performance. Those may never be needed to fetch, if the + // application fills arrays always in full starting from the first + // element of the array. + uniformSizeAndIdsByName[arrayName] = [ sz, id ]; + // Store placeholder integers in place that highlight that these + // >0 index locations are array indices pending population. + for (j = 0; j < sz; ++j) { + uniformLocsById[id] = j; + program.uniformArrayNamesById[id++] = arrayName; + } + } + } +}; + +var _emscripten_glGetUniformLocation = (program, name) => { + name = UTF8ToString(name); + if (program = GL.programs[program]) { + webglPrepareUniformLocationsBeforeFirstUse(program); + var uniformLocsById = program.uniformLocsById; + // Maps GLuint -> WebGLUniformLocation + var arrayIndex = 0; + var uniformBaseName = name; + // Invariant: when populating integer IDs for uniform locations, we must + // maintain the precondition that arrays reside in contiguous addresses, + // i.e. for a 'vec4 colors[10];', colors[4] must be at location + // colors[0]+4. However, user might call glGetUniformLocation(program, + // "colors") for an array, so we cannot discover based on the user input + // arguments whether the uniform we are dealing with is an array. The only + // way to discover which uniforms are arrays is to enumerate over all the + // active uniforms in the program. + var leftBrace = webglGetLeftBracePos(name); + // If user passed an array accessor "[index]", parse the array index off the accessor. + if (leftBrace > 0) { + 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. + uniformBaseName = name.slice(0, leftBrace); + } + // Have we cached the location of this uniform before? + // A pair [array length, GLint of the uniform location] + var sizeAndId = program.uniformSizeAndIdsByName[uniformBaseName]; + // If a uniform with this name exists, and if its index is within the + // array limits (if it's even an array), query the WebGLlocation, or + // return an existing cached location. + if (sizeAndId && arrayIndex < sizeAndId[0]) { + arrayIndex += sizeAndId[1]; + // Add the base location of the uniform to the array index offset. + if ((uniformLocsById[arrayIndex] = uniformLocsById[arrayIndex] || GLctx.getUniformLocation(program, name))) { + return arrayIndex; + } + } + } else { + // N.b. we are currently unable to distinguish between GL program IDs that + // never existed vs GL program IDs that have been deleted, so report + // GL_INVALID_VALUE in both cases. + GL.recordError(1281); + } + return -1; +}; + +var _glGetUniformLocation = _emscripten_glGetUniformLocation; + +var _emscripten_glLineWidth = x0 => GLctx.lineWidth(x0); + +var _glLineWidth = _emscripten_glLineWidth; + +var _emscripten_glLinkProgram = program => { + program = GL.programs[program]; + GLctx.linkProgram(program); + // Invalidate earlier computed uniform->ID mappings, those have now become stale + program.uniformLocsById = 0; + // Mark as null-like so that glGetUniformLocation() knows to populate this again. + program.uniformSizeAndIdsByName = {}; +}; + +var _glLinkProgram = _emscripten_glLinkProgram; + +var _emscripten_glPixelStorei = (pname, param) => { + if (pname == 3317) { + GL.unpackAlignment = param; + } else if (pname == 3314) { + GL.unpackRowLength = param; + } + GLctx.pixelStorei(pname, param); +}; + +var _glPixelStorei = _emscripten_glPixelStorei; + +var computeUnpackAlignedImageSize = (width, height, sizePerPixel) => { + function roundedToNextMultipleOf(x, y) { + return (x + y - 1) & -y; + } + var plainRowSize = (GL.unpackRowLength || width) * sizePerPixel; + var alignedRowSize = roundedToNextMultipleOf(plainRowSize, GL.unpackAlignment); + return height * alignedRowSize; +}; + +var colorChannelsInGlTextureFormat = format => { + // Micro-optimizations for size: map format to size by subtracting smallest + // enum value (0x1902) from all values first. Also omit the most common + // size value (1) from the list, which is assumed by formats not on the + // list. + var colorChannels = { + // 0x1902 /* GL_DEPTH_COMPONENT */ - 0x1902: 1, + // 0x1906 /* GL_ALPHA */ - 0x1902: 1, + 5: 3, + 6: 4, + // 0x1909 /* GL_LUMINANCE */ - 0x1902: 1, + 8: 2, + 29502: 3, + 29504: 4, + // 0x1903 /* GL_RED */ - 0x1902: 1, + 26917: 2, + 26918: 2, + // 0x8D94 /* GL_RED_INTEGER */ - 0x1902: 1, + 29846: 3, + 29847: 4 + }; + return colorChannels[format - 6402] || 1; +}; + +var heapObjectForWebGLType = type => { + // Micro-optimization for size: Subtract lowest GL enum number (0x1400/* GL_BYTE */) from type to compare + // smaller values for the heap, for shorter generated code size. + // Also the type HEAPU16 is not tested for explicitly, but any unrecognized type will return out HEAPU16. + // (since most types are HEAPU16) + type -= 5120; + if (type == 0) return HEAP8; + if (type == 1) return HEAPU8; + if (type == 2) return HEAP16; + if (type == 4) return HEAP32; + if (type == 6) return HEAPF32; + if (type == 5 || type == 28922 || type == 28520 || type == 30779 || type == 30782) return HEAPU32; + return HEAPU16; +}; + +var toTypedArrayIndex = (pointer, heap) => pointer >>> (31 - Math.clz32(heap.BYTES_PER_ELEMENT)); + +var emscriptenWebGLGetTexPixelData = (type, format, width, height, pixels) => { + var heap = heapObjectForWebGLType(type); + var sizePerPixel = colorChannelsInGlTextureFormat(format) * heap.BYTES_PER_ELEMENT; + var bytes = computeUnpackAlignedImageSize(width, height, sizePerPixel); + return heap.subarray(toTypedArrayIndex(pixels, heap), toTypedArrayIndex(pixels + bytes, heap)); +}; + +var _emscripten_glReadPixels = (x, y, width, height, format, type, pixels) => { + if (GL.currentContext.version >= 2) { + if (GLctx.currentPixelPackBufferBinding) { + GLctx.readPixels(x, y, width, height, format, type, pixels); + return; + } + var heap = heapObjectForWebGLType(type); + var target = toTypedArrayIndex(pixels, heap); + GLctx.readPixels(x, y, width, height, format, type, heap, target); + return; + } + var pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels); + if (!pixelData) { + GL.recordError(1280); + return; + } + GLctx.readPixels(x, y, width, height, format, type, pixelData); +}; + +var _glReadPixels = _emscripten_glReadPixels; + +var _emscripten_glShaderSource = (shader, count, string, length) => { + var source = GL.getSource(shader, count, string, length); + GLctx.shaderSource(GL.shaders[shader], source); +}; + +var _glShaderSource = _emscripten_glShaderSource; + +var _emscripten_glTexImage2D = (target, level, internalFormat, width, height, border, format, type, pixels) => { + if (GL.currentContext.version >= 2) { + if (GLctx.currentPixelUnpackBufferBinding) { + GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels); + return; + } + if (pixels) { + var heap = heapObjectForWebGLType(type); + var index = toTypedArrayIndex(pixels, heap); + GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, heap, index); + return; + } + } + var pixelData = pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels) : null; + GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixelData); +}; + +var _glTexImage2D = _emscripten_glTexImage2D; + +var _emscripten_glTexParameterf = (x0, x1, x2) => GLctx.texParameterf(x0, x1, x2); + +var _glTexParameterf = _emscripten_glTexParameterf; + +var _emscripten_glTexParameterfv = (target, pname, params) => { + var param = HEAPF32[((params) >> 2)]; + GLctx.texParameterf(target, pname, param); +}; + +var _glTexParameterfv = _emscripten_glTexParameterfv; + +var _emscripten_glTexParameteri = (x0, x1, x2) => GLctx.texParameteri(x0, x1, x2); + +var _glTexParameteri = _emscripten_glTexParameteri; + +var _emscripten_glTexStorage2D = (x0, x1, x2, x3, x4) => GLctx.texStorage2D(x0, x1, x2, x3, x4); + +var _glTexStorage2D = _emscripten_glTexStorage2D; + +var _emscripten_glTexStorage3D = (x0, x1, x2, x3, x4, x5) => GLctx.texStorage3D(x0, x1, x2, x3, x4, x5); + +var _glTexStorage3D = _emscripten_glTexStorage3D; + +var _emscripten_glTexSubImage2D = (target, level, xoffset, yoffset, width, height, format, type, pixels) => { + if (GL.currentContext.version >= 2) { + if (GLctx.currentPixelUnpackBufferBinding) { + GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + return; + } + if (pixels) { + var heap = heapObjectForWebGLType(type); + GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, heap, toTypedArrayIndex(pixels, heap)); + return; + } + } + var pixelData = pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels) : null; + GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixelData); +}; + +var _glTexSubImage2D = _emscripten_glTexSubImage2D; + +var _emscripten_glTexSubImage3D = (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) => { + if (GLctx.currentPixelUnpackBufferBinding) { + GLctx.texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + } else if (pixels) { + var heap = heapObjectForWebGLType(type); + GLctx.texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, heap, toTypedArrayIndex(pixels, heap)); + } else { + GLctx.texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, null); + } +}; + +var _glTexSubImage3D = _emscripten_glTexSubImage3D; + +var webglGetProgramUniformLocation = (program, location) => { + if (program) { + var webglLoc = program.uniformLocsById[location]; + // program.uniformLocsById[location] stores either an integer, or a + // WebGLUniformLocation. + // If an integer, we have not yet bound the location, so do it now. The + // integer value specifies the array index we should bind to. + if (typeof webglLoc == "number") { + program.uniformLocsById[location] = webglLoc = GLctx.getUniformLocation(program, program.uniformArrayNamesById[location] + (webglLoc > 0 ? `[${webglLoc}]` : "")); + } + // Else an already cached WebGLUniformLocation, return it. + return webglLoc; + } else { + GL.recordError(1282); + } +}; + +var webglGetUniformLocation = location => webglGetProgramUniformLocation(GLctx.currentProgram, location); + +var _emscripten_glUniform1f = (location, v0) => { + GLctx.uniform1f(webglGetUniformLocation(location), v0); +}; + +var _glUniform1f = _emscripten_glUniform1f; + +var miniTempWebGLFloatBuffers = []; + +var _emscripten_glUniform1fv = (location, count, value) => { + if (GL.currentContext.version >= 2) { + count && GLctx.uniform1fv(webglGetUniformLocation(location), HEAPF32, ((value) >> 2), count); + return; + } + if (count <= 288) { + // avoid allocation when uploading few enough uniforms + var view = miniTempWebGLFloatBuffers[count]; + for (var i = 0; i < count; ++i) { + view[i] = HEAPF32[(((value) + (4 * i)) >> 2)]; + } + } else { + var view = HEAPF32.subarray((((value) >> 2)), ((value + count * 4) >> 2)); + } + GLctx.uniform1fv(webglGetUniformLocation(location), view); +}; + +var _glUniform1fv = _emscripten_glUniform1fv; + +var _emscripten_glUniform1i = (location, v0) => { + GLctx.uniform1i(webglGetUniformLocation(location), v0); +}; + +var _glUniform1i = _emscripten_glUniform1i; + +var _emscripten_glUniform2f = (location, v0, v1) => { + GLctx.uniform2f(webglGetUniformLocation(location), v0, v1); +}; + +var _glUniform2f = _emscripten_glUniform2f; + +var _emscripten_glUniform2fv = (location, count, value) => { + if (GL.currentContext.version >= 2) { + count && GLctx.uniform2fv(webglGetUniformLocation(location), HEAPF32, ((value) >> 2), count * 2); + return; + } + if (count <= 144) { + // avoid allocation when uploading few enough uniforms + count *= 2; + var view = miniTempWebGLFloatBuffers[count]; + for (var i = 0; i < count; i += 2) { + view[i] = HEAPF32[(((value) + (4 * i)) >> 2)]; + view[i + 1] = HEAPF32[(((value) + (4 * i + 4)) >> 2)]; + } + } else { + var view = HEAPF32.subarray((((value) >> 2)), ((value + count * 8) >> 2)); + } + GLctx.uniform2fv(webglGetUniformLocation(location), view); +}; + +var _glUniform2fv = _emscripten_glUniform2fv; + +var _emscripten_glUniform3f = (location, v0, v1, v2) => { + GLctx.uniform3f(webglGetUniformLocation(location), v0, v1, v2); +}; + +var _glUniform3f = _emscripten_glUniform3f; + +var _emscripten_glUniform4f = (location, v0, v1, v2, v3) => { + GLctx.uniform4f(webglGetUniformLocation(location), v0, v1, v2, v3); +}; + +var _glUniform4f = _emscripten_glUniform4f; + +var _emscripten_glUniform4fv = (location, count, value) => { + if (GL.currentContext.version >= 2) { + count && GLctx.uniform4fv(webglGetUniformLocation(location), HEAPF32, ((value) >> 2), count * 4); + return; + } + if (count <= 72) { + // avoid allocation when uploading few enough uniforms + var view = miniTempWebGLFloatBuffers[4 * count]; + // hoist the heap out of the loop for size and for pthreads+growth. + var heap = HEAPF32; + value = ((value) >> 2); + count *= 4; + for (var i = 0; i < count; i += 4) { + var dst = value + i; + view[i] = heap[dst]; + view[i + 1] = heap[dst + 1]; + view[i + 2] = heap[dst + 2]; + view[i + 3] = heap[dst + 3]; + } + } else { + var view = HEAPF32.subarray((((value) >> 2)), ((value + count * 16) >> 2)); + } + GLctx.uniform4fv(webglGetUniformLocation(location), view); +}; + +var _glUniform4fv = _emscripten_glUniform4fv; + +var miniTempWebGLIntBuffers = []; + +var _emscripten_glUniform4iv = (location, count, value) => { + if (GL.currentContext.version >= 2) { + count && GLctx.uniform4iv(webglGetUniformLocation(location), HEAP32, ((value) >> 2), count * 4); + return; + } + if (count <= 72) { + // avoid allocation when uploading few enough uniforms + count *= 4; + var view = miniTempWebGLIntBuffers[count]; + for (var i = 0; i < count; i += 4) { + view[i] = HEAP32[(((value) + (4 * i)) >> 2)]; + view[i + 1] = HEAP32[(((value) + (4 * i + 4)) >> 2)]; + view[i + 2] = HEAP32[(((value) + (4 * i + 8)) >> 2)]; + view[i + 3] = HEAP32[(((value) + (4 * i + 12)) >> 2)]; + } + } else { + var view = HEAP32.subarray((((value) >> 2)), ((value + count * 16) >> 2)); + } + GLctx.uniform4iv(webglGetUniformLocation(location), view); +}; + +var _glUniform4iv = _emscripten_glUniform4iv; + +var _emscripten_glUniformBlockBinding = (program, uniformBlockIndex, uniformBlockBinding) => { + program = GL.programs[program]; + GLctx.uniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); +}; + +var _glUniformBlockBinding = _emscripten_glUniformBlockBinding; + +var _emscripten_glUniformMatrix2fv = (location, count, transpose, value) => { + if (GL.currentContext.version >= 2) { + count && GLctx.uniformMatrix2fv(webglGetUniformLocation(location), !!transpose, HEAPF32, ((value) >> 2), count * 4); + return; + } + if (count <= 72) { + // avoid allocation when uploading few enough uniforms + count *= 4; + var view = miniTempWebGLFloatBuffers[count]; + for (var i = 0; i < count; i += 4) { + view[i] = HEAPF32[(((value) + (4 * i)) >> 2)]; + view[i + 1] = HEAPF32[(((value) + (4 * i + 4)) >> 2)]; + view[i + 2] = HEAPF32[(((value) + (4 * i + 8)) >> 2)]; + view[i + 3] = HEAPF32[(((value) + (4 * i + 12)) >> 2)]; + } + } else { + var view = HEAPF32.subarray((((value) >> 2)), ((value + count * 16) >> 2)); + } + GLctx.uniformMatrix2fv(webglGetUniformLocation(location), !!transpose, view); +}; + +var _glUniformMatrix2fv = _emscripten_glUniformMatrix2fv; + +var _emscripten_glUniformMatrix3fv = (location, count, transpose, value) => { + if (GL.currentContext.version >= 2) { + count && GLctx.uniformMatrix3fv(webglGetUniformLocation(location), !!transpose, HEAPF32, ((value) >> 2), count * 9); + return; + } + if (count <= 32) { + // avoid allocation when uploading few enough uniforms + count *= 9; + var view = miniTempWebGLFloatBuffers[count]; + for (var i = 0; i < count; i += 9) { + view[i] = HEAPF32[(((value) + (4 * i)) >> 2)]; + view[i + 1] = HEAPF32[(((value) + (4 * i + 4)) >> 2)]; + view[i + 2] = HEAPF32[(((value) + (4 * i + 8)) >> 2)]; + view[i + 3] = HEAPF32[(((value) + (4 * i + 12)) >> 2)]; + view[i + 4] = HEAPF32[(((value) + (4 * i + 16)) >> 2)]; + view[i + 5] = HEAPF32[(((value) + (4 * i + 20)) >> 2)]; + view[i + 6] = HEAPF32[(((value) + (4 * i + 24)) >> 2)]; + view[i + 7] = HEAPF32[(((value) + (4 * i + 28)) >> 2)]; + view[i + 8] = HEAPF32[(((value) + (4 * i + 32)) >> 2)]; + } + } else { + var view = HEAPF32.subarray((((value) >> 2)), ((value + count * 36) >> 2)); + } + GLctx.uniformMatrix3fv(webglGetUniformLocation(location), !!transpose, view); +}; + +var _glUniformMatrix3fv = _emscripten_glUniformMatrix3fv; + +var _emscripten_glUniformMatrix4fv = (location, count, transpose, value) => { + if (GL.currentContext.version >= 2) { + count && GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, HEAPF32, ((value) >> 2), count * 16); + return; + } + if (count <= 18) { + // avoid allocation when uploading few enough uniforms + var view = miniTempWebGLFloatBuffers[16 * count]; + // hoist the heap out of the loop for size and for pthreads+growth. + var heap = HEAPF32; + value = ((value) >> 2); + count *= 16; + for (var i = 0; i < count; i += 16) { + var dst = value + i; + view[i] = heap[dst]; + view[i + 1] = heap[dst + 1]; + view[i + 2] = heap[dst + 2]; + view[i + 3] = heap[dst + 3]; + view[i + 4] = heap[dst + 4]; + view[i + 5] = heap[dst + 5]; + view[i + 6] = heap[dst + 6]; + view[i + 7] = heap[dst + 7]; + view[i + 8] = heap[dst + 8]; + view[i + 9] = heap[dst + 9]; + view[i + 10] = heap[dst + 10]; + view[i + 11] = heap[dst + 11]; + view[i + 12] = heap[dst + 12]; + view[i + 13] = heap[dst + 13]; + view[i + 14] = heap[dst + 14]; + view[i + 15] = heap[dst + 15]; + } + } else { + var view = HEAPF32.subarray((((value) >> 2)), ((value + count * 64) >> 2)); + } + GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, view); +}; + +var _glUniformMatrix4fv = _emscripten_glUniformMatrix4fv; + +var _emscripten_glUseProgram = program => { + program = GL.programs[program]; + GLctx.useProgram(program); + // Record the currently active program so that we can access the uniform + // mapping table of that program. + GLctx.currentProgram = program; +}; + +var _glUseProgram = _emscripten_glUseProgram; + +var _emscripten_glVertexAttribPointer = (index, size, type, normalized, stride, ptr) => { + var cb = GL.currentContext.clientBuffers[index]; + if (!GLctx.currentArrayBufferBinding) { + cb.size = size; + cb.type = type; + cb.normalized = normalized; + cb.stride = stride; + cb.ptr = ptr; + cb.clientside = true; + cb.vertexAttribPointerAdaptor = /** @this {WebGLRenderingContext} */ function(index, size, type, normalized, stride, ptr) { + this.vertexAttribPointer(index, size, type, normalized, stride, ptr); + }; + return; + } + cb.clientside = false; + GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr); +}; + +var _glVertexAttribPointer = _emscripten_glVertexAttribPointer; + +var _emscripten_glViewport = (x0, x1, x2, x3) => GLctx.viewport(x0, x1, x2, x3); + +var _glViewport = _emscripten_glViewport; + +function _mediapipe_find_canvas_event_target(canvasSelector) { + let target = findCanvasEventTarget(canvasSelector); + // WebGPU-on-worker uses this function to try to grab the canvas, but + // doesn't have a DOM element to find. So as a quick patch, if the default + // behavior is unsuccessful here then we try a webgpu canvas property + // which is set by the user directly on the Module, much like how our old + // pipeline used the Module.canvas property. See b/265271517 for details. + if (Module && !target) { + target = Module.canvasWebGpu; + } + return Emval.toHandle(target); +} + +function _mediapipe_webgl_tex_image_drawable(drawableHandle) { + const drawable = Emval.toValue(drawableHandle); + GLctx.texImage2D(GLctx.TEXTURE_2D, 0, GLctx.RGBA, GLctx.RGBA, GLctx.UNSIGNED_BYTE, drawable); +} + +var _random_get = (buffer, size) => randomFill(HEAPU8.subarray(buffer, buffer + size)); + +var _wgpuCommandEncoderBeginComputePass = (encoderPtr, descriptor) => { + var desc; + if (descriptor) { + desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "timestampWrites": WebGPU.makePassTimestampWrites(HEAPU32[(((descriptor) + (12)) >> 2)]) + }; + } + var commandEncoder = WebGPU.getJsObject(encoderPtr); + var ptr = _emwgpuCreateComputePassEncoder(0); + WebGPU.Internals.jsObjectInsert(ptr, commandEncoder.beginComputePass(desc)); + return ptr; +}; + +var _wgpuCommandEncoderBeginRenderPass = (encoderPtr, descriptor) => { + function makeColorAttachment(caPtr) { + var viewPtr = HEAPU32[(((caPtr) + (4)) >> 2)]; + if (viewPtr === 0) { + // Null `view` means no attachment in this slot. + return undefined; + } + var depthSlice = HEAPU32[(((caPtr) + (8)) >> 2)]; + if (depthSlice == 4294967295) depthSlice = undefined; + return { + "view": WebGPU.getJsObject(viewPtr), + "depthSlice": depthSlice, + "resolveTarget": WebGPU.getJsObject(HEAPU32[(((caPtr) + (12)) >> 2)]), + "clearValue": WebGPU.makeColor(caPtr + 24), + "loadOp": WebGPU.LoadOp[HEAP32[(((caPtr) + (16)) >> 2)]], + "storeOp": WebGPU.StoreOp[HEAP32[(((caPtr) + (20)) >> 2)]] + }; + } + function makeColorAttachments(count, caPtr) { + var attachments = []; + for (var i = 0; i < count; ++i) { + attachments.push(makeColorAttachment(caPtr + 56 * i)); + } + return attachments; + } + function makeDepthStencilAttachment(dsaPtr) { + if (dsaPtr === 0) return undefined; + return { + "view": WebGPU.getJsObject(HEAPU32[(((dsaPtr) + (4)) >> 2)]), + "depthClearValue": HEAPF32[(((dsaPtr) + (16)) >> 2)], + "depthLoadOp": WebGPU.LoadOp[HEAP32[(((dsaPtr) + (8)) >> 2)]], + "depthStoreOp": WebGPU.StoreOp[HEAP32[(((dsaPtr) + (12)) >> 2)]], + "depthReadOnly": !!(HEAPU32[(((dsaPtr) + (20)) >> 2)]), + "stencilClearValue": HEAPU32[(((dsaPtr) + (32)) >> 2)], + "stencilLoadOp": WebGPU.LoadOp[HEAP32[(((dsaPtr) + (24)) >> 2)]], + "stencilStoreOp": WebGPU.StoreOp[HEAP32[(((dsaPtr) + (28)) >> 2)]], + "stencilReadOnly": !!(HEAPU32[(((dsaPtr) + (36)) >> 2)]) + }; + } + function makeRenderPassDescriptor(descriptor) { + var nextInChainPtr = HEAPU32[((descriptor) >> 2)]; + var maxDrawCount = undefined; + if (nextInChainPtr !== 0) { + var sType = HEAP32[(((nextInChainPtr) + (4)) >> 2)]; + var renderPassMaxDrawCount = nextInChainPtr; + // Note: The user could have passed a really huge value here, which is technically valid in + // C but will not be allowed by WebGPU in JS because of [EnforceRange]. We intentionally + // ignore that case because it's not useful - apps can just pick a smaller maxDrawCount. + maxDrawCount = readI53FromI64((renderPassMaxDrawCount) + (8)); + } + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "colorAttachments": makeColorAttachments(HEAPU32[(((descriptor) + (12)) >> 2)], HEAPU32[(((descriptor) + (16)) >> 2)]), + "depthStencilAttachment": makeDepthStencilAttachment(HEAPU32[(((descriptor) + (20)) >> 2)]), + "occlusionQuerySet": WebGPU.getJsObject(HEAPU32[(((descriptor) + (24)) >> 2)]), + "timestampWrites": WebGPU.makePassTimestampWrites(HEAPU32[(((descriptor) + (28)) >> 2)]), + "maxDrawCount": maxDrawCount + }; + return desc; + } + var desc = makeRenderPassDescriptor(descriptor); + var commandEncoder = WebGPU.getJsObject(encoderPtr); + var ptr = _emwgpuCreateRenderPassEncoder(0); + WebGPU.Internals.jsObjectInsert(ptr, commandEncoder.beginRenderPass(desc)); + return ptr; +}; + +var _wgpuCommandEncoderCopyBufferToTexture = (encoderPtr, srcPtr, dstPtr, copySizePtr) => { + var commandEncoder = WebGPU.getJsObject(encoderPtr); + var copySize = WebGPU.makeExtent3D(copySizePtr); + commandEncoder.copyBufferToTexture(WebGPU.makeTexelCopyBufferInfo(srcPtr), WebGPU.makeTexelCopyTextureInfo(dstPtr), copySize); +}; + +var _wgpuCommandEncoderCopyTextureToBuffer = (encoderPtr, srcPtr, dstPtr, copySizePtr) => { + var commandEncoder = WebGPU.getJsObject(encoderPtr); + var copySize = WebGPU.makeExtent3D(copySizePtr); + commandEncoder.copyTextureToBuffer(WebGPU.makeTexelCopyTextureInfo(srcPtr), WebGPU.makeTexelCopyBufferInfo(dstPtr), copySize); +}; + +var _wgpuCommandEncoderCopyTextureToTexture = (encoderPtr, srcPtr, dstPtr, copySizePtr) => { + var commandEncoder = WebGPU.getJsObject(encoderPtr); + var copySize = WebGPU.makeExtent3D(copySizePtr); + commandEncoder.copyTextureToTexture(WebGPU.makeTexelCopyTextureInfo(srcPtr), WebGPU.makeTexelCopyTextureInfo(dstPtr), copySize); +}; + +var _wgpuCommandEncoderFinish = (encoderPtr, descriptor) => { + // TODO: Use the descriptor. + var commandEncoder = WebGPU.getJsObject(encoderPtr); + var ptr = _emwgpuCreateCommandBuffer(0); + WebGPU.Internals.jsObjectInsert(ptr, commandEncoder.finish()); + return ptr; +}; + +var _wgpuComputePassEncoderDispatchWorkgroups = (passPtr, x, y, z) => { + var pass = WebGPU.getJsObject(passPtr); + pass.dispatchWorkgroups(x, y, z); +}; + +var _wgpuComputePassEncoderEnd = passPtr => { + var pass = WebGPU.getJsObject(passPtr); + pass.end(); +}; + +var _wgpuComputePassEncoderSetBindGroup = (passPtr, groupIndex, groupPtr, dynamicOffsetCount, dynamicOffsetsPtr) => { + var pass = WebGPU.getJsObject(passPtr); + var group = WebGPU.getJsObject(groupPtr); + if (dynamicOffsetCount == 0) { + pass.setBindGroup(groupIndex, group); + } else { + pass.setBindGroup(groupIndex, group, HEAPU32, ((dynamicOffsetsPtr) >> 2), dynamicOffsetCount); + } +}; + +var _wgpuComputePassEncoderSetPipeline = (passPtr, pipelinePtr) => { + var pass = WebGPU.getJsObject(passPtr); + var pipeline = WebGPU.getJsObject(pipelinePtr); + pass.setPipeline(pipeline); +}; + +var _wgpuComputePipelineGetBindGroupLayout = (pipelinePtr, groupIndex) => { + var pipeline = WebGPU.getJsObject(pipelinePtr); + var ptr = _emwgpuCreateBindGroupLayout(0); + WebGPU.Internals.jsObjectInsert(ptr, pipeline.getBindGroupLayout(groupIndex)); + return ptr; +}; + +var _wgpuDeviceCreateBindGroup = (devicePtr, descriptor) => { + function makeEntry(entryPtr) { + var bufferPtr = HEAPU32[(((entryPtr) + (8)) >> 2)]; + var samplerPtr = HEAPU32[(((entryPtr) + (32)) >> 2)]; + var textureViewPtr = HEAPU32[(((entryPtr) + (36)) >> 2)]; + var externalTexturePtr = 0; + WebGPU.iterateExtensions(entryPtr, { + 14: ptr => { + externalTexturePtr = HEAPU32[(((ptr) + (8)) >> 2)]; + } + }); + var resource; + if (bufferPtr) { + // Note the sentinel UINT64_MAX will be read as -1. + var size = readI53FromI64((entryPtr) + (24)); + if (size == -1) size = undefined; + resource = { + "buffer": WebGPU.getJsObject(bufferPtr), + "offset": readI53FromI64((entryPtr) + (16)), + "size": size + }; + } else { + resource = WebGPU.getJsObject(samplerPtr || textureViewPtr || externalTexturePtr); + } + return { + "binding": HEAPU32[(((entryPtr) + (4)) >> 2)], + "resource": resource + }; + } + function makeEntries(count, entriesPtrs) { + var entries = []; + for (var i = 0; i < count; ++i) { + entries.push(makeEntry(entriesPtrs + 40 * i)); + } + return entries; + } + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "layout": WebGPU.getJsObject(HEAPU32[(((descriptor) + (12)) >> 2)]), + "entries": makeEntries(HEAPU32[(((descriptor) + (16)) >> 2)], HEAPU32[(((descriptor) + (20)) >> 2)]) + }; + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreateBindGroup(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createBindGroup(desc)); + return ptr; +}; + +var _wgpuDeviceCreateBindGroupLayout = (devicePtr, descriptor) => { + function makeBufferEntry(substructPtr) { + var typeInt = HEAPU32[(((substructPtr) + (4)) >> 2)]; + if (!typeInt) return undefined; + return { + "type": WebGPU.BufferBindingType[typeInt], + "hasDynamicOffset": !!(HEAPU32[(((substructPtr) + (8)) >> 2)]), + "minBindingSize": readI53FromI64((substructPtr) + (16)) + }; + } + function makeSamplerEntry(substructPtr) { + var typeInt = HEAPU32[(((substructPtr) + (4)) >> 2)]; + if (!typeInt) return undefined; + return { + "type": WebGPU.SamplerBindingType[typeInt] + }; + } + function makeTextureEntry(substructPtr) { + var sampleTypeInt = HEAPU32[(((substructPtr) + (4)) >> 2)]; + if (!sampleTypeInt) return undefined; + return { + "sampleType": WebGPU.TextureSampleType[sampleTypeInt], + "viewDimension": WebGPU.TextureViewDimension[HEAP32[(((substructPtr) + (8)) >> 2)]], + "multisampled": !!(HEAPU32[(((substructPtr) + (12)) >> 2)]) + }; + } + function makeStorageTextureEntry(substructPtr) { + var accessInt = HEAPU32[(((substructPtr) + (4)) >> 2)]; + if (!accessInt) return undefined; + return { + "access": WebGPU.StorageTextureAccess[accessInt], + "format": WebGPU.TextureFormat[HEAP32[(((substructPtr) + (8)) >> 2)]], + "viewDimension": WebGPU.TextureViewDimension[HEAP32[(((substructPtr) + (12)) >> 2)]] + }; + } + function makeEntry(entryPtr) { + var entry = { + "binding": HEAPU32[(((entryPtr) + (4)) >> 2)], + "visibility": HEAPU32[(((entryPtr) + (8)) >> 2)], + "buffer": makeBufferEntry(entryPtr + 24), + "sampler": makeSamplerEntry(entryPtr + 48), + "texture": makeTextureEntry(entryPtr + 56), + "storageTexture": makeStorageTextureEntry(entryPtr + 72) + }; + WebGPU.iterateExtensions(entryPtr, { + 13: ptr => { + entry["externalTexture"] = {}; + } + }); + return entry; + } + function makeEntries(count, entriesPtrs) { + var entries = []; + for (var i = 0; i < count; ++i) { + entries.push(makeEntry(entriesPtrs + 88 * i)); + } + return entries; + } + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "entries": makeEntries(HEAPU32[(((descriptor) + (12)) >> 2)], HEAPU32[(((descriptor) + (16)) >> 2)]) + }; + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreateBindGroupLayout(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createBindGroupLayout(desc)); + return ptr; +}; + +var _wgpuDeviceCreateCommandEncoder = (devicePtr, descriptor) => { + var desc; + if (descriptor) { + desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4) + }; + } + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreateCommandEncoder(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createCommandEncoder(desc)); + return ptr; +}; + +var _wgpuDeviceCreateComputePipeline = (devicePtr, descriptor) => { + var desc = WebGPU.makeComputePipelineDesc(descriptor); + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreateComputePipeline(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createComputePipeline(desc)); + return ptr; +}; + +var _wgpuDeviceCreatePipelineLayout = (devicePtr, descriptor) => { + var bglCount = HEAPU32[(((descriptor) + (12)) >> 2)]; + var bglPtr = HEAPU32[(((descriptor) + (16)) >> 2)]; + var bgls = []; + for (var i = 0; i < bglCount; ++i) { + bgls.push(WebGPU.getJsObject(HEAPU32[(((bglPtr) + (4 * i)) >> 2)])); + } + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "bindGroupLayouts": bgls, + "immediateSize": HEAPU32[(((descriptor) + (20)) >> 2)] + }; + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreatePipelineLayout(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createPipelineLayout(desc)); + return ptr; +}; + +var _wgpuDeviceCreateRenderPipeline = (devicePtr, descriptor) => { + var desc = WebGPU.makeRenderPipelineDesc(descriptor); + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreateRenderPipeline(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createRenderPipeline(desc)); + return ptr; +}; + +var _wgpuDeviceCreateSampler = (devicePtr, descriptor) => { + var desc; + if (descriptor) { + desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "addressModeU": WebGPU.AddressMode[HEAP32[(((descriptor) + (12)) >> 2)]], + "addressModeV": WebGPU.AddressMode[HEAP32[(((descriptor) + (16)) >> 2)]], + "addressModeW": WebGPU.AddressMode[HEAP32[(((descriptor) + (20)) >> 2)]], + "magFilter": WebGPU.FilterMode[HEAP32[(((descriptor) + (24)) >> 2)]], + "minFilter": WebGPU.FilterMode[HEAP32[(((descriptor) + (28)) >> 2)]], + "mipmapFilter": WebGPU.MipmapFilterMode[HEAP32[(((descriptor) + (32)) >> 2)]], + "lodMinClamp": HEAPF32[(((descriptor) + (36)) >> 2)], + "lodMaxClamp": HEAPF32[(((descriptor) + (40)) >> 2)], + "compare": WebGPU.CompareFunction[HEAP32[(((descriptor) + (44)) >> 2)]], + "maxAnisotropy": HEAPU16[(((descriptor) + (48)) >> 1)] + }; + } + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreateSampler(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createSampler(desc)); + return ptr; +}; + +var _wgpuDeviceCreateTexture = (devicePtr, descriptor) => { + var nextInChainPtr = HEAPU32[((descriptor) >> 2)]; + var textureBindingViewDimension; + if (nextInChainPtr !== 0) { + var sType = HEAP32[(((nextInChainPtr) + (4)) >> 2)]; + var textureBindingViewDimensionDescriptor = nextInChainPtr; + textureBindingViewDimension = WebGPU.TextureViewDimension[HEAP32[(((textureBindingViewDimensionDescriptor) + (8)) >> 2)]]; + } + var desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "size": WebGPU.makeExtent3D(descriptor + 28), + "mipLevelCount": HEAPU32[(((descriptor) + (44)) >> 2)], + "sampleCount": HEAPU32[(((descriptor) + (48)) >> 2)], + "dimension": WebGPU.TextureDimension[HEAP32[(((descriptor) + (24)) >> 2)]], + "format": WebGPU.TextureFormat[HEAP32[(((descriptor) + (40)) >> 2)]], + "usage": HEAPU32[(((descriptor) + (16)) >> 2)], + "textureBindingViewDimension": textureBindingViewDimension + }; + var viewFormatCount = HEAPU32[(((descriptor) + (52)) >> 2)]; + if (viewFormatCount) { + var viewFormatsPtr = HEAPU32[(((descriptor) + (56)) >> 2)]; + // viewFormatsPtr pointer to an array of TextureFormat which is an enum of size uint32_t + desc["viewFormats"] = Array.from(HEAP32.subarray((((viewFormatsPtr) >> 2)), ((viewFormatsPtr + viewFormatCount * 4) >> 2)), format => WebGPU.TextureFormat[format]); + } + var device = WebGPU.getJsObject(devicePtr); + var ptr = _emwgpuCreateTexture(0); + WebGPU.Internals.jsObjectInsert(ptr, device.createTexture(desc)); + return ptr; +}; + +var _wgpuQueueSubmit = (queuePtr, commandCount, commands) => { + var queue = WebGPU.getJsObject(queuePtr); + var cmds = Array.from(HEAP32.subarray((((commands) >> 2)), ((commands + commandCount * 4) >> 2)), id => WebGPU.getJsObject(id)); + queue.submit(cmds); +}; + +function _wgpuQueueWriteBuffer(queuePtr, bufferPtr, bufferOffset_low, bufferOffset_high, data, size) { + var bufferOffset = convertI32PairToI53Checked(bufferOffset_low, bufferOffset_high); + var queue = WebGPU.getJsObject(queuePtr); + var buffer = WebGPU.getJsObject(bufferPtr); + // There is a size limitation for ArrayBufferView. Work around by passing in a subarray + // instead of the whole heap. crbug.com/1201109 + var subarray = HEAPU8.subarray(data, data + size); + queue.writeBuffer(buffer, bufferOffset, subarray, 0, size); +} + +var _wgpuQueueWriteTexture = (queuePtr, destinationPtr, data, dataSize, dataLayoutPtr, writeSizePtr) => { + var queue = WebGPU.getJsObject(queuePtr); + var destination = WebGPU.makeTexelCopyTextureInfo(destinationPtr); + var dataLayout = WebGPU.makeTexelCopyBufferLayout(dataLayoutPtr); + var writeSize = WebGPU.makeExtent3D(writeSizePtr); + // This subarray isn't strictly necessary, but helps work around an issue + // where Chromium makes a copy of the entire heap. crbug.com/1134457 + var subarray = HEAPU8.subarray(data, data + dataSize); + queue.writeTexture(destination, subarray, dataLayout, writeSize); +}; + +var _wgpuRenderPassEncoderDraw = (passPtr, vertexCount, instanceCount, firstVertex, firstInstance) => { + firstVertex >>>= 0; + firstInstance >>>= 0; + var pass = WebGPU.getJsObject(passPtr); + pass.draw(vertexCount, instanceCount, firstVertex, firstInstance); +}; + +var _wgpuRenderPassEncoderEnd = encoderPtr => { + var encoder = WebGPU.getJsObject(encoderPtr); + encoder.end(); +}; + +var _wgpuRenderPassEncoderSetBindGroup = (passPtr, groupIndex, groupPtr, dynamicOffsetCount, dynamicOffsetsPtr) => { + var pass = WebGPU.getJsObject(passPtr); + var group = WebGPU.getJsObject(groupPtr); + if (dynamicOffsetCount == 0) { + pass.setBindGroup(groupIndex, group); + } else { + pass.setBindGroup(groupIndex, group, HEAPU32, ((dynamicOffsetsPtr) >> 2), dynamicOffsetCount); + } +}; + +var _wgpuRenderPassEncoderSetPipeline = (passPtr, pipelinePtr) => { + var pass = WebGPU.getJsObject(passPtr); + var pipeline = WebGPU.getJsObject(pipelinePtr); + pass.setPipeline(pipeline); +}; + +var _wgpuRenderPipelineGetBindGroupLayout = (pipelinePtr, groupIndex) => { + var pipeline = WebGPU.getJsObject(pipelinePtr); + var ptr = _emwgpuCreateBindGroupLayout(0); + WebGPU.Internals.jsObjectInsert(ptr, pipeline.getBindGroupLayout(groupIndex)); + return ptr; +}; + +var _wgpuTextureCreateView = (texturePtr, descriptor) => { + var desc; + if (descriptor) { + var swizzle; + var nextInChainPtr = HEAPU32[((descriptor) >> 2)]; + if (nextInChainPtr !== 0) { + var sType = HEAP32[(((nextInChainPtr) + (4)) >> 2)]; + var swizzleDescriptor = nextInChainPtr; + var swizzlePtr = swizzleDescriptor + 8; + var r = WebGPU.ComponentSwizzle[HEAP32[((swizzlePtr) >> 2)]] || "r"; + var g = WebGPU.ComponentSwizzle[HEAP32[(((swizzlePtr) + (4)) >> 2)]] || "g"; + var b = WebGPU.ComponentSwizzle[HEAP32[(((swizzlePtr) + (8)) >> 2)]] || "b"; + var a = WebGPU.ComponentSwizzle[HEAP32[(((swizzlePtr) + (12)) >> 2)]] || "a"; + swizzle = `${r}${g}${b}${a}`; + } + var mipLevelCount = HEAPU32[(((descriptor) + (24)) >> 2)]; + var arrayLayerCount = HEAPU32[(((descriptor) + (32)) >> 2)]; + desc = { + "label": WebGPU.makeStringFromOptionalStringView(descriptor + 4), + "format": WebGPU.TextureFormat[HEAP32[(((descriptor) + (12)) >> 2)]], + "dimension": WebGPU.TextureViewDimension[HEAP32[(((descriptor) + (16)) >> 2)]], + "baseMipLevel": HEAPU32[(((descriptor) + (20)) >> 2)], + "mipLevelCount": mipLevelCount === 4294967295 ? undefined : mipLevelCount, + "baseArrayLayer": HEAPU32[(((descriptor) + (28)) >> 2)], + "arrayLayerCount": arrayLayerCount === 4294967295 ? undefined : arrayLayerCount, + "aspect": WebGPU.TextureAspect[HEAP32[(((descriptor) + (36)) >> 2)]], + "usage": HEAPU32[(((descriptor) + (40)) >> 2)], + "swizzle": swizzle + }; + } + var texture = WebGPU.getJsObject(texturePtr); + var ptr = _emwgpuCreateTextureView(0); + WebGPU.Internals.jsObjectInsert(ptr, texture.createView(desc)); + return ptr; +}; + +var _wgpuTextureDestroy = texturePtr => { + WebGPU.getJsObject(texturePtr).destroy(); +}; + +var _wgpuTextureGetFormat = texturePtr => { + var texture = WebGPU.getJsObject(texturePtr); + // Should return the enum integer instead of string. + return WebGPU.TextureFormat.indexOf(texture.format); +}; + +var getCFunc = ident => { + var func = Module["_" + ident]; + // closure exported function + return func; +}; + +var writeArrayToMemory = (array, buffer) => { + HEAP8.set(array, buffer); +}; + +/** + * @param {string|null=} returnType + * @param {Array=} argTypes + * @param {Array=} args + * @param {Object=} opts + */ var ccall = (ident, returnType, argTypes, args, opts) => { + // For fast lookup of conversion functions + var toC = { + "string": str => { + var ret = 0; + if (str !== null && str !== undefined && str !== 0) { + // null string + ret = stringToUTF8OnStack(str); + } + return ret; + }, + "array": arr => { + var ret = stackAlloc(arr.length); + writeArrayToMemory(arr, ret); + return ret; + } + }; + function convertReturnValue(ret) { + if (returnType === "string") { + return UTF8ToString(ret); + } + if (returnType === "boolean") return Boolean(ret); + return ret; + } + var func = getCFunc(ident); + var cArgs = []; + var stack = 0; + if (args) { + for (var i = 0; i < args.length; i++) { + var converter = toC[argTypes[i]]; + if (converter) { + if (stack === 0) stack = stackSave(); + cArgs[i] = converter(args[i]); + } else { + cArgs[i] = args[i]; + } + } + } + var ret = func(...cArgs); + function onDone(ret) { + if (stack !== 0) stackRestore(stack); + return convertReturnValue(ret); + } + ret = onDone(ret); + return ret; +}; + +var FS_createPath = (...args) => FS.createPath(...args); + +var FS_unlink = (...args) => FS.unlink(...args); + +var FS_createLazyFile = (...args) => FS.createLazyFile(...args); + +var FS_createDevice = (...args) => FS.createDevice(...args); + +FS.createPreloadedFile = FS_createPreloadedFile; + +FS.preloadFile = FS_preloadFile; + +FS.staticInit(); + +// Signal GL rendering layer that processing of a new frame is about to +// start. This helps it optimize VBO double-buffering and reduce GPU stalls. +registerPreMainLoop(() => GL.newRenderingFrameStarted()); + +for (let i = 0; i < 32; ++i) tempFixedLengthArray.push(new Array(i)); + +var miniTempWebGLFloatBuffersStorage = new Float32Array(288); + +// Create GL_POOL_TEMP_BUFFERS_SIZE+1 temporary buffers, for uploads of size 0 through GL_POOL_TEMP_BUFFERS_SIZE inclusive +for (/**@suppress{duplicate}*/ var i = 0; i <= 288; ++i) { + miniTempWebGLFloatBuffers[i] = miniTempWebGLFloatBuffersStorage.subarray(0, i); +} + +var miniTempWebGLIntBuffersStorage = new Int32Array(288); + +// Create GL_POOL_TEMP_BUFFERS_SIZE+1 temporary buffers, for uploads of size 0 through GL_POOL_TEMP_BUFFERS_SIZE inclusive +for (/**@suppress{duplicate}*/ var i = 0; i <= 288; ++i) { + miniTempWebGLIntBuffers[i] = miniTempWebGLIntBuffersStorage.subarray(0, i); +} + +// End JS library code +// include: postlibrary.js +// This file is included after the automatically-generated JS library code +// but before the wasm module is created. +{ + // Begin ATMODULES hooks + if (Module["preloadPlugins"]) preloadPlugins = Module["preloadPlugins"]; + if (Module["noExitRuntime"]) noExitRuntime = Module["noExitRuntime"]; + if (Module["print"]) out = Module["print"]; + if (Module["printErr"]) err = Module["printErr"]; + if (Module["wasmBinary"]) wasmBinary = Module["wasmBinary"]; + // End ATMODULES hooks + if (Module["arguments"]) programArgs = Module["arguments"]; + if (Module["thisProgram"]) thisProgram = Module["thisProgram"]; + if (Module["preInit"]) { + if (typeof Module["preInit"] == "function") Module["preInit"] = [ Module["preInit"] ]; + while (Module["preInit"].length > 0) { + Module["preInit"].shift()(); + } + } +} + +// Begin runtime exports +Module["addRunDependency"] = addRunDependency; + +Module["removeRunDependency"] = removeRunDependency; + +Module["ccall"] = ccall; + +Module["stringToNewUTF8"] = stringToNewUTF8; + +Module["FS_preloadFile"] = FS_preloadFile; + +Module["FS_unlink"] = FS_unlink; + +Module["FS_createPath"] = FS_createPath; + +Module["FS_createDevice"] = FS_createDevice; + +Module["FS_createDataFile"] = FS_createDataFile; + +Module["FS_createLazyFile"] = FS_createLazyFile; + +// End runtime exports +// Begin JS library exports +// End JS library exports +// end include: postlibrary.js +var ASM_CONSTS = { + 1515718: $0 => { + const canvas = Emval.toValue($0); + const context = canvas.getContext("webgpu"); + return WebGPU.importJsTexture(context.getCurrentTexture()); + }, + 1515861: ($0, $1, $2, $3, $4) => { + const drawable = Emval.toValue($0); + const device = WebGPU.getJsObject($1); + const texture = WebGPU.getJsObject($2); + const width = $3; + const height = $4; + device.queue.copyExternalImageToTexture({ + source: drawable + }, { + texture + }, [ width, height ]); + }, + 1516120: ($0, $1, $2, $3) => { + const sourceExtTex = Emval.toValue($0); + const device = WebGPU.getJsObject($1); + const sampler = WebGPU.getJsObject($2); + const bgLayout = WebGPU.getJsObject($3); + const bindGroup = device.createBindGroup({ + layout: bgLayout, + entries: [ { + binding: 0, + resource: sampler + }, { + binding: 1, + resource: sourceExtTex + } ] + }); + return WebGPU.importJsBindGroup(bindGroup); + }, + 1516490: ($0, $1) => { + const input = Emval.toValue($0); + const output = Emval.toValue($1); + const ctx = output.getContext("2d"); + ctx.drawImage(input, 0, 0, output.width, output.height); + }, + 1516655: ($0, $1) => { + const inputArray = Emval.toValue($0); + const output = Emval.toValue($1); + const ctx = output.getContext("2d"); + const image_data = new ImageData(inputArray, output.width, output.height); + ctx.putImageData(image_data, 0, 0); + }, + 1516879: ($0, $1) => { + const input = Emval.toValue($0); + const outputArray = Emval.toValue($1); + const ctx = input.getContext("2d"); + const data = ctx.getImageData(0, 0, input.width, input.height); + outputArray.set(data.data); + }, + 1517083: () => (typeof HTMLCanvasElement !== "undefined"), + 1517138: () => !!Module["preinitializedWebGPUDevice"], + 1517189: () => { + specialHTMLTargets["#canvas"] = Module.canvas; + } +}; + +function BeginGlQueryTiming(calc_name, num_repetitions) { + const gl = Module.canvas.getContext("webgl2"); + const query = gl.createQuery(); + Module.WEBGL_SHADER_CALC_METRICS = Module.WEBGL_SHADER_CALC_METRICS || {}; + Module.WEBGL_SHADER_CALC_METRICS[UTF8ToString(calc_name)] = { + query, + repetitions: num_repetitions + }; + Module.WEBGL_QUERY_TIMER_EXT = Module.WEBGL_QUERY_TIMER_EXT || gl.getExtension("EXT_disjoint_timer_query_webgl2"); + gl.beginQuery(Module.WEBGL_QUERY_TIMER_EXT.TIME_ELAPSED_EXT, query); +} + +function EndGlQueryTiming(calc_name) { + const gl = Module.canvas.getContext("webgl2"); + gl.endQuery(Module.WEBGL_QUERY_TIMER_EXT.TIME_ELAPSED_EXT, Module.WEBGL_SHADER_CALC_METRICS[UTF8ToString(calc_name)].query); +} + +function JsWrapImageConverter() { + if (!Module._imageConverter) { + Module._imageConverter = (binaryPtr, binarySize, width, height, numChannels, makeDeepCopy, outputType) => { + const imageData = new outputType(makeDeepCopy ? Module.HEAPU8.slice(binaryPtr, binaryPtr + binarySize).buffer : Module.HEAPU8.buffer, binaryPtr, width * height * numChannels); + return { + data: imageData, + width, + height + }; + }; + } +} + +function JsOnUint8ArrayImageListener(output_stream_name, binary_ptr, binary_size, width, height, num_channels, make_deep_copy, timestamp_ms) { + const image = Module._imageConverter(binary_ptr, binary_size, width, height, num_channels, make_deep_copy, Uint8Array); + Module._wrapSimpleListenerOutput(output_stream_name, image, timestamp_ms); +} + +function JsOnFloat32ArrayImageListener(output_stream_name, binary_ptr, binary_size, width, height, num_channels, make_deep_copy, timestamp_ms) { + const image = Module._imageConverter(binary_ptr, binary_size, width, height, num_channels, make_deep_copy, Float32Array); + Module._wrapSimpleListenerOutput(output_stream_name, image, timestamp_ms); +} + +function JsOnWebGLTextureListener(output_stream_name, name, width, height, timestamp_ms) { + Module._wrapSimpleListenerOutput(output_stream_name, { + data: GL.textures[name], + width, + height + }, timestamp_ms); +} + +function JsOnUint8ArrayImageVectorListener(output_stream_name, binary_ptr, binary_size, width, height, num_channels, make_deep_copy, timestamp_ms) { + const image = Module._imageConverter(binary_ptr, binary_size, width, height, num_channels, make_deep_copy, Uint8Array); + Module._wrapSimpleListenerOutput(output_stream_name, image, false, timestamp_ms); +} + +function JsOnFloat32ArrayImageVectorListener(output_stream_name, binary_ptr, binary_size, width, height, num_channels, make_deep_copy, timestamp_ms) { + const image = Module._imageConverter(binary_ptr, binary_size, width, height, num_channels, make_deep_copy, Float32Array); + Module._wrapSimpleListenerOutput(output_stream_name, image, false, timestamp_ms); +} + +function JsOnWebGLTextureVectorListener(output_stream_name, name, width, height, timestamp_ms) { + Module._wrapSimpleListenerOutput(output_stream_name, { + data: GL.textures[name], + width, + height + }, false, timestamp_ms); +} + +function JsWrapLoggingHelpers() { + if (!Module["_decodeBase64"]) { + Module["_decodeBase64"] = function(encoded_key_ptr) { + const encodedStr = UTF8ToString(encoded_key_ptr); + return atob(encodedStr); + }; + } +} + +function JsOnEmptyPacketListener(output_stream_name, timestamp) { + Module._wrapEmptyPacketListenerOutput(output_stream_name, timestamp); +} + +function JsOnVectorFinishedListener(output_stream_name, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, undefined, true, timestamp); +} + +function JsOnSimpleListenerBool(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, timestamp); +} + +function JsOnVectorListenerBool(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, false, timestamp); +} + +function JsOnSimpleListenerInt(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, timestamp); +} + +function JsOnVectorListenerInt(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, false, timestamp); +} + +function JsOnSimpleListenerUint(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, timestamp); +} + +function JsOnVectorListenerUint(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, false, timestamp); +} + +function JsOnSimpleListenerDouble(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, timestamp); +} + +function JsOnVectorListenerDouble(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, false, timestamp); +} + +function JsOnSimpleListenerFloat(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, timestamp); +} + +function JsOnVectorListenerFloat(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, out_data, false, timestamp); +} + +function JsOnSimpleListenerString(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, UTF8ToString(out_data), timestamp); +} + +function JsOnVectorListenerString(output_stream_name, out_data, timestamp) { + Module._wrapSimpleListenerOutput(output_stream_name, UTF8ToString(out_data), false, timestamp); +} + +function JsOnVectorListenerProto(output_stream_name, proto_ptr, proto_size, make_deep_copy, timestamp) { + const newProtoArray = make_deep_copy ? Module.HEAPU8.slice(proto_ptr, proto_ptr + proto_size) : new Uint8Array(Module.HEAPU8.buffer, proto_ptr, proto_size); + Module._wrapSimpleListenerOutput(output_stream_name, newProtoArray, false, timestamp); +} + +function JsWrapSimpleListeners() { + if (!Module._wrapSimpleListenerOutput) { + Module._wrapSimpleListenerOutput = (outputStreamName, ...args) => { + if (Module.simpleListeners) { + const streamName = UTF8ToString(outputStreamName); + if (Module.simpleListeners[streamName]) { + Module.simpleListeners[streamName](...args); + } + } + }; + } + if (!Module._wrapEmptyPacketListenerOutput) { + Module._wrapEmptyPacketListenerOutput = (outputStreamName, timestamp) => { + if (Module.emptyPacketListeners) { + const streamName = UTF8ToString(outputStreamName); + if (Module.emptyPacketListeners[streamName]) { + Module.emptyPacketListeners[streamName](timestamp); + } + } + }; + } +} + +function JsOnSimpleListenerBinaryArray(output_stream_name, binary_ptr, binary_size, make_deep_copy, timestamp) { + const newProtoArray = make_deep_copy ? Module.HEAPU8.slice(binary_ptr, binary_ptr + binary_size) : new Uint8Array(Module.HEAPU8.buffer, binary_ptr, binary_size); + Module._wrapSimpleListenerOutput(output_stream_name, newProtoArray, timestamp); +} + +function mediapipe_import_external_texture(device_handle, source_handle) { + const device = WebGPU.getJsObject(device_handle); + const source = Emval.toValue(source_handle); + const externalTexture = device.importExternalTexture({ + source + }); + return Emval.toHandle(externalTexture); +} + +function mediapipe_create_utility_canvas2d() { + let canvas; + if (typeof HTMLCanvasElement !== "undefined") { + canvas = document.createElement("canvas"); + canvas.style.display = "none"; + } else { + canvas = new OffscreenCanvas(0, 0); + } + return Emval.toHandle(canvas); +} + +function GetAdapterArchitecture() { + const device = Module["preinitializedWebGPUDevice"]; + const architecture = device.adapterInfo ? device.adapterInfo.architecture : "Unknown"; + return stringToNewUTF8(architecture); +} + +function GetAdapterDescription() { + const device = Module["preinitializedWebGPUDevice"]; + const description = device.adapterInfo ? device.adapterInfo.description : "Unknown"; + return stringToNewUTF8(description); +} + +function GetAdapterDeviceName() { + const device = Module["preinitializedWebGPUDevice"]; + const deviceName = device.adapterInfo ? device.adapterInfo.device : "Unknown"; + return stringToNewUTF8(deviceName); +} + +function GetAdapterVendor() { + const device = Module["preinitializedWebGPUDevice"]; + const vendor = device.adapterInfo ? device.adapterInfo.vendor : "Unknown"; + return stringToNewUTF8(vendor); +} + +function __asyncjs__mediapipe_map_buffer_jspi(buffer_handle, data) { + return Asyncify.handleAsync(async () => { + const buffer = WebGPU.getJsObject(buffer_handle); + if ("mapSync" in buffer) { + buffer.mapSync(GPUMapMode.READ); + } else { + await buffer.mapAsync(GPUMapMode.READ); + } + const mapped = buffer.getMappedRange(); + HEAPU8.set(new Uint8Array(mapped), data); + buffer.unmap(); + }); +} + +function UseBottomLeftGpuOrigin() { + return (Module && Module.gpuOriginForWebTexturesIsBottomLeft); +} + +function custom_emscripten_dbgn(str, len) { + if (typeof (dbg) !== "undefined") { + dbg(UTF8ToString(str, len)); + } else { + if (typeof (custom_dbg) === "undefined") { + function custom_dbg(text) { + console.warn.apply(console, arguments); + } + } + custom_dbg(UTF8ToString(str, len)); + } +} + +function JsWrapErrorListenerInternal(code, message) { + if (Module.errorListener) { + const stringMessage = UTF8ToString(message); + Module.errorListener(code, stringMessage); + } +} + +// Imports from the Wasm binary. +var _free, _malloc, _interactive_segmenter_create, _interactive_segmenter_set_image, _interactive_segmenter_segment, _interactive_segmenter_close, _wgpuDeviceAddRef, _addBoundTextureAsImageToStream, _attachImageListener, _attachImageVectorListener, _mediapipeLoggerGetEncodedApiKey, _registerModelResourcesGraphService, _bindTextureToStream, _addBoundTextureToStream, _addDoubleToInputStream, _addFloatToInputStream, _addBoolToInputStream, _addIntToInputStream, _addUintToInputStream, _addStringToInputStream, _addRawDataSpanToInputStream, _allocateBoolVector, _allocateFloatVector, _allocateDoubleVector, _allocateIntVector, _allocateUintVector, _allocateStringVector, _addBoolVectorEntry, _addFloatVectorEntry, _addDoubleVectorEntry, _addIntVectorEntry, _addUintVectorEntry, _addStringVectorEntry, _addBoolVectorToInputStream, _addFloatVectorToInputStream, _addDoubleVectorToInputStream, _addIntVectorToInputStream, _addUintVectorToInputStream, _addStringVectorToInputStream, _addFlatHashMapToInputStream, _addProtoToInputStream, _addEmptyPacketToInputStream, _addBoolToInputSidePacket, _addDoubleToInputSidePacket, _addFloatToInputSidePacket, _addIntToInputSidePacket, _addUintToInputSidePacket, _addStringToInputSidePacket, _addRawDataSpanToInputSidePacket, _addProtoToInputSidePacket, _addBoolVectorToInputSidePacket, _addDoubleVectorToInputSidePacket, _addFloatVectorToInputSidePacket, _addIntVectorToInputSidePacket, _addUintVectorToInputSidePacket, _addStringVectorToInputSidePacket, _attachBoolListener, _attachBoolVectorListener, _attachDoubleListener, _attachDoubleVectorListener, _attachFloatListener, _attachFloatVectorListener, _attachIntListener, _attachIntVectorListener, _attachUintListener, _attachUintVectorListener, _attachStringListener, _attachStringVectorListener, _attachProtoListener, _attachProtoVectorListener, _getGraphConfig, ___getTypeName, _emwgpuCreateBindGroup, _emwgpuCreateBindGroupLayout, _emwgpuCreateCommandBuffer, _emwgpuCreateCommandEncoder, _emwgpuCreateComputePassEncoder, _emwgpuCreateComputePipeline, _emwgpuCreateExternalTexture, _emwgpuCreatePipelineLayout, _emwgpuCreateQuerySet, _emwgpuCreateRenderBundle, _emwgpuCreateRenderBundleEncoder, _emwgpuCreateRenderPassEncoder, _emwgpuCreateRenderPipeline, _emwgpuCreateSampler, _emwgpuCreateSurface, _emwgpuCreateTexture, _emwgpuCreateTextureView, _emwgpuCreateAdapter, _emwgpuImportBuffer, _emwgpuCreateDevice, _emwgpuCreateQueue, _emwgpuCreateShaderModule, _emwgpuOnCreateComputePipelineCompleted, _emwgpuOnCreateRenderPipelineCompleted, _clearSubgraphs, _pushBinarySubgraph, _pushTextSubgraph, _changeBinaryGraph, _changeTextGraph, _processGl, _process, _bindTextureToCanvas, _requestShaderRefreshOnGraphChange, _waitUntilIdle, _closeGraph, _setAutoRenderToScreen, _emscripten_builtin_memalign, _memalign, __emscripten_tempret_set, __emscripten_stack_restore, __emscripten_stack_alloc, _emscripten_stack_get_current, dynCall_ji, dynCall_jii, dynCall_iiiijij, dynCall_vij, dynCall_viiji, dynCall_viji, dynCall_iiiji, dynCall_ijj, dynCall_jjj, dynCall_iiiijj, dynCall_viijj, dynCall_viiijjj, dynCall_viijii, dynCall_vijjj, dynCall_vj, dynCall_viij, dynCall_jiji, dynCall_iiiiij, dynCall_iiiiijj, dynCall_iiiiiijj, memory, _kVersionStampBuildChangelistStr, _kVersionStampCitcSnapshotStr, _kVersionStampCitcWorkspaceIdStr, _kVersionStampSourceUriStr, _kVersionStampBuildClientStr, _kVersionStampBuildClientMintStatusStr, _kVersionStampBuildCompilerStr, _kVersionStampBuildDateTimePstStr, _kVersionStampBuildDepotPathStr, _kVersionStampBuildIdStr, _kVersionStampBuildInfoStr, _kVersionStampBuildLabelStr, _kVersionStampBuildTargetStr, _kVersionStampBuildTimestampStr, _kVersionStampBuildToolStr, _kVersionStampG3BuildTargetStr, _kVersionStampVerifiableStr, _kVersionStampBuildFdoTypeStr, _kVersionStampBuildBaselineChangelistStr, _kVersionStampBuildLtoTypeStr, _kVersionStampBuildPropellerTypeStr, _kVersionStampBuildPghoTypeStr, _kVersionStampBuildFdoProfileChangelistStr, _kVersionStampBuildMemprofProfileChangelistStr, _kVersionStampBuildUsernameStr, _kVersionStampBuildHostnameStr, _kVersionStampBuildDirectoryStr, _kVersionStampBuildChangelistInt, _kVersionStampCitcSnapshotInt, _kVersionStampBuildClientMintStatusInt, _kVersionStampBuildTimestampInt, _kVersionStampVerifiableInt, _kVersionStampBuildCoverageEnabledInt, _kVersionStampBuildBaselineChangelistInt, _kVersionStampPrecookedTimestampStr, _kVersionStampPrecookedClientInfoStr, __indirect_function_table, _kVersionStampBuildHasHardeningProtobuf, wasmMemory, wasmTable; + +function assignWasmExports(wasmExports) { + _free = Module["_free"] = wasmExports["Vd"]; + _malloc = Module["_malloc"] = wasmExports["Wd"]; + _interactive_segmenter_create = Module["_interactive_segmenter_create"] = wasmExports["Xd"]; + _interactive_segmenter_set_image = Module["_interactive_segmenter_set_image"] = wasmExports["Yd"]; + _interactive_segmenter_segment = Module["_interactive_segmenter_segment"] = wasmExports["Zd"]; + _interactive_segmenter_close = Module["_interactive_segmenter_close"] = wasmExports["_d"]; + _wgpuDeviceAddRef = wasmExports["$d"]; + _addBoundTextureAsImageToStream = Module["_addBoundTextureAsImageToStream"] = wasmExports["ae"]; + _attachImageListener = Module["_attachImageListener"] = wasmExports["be"]; + _attachImageVectorListener = Module["_attachImageVectorListener"] = wasmExports["ce"]; + _mediapipeLoggerGetEncodedApiKey = Module["_mediapipeLoggerGetEncodedApiKey"] = wasmExports["de"]; + _registerModelResourcesGraphService = Module["_registerModelResourcesGraphService"] = wasmExports["ee"]; + _bindTextureToStream = Module["_bindTextureToStream"] = wasmExports["fe"]; + _addBoundTextureToStream = Module["_addBoundTextureToStream"] = wasmExports["ge"]; + _addDoubleToInputStream = Module["_addDoubleToInputStream"] = wasmExports["he"]; + _addFloatToInputStream = Module["_addFloatToInputStream"] = wasmExports["ie"]; + _addBoolToInputStream = Module["_addBoolToInputStream"] = wasmExports["je"]; + _addIntToInputStream = Module["_addIntToInputStream"] = wasmExports["ke"]; + _addUintToInputStream = Module["_addUintToInputStream"] = wasmExports["le"]; + _addStringToInputStream = Module["_addStringToInputStream"] = wasmExports["me"]; + _addRawDataSpanToInputStream = Module["_addRawDataSpanToInputStream"] = wasmExports["ne"]; + _allocateBoolVector = Module["_allocateBoolVector"] = wasmExports["oe"]; + _allocateFloatVector = Module["_allocateFloatVector"] = wasmExports["pe"]; + _allocateDoubleVector = Module["_allocateDoubleVector"] = wasmExports["qe"]; + _allocateIntVector = Module["_allocateIntVector"] = wasmExports["re"]; + _allocateUintVector = Module["_allocateUintVector"] = wasmExports["se"]; + _allocateStringVector = Module["_allocateStringVector"] = wasmExports["te"]; + _addBoolVectorEntry = Module["_addBoolVectorEntry"] = wasmExports["ue"]; + _addFloatVectorEntry = Module["_addFloatVectorEntry"] = wasmExports["ve"]; + _addDoubleVectorEntry = Module["_addDoubleVectorEntry"] = wasmExports["we"]; + _addIntVectorEntry = Module["_addIntVectorEntry"] = wasmExports["xe"]; + _addUintVectorEntry = Module["_addUintVectorEntry"] = wasmExports["ye"]; + _addStringVectorEntry = Module["_addStringVectorEntry"] = wasmExports["ze"]; + _addBoolVectorToInputStream = Module["_addBoolVectorToInputStream"] = wasmExports["Ae"]; + _addFloatVectorToInputStream = Module["_addFloatVectorToInputStream"] = wasmExports["Be"]; + _addDoubleVectorToInputStream = Module["_addDoubleVectorToInputStream"] = wasmExports["Ce"]; + _addIntVectorToInputStream = Module["_addIntVectorToInputStream"] = wasmExports["De"]; + _addUintVectorToInputStream = Module["_addUintVectorToInputStream"] = wasmExports["Ee"]; + _addStringVectorToInputStream = Module["_addStringVectorToInputStream"] = wasmExports["Fe"]; + _addFlatHashMapToInputStream = Module["_addFlatHashMapToInputStream"] = wasmExports["Ge"]; + _addProtoToInputStream = Module["_addProtoToInputStream"] = wasmExports["He"]; + _addEmptyPacketToInputStream = Module["_addEmptyPacketToInputStream"] = wasmExports["Ie"]; + _addBoolToInputSidePacket = Module["_addBoolToInputSidePacket"] = wasmExports["Je"]; + _addDoubleToInputSidePacket = Module["_addDoubleToInputSidePacket"] = wasmExports["Ke"]; + _addFloatToInputSidePacket = Module["_addFloatToInputSidePacket"] = wasmExports["Le"]; + _addIntToInputSidePacket = Module["_addIntToInputSidePacket"] = wasmExports["Me"]; + _addUintToInputSidePacket = Module["_addUintToInputSidePacket"] = wasmExports["Ne"]; + _addStringToInputSidePacket = Module["_addStringToInputSidePacket"] = wasmExports["Oe"]; + _addRawDataSpanToInputSidePacket = Module["_addRawDataSpanToInputSidePacket"] = wasmExports["Pe"]; + _addProtoToInputSidePacket = Module["_addProtoToInputSidePacket"] = wasmExports["Qe"]; + _addBoolVectorToInputSidePacket = Module["_addBoolVectorToInputSidePacket"] = wasmExports["Re"]; + _addDoubleVectorToInputSidePacket = Module["_addDoubleVectorToInputSidePacket"] = wasmExports["Se"]; + _addFloatVectorToInputSidePacket = Module["_addFloatVectorToInputSidePacket"] = wasmExports["Te"]; + _addIntVectorToInputSidePacket = Module["_addIntVectorToInputSidePacket"] = wasmExports["Ue"]; + _addUintVectorToInputSidePacket = Module["_addUintVectorToInputSidePacket"] = wasmExports["Ve"]; + _addStringVectorToInputSidePacket = Module["_addStringVectorToInputSidePacket"] = wasmExports["We"]; + _attachBoolListener = Module["_attachBoolListener"] = wasmExports["Xe"]; + _attachBoolVectorListener = Module["_attachBoolVectorListener"] = wasmExports["Ye"]; + _attachDoubleListener = Module["_attachDoubleListener"] = wasmExports["Ze"]; + _attachDoubleVectorListener = Module["_attachDoubleVectorListener"] = wasmExports["_e"]; + _attachFloatListener = Module["_attachFloatListener"] = wasmExports["$e"]; + _attachFloatVectorListener = Module["_attachFloatVectorListener"] = wasmExports["af"]; + _attachIntListener = Module["_attachIntListener"] = wasmExports["bf"]; + _attachIntVectorListener = Module["_attachIntVectorListener"] = wasmExports["cf"]; + _attachUintListener = Module["_attachUintListener"] = wasmExports["df"]; + _attachUintVectorListener = Module["_attachUintVectorListener"] = wasmExports["ef"]; + _attachStringListener = Module["_attachStringListener"] = wasmExports["ff"]; + _attachStringVectorListener = Module["_attachStringVectorListener"] = wasmExports["gf"]; + _attachProtoListener = Module["_attachProtoListener"] = wasmExports["hf"]; + _attachProtoVectorListener = Module["_attachProtoVectorListener"] = wasmExports["jf"]; + _getGraphConfig = Module["_getGraphConfig"] = wasmExports["kf"]; + ___getTypeName = wasmExports["lf"]; + _emwgpuCreateBindGroup = wasmExports["mf"]; + _emwgpuCreateBindGroupLayout = wasmExports["nf"]; + _emwgpuCreateCommandBuffer = wasmExports["of"]; + _emwgpuCreateCommandEncoder = wasmExports["pf"]; + _emwgpuCreateComputePassEncoder = wasmExports["qf"]; + _emwgpuCreateComputePipeline = wasmExports["rf"]; + _emwgpuCreateExternalTexture = wasmExports["sf"]; + _emwgpuCreatePipelineLayout = wasmExports["tf"]; + _emwgpuCreateQuerySet = wasmExports["uf"]; + _emwgpuCreateRenderBundle = wasmExports["vf"]; + _emwgpuCreateRenderBundleEncoder = wasmExports["wf"]; + _emwgpuCreateRenderPassEncoder = wasmExports["xf"]; + _emwgpuCreateRenderPipeline = wasmExports["yf"]; + _emwgpuCreateSampler = wasmExports["zf"]; + _emwgpuCreateSurface = wasmExports["Af"]; + _emwgpuCreateTexture = wasmExports["Bf"]; + _emwgpuCreateTextureView = wasmExports["Cf"]; + _emwgpuCreateAdapter = wasmExports["Df"]; + _emwgpuImportBuffer = wasmExports["Ef"]; + _emwgpuCreateDevice = wasmExports["Ff"]; + _emwgpuCreateQueue = wasmExports["Gf"]; + _emwgpuCreateShaderModule = wasmExports["Hf"]; + _emwgpuOnCreateComputePipelineCompleted = wasmExports["If"]; + _emwgpuOnCreateRenderPipelineCompleted = wasmExports["Jf"]; + _clearSubgraphs = Module["_clearSubgraphs"] = wasmExports["Kf"]; + _pushBinarySubgraph = Module["_pushBinarySubgraph"] = wasmExports["Lf"]; + _pushTextSubgraph = Module["_pushTextSubgraph"] = wasmExports["Mf"]; + _changeBinaryGraph = Module["_changeBinaryGraph"] = wasmExports["Nf"]; + _changeTextGraph = Module["_changeTextGraph"] = wasmExports["Of"]; + _processGl = Module["_processGl"] = wasmExports["Pf"]; + _process = Module["_process"] = wasmExports["Qf"]; + _bindTextureToCanvas = Module["_bindTextureToCanvas"] = wasmExports["Rf"]; + _requestShaderRefreshOnGraphChange = Module["_requestShaderRefreshOnGraphChange"] = wasmExports["Sf"]; + _waitUntilIdle = Module["_waitUntilIdle"] = wasmExports["Tf"]; + _closeGraph = Module["_closeGraph"] = wasmExports["Uf"]; + _setAutoRenderToScreen = Module["_setAutoRenderToScreen"] = wasmExports["Vf"]; + _emscripten_builtin_memalign = wasmExports["Xf"]; + _memalign = wasmExports["Yf"]; + __emscripten_tempret_set = wasmExports["Zf"]; + __emscripten_stack_restore = wasmExports["_f"]; + __emscripten_stack_alloc = wasmExports["$f"]; + _emscripten_stack_get_current = wasmExports["ag"]; + dynCall_ji = wasmExports["dynCall_ji"]; + dynCall_jii = wasmExports["dynCall_jii"]; + dynCall_iiiijij = wasmExports["dynCall_iiiijij"]; + dynCall_vij = wasmExports["dynCall_vij"]; + dynCall_viiji = wasmExports["dynCall_viiji"]; + dynCall_viji = wasmExports["dynCall_viji"]; + dynCall_iiiji = wasmExports["dynCall_iiiji"]; + dynCall_ijj = wasmExports["dynCall_ijj"]; + dynCall_jjj = wasmExports["dynCall_jjj"]; + dynCall_iiiijj = wasmExports["dynCall_iiiijj"]; + dynCall_viijj = wasmExports["dynCall_viijj"]; + dynCall_viiijjj = wasmExports["dynCall_viiijjj"]; + dynCall_viijii = wasmExports["dynCall_viijii"]; + dynCall_vijjj = wasmExports["dynCall_vijjj"]; + dynCall_vj = wasmExports["dynCall_vj"]; + dynCall_viij = wasmExports["dynCall_viij"]; + dynCall_jiji = wasmExports["dynCall_jiji"]; + dynCall_iiiiij = wasmExports["dynCall_iiiiij"]; + dynCall_iiiiijj = wasmExports["dynCall_iiiiijj"]; + dynCall_iiiiiijj = wasmExports["dynCall_iiiiiijj"]; + memory = wasmMemory = wasmExports["id"]; + _kVersionStampBuildChangelistStr = Module["_kVersionStampBuildChangelistStr"] = wasmExports["kd"].value; + _kVersionStampCitcSnapshotStr = Module["_kVersionStampCitcSnapshotStr"] = wasmExports["ld"].value; + _kVersionStampCitcWorkspaceIdStr = Module["_kVersionStampCitcWorkspaceIdStr"] = wasmExports["md"].value; + _kVersionStampSourceUriStr = Module["_kVersionStampSourceUriStr"] = wasmExports["nd"].value; + _kVersionStampBuildClientStr = Module["_kVersionStampBuildClientStr"] = wasmExports["od"].value; + _kVersionStampBuildClientMintStatusStr = Module["_kVersionStampBuildClientMintStatusStr"] = wasmExports["pd"].value; + _kVersionStampBuildCompilerStr = Module["_kVersionStampBuildCompilerStr"] = wasmExports["qd"].value; + _kVersionStampBuildDateTimePstStr = Module["_kVersionStampBuildDateTimePstStr"] = wasmExports["rd"].value; + _kVersionStampBuildDepotPathStr = Module["_kVersionStampBuildDepotPathStr"] = wasmExports["sd"].value; + _kVersionStampBuildIdStr = Module["_kVersionStampBuildIdStr"] = wasmExports["td"].value; + _kVersionStampBuildInfoStr = Module["_kVersionStampBuildInfoStr"] = wasmExports["ud"].value; + _kVersionStampBuildLabelStr = Module["_kVersionStampBuildLabelStr"] = wasmExports["vd"].value; + _kVersionStampBuildTargetStr = Module["_kVersionStampBuildTargetStr"] = wasmExports["wd"].value; + _kVersionStampBuildTimestampStr = Module["_kVersionStampBuildTimestampStr"] = wasmExports["xd"].value; + _kVersionStampBuildToolStr = Module["_kVersionStampBuildToolStr"] = wasmExports["yd"].value; + _kVersionStampG3BuildTargetStr = Module["_kVersionStampG3BuildTargetStr"] = wasmExports["zd"].value; + _kVersionStampVerifiableStr = Module["_kVersionStampVerifiableStr"] = wasmExports["Ad"].value; + _kVersionStampBuildFdoTypeStr = Module["_kVersionStampBuildFdoTypeStr"] = wasmExports["Bd"].value; + _kVersionStampBuildBaselineChangelistStr = Module["_kVersionStampBuildBaselineChangelistStr"] = wasmExports["Cd"].value; + _kVersionStampBuildLtoTypeStr = Module["_kVersionStampBuildLtoTypeStr"] = wasmExports["Dd"].value; + _kVersionStampBuildPropellerTypeStr = Module["_kVersionStampBuildPropellerTypeStr"] = wasmExports["Ed"].value; + _kVersionStampBuildPghoTypeStr = Module["_kVersionStampBuildPghoTypeStr"] = wasmExports["Fd"].value; + _kVersionStampBuildFdoProfileChangelistStr = Module["_kVersionStampBuildFdoProfileChangelistStr"] = wasmExports["Gd"].value; + _kVersionStampBuildMemprofProfileChangelistStr = Module["_kVersionStampBuildMemprofProfileChangelistStr"] = wasmExports["Hd"].value; + _kVersionStampBuildUsernameStr = Module["_kVersionStampBuildUsernameStr"] = wasmExports["Id"].value; + _kVersionStampBuildHostnameStr = Module["_kVersionStampBuildHostnameStr"] = wasmExports["Jd"].value; + _kVersionStampBuildDirectoryStr = Module["_kVersionStampBuildDirectoryStr"] = wasmExports["Kd"].value; + _kVersionStampBuildChangelistInt = Module["_kVersionStampBuildChangelistInt"] = wasmExports["Ld"].value; + _kVersionStampCitcSnapshotInt = Module["_kVersionStampCitcSnapshotInt"] = wasmExports["Md"].value; + _kVersionStampBuildClientMintStatusInt = Module["_kVersionStampBuildClientMintStatusInt"] = wasmExports["Nd"].value; + _kVersionStampBuildTimestampInt = Module["_kVersionStampBuildTimestampInt"] = wasmExports["Od"].value; + _kVersionStampVerifiableInt = Module["_kVersionStampVerifiableInt"] = wasmExports["Pd"].value; + _kVersionStampBuildCoverageEnabledInt = Module["_kVersionStampBuildCoverageEnabledInt"] = wasmExports["Qd"].value; + _kVersionStampBuildBaselineChangelistInt = Module["_kVersionStampBuildBaselineChangelistInt"] = wasmExports["Rd"].value; + _kVersionStampPrecookedTimestampStr = Module["_kVersionStampPrecookedTimestampStr"] = wasmExports["Sd"].value; + _kVersionStampPrecookedClientInfoStr = Module["_kVersionStampPrecookedClientInfoStr"] = wasmExports["Td"].value; + __indirect_function_table = wasmTable = wasmExports["Ud"]; + _kVersionStampBuildHasHardeningProtobuf = Module["_kVersionStampBuildHasHardeningProtobuf"] = wasmExports["Wf"].value; +} + +var wasmImports = { + /** @export */ hd: BeginGlQueryTiming, + /** @export */ gd: EndGlQueryTiming, + /** @export */ fd: GetAdapterArchitecture, + /** @export */ ed: GetAdapterDescription, + /** @export */ dd: GetAdapterDeviceName, + /** @export */ cd: GetAdapterVendor, + /** @export */ bd: JsOnEmptyPacketListener, + /** @export */ ad: JsOnFloat32ArrayImageListener, + /** @export */ $c: JsOnFloat32ArrayImageVectorListener, + /** @export */ nb: JsOnSimpleListenerBinaryArray, + /** @export */ _c: JsOnSimpleListenerBool, + /** @export */ Zc: JsOnSimpleListenerDouble, + /** @export */ Yc: JsOnSimpleListenerFloat, + /** @export */ Xc: JsOnSimpleListenerInt, + /** @export */ Wc: JsOnSimpleListenerString, + /** @export */ Vc: JsOnSimpleListenerUint, + /** @export */ Uc: JsOnUint8ArrayImageListener, + /** @export */ Tc: JsOnUint8ArrayImageVectorListener, + /** @export */ Q: JsOnVectorFinishedListener, + /** @export */ Sc: JsOnVectorListenerBool, + /** @export */ Rc: JsOnVectorListenerDouble, + /** @export */ Qc: JsOnVectorListenerFloat, + /** @export */ Pc: JsOnVectorListenerInt, + /** @export */ Oc: JsOnVectorListenerProto, + /** @export */ Nc: JsOnVectorListenerString, + /** @export */ Mc: JsOnVectorListenerUint, + /** @export */ Lc: JsOnWebGLTextureListener, + /** @export */ Kc: JsOnWebGLTextureVectorListener, + /** @export */ Jc: JsWrapErrorListenerInternal, + /** @export */ mb: JsWrapImageConverter, + /** @export */ Ic: JsWrapLoggingHelpers, + /** @export */ v: JsWrapSimpleListeners, + /** @export */ lb: UseBottomLeftGpuOrigin, + /** @export */ wb: __asyncjs__mediapipe_map_buffer_jspi, + /** @export */ u: ___cxa_throw, + /** @export */ Hc: ___syscall_dup, + /** @export */ Gc: ___syscall_faccessat, + /** @export */ kb: ___syscall_fcntl64, + /** @export */ Fc: ___syscall_fstat64, + /** @export */ Kb: ___syscall_ftruncate64, + /** @export */ Ec: ___syscall_ioctl, + /** @export */ Dc: ___syscall_lstat64, + /** @export */ Cc: ___syscall_newfstatat, + /** @export */ jb: ___syscall_openat, + /** @export */ Bc: ___syscall_stat64, + /** @export */ wc: __abort_js, + /** @export */ Hb: __embind_register_bigint, + /** @export */ vc: __embind_register_bool, + /** @export */ uc: __embind_register_emval, + /** @export */ hb: __embind_register_float, + /** @export */ J: __embind_register_integer, + /** @export */ q: __embind_register_memory_view, + /** @export */ tc: __embind_register_std_string, + /** @export */ La: __embind_register_std_wstring, + /** @export */ sc: __embind_register_void, + /** @export */ aa: __emval_create_invoker, + /** @export */ p: __emval_decref, + /** @export */ Ka: __emval_get_global, + /** @export */ gb: __emval_get_property, + /** @export */ ja: __emval_incref, + /** @export */ Ja: __emval_instanceof, + /** @export */ $: __emval_invoke, + /** @export */ ua: __emval_new_cstring, + /** @export */ _: __emval_run_destructors, + /** @export */ fb: __emval_set_property, + /** @export */ rc: __emval_typeof, + /** @export */ Gb: __gmtime_js, + /** @export */ Fb: __localtime_js, + /** @export */ Eb: __mktime_js, + /** @export */ Db: __mmap_js, + /** @export */ Cb: __munmap_js, + /** @export */ qc: __tzset_js, + /** @export */ Jb: _clock_time_get, + /** @export */ pc: custom_emscripten_dbgn, + /** @export */ Z: _emscripten_asm_const_int, + /** @export */ eb: _emscripten_asm_const_ptr, + /** @export */ Ia: _emscripten_errn, + /** @export */ oc: _emscripten_get_heap_max, + /** @export */ y: _emscripten_get_now, + /** @export */ S: _emscripten_has_asyncify, + /** @export */ nc: _emscripten_outn, + /** @export */ mc: _emscripten_pc_get_function, + /** @export */ lc: _emscripten_resize_heap, + /** @export */ db: _emscripten_stack_snapshot, + /** @export */ kc: _emscripten_stack_unwind_buffer, + /** @export */ jc: _emscripten_webgl_create_context, + /** @export */ ic: _emscripten_webgl_destroy_context, + /** @export */ hc: _emscripten_webgl_get_context_attributes, + /** @export */ ia: _emscripten_webgl_get_current_context, + /** @export */ gc: _emscripten_webgl_make_context_current, + /** @export */ P: _emscripten_webgpu_get_device, + /** @export */ fc: _emwgpuBufferDestroy, + /** @export */ ec: _emwgpuBufferGetMappedRange, + /** @export */ dc: _emwgpuBufferUnmap, + /** @export */ t: _emwgpuDelete, + /** @export */ cc: _emwgpuDeviceCreateBuffer, + /** @export */ Bb: _emwgpuDeviceCreateComputePipelineAsync, + /** @export */ Ab: _emwgpuDeviceCreateRenderPipelineAsync, + /** @export */ bc: _emwgpuDeviceCreateShaderModule, + /** @export */ ac: _emwgpuDeviceDestroy, + /** @export */ $b: _emwgpuWaitAny, + /** @export */ Ac: _environ_get, + /** @export */ zc: _environ_sizes_get, + /** @export */ cb: _exit, + /** @export */ Na: _fd_close, + /** @export */ ib: _fd_read, + /** @export */ Ib: _fd_seek, + /** @export */ Ma: _fd_write, + /** @export */ b: _glActiveTexture, + /** @export */ ta: _glAttachShader, + /** @export */ _b: _glBindAttribLocation, + /** @export */ c: _glBindBuffer, + /** @export */ bb: _glBindBufferBase, + /** @export */ s: _glBindFramebuffer, + /** @export */ a: _glBindTexture, + /** @export */ m: _glBindVertexArray, + /** @export */ ab: _glBlendEquation, + /** @export */ Zb: _glBlendFunc, + /** @export */ j: _glBufferData, + /** @export */ I: _glClear, + /** @export */ H: _glClearColor, + /** @export */ ea: _glClientWaitSync, + /** @export */ ha: _glColorMask, + /** @export */ $a: _glCompileShader, + /** @export */ _a: _glCreateProgram, + /** @export */ Za: _glCreateShader, + /** @export */ o: _glDeleteBuffers, + /** @export */ R: _glDeleteFramebuffers, + /** @export */ h: _glDeleteProgram, + /** @export */ sa: _glDeleteShader, + /** @export */ ra: _glDeleteSync, + /** @export */ D: _glDeleteTextures, + /** @export */ A: _glDeleteVertexArrays, + /** @export */ Ya: _glDetachShader, + /** @export */ G: _glDisable, + /** @export */ n: _glDisableVertexAttribArray, + /** @export */ i: _glDrawArrays, + /** @export */ ga: _glDrawBuffers, + /** @export */ Yb: _glEnable, + /** @export */ l: _glEnableVertexAttribArray, + /** @export */ Xa: _glFenceSync, + /** @export */ qa: _glFinish, + /** @export */ w: _glFlush, + /** @export */ C: _glFramebufferTexture2D, + /** @export */ Wa: _glFramebufferTextureLayer, + /** @export */ r: _glGenBuffers, + /** @export */ Y: _glGenFramebuffers, + /** @export */ F: _glGenTextures, + /** @export */ B: _glGenVertexArrays, + /** @export */ Va: _glGetAttribLocation, + /** @export */ fa: _glGetError, + /** @export */ Xb: _glGetFloatv, + /** @export */ x: _glGetIntegerv, + /** @export */ Wb: _glGetProgramiv, + /** @export */ Vb: _glGetShaderInfoLog, + /** @export */ Ub: _glGetShaderiv, + /** @export */ O: _glGetString, + /** @export */ Tb: _glGetUniformBlockIndex, + /** @export */ d: _glGetUniformLocation, + /** @export */ Sb: _glLineWidth, + /** @export */ Ua: _glLinkProgram, + /** @export */ pa: _glPixelStorei, + /** @export */ oa: _glReadPixels, + /** @export */ Ta: _glShaderSource, + /** @export */ E: _glTexImage2D, + /** @export */ na: _glTexParameterf, + /** @export */ Sa: _glTexParameterfv, + /** @export */ f: _glTexParameteri, + /** @export */ ma: _glTexStorage2D, + /** @export */ Rb: _glTexStorage3D, + /** @export */ X: _glTexSubImage2D, + /** @export */ Qb: _glTexSubImage3D, + /** @export */ N: _glUniform1f, + /** @export */ la: _glUniform1fv, + /** @export */ e: _glUniform1i, + /** @export */ W: _glUniform2f, + /** @export */ Pb: _glUniform2fv, + /** @export */ Ha: _glUniform3f, + /** @export */ Ra: _glUniform4f, + /** @export */ V: _glUniform4fv, + /** @export */ Ob: _glUniform4iv, + /** @export */ Nb: _glUniformBlockBinding, + /** @export */ Mb: _glUniformMatrix2fv, + /** @export */ Lb: _glUniformMatrix3fv, + /** @export */ Ga: _glUniformMatrix4fv, + /** @export */ g: _glUseProgram, + /** @export */ k: _glVertexAttribPointer, + /** @export */ U: _glViewport, + /** @export */ zb: mediapipe_create_utility_canvas2d, + /** @export */ yb: _mediapipe_find_canvas_event_target, + /** @export */ xb: mediapipe_import_external_texture, + /** @export */ vb: _mediapipe_webgl_tex_image_drawable, + /** @export */ yc: _proc_exit, + /** @export */ xc: _random_get, + /** @export */ Fa: _wgpuCommandEncoderBeginComputePass, + /** @export */ Ea: _wgpuCommandEncoderBeginRenderPass, + /** @export */ ub: _wgpuCommandEncoderCopyBufferToTexture, + /** @export */ tb: _wgpuCommandEncoderCopyTextureToBuffer, + /** @export */ sb: _wgpuCommandEncoderCopyTextureToTexture, + /** @export */ M: _wgpuCommandEncoderFinish, + /** @export */ Da: _wgpuComputePassEncoderDispatchWorkgroups, + /** @export */ Ca: _wgpuComputePassEncoderEnd, + /** @export */ Ba: _wgpuComputePassEncoderSetBindGroup, + /** @export */ Aa: _wgpuComputePassEncoderSetPipeline, + /** @export */ za: _wgpuComputePipelineGetBindGroupLayout, + /** @export */ da: _wgpuDeviceCreateBindGroup, + /** @export */ rb: _wgpuDeviceCreateBindGroupLayout, + /** @export */ L: _wgpuDeviceCreateCommandEncoder, + /** @export */ qb: _wgpuDeviceCreateComputePipeline, + /** @export */ pb: _wgpuDeviceCreatePipelineLayout, + /** @export */ Qa: _wgpuDeviceCreateRenderPipeline, + /** @export */ T: _wgpuDeviceCreateSampler, + /** @export */ ca: _wgpuDeviceCreateTexture, + /** @export */ K: _wgpuQueueSubmit, + /** @export */ ka: _wgpuQueueWriteBuffer, + /** @export */ ob: _wgpuQueueWriteTexture, + /** @export */ ya: _wgpuRenderPassEncoderDraw, + /** @export */ xa: _wgpuRenderPassEncoderEnd, + /** @export */ wa: _wgpuRenderPassEncoderSetBindGroup, + /** @export */ va: _wgpuRenderPassEncoderSetPipeline, + /** @export */ Pa: _wgpuRenderPipelineGetBindGroupLayout, + /** @export */ z: _wgpuTextureCreateView, + /** @export */ Oa: _wgpuTextureDestroy, + /** @export */ ba: _wgpuTextureGetFormat +}; + +// include: postamble.js +// === Auto-generated postamble setup entry stuff === +async function run() { + if (runDependencies > 0) { + await new Promise(resolve => dependenciesFulfilled = resolve); + } + preRun(); + // a preRun added a dependency, run will be called later + if (runDependencies > 0) { + await new Promise(resolve => dependenciesFulfilled = resolve); + } + function doRun() { + // run may have just been called through dependencies being fulfilled just in this very frame, + // or while the async setStatus time below was happening + Module["calledRun"] = true; + if (ABORT) return; + initRuntime(); + Module["onRuntimeInitialized"]?.(); + postRun(); + } + if (Module["setStatus"]) { + Module["setStatus"]("Running..."); + // Yield the main thread to allow the browser to paint "Running...", then clear + // the status text after the synchronous doRun() completes. + await new Promise(resolve => { + setTimeout(() => { + setTimeout(() => Module["setStatus"](""), 1); + doRun(); + resolve(); + }, 1); + }); + } else { + doRun(); + } +} + +var wasmExports; + +// In modularize mode the generated code is within a factory function so we +// can use await here (since it's not top-level-await). +wasmExports = await createWasm(); + +await run(); + + + return Module; + }; +})(); + +// Export using a UMD style export, or ES6 exports if selected +if (typeof exports === 'object' && typeof module === 'object') { + module.exports = ModuleFactory; + // This default export looks redundant, but it allows TS to import this + // commonjs style module. + module.exports.default = ModuleFactory; +} else if (typeof define === 'function' && define['amd']) + define([], () => ModuleFactory); diff --git a/frontend/public/mediapipe/wasm/vision_wasm_nosimd_internal.wasm b/frontend/public/mediapipe/wasm/vision_wasm_nosimd_internal.wasm new file mode 100644 index 0000000..dadba54 Binary files /dev/null and b/frontend/public/mediapipe/wasm/vision_wasm_nosimd_internal.wasm differ diff --git a/frontend/shadow-cljs.edn b/frontend/shadow-cljs.edn index 1713ebb..977814f 100644 --- a/frontend/shadow-cljs.edn +++ b/frontend/shadow-cljs.edn @@ -13,12 +13,12 @@ [re-frame "1.4.3"]] ;; Dev server for the CLJS half, on a different port from serve.py (8777) so the - ;; old tool and the port can run side by side — which is the whole point of - ;; keeping js/ around as the numeric oracle. + ;; old tool and the port can run side by side. js/ remains the source for the + ;; measurement stages not yet ported. ;; ;; Two roots: `public` holds the host page, `..` is the repo root so the bundle ;; at /static/arthur/js/ resolves, and so manifest.json, audio.wav and frames/ - ;; are reachable when step 6 needs real footage. + ;; are reachable for real footage. ;; ;; THE ORDER IS LOAD-BEARING. The repo root has an index.html too — the old ;; tool's — so with `..` first, /index.html would quietly serve the prototype diff --git a/frontend/src/arthur/core.cljs b/frontend/src/arthur/core.cljs index 92a8041..6ed9e1c 100644 --- a/frontend/src/arthur/core.cljs +++ b/frontend/src/arthur/core.cljs @@ -4,6 +4,7 @@ port-plan step 3: the hand-written scene plays at 30fps against audio, scrubs, and runs at ½× and ¼×." (:require [arthur.db :as db] + [arthur.events.footage] [arthur.events.playback] [arthur.subs.playback] [arthur.subs.render] diff --git a/frontend/src/arthur/db.cljs b/frontend/src/arthur/db.cljs index 2f07566..ccc3fe3 100644 --- a/frontend/src/arthur/db.cljs +++ b/frontend/src/arthur/db.cljs @@ -23,7 +23,7 @@ because there is one clip per scene today. Copying them by hand into this table is how one of them comes to disagree with the scene it describes." [label scene store] - (merge {:label label :scene scene :store store} + (merge {:label label :scene scene :store store :audio "/audio.wav"} (select-keys scene [:fps :frames :width :height]))) (def scenes @@ -50,7 +50,9 @@ ;; footage's. That is what deleting `makeXform` buys — the framing became a ;; transform on a node, so nothing downstream of the freeze knows the frame ;; size — and it is why ui/player no longer hardcodes 320x200. - :clip (select-keys (:take scenes) [:fps :frames :width :height]) + :clip (select-keys (:take scenes) [:fps :frames :width :height :audio]) + + :footage {:id nil :label nil :loading? false :status nil} ;; --- transport --- ;; diff --git a/frontend/src/arthur/demo/take.cljs b/frontend/src/arthur/demo/take.cljs index 4db3548..54c4827 100644 --- a/frontend/src/arthur/demo/take.cljs +++ b/frontend/src/arthur/demo/take.cljs @@ -1,8 +1,8 @@ (ns arthur.demo.take "The synthetic take: the whole vertical slice, with no video file in it. - This is port-plan step 5's deliverable and it is the first thing in the tree - that runs every stage in order — + This is port-plan step 5's deliverable. `flow/take` now composes the shared + measurement path for both this generator and real footage — synth ──▶ measure/anchor ──▶ condition/anchor │ │ @@ -26,10 +26,8 @@ written two ways. That is the claim \"stabilisation is a channel, not a mode\" made checkable by eye: switching between them is a document edit, tier 1, and not one byte of tier 2 differs." - (:require [arthur.flow.condition :as condition] - [arthur.flow.freeze :as freeze] - [arthur.flow.measure.anchor :as anchor] - [arthur.flow.measure.mouth :as mouth] + (:require [arthur.flow.freeze :as freeze] + [arthur.flow.take :as take] [arthur.synth :as synth])) (def frames 229) @@ -51,14 +49,6 @@ ;; anchor-test exercises 0.5625 and this does not. 1) -(def ^:private knobs - "The prototype's own defaults, from index.html, so the first thing anyone sees - is the thing it was tuned to look like." - {:anchor-avg 2 ; smoothWin - :contour-avg 1 ; contourSmooth - :verts 8 ; vertices - :aperture-cut 0.12}) ; apertureThresh 120/1000 - (def analysis "Stage 2's output, synthesised. A seeded generator, so a wrong pose is reproducible rather than something that happened once." @@ -66,26 +56,13 @@ (def measured "Stages 3 and 4, in the order the stage split requires." - (delay - (let [dense @analysis - fitted (anchor/fit {:aspect aspect} {:dense dense}) - anchored (condition/anchor knobs fitted) - rings (mouth/measure {:aspect aspect} - {:dense dense :transforms (:transforms anchored)})] - (assoc anchored - :outer (condition/contours knobs (:outer rings)) - :inner (condition/contours knobs (:inner rings)) - ;; NOT smoothed. The aperture is the inner ring's own height read off - ;; as a scalar, and `contour avg` is a spatial-correspondence - ;; smoother over a ring; running it over a scalar would be a second, - ;; undocumented low-pass on a signal that then decides visibility. - :aperture (:aperture rings))))) + (delay (take/measure (assoc take/knobs :aspect aspect) {:dense @analysis}))) (def params "What the freeze was handed. Public because it is the honest way to re-freeze at other settings — a test that built its own copy would be asserting about a clip nobody looks at." - (merge knobs + (merge take/knobs {:name "take" :fps fps :stage stage diff --git a/frontend/src/arthur/events/footage.cljs b/frontend/src/arthur/events/footage.cljs new file mode 100644 index 0000000..f616128 --- /dev/null +++ b/frontend/src/arthur/events/footage.cljs @@ -0,0 +1,114 @@ +(ns arthur.events.footage + "Load and freeze extracted footage once, outside the playback loop." + (:require [arthur.events.playback :as pb] + [arthur.flow.detect :as detect] + [arthur.flow.ingest :as ingest] + [arthur.flow.take :as take] + [arthur.footage.store :as store] + [re-frame.core :as rf])) + +(defn- detect-frames! [manifest model] + (let [canvas (.createElement js/document "canvas") + ctx (.getContext canvas "2d") + raw (atom []) + dims (atom nil) + total (:frames manifest) + load-id (.now js/Date)] + (js/Promise. + (fn [resolve reject] + (letfn [(next-frame [i] + (if (= i total) + (try + (resolve (assoc (detect/fill-gaps @raw) :dimensions @dims)) + (catch :default error (reject error))) + (-> (ingest/image! (ingest/frame-url manifest i load-id)) + (.then + (fn [image] + (let [wh [(.-naturalWidth image) (.-naturalHeight image)]] + (when (and @dims (not= @dims wh)) + (throw (ex-info (str "frame " (inc i) " has different dimensions") + {:expected @dims :actual wh}))) + (reset! dims wh) + (set! (.-width canvas) (first wh)) + (set! (.-height canvas) (second wh)) + (.drawImage ctx image 0 0) + (swap! raw conj (detect/detect! model canvas)) + (when (or (zero? i) (zero? (mod (inc i) 4)) (= (inc i) total)) + (rf/dispatch [::progress (str "detecting " (inc i) "/" total)])) + ;; Let the status and the transport paint between sync + ;; MediaPipe calls, and release each decoded PNG. + (js/setTimeout #(next-frame (inc i)) 0)))) + (.catch reject))))] + (next-frame 0)))))) + +(defn- build-clip [manifest {:keys [dense detected dimensions missing first-real]}] + (let [[w h] dimensions + params (merge take/knobs + {:name "footage" :fps (:fps manifest) :aspect (/ w h) + :stage [320 200] :expose 2 :head :as-filmed + :analysis (str "mediapipe:1.0.1/" (:source manifest))}) + frozen (take/build params {:dense dense :detected detected}) + scene (:scene frozen)] + (assoc (select-keys scene [:fps :frames :width :height]) + :scene scene :store (:store frozen) + ;; Re-extraction often overwrites audio.wav under the same name. A new + ;; URL makes the element fetch the new sound when this clip is loaded. + :audio (str (ingest/audio-url manifest) "?v=" (.now js/Date)) + :label (or (:source manifest) "footage") + :summary (str (:frames manifest) " frames · " w "×" h " · " + (:fps manifest) " fps" + (when (pos? missing) + (str " · " missing " without a face" + (when (pos? first-real) + (str " (first found on " (inc first-real) ")")))))))) + +(rf/reg-fx + ::begin! + (fn [_] + (-> (ingest/manifest!) + (.then (fn [manifest] + (rf/dispatch [::progress "loading MediaPipe…"]) + (-> (detect/landmarker!) + (.then (fn [model] + (rf/dispatch [::progress "loading frames…"]) + (-> (detect-frames! manifest model) + (.then (fn [track] (build-clip manifest track))))))))) + (.then (fn [entry] + (let [id (store/install! entry)] + (rf/dispatch [::loaded id (:summary entry)])))) + (.catch (fn [error] + (js/console.error error) + (rf/dispatch [::failed (or (.-message error) (str error))])))))) + +(rf/reg-event-fx + ::load + (fn [{:keys [db]} _] + (if (get-in db [:footage :loading?]) + {} + {:db (assoc db :footage (assoc (:footage db) :loading? true + :status "reading manifest.json…")) + ::pb/pause! nil + ::begin! nil}))) + +(rf/reg-event-db + ::progress + (fn [db [_ message]] (assoc-in db [:footage :status] message))) + +(rf/reg-event-db + ::failed + (fn [db [_ message]] + (assoc db :footage (assoc (:footage db) + :loading? false :status (str "load failed: " message))))) + +(rf/reg-event-fx + ::loaded + (fn [{:keys [db]} [_ id summary]] + (let [clip (store/entry id)] + {:db (-> db + (assoc :scene/current id + :clip (select-keys clip [:fps :frames :width :height :audio]) + :footage {:id id :label (:label clip) + :loading? false :status summary}) + (assoc-in [:playback :frame] 0) + (assoc-in [:playback :playing?] false)) + ::pb/pause! nil}))) diff --git a/frontend/src/arthur/events/playback.cljs b/frontend/src/arthur/events/playback.cljs index f0d7129..2b69389 100644 --- a/frontend/src/arthur/events/playback.cljs +++ b/frontend/src/arthur/events/playback.cljs @@ -11,7 +11,7 @@ a small app-db. If global interceptors are added later they are added to a chain these events are excluded from, not to `reg-global-interceptor`." (:require [arthur.clock :as clock] - [arthur.db :as db] + [arthur.footage.store :as footage] [re-frame.core :as rf])) (defn- fps [db] (get-in db [:clip :fps])) @@ -92,12 +92,14 @@ ;; Changing the clip changes the resolver, the frame count and the rate all ;; at once, so the playhead goes home rather than being left pointing at a ;; frame the new clip may not have. - (let [{:keys [fps frames] :as clip} (get db/scenes id)] + (let [{:keys [fps frames] :as clip} (footage/entry id)] {:db (-> db (assoc :scene/current id) ;; The stage travels with the clip: two clips may be different ;; sizes, and the raster the loop paints into is the clip's, not ;; the app's. - (assoc :clip (select-keys clip [:fps :frames :width :height])) - (assoc-in [:playback :frame] 0)) + (assoc :clip (select-keys clip [:fps :frames :width :height :audio])) + (assoc-in [:playback :frame] 0) + (assoc-in [:playback :playing?] false)) + ::pause! nil ::seek! [fps frames 0]}))) diff --git a/frontend/src/arthur/flow/detect.cljs b/frontend/src/arthur/flow/detect.cljs new file mode 100644 index 0000000..a2986dd --- /dev/null +++ b/frontend/src/arthur/flow/detect.cljs @@ -0,0 +1,58 @@ +(ns arthur.flow.detect + "The only MediaPipe boundary. Landmarks leave here as ordinary CLJS values.") + +(defonce ^:private instance (atom nil)) +(defonce ^:private pending (atom nil)) + +(defn landmarker! + "Initialize once, using the vendored wasm and the local model. CPU also works + in browsers where a GPU delegate initializes but fails on its first frame." + [] + (if-let [model @instance] + (js/Promise.resolve model) + (or @pending + (if-let [vision (aget js/window "Vision")] + (let [resolver (aget vision "FilesetResolver") + landmarker (aget vision "FaceLandmarker") + ready (-> (.call (aget resolver "forVisionTasks") resolver "/mediapipe/wasm") + (.then (fn [fileset] + (.call (aget landmarker "createFromOptions") + landmarker fileset + #js {:baseOptions + #js {:modelAssetPath "/mediapipe/face_landmarker.task" + :delegate "CPU"} + :runningMode "IMAGE" + :numFaces 1}))) + (.then (fn [model] + (reset! instance model) + model)) + (.catch (fn [e] + (reset! pending nil) + (throw e))))] + (reset! pending ready) + ready) + (js/Promise.reject (js/Error. "local MediaPipe script did not load")))))) + +(defn detect! + "Detect one already-drawn canvas frame. nil means no face was detected." + [model canvas] + (when-let [face (aget (aget (.call (aget model "detect") model canvas) + "faceLandmarks") 0)] + (mapv (fn [p] {:x (.-x p) :y (.-y p) :z (.-z p)}) face))) + +(defn fill-gaps + "Keep the detection mask while supplying real poses for measurement. A leading + gap uses the first observed face; later gaps hold the previous observed pose. + Freeze uses the mask to mark those frames absent in the channel blocks." + [raw] + (let [first-real (first (keep-indexed (fn [i frame] (when frame i)) raw))] + (when-not first-real + (throw (ex-info "no face found in any frame — check framing and light" {}))) + {:dense (loop [i 0 last-face (nth raw first-real) out []] + (if (= i (count raw)) + out + (let [face (or (nth raw i) last-face)] + (recur (inc i) face (conj out face))))) + :detected (mapv some? raw) + :missing (count (remove some? raw)) + :first-real first-real})) diff --git a/frontend/src/arthur/flow/ingest.cljs b/frontend/src/arthur/flow/ingest.cljs new file mode 100644 index 0000000..dcf47db --- /dev/null +++ b/frontend/src/arthur/flow/ingest.cljs @@ -0,0 +1,44 @@ +(ns arthur.flow.ingest + "Read a pre-extracted take. The manifest owns timing and the exact frame count." + (:require [clojure.string :as str])) + +(defn- valid-manifest [m] + (let [fps (js/Number (:fps m)) + frames (js/Number (:frames m))] + (when-not (and (js/Number.isFinite fps) (pos? fps) + (js/Number.isInteger frames) (<= 1 frames 900) + (string? (:dir m)) (seq (:dir m)) + (string? (:audio m)) (seq (:audio m))) + (throw (ex-info "manifest.json needs fps, frames (1–900), dir and audio" {:manifest m}))) + (assoc m :fps fps :frames frames))) + +(defn manifest! + [] + (-> (js/fetch "/manifest.json" #js {:cache "no-store"}) + (.then (fn [response] + (when-not (.-ok response) + (throw (ex-info "manifest.json was not found; run extract.sh first" + {:status (.-status response)}))) + (.json response))) + (.then (fn [json] (valid-manifest (js->clj json :keywordize-keys true)))))) + +(defn- asset-url [path] + ;; Manifest paths are relative to the extraction root, served at / in dev. + (str "/" (str/replace path #"^/+" ""))) + +(defn audio-url [manifest] + (asset-url (:audio manifest))) + +(defn frame-url [manifest i load-id] + (str (asset-url (str (str/replace (:dir manifest) #"/+$" "") + "/" (.padStart (str (inc i)) 4 "0") ".png")) + "?v=" load-id)) + +(defn image! [src] + (js/Promise. + (fn [resolve reject] + (let [image (js/Image.)] + (set! (.-onload image) #(resolve image)) + (set! (.-onerror image) #(reject (ex-info (str "frame did not load: " src) + {:src src}))) + (set! (.-src image) src))))) diff --git a/frontend/src/arthur/flow/take.cljs b/frontend/src/arthur/flow/take.cljs new file mode 100644 index 0000000..c3ac5c0 --- /dev/null +++ b/frontend/src/arthur/flow/take.cljs @@ -0,0 +1,26 @@ +(ns arthur.flow.take + "The shared landmark-to-channel path for synthetic and detected takes." + (:require [arthur.flow.condition :as condition] + [arthur.flow.freeze :as freeze] + [arthur.flow.measure.anchor :as anchor] + [arthur.flow.measure.mouth :as mouth])) + +(def knobs + {:anchor-avg 2 :contour-avg 1 :verts 8 :aperture-cut 0.12}) + +(defn measure + "Condition the anchor before measuring rings through it." + [{:keys [aspect] :as params} {:keys [dense detected]}] + (let [fitted (anchor/fit {:aspect aspect} {:dense dense}) + anchored (condition/anchor params fitted) + rings (mouth/measure {:aspect aspect} + {:dense dense :transforms (:transforms anchored)})] + (assoc anchored + :outer (condition/contours params (:outer rings)) + :inner (condition/contours params (:inner rings)) + :aperture (:aperture rings) + :detected detected))) + +(defn build + [params inputs] + (freeze/clip params (measure params inputs))) diff --git a/frontend/src/arthur/footage/store.cljs b/frontend/src/arthur/footage/store.cljs new file mode 100644 index 0000000..21a6cd8 --- /dev/null +++ b/frontend/src/arthur/footage/store.cljs @@ -0,0 +1,16 @@ +(ns arthur.footage.store + "Loaded clip artifacts live outside app-db. The db keeps only their id." + (:require [arthur.db :as db])) + +(defonce ^:private loaded (atom nil)) +(defonce ^:private serial (atom 0)) + +(defn install! [entry] + (let [id (keyword "footage" (str (swap! serial inc)))] + (reset! loaded (assoc entry :id id)) + id)) + +(defn entry [id] + (if (= id (:id @loaded)) + @loaded + (get db/scenes id))) diff --git a/frontend/src/arthur/subs/playback.cljs b/frontend/src/arthur/subs/playback.cljs index 9bdd5ff..451f365 100644 --- a/frontend/src/arthur/subs/playback.cljs +++ b/frontend/src/arthur/subs/playback.cljs @@ -16,3 +16,5 @@ ;; take their size from the document rather than from a constant. (rf/reg-sub ::width (fn [db _] (get-in db [:clip :width]))) (rf/reg-sub ::height (fn [db _] (get-in db [:clip :height]))) +(rf/reg-sub ::audio (fn [db _] (get-in db [:clip :audio]))) +(rf/reg-sub ::footage (fn [db _] (:footage db))) diff --git a/frontend/src/arthur/subs/render.cljs b/frontend/src/arthur/subs/render.cljs index 0c143d3..12dbb5e 100644 --- a/frontend/src/arthur/subs/render.cljs +++ b/frontend/src/arthur/subs/render.cljs @@ -7,14 +7,14 @@ CLOSURE that produces geometry at a frame. So a scene edit costs one recomputation here and a frame costs a lookup and a blit — and, crucially, the playhead is not an input, so moving it cannot invalidate this." - (:require [arthur.db :as db] - [arthur.domain.palette :as pal] + (:require [arthur.domain.palette :as pal] [arthur.domain.scene :as scene] + [arthur.footage.store :as footage] [re-frame.core :as rf])) (rf/reg-sub ::scene-id (fn [db _] (:scene/current db))) -(rf/reg-sub ::scene (fn [db _] (get-in db/scenes [(:scene/current db) :scene]))) +(rf/reg-sub ::scene (fn [db _] (:scene (footage/entry (:scene/current db))))) (rf/reg-sub ::exposure @@ -49,7 +49,7 @@ ;; Tier 2, behind a handle, and never in app-db itself — what is in the db is ;; the id of the clip whose blocks these are. The hand-written demo has none; ;; the swarm is entirely dense. - (get-in db/scenes [(:scene/current db) :store]))) + (:store (footage/entry (:scene/current db))))) (rf/reg-sub ::resolver diff --git a/frontend/src/arthur/ui/shell.cljs b/frontend/src/arthur/ui/shell.cljs index cc63a9f..d43ba80 100644 --- a/frontend/src/arthur/ui/shell.cljs +++ b/frontend/src/arthur/ui/shell.cljs @@ -7,6 +7,7 @@ why scrubbing at speed does not re-render the page." (:require [arthur.clock :as clock] [arthur.db :as db] + [arthur.events.footage :as footage] [arthur.events.playback :as pb] [arthur.subs.playback :as sub] [arthur.subs.render :as render] @@ -16,16 +17,17 @@ (def ^:private zoom 2) (defn- audio [] - [:audio + (let [src @(rf/subscribe [::sub/audio])] + [:audio {:ref #(when % (clock/attach! %)) - :src "/audio.wav" + :src src :preload "auto" ;; Transport state follows the ELEMENT, not the other way round: the audio ;; is the clock, so anything that can change its state — the end of the ;; file, the OS media keys, a browser autoplay block — has to be able to ;; correct the document rather than be contradicted by it. :on-play #(rf/dispatch [::pb/play]) - :on-pause #(rf/dispatch [::pb/pause])}]) + :on-pause #(rf/dispatch [::pb/pause])}])) (defn- transport [] (let [playing? @(rf/subscribe [::sub/playing?]) @@ -33,7 +35,8 @@ frame @(rf/subscribe [::sub/frame]) frames @(rf/subscribe [::sub/frames]) fps @(rf/subscribe [::sub/fps]) - expose @(rf/subscribe [::render/exposure])] + expose @(rf/subscribe [::render/exposure]) + {:keys [id label loading? status]} @(rf/subscribe [::sub/footage])] [:div.transport [:div.row [:button {:on-click #(rf/dispatch [::pb/toggle])} @@ -52,6 +55,13 @@ [:button {:class (when (= id @(rf/subscribe [::render/scene-id])) "on") :on-click #(rf/dispatch [::pb/select-scene id])} label])) + (when id + [:button {:class (when (= id @(rf/subscribe [::render/scene-id])) "on") + :on-click #(rf/dispatch [::pb/select-scene id])} + (or label "footage")]) + [:button {:disabled loading? + :on-click #(rf/dispatch [::footage/load])} + (if loading? "loading…" "load frames")] [:span.gap] (doall (for [r db/rates] @@ -77,7 +87,8 @@ [:span {:class (when (and drop (> drop 1.35)) "warn")} (str (.toFixed (or fps 0) 1) " paint/s" (when (and drop (pos? drop)) - (str " · " (.toFixed drop 2) " frames/paint")))])]])) + (str " · " (.toFixed drop 2) " frames/paint")))])] + (when status [:div.load-status status])])) (defn- stage [] ;; The canvas is the STAGE's size, and the stage is the clip's — not a constant @@ -98,5 +109,5 @@ [audio] [transport] [:p.note - "Audio-clocked: the frame is ⌊currentTime · fps⌋, so a slow loop drops " - "frames instead of drifting. ½× and ¼× are playbackRate."]]) + "Extract a clip with extract.sh, then load frames. The manifest supplies " + "the frame count, audio and fps."]])