@weadmin/weixin-minigame-helper-mcp 0.1.21 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/mcp/game-bundler-worker.js +2879 -1
- package/mcp/index.js +27833 -7
- package/media/wx-compat.js +12441 -1
- package/media/wx-compat.js.map +7 -0
- package/package.json +2 -1
- package/templates/preview.html +2 -2
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../packages/wx-compat/node_modules/brotli-wasm/pkg.web/brotli_wasm.js", "../../../packages/wx-compat/src/brotli-decoder.ts", "../../../packages/wx-compat/src/virtual-fs.ts", "../../../packages/wx-compat/src/native-globals.ts", "../../../packages/wx-compat/src/url-utils.ts", "../../../packages/wx-compat/src/constants.ts", "../../../packages/wx-compat/src/zip-decoder.ts", "../../../packages/wx-compat/src/file-system.ts", "../../../packages/wx-compat/src/canvas.ts", "../../../packages/wx-compat/src/system-info.ts", "../../../packages/wx-compat/src/storage.ts", "../../../packages/wx-compat/src/animation-frame.ts", "../../../packages/wx-compat/src/audio.ts", "../../../packages/wx-compat/src/network-monitor.ts", "../../../packages/wx-compat/src/network.ts", "../../../packages/wx-compat/src/device.ts", "../../../packages/wx-compat/src/image.ts", "../../../packages/wx-compat/src/perf.ts", "../../../packages/wx-compat/src/lifecycle.ts", "../../../packages/wx-compat/src/logger.ts", "../../../packages/wx-compat/src/env.ts", "../../../packages/wx-compat/src/render-helpers.ts", "../../../packages/wx-compat/src/ui.ts", "../../../packages/wx-compat/src/input-events.ts", "../../../packages/wx-compat/src/cursor.ts", "../../../packages/wx-compat/src/sensors.ts", "../../../packages/wx-compat/src/device-extras.ts", "../../../packages/wx-compat/src/data-analysis.ts", "../../../packages/wx-compat/src/worker-compat.ts", "../../../packages/wx-compat/src/utils.ts", "../../../packages/wx-compat/node_modules/@tencent/wxapkg-browser/dist/index.js", "../../../packages/wx-compat/src/wxapkg-loader.ts", "../../../packages/wx-compat/src/module-compat.ts", "../../../packages/wx-compat/src/jsbridge.ts", "../../../packages/wx-compat/src/plugin-compat.ts", "../../../packages/wx-compat/src/globals-compat.ts", "../../../packages/wx-compat/src/permission.ts", "../../../packages/wx-compat/src/clean-globals.ts", "../../../packages/wx-compat/src/api-monitor.ts", "../../../packages/wx-compat/src/share.ts", "../../../packages/wx-compat/src/auth.ts", "../../../packages/wx-compat/src/open-data.ts", "../../../packages/wx-compat/src/ad.ts", "../../../packages/wx-compat/src/media.ts", "../../../packages/wx-compat/src/router.ts", "../../../packages/wx-compat/src/payment.ts", "../../../packages/wx-compat/src/playable.ts", "../../../packages/wx-compat/src/recorder.ts", "../../../packages/wx-compat/src/stubs.ts", "../../../packages/wx-compat/src/wx-compat.ts"],
|
|
4
|
+
"sourcesContent": ["\nlet wasm;\n\nconst heap = new Array(32).fill(undefined);\n\nheap.push(undefined, null, true, false);\n\nfunction getObject(idx) { return heap[idx]; }\n\nconst cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });\n\ncachedTextDecoder.decode();\n\nlet cachegetUint8Memory0 = null;\nfunction getUint8Memory0() {\n if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {\n cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);\n }\n return cachegetUint8Memory0;\n}\n\nfunction getStringFromWasm0(ptr, len) {\n return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));\n}\n\nlet heap_next = heap.length;\n\nfunction addHeapObject(obj) {\n if (heap_next === heap.length) heap.push(heap.length + 1);\n const idx = heap_next;\n heap_next = heap[idx];\n\n heap[idx] = obj;\n return idx;\n}\n\nlet WASM_VECTOR_LEN = 0;\n\nconst cachedTextEncoder = new TextEncoder('utf-8');\n\nconst encodeString = (typeof cachedTextEncoder.encodeInto === 'function'\n ? function (arg, view) {\n return cachedTextEncoder.encodeInto(arg, view);\n}\n : function (arg, view) {\n const buf = cachedTextEncoder.encode(arg);\n view.set(buf);\n return {\n read: arg.length,\n written: buf.length\n };\n});\n\nfunction passStringToWasm0(arg, malloc, realloc) {\n\n if (realloc === undefined) {\n const buf = cachedTextEncoder.encode(arg);\n const ptr = malloc(buf.length);\n getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf);\n WASM_VECTOR_LEN = buf.length;\n return ptr;\n }\n\n let len = arg.length;\n let ptr = malloc(len);\n\n const mem = getUint8Memory0();\n\n let offset = 0;\n\n for (; offset < len; offset++) {\n const code = arg.charCodeAt(offset);\n if (code > 0x7F) break;\n mem[ptr + offset] = code;\n }\n\n if (offset !== len) {\n if (offset !== 0) {\n arg = arg.slice(offset);\n }\n ptr = realloc(ptr, len, len = offset + arg.length * 3);\n const view = getUint8Memory0().subarray(ptr + offset, ptr + len);\n const ret = encodeString(arg, view);\n\n offset += ret.written;\n }\n\n WASM_VECTOR_LEN = offset;\n return ptr;\n}\n\nlet cachegetInt32Memory0 = null;\nfunction getInt32Memory0() {\n if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {\n cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);\n }\n return cachegetInt32Memory0;\n}\n\nfunction dropObject(idx) {\n if (idx < 36) return;\n heap[idx] = heap_next;\n heap_next = idx;\n}\n\nfunction takeObject(idx) {\n const ret = getObject(idx);\n dropObject(idx);\n return ret;\n}\n\nfunction passArray8ToWasm0(arg, malloc) {\n const ptr = malloc(arg.length * 1);\n getUint8Memory0().set(arg, ptr / 1);\n WASM_VECTOR_LEN = arg.length;\n return ptr;\n}\n\nlet stack_pointer = 32;\n\nfunction addBorrowedObject(obj) {\n if (stack_pointer == 1) throw new Error('out of js stack');\n heap[--stack_pointer] = obj;\n return stack_pointer;\n}\n\nfunction getArrayU8FromWasm0(ptr, len) {\n return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);\n}\n/**\n* @param {Uint8Array} buf\n* @param {any} raw_options\n* @returns {Uint8Array}\n*/\nexport function compress(buf, raw_options) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n const ptr0 = passArray8ToWasm0(buf, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n wasm.compress(retptr, ptr0, len0, addBorrowedObject(raw_options));\n var r0 = getInt32Memory0()[retptr / 4 + 0];\n var r1 = getInt32Memory0()[retptr / 4 + 1];\n var r2 = getInt32Memory0()[retptr / 4 + 2];\n var r3 = getInt32Memory0()[retptr / 4 + 3];\n if (r3) {\n throw takeObject(r2);\n }\n var v1 = getArrayU8FromWasm0(r0, r1).slice();\n wasm.__wbindgen_free(r0, r1 * 1);\n return v1;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n heap[stack_pointer++] = undefined;\n }\n}\n\n/**\n* @param {Uint8Array} buf\n* @returns {Uint8Array}\n*/\nexport function decompress(buf) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n const ptr0 = passArray8ToWasm0(buf, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n wasm.decompress(retptr, ptr0, len0);\n var r0 = getInt32Memory0()[retptr / 4 + 0];\n var r1 = getInt32Memory0()[retptr / 4 + 1];\n var r2 = getInt32Memory0()[retptr / 4 + 2];\n var r3 = getInt32Memory0()[retptr / 4 + 3];\n if (r3) {\n throw takeObject(r2);\n }\n var v1 = getArrayU8FromWasm0(r0, r1).slice();\n wasm.__wbindgen_free(r0, r1 * 1);\n return v1;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n}\n\nfunction isLikeNone(x) {\n return x === undefined || x === null;\n}\n/**\n* Same as [`brotli::BrotliResult`] except [`brotli::BrotliResult::ResultFailure`].\n*\n* Always `> 0`.\n*\n* `ResultFailure` is removed\n* because we will convert the failure to an actual negative error code (if available) and pass it elsewhere.\n*/\nexport const BrotliStreamResultCode = Object.freeze({ ResultSuccess:1,\"1\":\"ResultSuccess\",NeedsMoreInput:2,\"2\":\"NeedsMoreInput\",NeedsMoreOutput:3,\"3\":\"NeedsMoreOutput\", });\n/**\n* Returned by every successful (de)compression.\n*/\nexport class BrotliStreamResult {\n\n static __wrap(ptr) {\n const obj = Object.create(BrotliStreamResult.prototype);\n obj.ptr = ptr;\n\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.ptr;\n this.ptr = 0;\n\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_brotlistreamresult_free(ptr);\n }\n /**\n * Result code.\n *\n * See [`BrotliStreamResultCode`] for available values.\n *\n * When error, the error code is not passed here but rather goes to `Err`.\n */\n get code() {\n const ret = wasm.__wbg_get_brotlistreamresult_code(this.ptr);\n return ret >>> 0;\n }\n /**\n * Result code.\n *\n * See [`BrotliStreamResultCode`] for available values.\n *\n * When error, the error code is not passed here but rather goes to `Err`.\n * @param {number} arg0\n */\n set code(arg0) {\n wasm.__wbg_set_brotlistreamresult_code(this.ptr, arg0);\n }\n /**\n * Output buffer\n */\n get buf() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.__wbg_get_brotlistreamresult_buf(retptr, this.ptr);\n var r0 = getInt32Memory0()[retptr / 4 + 0];\n var r1 = getInt32Memory0()[retptr / 4 + 1];\n var v0 = getArrayU8FromWasm0(r0, r1).slice();\n wasm.__wbindgen_free(r0, r1 * 1);\n return v0;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * Output buffer\n * @param {Uint8Array} arg0\n */\n set buf(arg0) {\n const ptr0 = passArray8ToWasm0(arg0, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n wasm.__wbg_set_brotlistreamresult_buf(this.ptr, ptr0, len0);\n }\n /**\n * Consumed bytes of the input buffer\n */\n get input_offset() {\n const ret = wasm.__wbg_get_brotlistreamresult_input_offset(this.ptr);\n return ret >>> 0;\n }\n /**\n * Consumed bytes of the input buffer\n * @param {number} arg0\n */\n set input_offset(arg0) {\n wasm.__wbg_set_brotlistreamresult_input_offset(this.ptr, arg0);\n }\n}\n/**\n*/\nexport class CompressStream {\n\n static __wrap(ptr) {\n const obj = Object.create(CompressStream.prototype);\n obj.ptr = ptr;\n\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.ptr;\n this.ptr = 0;\n\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_compressstream_free(ptr);\n }\n /**\n * @param {number | undefined} quality\n */\n constructor(quality) {\n const ret = wasm.compressstream_new(!isLikeNone(quality), isLikeNone(quality) ? 0 : quality);\n return CompressStream.__wrap(ret);\n }\n /**\n * @param {Uint8Array | undefined} input_opt\n * @param {number} output_size\n * @returns {BrotliStreamResult}\n */\n compress(input_opt, output_size) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n var ptr0 = isLikeNone(input_opt) ? 0 : passArray8ToWasm0(input_opt, wasm.__wbindgen_malloc);\n var len0 = WASM_VECTOR_LEN;\n wasm.compressstream_compress(retptr, this.ptr, ptr0, len0, output_size);\n var r0 = getInt32Memory0()[retptr / 4 + 0];\n var r1 = getInt32Memory0()[retptr / 4 + 1];\n var r2 = getInt32Memory0()[retptr / 4 + 2];\n if (r2) {\n throw takeObject(r1);\n }\n return BrotliStreamResult.__wrap(r0);\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @returns {number}\n */\n total_out() {\n const ret = wasm.compressstream_total_out(this.ptr);\n return ret >>> 0;\n }\n}\n/**\n*/\nexport class DecompressStream {\n\n static __wrap(ptr) {\n const obj = Object.create(DecompressStream.prototype);\n obj.ptr = ptr;\n\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.ptr;\n this.ptr = 0;\n\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_decompressstream_free(ptr);\n }\n /**\n */\n constructor() {\n const ret = wasm.decompressstream_new();\n return DecompressStream.__wrap(ret);\n }\n /**\n * @param {Uint8Array} input\n * @param {number} output_size\n * @returns {BrotliStreamResult}\n */\n decompress(input, output_size) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n const ptr0 = passArray8ToWasm0(input, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n wasm.decompressstream_decompress(retptr, this.ptr, ptr0, len0, output_size);\n var r0 = getInt32Memory0()[retptr / 4 + 0];\n var r1 = getInt32Memory0()[retptr / 4 + 1];\n var r2 = getInt32Memory0()[retptr / 4 + 2];\n if (r2) {\n throw takeObject(r1);\n }\n return BrotliStreamResult.__wrap(r0);\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @returns {number}\n */\n total_out() {\n const ret = wasm.decompressstream_total_out(this.ptr);\n return ret >>> 0;\n }\n}\n\nasync function load(module, imports) {\n if (typeof Response === 'function' && module instanceof Response) {\n if (typeof WebAssembly.instantiateStreaming === 'function') {\n try {\n return await WebAssembly.instantiateStreaming(module, imports);\n\n } catch (e) {\n if (module.headers.get('Content-Type') != 'application/wasm') {\n console.warn(\"`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n\", e);\n\n } else {\n throw e;\n }\n }\n }\n\n const bytes = await module.arrayBuffer();\n return await WebAssembly.instantiate(bytes, imports);\n\n } else {\n const instance = await WebAssembly.instantiate(module, imports);\n\n if (instance instanceof WebAssembly.Instance) {\n return { instance, module };\n\n } else {\n return instance;\n }\n }\n}\n\nasync function init(input) {\n if (typeof input === 'undefined') {\n input = new URL('brotli_wasm_bg.wasm', import.meta.url);\n }\n const imports = {};\n imports.wbg = {};\n imports.wbg.__wbindgen_is_undefined = function(arg0) {\n const ret = getObject(arg0) === undefined;\n return ret;\n };\n imports.wbg.__wbindgen_is_object = function(arg0) {\n const val = getObject(arg0);\n const ret = typeof(val) === 'object' && val !== null;\n return ret;\n };\n imports.wbg.__wbindgen_string_new = function(arg0, arg1) {\n const ret = getStringFromWasm0(arg0, arg1);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_error_new = function(arg0, arg1) {\n const ret = new Error(getStringFromWasm0(arg0, arg1));\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_json_serialize = function(arg0, arg1) {\n const obj = getObject(arg1);\n const ret = JSON.stringify(obj === undefined ? null : obj);\n const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n getInt32Memory0()[arg0 / 4 + 1] = len0;\n getInt32Memory0()[arg0 / 4 + 0] = ptr0;\n };\n imports.wbg.__wbg_new_693216e109162396 = function() {\n const ret = new Error();\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_stack_0ddaca5d1abfb52f = function(arg0, arg1) {\n const ret = getObject(arg1).stack;\n const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n getInt32Memory0()[arg0 / 4 + 1] = len0;\n getInt32Memory0()[arg0 / 4 + 0] = ptr0;\n };\n imports.wbg.__wbg_error_09919627ac0992f5 = function(arg0, arg1) {\n try {\n console.error(getStringFromWasm0(arg0, arg1));\n } finally {\n wasm.__wbindgen_free(arg0, arg1);\n }\n };\n imports.wbg.__wbindgen_object_drop_ref = function(arg0) {\n takeObject(arg0);\n };\n imports.wbg.__wbindgen_throw = function(arg0, arg1) {\n throw new Error(getStringFromWasm0(arg0, arg1));\n };\n\n if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {\n input = fetch(input);\n }\n\n\n\n const { instance, module } = await load(await input, imports);\n\n wasm = instance.exports;\n init.__wbindgen_wasm_module = module;\n\n return wasm;\n}\n\nexport default init;\n\n", "/**\r\n * brotli-decoder.ts \u2014 asynchronous Brotli decoder shared by every VFS read\r\n * path that may receive a `.br`-compressed asset (e.g. Unity\r\n * `*.wasm.code.unityweb.wasm.br`).\r\n *\r\n * Background\r\n * ----------\r\n * In the real WeChat Mini-Game runtime, `.br` files are transparently\r\n * decompressed at the HTTP / fs layer so the caller only ever sees the raw\r\n * payload. Our browser preview used to rely on the same trick \u2014 the dev\r\n * server set `Content-Encoding: br` and the browser did the decoding. In\r\n * wxapkg mode however the files live in the in-memory VFS (unpacked from a\r\n * binary wxapkg archive) and are served through the `wxvfs:` synthetic\r\n * Response path, which bypasses the network stack entirely. Nobody\r\n * decompresses them, so the raw brotli stream leaks all the way into\r\n * `WebAssembly.instantiate` which then errors out with:\r\n *\r\n * CompileError: WebAssembly.instantiate(): expected magic word\r\n * 00 61 73 6d, found cb ff ff 3f @+0\r\n *\r\n * (The `cb` byte is the typical first byte of a brotli stream.)\r\n *\r\n * Strategy\r\n * --------\r\n * 1. Prefer the native `DecompressionStream('br')` \u2014 it is zero-cost and\r\n * available in Chromium \u2265 131 (stable late-2024) and Edge. When the\r\n * iframe runs inside VSCode's Electron runtime this is the common case.\r\n *\r\n * 2. Fallback to `brotli-wasm` (a Rust-compiled wasm decoder). The wasm\r\n * bytes are inlined into the wx-compat IIFE at build time via esbuild's\r\n * `.wasm` binary loader, so no extra network request is issued \u2014 critical\r\n * for our srcdoc iframe whose document origin is \"null\" and therefore\r\n * cannot resolve any relative URL.\r\n *\r\n * The module memoises its bootstrap so concurrent callers share a single\r\n * decoder instance and a single feature-detection attempt.\r\n */\r\n\r\nimport { nativeConsole } from './native-globals';\r\nimport { primeBrotliSync } from './virtual-fs';\r\n\r\n// \u2500\u2500\u2500 Native DecompressionStream path \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Try to decode `bytes` using the platform's `DecompressionStream('br')`.\r\n * Returns `null` (not an error) when the runtime does not support the 'br'\r\n * format so the caller can move on to the wasm fallback.\r\n */\r\nasync function decompressWithNativeStream(\r\n bytes: Uint8Array,\r\n): Promise<Uint8Array | null> {\r\n const DS = (globalThis as unknown as { DecompressionStream?: typeof DecompressionStream })\r\n .DecompressionStream;\r\n if (typeof DS !== 'function') return null;\r\n\r\n let stream: DecompressionStream;\r\n try {\r\n // Constructing with an unsupported format throws TypeError synchronously.\r\n stream = new DS('br' as CompressionFormat);\r\n } catch {\r\n return null;\r\n }\r\n\r\n try {\r\n const source = new Blob([bytes]).stream();\r\n const decoded = source.pipeThrough(stream);\r\n const out = new Response(decoded);\r\n const buf = await out.arrayBuffer();\r\n return new Uint8Array(buf);\r\n } catch (e) {\r\n // A genuine decode failure (corrupt payload). Fall through to the wasm\r\n // decoder which sometimes disagrees about framing quirks, then surface\r\n // the error from there if both fail.\r\n nativeConsole.warn('[wx-compat][brotli] DecompressionStream(br) failed:', e);\r\n return null;\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 brotli-wasm fallback path \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n// `brotli-wasm`'s web entry exposes `init(bytesOrUrl)` and `decompress(buf)`.\r\n// When `init()` is called with a `BufferSource`, it skips all `fetch()` logic\r\n// and calls `WebAssembly.instantiate(bytes, imports)` directly \u2014 exactly what\r\n// we need inside a srcdoc iframe.\r\n//\r\n// The `.wasm` import is rewritten by esbuild's `binary` loader (configured in\r\n// build.mjs) into an inlined `Uint8Array`, so this module pulls in roughly\r\n// ~1 MB of base64-decoded bytes at runtime but issues zero network requests.\r\n//\r\n// We import `pkg.web/brotli_wasm.js` directly (instead of the package root\r\n// `index.web.js`) because the root entry eagerly calls `init()` with no\r\n// argument, which would trigger an implicit `fetch('brotli_wasm_bg.wasm')`\r\n// resolved against the srcdoc document's \"null\" base URL and hard-fail.\r\nimport initBrotliWasm, { decompress as brotliWasmDecompress } from 'brotli-wasm/pkg.web/brotli_wasm.js';\r\n// esbuild inlines this as a Uint8Array thanks to `loader: { '.wasm': 'binary' }`.\r\nimport brotliWasmBytes from 'brotli-wasm/pkg.web/brotli_wasm_bg.wasm';\r\n\r\nlet brotliWasmInitPromise: Promise<void> | null = null;\r\n// Becomes `true` once `initBrotliWasm` has resolved. After this flips we may\r\n// invoke `brotliWasmDecompress()` synchronously (the decompress entrypoint\r\n// itself is a pure WASM call \u2014 only the module instantiation is async).\r\nlet brotliWasmReady = false;\r\n\r\nfunction ensureBrotliWasmInitialized(): Promise<void> {\r\n if (!brotliWasmInitPromise) {\r\n brotliWasmInitPromise = (async () => {\r\n // The `.wasm` binary loader gives us a Uint8Array at module init; re-\r\n // slice the underlying buffer so the wasm instantiator sees an exact\r\n // BufferSource. (Some bundlers hand out a shared buffer with a nonzero\r\n // byteOffset which confuses WebAssembly.instantiate.)\r\n const src = brotliWasmBytes as unknown as Uint8Array;\r\n const copy = new Uint8Array(src.byteLength);\r\n copy.set(src);\r\n await initBrotliWasm(copy);\r\n brotliWasmReady = true;\r\n nativeConsole.log(\r\n `[wx-compat][brotli] brotli-wasm initialised (${(copy.byteLength / 1024).toFixed(1)} KB inlined)`,\r\n );\r\n })().catch((e) => {\r\n // Reset so a later call can retry (and also surface a useful error).\r\n brotliWasmInitPromise = null;\r\n brotliWasmReady = false;\r\n nativeConsole.error('[wx-compat][brotli] brotli-wasm init failed:', e);\r\n throw e;\r\n });\r\n }\r\n return brotliWasmInitPromise;\r\n}\r\n\r\nasync function decompressWithBrotliWasm(bytes: Uint8Array): Promise<Uint8Array> {\r\n await ensureBrotliWasmInitialized();\r\n return brotliWasmDecompress(bytes);\r\n}\r\n\r\n// \u2500\u2500\u2500 Preheat / sync API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Fire-and-forget warm-up. Call this once during wx-compat install so that\r\n * by the time the game code starts issuing synchronous reads against `.br`\r\n * assets the WASM decoder is already instantiated and `decompressBrotliSync`\r\n * can succeed. Safe to call multiple times \u2014 init is memoised. Errors are\r\n * swallowed (and logged) because init failure is handled gracefully by the\r\n * async decoder paths which fall back to `DecompressionStream('br')`.\r\n */\r\nexport function preheatBrotliWasm(): void {\r\n // Intentionally no await \u2014 run in background.\r\n ensureBrotliWasmInitialized().catch(() => {\r\n /* already logged by ensureBrotliWasmInitialized */\r\n });\r\n}\r\n\r\n/** Whether `decompressBrotliSync` can be called without failing. */\r\nexport function isBrotliWasmReady(): boolean {\r\n return brotliWasmReady;\r\n}\r\n\r\n/**\r\n * Synchronously decompress a brotli-compressed buffer using `brotli-wasm`.\r\n *\r\n * IMPORTANT: This only works AFTER `preheatBrotliWasm()` (or any prior\r\n * `decompressBrotli()` call) has resolved. Before that point the wasm module\r\n * is still being instantiated and this function will return `null`. Callers\r\n * are expected to treat `null` as \"cannot decode synchronously, surface the\r\n * error the same way the platform would\".\r\n *\r\n * The native `DecompressionStream('br')` path is NOT available here because\r\n * it streams asynchronously \u2014 only the wasm decoder is truly sync.\r\n */\r\nexport function decompressBrotliSync(\r\n input: ArrayBuffer | Uint8Array,\r\n): Uint8Array | null {\r\n if (!brotliWasmReady) return null;\r\n try {\r\n const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);\r\n return brotliWasmDecompress(bytes);\r\n } catch (e) {\r\n nativeConsole.warn('[wx-compat][brotli] sync decode failed:', e);\r\n return null;\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Decompress a brotli-compressed buffer. Picks the most efficient decoder\r\n * available at runtime. Throws only when *both* the native\r\n * `DecompressionStream('br')` and the `brotli-wasm` fallback fail.\r\n */\r\nexport async function decompressBrotli(\r\n input: ArrayBuffer | Uint8Array,\r\n): Promise<Uint8Array> {\r\n const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);\r\n\r\n const native = await decompressWithNativeStream(bytes);\r\n if (native) return native;\r\n\r\n return decompressWithBrotliWasm(bytes);\r\n}\r\n\r\n/**\r\n * Check whether a VFS path looks like a brotli-compressed asset. Used by\r\n * callers that need to decide \"read-through\" vs \"decode-first\" without\r\n * touching the bytes themselves.\r\n */\r\nexport function isBrotliPath(path: string): boolean {\r\n return typeof path === 'string' && path.toLowerCase().endsWith('.br');\r\n}\r\n\r\n// Wire our sync decoder into virtual-fs so `getDecodedArrayBufferSync` can\r\n// transparently decompress `.br` entries once the wasm module is warm. We do\r\n// this here (rather than via a direct import in virtual-fs) to keep the two\r\n// modules decoupled at import time and avoid pulling the ~1 MB inlined wasm\r\n// blob into virtual-fs's module graph when nobody needs it.\r\nprimeBrotliSync((bytes) => decompressBrotliSync(bytes));\r\n", "/**\r\n * Virtual in-memory file system for the preview runtime.\r\n *\r\n * Motivation\r\n * ----------\r\n * The preview historically assumed a real HTTP static server: every\r\n * `require()`, `loadSubpackage()` and asset fetch was translated to an\r\n * `http://host/<path>` URL. That assumption does not hold in two new\r\n * scenarios the npm package must now support:\r\n *\r\n * 1. \"directory\" mode running inside a React-Native WebView, where the game\r\n * files have already been decompressed locally (or are being streamed in\r\n * from the native side) and there is no HTTP server at all. The caller\r\n * wants to hand us the file bytes directly.\r\n *\r\n * 2. \"wxapkg\" mode where the npm package itself downloads the wxapkg binary\r\n * (main package / subpackages / plugins) from a CDN and unpacks it in\r\n * the browser \u2014 no server-side unpacking, no static file serving.\r\n *\r\n * In both cases we need a shared place to stash \"decoded\" file bytes that\r\n * the existing synchronous module loader (and asset XHR/fetch) can read from\r\n * without doing any real network I/O.\r\n *\r\n * Design\r\n * ------\r\n * - `put()` / `putText()` register a file under a normalized absolute path\r\n * (always leading \"/\", no double slashes, always `.js`/`.json`/... kept).\r\n * - `getText()` / `getArrayBuffer()` read it back synchronously.\r\n * - `resolveGameUrl()` (in url-utils.ts) checks VFS first: if the file is\r\n * present, it returns a `wxvfs:<path>` pseudo-URL instead of the usual\r\n * `http://...`. The patched XHR / fetch / native-XHR layer recognises\r\n * `wxvfs:` and reads from memory. This keeps the 'sync XHR' invariant\r\n * that module-compat.ts depends on \u2014 `new XHR(); open(...,false); send();`\r\n * still works, it just hits memory.\r\n *\r\n * Why not real `blob:` URLs?\r\n * --------------------------\r\n * Safari forbids `responseType='blob'` on synchronous XHR, and some browsers\r\n * do not allow synchronous XHR on `blob:` URLs at all when the current\r\n * document origin is \"null\" (which is exactly our srcdoc iframe's situation).\r\n * A plain `wxvfs:` scheme that we intercept ourselves is the only reliable\r\n * path.\r\n */\r\n\r\nimport { nativeConsole } from './native-globals';\r\n\r\n// \u2500\u2500\u2500 Entry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ninterface VfsEntry {\r\n /** Raw bytes. Text entries are decoded on demand. */\r\n data: Uint8Array;\r\n /** Whether the entry is known to be UTF-8 text (.js / .json / etc.). */\r\n isText: boolean;\r\n}\r\n\r\nconst entries = new Map<string, VfsEntry>();\r\n\r\n// \u2500\u2500\u2500 Path normalisation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Normalise a logical file path so that all callers (put / has / get,\r\n * and the resolveGameUrl detector) agree on a single canonical form.\r\n *\r\n * Rules:\r\n * - Always prefixed with exactly one '/'.\r\n * - No '..' / '.' segments (they are collapsed).\r\n * - No empty segments (repeated '/' collapsed to one).\r\n * - Case-sensitive \u2014 matching WeChat real-device behaviour on iOS/Android.\r\n *\r\n * Examples:\r\n * \"game.js\" \u2192 \"/game.js\"\r\n * \"/game.js\" \u2192 \"/game.js\"\r\n * \"subpackages/a//x.js\" \u2192 \"/subpackages/a/x.js\"\r\n * \"./src/../game.js\" \u2192 \"/game.js\"\r\n */\r\nexport function normalizePath(path: string): string {\r\n if (!path) return '/';\r\n const parts = path.split('/');\r\n const stack: string[] = [];\r\n for (const seg of parts) {\r\n if (!seg || seg === '.') continue;\r\n if (seg === '..') {\r\n stack.pop();\r\n continue;\r\n }\r\n stack.push(seg);\r\n }\r\n return '/' + stack.join('/');\r\n}\r\n\r\n// \u2500\u2500\u2500 Mutators \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Store arbitrary bytes at `path` (will be treated as binary). */\r\nexport function put(path: string, data: ArrayBuffer | Uint8Array): void {\r\n const key = normalizePath(path);\r\n const u8 = data instanceof Uint8Array\r\n ? data\r\n : new Uint8Array(data);\r\n entries.set(key, { data: u8, isText: isTextPath(key) });\r\n // A caller just overwrote the raw bytes of a `.br` path \u2014 any cached\r\n // \"decoded\" state for that path is now stale and must be forgotten.\r\n decodedPaths.delete(key);\r\n}\r\n\r\n/** Store a text file (js/json/html/\u2026) at `path`. */\r\nexport function putText(path: string, text: string): void {\r\n const key = normalizePath(path);\r\n const u8 = new TextEncoder().encode(text);\r\n entries.set(key, { data: u8, isText: true });\r\n decodedPaths.delete(key);\r\n}\r\n\r\n/**\r\n * Accept anything the host might hand us (string | ArrayBuffer | Uint8Array |\r\n * number[]) and store it under `path`. This is the workhorse for preload\r\n * pools delivered via postMessage where JSON-ish structures are common.\r\n */\r\nexport function putAny(\r\n path: string,\r\n data: string | ArrayBuffer | Uint8Array | number[],\r\n): void {\r\n if (typeof data === 'string') {\r\n putText(path, data);\r\n } else if (data instanceof Uint8Array) {\r\n put(path, data);\r\n } else if (Array.isArray(data)) {\r\n put(path, new Uint8Array(data));\r\n } else {\r\n put(path, data);\r\n }\r\n}\r\n\r\n/** Merge a whole batch of files at once. */\r\nexport function putBatch(\r\n files: Record<string, string | ArrayBuffer | Uint8Array | number[]>,\r\n): void {\r\n for (const [p, d] of Object.entries(files)) putAny(p, d);\r\n}\r\n\r\n/** Remove a single entry (mainly used by tests). */\r\nexport function remove(path: string): boolean {\r\n const key = normalizePath(path);\r\n decodedPaths.delete(key);\r\n return entries.delete(key);\r\n}\r\n\r\n/** Wipe the whole VFS. */\r\nexport function clear(): void {\r\n entries.clear();\r\n decodedPaths.clear();\r\n}\r\n\r\n// \u2500\u2500\u2500 Accessors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport function has(path: string): boolean {\r\n return entries.has(normalizePath(path));\r\n}\r\n\r\nexport function getEntry(path: string): VfsEntry | undefined {\r\n return entries.get(normalizePath(path));\r\n}\r\n\r\nexport function getText(path: string): string | undefined {\r\n const e = entries.get(normalizePath(path));\r\n if (!e) return undefined;\r\n return new TextDecoder().decode(e.data);\r\n}\r\n\r\nexport function getArrayBuffer(path: string): ArrayBuffer | undefined {\r\n const e = entries.get(normalizePath(path));\r\n if (!e) return undefined;\r\n // Return a fresh ArrayBuffer view so callers can freely transfer it.\r\n const copy = new Uint8Array(e.data.byteLength);\r\n copy.set(e.data);\r\n return copy.buffer;\r\n}\r\n\r\n// \u2500\u2500\u2500 Brotli-aware async accessor \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n//\r\n// wxapkg archives happily carry `.wasm.br`, `.data.br` etc. straight into the\r\n// VFS as their raw brotli payload. On the real device the platform fs / HTTP\r\n// stack transparently decompresses them before the engine sees the bytes; in\r\n// our preview we have to do it ourselves because `wxvfs:` short-circuits the\r\n// network path. `getDecodedArrayBuffer()` is the single place where that\r\n// decoding happens \u2014 it's awaited by `wxResourceFetch` and the VFS fetch\r\n// shim so callers receive WASM / texture / audio data in its canonical form.\r\n//\r\n// The decoded buffer is memoised back into the VFS under the same path (as a\r\n// fresh opaque entry) so subsequent reads of the *same* `.br` asset skip the\r\n// decoder entirely. We also expose `getDecodedArrayBufferSync` for the rare\r\n// caller (sync XHR) that just wants a best-effort read without triggering\r\n// decoding \u2014 it returns `undefined` for `.br` entries that haven't been\r\n// decoded yet, leaving the caller to fall back or surface a 404-ish error.\r\n\r\n// Tracks in-flight decode promises keyed by normalised path so concurrent\r\n// readers share a single decode pass.\r\nconst decodeInflight = new Map<string, Promise<ArrayBuffer | undefined>>();\r\n\r\nfunction isBrotliKey(key: string): boolean {\r\n return key.toLowerCase().endsWith('.br');\r\n}\r\n\r\n/**\r\n * Like `getArrayBuffer`, but transparently decompresses `.br` entries using\r\n * the shared brotli decoder. The decoded bytes are cached back into the VFS\r\n * so subsequent reads (sync or async) return the plain payload immediately.\r\n *\r\n * Returns `undefined` when the path is not in the VFS.\r\n */\r\nexport async function getDecodedArrayBuffer(\r\n path: string,\r\n): Promise<ArrayBuffer | undefined> {\r\n const key = normalizePath(path);\r\n const e = entries.get(key);\r\n if (!e) return undefined;\r\n\r\n // Non-brotli entries: fast path, identical to `getArrayBuffer`.\r\n if (!isBrotliKey(key)) {\r\n const copy = new Uint8Array(e.data.byteLength);\r\n copy.set(e.data);\r\n return copy.buffer;\r\n }\r\n\r\n // Already-decoded: the entry still lives under the `.br` key but its bytes\r\n // are the decompressed payload. We flag this by storing `isText=false` AND\r\n // replacing `.data` with the decoded bytes in-place (see below), which\r\n // makes the \"decoded\" check equivalent to \"first byte is NOT cb/ce/\u2026 AND\r\n // is not a brotli stream anymore\". Rather than sniff bytes here, we use\r\n // the `decoded` map below as the single source of truth.\r\n if (decodedPaths.has(key)) {\r\n const copy = new Uint8Array(e.data.byteLength);\r\n copy.set(e.data);\r\n return copy.buffer;\r\n }\r\n\r\n // Coalesce concurrent decodes of the same path.\r\n const existing = decodeInflight.get(key);\r\n if (existing) return existing;\r\n\r\n // Import lazily to avoid a cycle between `virtual-fs` and `brotli-decoder`\r\n // (the latter imports from native-globals, which is fine, but keeping the\r\n // import dynamic documents the dependency direction clearly).\r\n const decodingPromise = (async () => {\r\n const { decompressBrotli } = await import('./brotli-decoder');\r\n const decoded = await decompressBrotli(e.data);\r\n // Swap the VFS entry's bytes for the decoded payload so every future\r\n // reader \u2014 sync or async \u2014 gets the plain buffer at zero cost.\r\n entries.set(key, { data: decoded, isText: false });\r\n decodedPaths.add(key);\r\n const out = new Uint8Array(decoded.byteLength);\r\n out.set(decoded);\r\n nativeConsole.log(\r\n `[wx-compat][vfs] brotli-decoded ${key} (${e.data.byteLength} \u2192 ${decoded.byteLength} bytes)`,\r\n );\r\n return out.buffer;\r\n })()\r\n .catch((err) => {\r\n nativeConsole.error(`[wx-compat][vfs] failed to brotli-decode ${key}:`, err);\r\n return undefined;\r\n })\r\n .finally(() => {\r\n decodeInflight.delete(key);\r\n });\r\n\r\n decodeInflight.set(key, decodingPromise);\r\n return decodingPromise;\r\n}\r\n\r\n// Paths whose VFS entry has been replaced with its decompressed payload.\r\n// Kept separate from the `entries` map so we don't have to sniff bytes to\r\n// tell \"decoded\" apart from \"still compressed\".\r\nconst decodedPaths = new Set<string>();\r\n\r\n/**\r\n * Synchronous accessor that only succeeds for plain (non-brotli) entries or\r\n * `.br` entries whose decompressed payload is already cached. Returns\r\n * `undefined` otherwise \u2014 the caller is expected to be a sync XHR path that\r\n * cannot await and would rather surface a 404 than block.\r\n *\r\n * When the `.br` entry has not been decoded yet we try one last shot via\r\n * `decompressBrotliSync()` (wasm, pre-warmed at wx-compat install time). If\r\n * that succeeds we mutate the entry in place so subsequent readers \u2014 sync\r\n * or async \u2014 get the plain payload for free. If the wasm module is not yet\r\n * ready we bail out and return `undefined`, matching the old behaviour.\r\n */\r\nexport function getDecodedArrayBufferSync(path: string): ArrayBuffer | undefined {\r\n const key = normalizePath(path);\r\n const e = entries.get(key);\r\n if (!e) return undefined;\r\n if (isBrotliKey(key) && !decodedPaths.has(key)) {\r\n // Static import would create a cycle (brotli-decoder \u2192 native-globals \u2192\r\n // \u2026) \u2014 use the bundler-friendly dynamic access through the module cache\r\n // set up by the eager import in the async accessor above. In practice\r\n // `decompressBrotli()` has virtually always been called at least once\r\n // before the sync path is hit (the warm-up runs during installGlobalShims).\r\n const decoded = _trySyncBrotliDecode(e.data);\r\n if (!decoded) return undefined;\r\n entries.set(key, { data: decoded, isText: false });\r\n decodedPaths.add(key);\r\n\r\n const copy = new Uint8Array(decoded.byteLength);\r\n copy.set(decoded);\r\n return copy.buffer;\r\n }\r\n const copy = new Uint8Array(e.data.byteLength);\r\n copy.set(e.data);\r\n return copy.buffer;\r\n}\r\n\r\n// Lazy getter for the sync brotli decoder. Resolved through a module-scope\r\n// holder set by `primeBrotliSync()` so that TS / esbuild doesn't create a\r\n// hard cycle between virtual-fs and brotli-decoder at module-init time.\r\nlet _brotliSyncFn: ((bytes: Uint8Array) => Uint8Array | null) | null = null;\r\n\r\n/**\r\n * Injected by `brotli-decoder` once it has loaded. Keeps the two modules\r\n * decoupled at import time while still enabling a sync fallback in the VFS.\r\n */\r\nexport function primeBrotliSync(fn: (bytes: Uint8Array) => Uint8Array | null): void {\r\n _brotliSyncFn = fn;\r\n}\r\n\r\nfunction _trySyncBrotliDecode(bytes: Uint8Array): Uint8Array | null {\r\n if (!_brotliSyncFn) return null;\r\n try {\r\n return _brotliSyncFn(bytes);\r\n } catch (e) {\r\n nativeConsole.warn('[wx-compat][vfs] sync brotli decode threw:', e);\r\n return null;\r\n }\r\n}\r\n\r\nexport function listPaths(): string[] {\r\n return Array.from(entries.keys());\r\n}\r\n\r\nexport function size(): number {\r\n return entries.size;\r\n}\r\n\r\n// \u2500\u2500\u2500 Heuristics \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst TEXT_EXTS = new Set(['.js', '.mjs', '.cjs', '.json', '.txt', '.html', '.htm', '.css', '.svg', '.wxml', '.wxss', '.xml']);\r\n\r\nfunction isTextPath(path: string): boolean {\r\n const dot = path.lastIndexOf('.');\r\n if (dot < 0) return false;\r\n return TEXT_EXTS.has(path.substring(dot).toLowerCase());\r\n}\r\n\r\n// \u2500\u2500\u2500 wxvfs: pseudo-URL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Scheme used to route fetch / XHR targets back to the VFS. */\r\nexport const WXVFS_SCHEME = 'wxvfs:';\r\n\r\nexport function isVfsUrl(url: string): boolean {\r\n return typeof url === 'string' && url.startsWith(WXVFS_SCHEME);\r\n}\r\n\r\n/** Build a `wxvfs:<normalizedPath>` url. */\r\nexport function toVfsUrl(path: string): string {\r\n return WXVFS_SCHEME + normalizePath(path);\r\n}\r\n\r\n/** Extract the normalised path from a `wxvfs:<path>` url. */\r\nexport function fromVfsUrl(url: string): string {\r\n if (!isVfsUrl(url)) return url;\r\n return normalizePath(url.substring(WXVFS_SCHEME.length));\r\n}\r\n\r\n// \u2500\u2500\u2500 Networking policy \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nlet networkFallbackEnabled = true;\r\n\r\n/**\r\n * Control whether the resolver is allowed to fall back to the real network\r\n * (`assetBaseUrl`) when a path is NOT in the VFS. When `false` the runtime\r\n * operates fully offline: missing files resolve to a `wxvfs:` url that the\r\n * sync XHR / fetch interceptor reports as HTTP 404.\r\n *\r\n * RN / directory-preload use-cases typically want this turned off \u2014 all\r\n * required files should have been registered by the caller ahead of time.\r\n */\r\nexport function setNetworkFallback(enabled: boolean): void {\r\n networkFallbackEnabled = !!enabled;\r\n}\r\n\r\nexport function isNetworkFallbackEnabled(): boolean {\r\n return networkFallbackEnabled;\r\n}\r\n\r\n// \u2500\u2500\u2500 Bootstrap: drain any preload pool installed BEFORE wx-compat loaded \u2500\u2500\r\n//\r\n// iframe-manager may stash a preload pool on `window.__wxPreloadedFiles`\r\n// synchronously in <script>, i.e. before the wx-compat IIFE runs. We pick\r\n// it up here so that the very first XHR in the sandbox can already hit\r\n// memory. Multiple install sites are supported so `preloadFiles()` APIs\r\n// added later can pipeline into the same pool.\r\n\r\ninterface PreloadPoolGlobal {\r\n __wxPreloadedFiles?: Record<string, string | ArrayBuffer | Uint8Array | number[]>;\r\n __wxNetworkFallback?: boolean;\r\n}\r\n\r\nexport function drainPreloadPoolFromWindow(): void {\r\n const win = window as unknown as PreloadPoolGlobal;\r\n const pool = win.__wxPreloadedFiles;\r\n if (pool && typeof pool === 'object') {\r\n const n = Object.keys(pool).length;\r\n if (n > 0) {\r\n putBatch(pool);\r\n nativeConsole.log(\r\n `[wx-compat][vfs] Drained ${n} preloaded file(s) from window.__wxPreloadedFiles: ` +\r\n Object.keys(pool).slice(0, 8).join(', ') +\r\n (n > 8 ? ` (+${n - 8} more)` : ''),\r\n );\r\n }\r\n // Free the global \u2014 we've copied the bytes into our Map.\r\n delete win.__wxPreloadedFiles;\r\n }\r\n if (typeof win.__wxNetworkFallback === 'boolean') {\r\n setNetworkFallback(win.__wxNetworkFallback);\r\n nativeConsole.log(`[wx-compat][vfs] networkFallback=${win.__wxNetworkFallback}`);\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 Runtime install-time API (for postMessage driven preloading) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n//\r\n// The host page (iframe-manager) may want to ship additional files AFTER\r\n// wx-compat has already initialised (for example, when `preloadFiles()` is\r\n// called imperatively on the preview instance). Expose a window-level\r\n// installer that iframe-manager can postMessage into.\r\n\r\nexport function installRuntimeHooks(): void {\r\n const win = window as unknown as Record<string, unknown>;\r\n win.__wxVfsPut = (path: string, data: ArrayBuffer | Uint8Array | string) => putAny(path, data);\r\n win.__wxVfsPutBatch = (files: Record<string, string | ArrayBuffer | Uint8Array | number[]>) => putBatch(files);\r\n win.__wxVfsHas = (path: string) => has(path);\r\n win.__wxVfsListPaths = () => listPaths();\r\n win.__wxVfsSetNetworkFallback = (enabled: boolean) => setNetworkFallback(enabled);\r\n}\r\n", "/**\r\n * Native Browser Globals \u2014 captured at module load time.\r\n *\r\n * Cocos web-adapter.js (and similar game adapters) overwrite browser globals\r\n * with their own implementations that internally call wx.* APIs. Our wx.*\r\n * implementations use the native browser APIs, which creates circular calls:\r\n *\r\n * web-adapter Image() \u2192 wx.createImage() \u2192 new Image() \u2192 web-adapter Image() \u2192 \u2026\r\n *\r\n * To break the cycle, we capture every native constructor / factory at import\r\n * time \u2014 BEFORE any game adapter can overwrite them. All other wx-compat\r\n * modules MUST import from here instead of using the global directly.\r\n *\r\n * This module is imported first by wx-compat.ts (before any game code runs),\r\n * so the captures happen before web-adapter.js can touch anything.\r\n */\r\n\r\nimport { fromVfsUrl, getDecodedArrayBuffer as vfsGetDecoded, has as vfsHas } from './virtual-fs';\r\n\r\n// \u2500\u2500\u2500 DOM Constructors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Native Image constructor \u2014 used by wx.createImage() */\r\nexport const NativeImage = window.Image;\r\n\r\n/** Native Audio constructor \u2014 used by createInnerAudioContext() */\r\nexport const NativeAudio = window.Audio;\r\n\r\n/** Native XMLHttpRequest \u2014 used by synchronous module loading (require) */\r\nexport const NativeXMLHttpRequest = window.XMLHttpRequest;\r\n\r\n/** Native WebSocket \u2014 used by wx.connectSocket() */\r\nexport const NativeWebSocket = window.WebSocket;\r\n\r\n// \u2500\u2500\u2500 Animation Frame \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Native requestAnimationFrame \u2014 used by our wrapped version */\r\nexport const nativeRequestAnimationFrame = window.requestAnimationFrame.bind(window);\r\n\r\n/** Native cancelAnimationFrame \u2014 used by our wrapped version */\r\nexport const nativeCancelAnimationFrame = window.cancelAnimationFrame.bind(window);\r\n\r\n// \u2500\u2500\u2500 Document Methods \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Native document.createElement \u2014 used for canvas/img/audio creation */\r\nexport const nativeCreateElement = document.createElement.bind(document);\r\n\r\n// \u2500\u2500\u2500 Web Audio \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Native AudioContext constructor */\r\nexport const NativeAudioContext =\r\n window.AudioContext || (window as unknown as Record<string, unknown>).webkitAudioContext as typeof AudioContext;\r\n\r\n// \u2500\u2500\u2500 Performance \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Native performance object */\r\nexport const nativePerformance = window.performance;\r\n\r\n// \u2500\u2500\u2500 Fetch / Network \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Native fetch \u2014 in case an adapter replaces it */\r\nexport const nativeFetch = window.fetch.bind(window);\r\n\r\n/**\r\n * VFS-aware fetch for *resource* requests.\r\n *\r\n * Same signature as the native `fetch`, but handles our private `wxvfs:` scheme:\r\n * when the resolved URL points into the in-memory virtual file system, the\r\n * bytes are served as a synthetic same-origin `Response` without hitting the\r\n * network \u2014 mirroring `patchFetchBaseUrl`'s behavior on `window.fetch`.\r\n *\r\n * Why: `nativeFetch` is captured *before* any patch, so it doesn't know about\r\n * `wxvfs:`. Any call site that does `nativeFetch(resolveGameUrl(...))` is a\r\n * latent bug, because `resolveGameUrl` can (and does) return `wxvfs:\u2026` when\r\n * the asset lives in the VFS. Call sites that load *game resources* (wasm,\r\n * package file reads, subpackage scripts, wxapkg-internal assets, \u2026) must go\r\n * through this wrapper instead of `nativeFetch` directly.\r\n *\r\n * Real HTTP use cases (wx.request / wx.downloadFile / CDN proxy) should keep\r\n * using `nativeFetch` \u2014 they never produce wxvfs: URLs and benefit from the\r\n * bypass.\r\n */\r\nexport async function wxResourceFetch(\r\n input: string | URL,\r\n init?: RequestInit,\r\n): Promise<Response> {\r\n const url = typeof input === 'string' ? input : input.toString();\r\n\r\n // Fast path: wxvfs: \u2192 serve from in-memory VFS as a synthetic Response.\r\n // `.br`-compressed entries are transparently decoded via getDecodedArrayBuffer\r\n // so callers (WXWebAssembly.instantiate, XHR for large binary assets, etc.)\r\n // receive the canonical uncompressed bytes without any HTTP layer help.\r\n //\r\n // Defensive `.br` fallback: resolveGameUrl already retargets missing\r\n // `foo.wasm` to `foo.wasm.br` when available, but direct callers that\r\n // hand us a pre-built `wxvfs:` url (bypassing the resolver) still benefit\r\n // from the same transparent rewrite here.\r\n if (url.startsWith('wxvfs:')) {\r\n const originalPath = fromVfsUrl(url);\r\n let path = originalPath;\r\n let rewroteToBr = false;\r\n if (!vfsHas(path)) {\r\n if (!path.toLowerCase().endsWith('.br') && vfsHas(path + '.br')) {\r\n path = path + '.br';\r\n rewroteToBr = true;\r\n nativeConsole.log(\r\n `[wx-compat][wxResourceFetch] .br fallback: ${originalPath} \u2192 ${path}`,\r\n );\r\n } else {\r\n nativeConsole.warn(\r\n `[wx-compat][wxResourceFetch] VFS miss for ${originalPath} (no .br variant either) \u2192 404`,\r\n );\r\n return new Response(null, { status: 404, statusText: 'Not Found' });\r\n }\r\n }\r\n const buffer = await vfsGetDecoded(path);\r\n if (!buffer) {\r\n // Either the entry vanished between the `has` check and the decode,\r\n // or brotli decoding failed. Both surface as 502 so callers can\r\n // distinguish \"missing\" (404) from \"broken payload\".\r\n nativeConsole.error(\r\n `[wx-compat][wxResourceFetch] VFS decode failed for ${path}` +\r\n (rewroteToBr ? ` (original request: ${originalPath})` : '') +\r\n ' \u2192 502',\r\n );\r\n return new Response(null, { status: 502, statusText: 'VFS decode failed' });\r\n }\r\n nativeConsole.log(\r\n `[wx-compat][wxResourceFetch] VFS hit ${path}${rewroteToBr ? ` (via .br fallback from ${originalPath})` : ''}` +\r\n ` \u2192 ${buffer.byteLength} bytes`,\r\n );\r\n return new Response(buffer, {\r\n status: 200,\r\n statusText: 'OK',\r\n headers: { 'Content-Length': String(buffer.byteLength) },\r\n });\r\n }\r\n\r\n return nativeFetch(url, init);\r\n}\r\n\r\n// \u2500\u2500\u2500 Console \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Native console methods \u2014 saved before log interception patches them */\r\nexport const nativeConsole = {\r\n log: console.log.bind(console),\r\n warn: console.warn.bind(console),\r\n error: console.error.bind(console),\r\n debug: console.debug.bind(console),\r\n info: console.info.bind(console),\r\n};\r\n\r\n// \u2500\u2500\u2500 Native Document Reference \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Full native document \u2014 preserved for internal use after cleanGlobals strips document properties */\r\nexport const nativeDocument = document;\r\n\r\n/** Native document.body \u2014 captured before cleanup */\r\nexport const nativeBody = document.body;\r\n\r\n/** Native document.getElementById \u2014 for internal DOM queries */\r\nexport const nativeGetElementById = document.getElementById.bind(document);\r\n\r\n/** Native document.addEventListener \u2014 for internal event listeners */\r\nexport const nativeDocAddEventListener = document.addEventListener.bind(document);\r\n\r\n/** Native document.removeEventListener \u2014 for internal event listeners */\r\nexport const nativeDocRemoveEventListener = document.removeEventListener.bind(document);\r\n\r\n// \u2500\u2500\u2500 IndexedDB \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Native indexedDB \u2014 captured before cleanGlobals() removes it from window.\r\n * Used by FileSystemManager for persistent file storage. */\r\nexport const nativeIndexedDB: IDBFactory = window.indexedDB;\r\n\r\n// \u2500\u2500\u2500 Storage \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Native localStorage \u2014 captured before cleanGlobals() deletes it from window.\r\n * The wx storage shim (storage.ts) uses this alias so it keeps working after\r\n * the sandbox removes window.localStorage from game code's reach. */\r\nexport const nativeLocalStorage: Storage = window.localStorage;\r\n\r\n// \u2500\u2500\u2500 Location \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Native location \u2014 captured before cleanGlobals() may remove window.location */\r\nexport const nativeLocation: Location = window.location;\r\n\r\n// \u2500\u2500\u2500 Device Pixel Ratio \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Native devicePixelRatio \u2014 captured before cleanGlobals() may remove it */\r\nexport const nativeDevicePixelRatio: number = window.devicePixelRatio || 2;\r\n\r\n// \u2500\u2500\u2500 Document Fonts \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Native document.fonts \u2014 captured before cleanGlobals() strips document */\r\nexport const nativeDocFonts: FontFaceSet = document.fonts;\r\n\r\n// \u2500\u2500\u2500 Document Head & Body \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Native document.head \u2014 captured before cleanup */\r\nexport const nativeHead: HTMLHeadElement = document.head;\r\n\r\n// \u2500\u2500\u2500 __global Escape Hatch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * WeChat DevTools uses window.__global to preserve native browser APIs\r\n * that system code needs after the sandbox cleanup removes them from window/document.\r\n *\r\n * We set this up early so cleanGlobals() preserves it, and our internal code\r\n * (mouse-touch emulation, canvas centering, logger) can access full DOM via __global.\r\n */\r\nconst win = window as unknown as Record<string, unknown>;\r\nif (!win.__global) {\r\n win.__global = {};\r\n}\r\nconst __global = win.__global as Record<string, unknown>;\r\n__global.document = document;\r\n__global.window = window;\r\n__global.localStorage = window.localStorage;\r\n__global.location = window.location;\r\n// Use the simulated DPR from window.__wxDevicePixelRatio (set by game-host.ts)\r\n// or URL params (legacy mode) instead of the browser's native devicePixelRatio.\r\n// This ensures __global.devicePixelRatio matches the selected device's DPR\r\n// (e.g. 3 for iPhone 12 Pro).\r\nconst _wxDpr = typeof (window as unknown as Record<string, unknown>).__wxDevicePixelRatio === 'number'\r\n ? ((window as unknown as Record<string, unknown>).__wxDevicePixelRatio as number)\r\n : 0;\r\nconst _dprParam = _wxDpr || parseFloat(new URLSearchParams(window.location.search).get('dpr') || '0');\r\n__global.devicePixelRatio = (_dprParam > 0 && _dprParam <= 5) ? _dprParam : (window.devicePixelRatio || 2);\r\nconsole.log(\r\n `[wx-compat][native-globals] __global.devicePixelRatio=${__global.devicePixelRatio}` +\r\n ` | URL dpr param=${_dprParam} | native window.devicePixelRatio=${window.devicePixelRatio}`\r\n);\r\n", "/**\r\n * URL utilities for resolving relative paths in srcdoc iframes.\r\n *\r\n * In srcdoc iframes, the document origin is \"null\", so relative paths like\r\n * \"/game.json\" or \"background.png\" resolve to vscode-webview:// which returns 403.\r\n * This module provides a helper to rewrite them to the game server's absolute URL.\r\n *\r\n * The base URL is provided by the plugin layer via `window.__wxAssetBaseUrl`,\r\n * which is set from the `assetBaseUrl` option in GameLoaderConfig.\r\n *\r\n * Virtual FS short-circuit\r\n * ------------------------\r\n * When the preview is run with an in-memory file pool (either preloaded by\r\n * the host, or populated by unpacking wxapkg binaries at runtime), the\r\n * resolver first checks the VFS. On a hit it returns `wxvfs:<normalizedPath>`,\r\n * a pseudo-url that the patched XHR / fetch interceptors know how to serve\r\n * synchronously from memory. This is how we make the classic synchronous\r\n * `require()` path work with no HTTP server at all.\r\n */\r\n\r\nimport { isVfsUrl, has as vfsHas, toVfsUrl, isNetworkFallbackEnabled } from './virtual-fs';\r\nimport { NativeXMLHttpRequest, nativeConsole } from './native-globals';\r\n\r\n/**\r\n * Resolve a relative URL against the game server base URL, or redirect it\r\n * to the in-memory VFS when applicable.\r\n *\r\n * Returns the original URL unchanged if it's already absolute\r\n * (http/https/blob/data/wxfile/wxvfs).\r\n */\r\nexport function resolveGameUrl(url: string): string {\r\n if (!url) return url;\r\n // Already absolute \u2014 no rewriting needed\r\n if (url.startsWith('http://') || url.startsWith('https://') ||\r\n url.startsWith('blob:') || url.startsWith('data:') ||\r\n url.startsWith('wxfile://') || isVfsUrl(url)) {\r\n return url;\r\n }\r\n\r\n // 1. VFS short-circuit: if the requested path is in the virtual FS, route\r\n // to a `wxvfs:` url so the native-XHR / fetch interceptors can read it\r\n // from memory without touching the network.\r\n //\r\n // We only take this branch when the path actually exists in the VFS.\r\n // Misses still go to the normal network path below (preserving the\r\n // legacy remote-static-server behaviour for mixed setups).\r\n //\r\n // \u2500\u2500 Transparent `.br` fallback \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // wxapkg archives often ship `foo.wasm` / `foo.data` as their brotli-\r\n // compressed counterparts `foo.wasm.br` / `foo.data.br`. The engine\r\n // itself requests the *uncompressed* filename (it has no knowledge\r\n // of the on-disk compression), so a strict `vfsHas(path)` check\r\n // misses even though the bytes are actually available under the\r\n // `.br` key. We recover transparently here and point the pseudo-URL\r\n // at the `.br` entry; `wxResourceFetch` \u2192 `getDecodedArrayBuffer`\r\n // will run the brotli decoder and hand the canonical uncompressed\r\n // bytes back to the caller.\r\n const normalized = url.startsWith('/') ? url : '/' + url;\r\n if (vfsHas(normalized)) {\r\n return toVfsUrl(normalized);\r\n }\r\n if (!normalized.toLowerCase().endsWith('.br') && vfsHas(normalized + '.br')) {\r\n\r\n return toVfsUrl(normalized + '.br');\r\n }\r\n\r\n // 2. No VFS hit: consult assetBaseUrl as before.\r\n const win = window as Record<string, unknown>;\r\n const baseUrl = win.__wxAssetBaseUrl as string | undefined;\r\n if (!baseUrl) {\r\n // 3. No baseUrl either. If the host has opted into \"offline\" mode (no\r\n // network fallback), synthesise a wxvfs url anyway so the XHR\r\n // interceptor will 404 instead of returning vscode-webview://...\r\n // which confuses error reporting.\r\n if (!isNetworkFallbackEnabled()) {\r\n nativeConsole.warn(\r\n `[wx-compat][resolveGameUrl] VFS miss + no baseUrl + offline: will 404 ${normalized}`,\r\n );\r\n return toVfsUrl(normalized);\r\n }\r\n return url;\r\n }\r\n // Strip leading slash for paths like \"/game.json\" since baseUrl ends with \"/\"\r\n if (url.startsWith('/')) {\r\n return baseUrl + url.substring(1);\r\n }\r\n return baseUrl + url;\r\n}\r\n\r\n// \u2500\u2500\u2500 Game Manifest Loading \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Minimal shape of the game manifest we care about. Both `app-config.json`\r\n * (wxapkg-decoded output) and `game.json` (raw source layout) carry the same\r\n * top-level fields that wx-compat needs:\r\n * - `deviceOrientation`\r\n * - `subPackages` (some exports also spell it `subpackages`)\r\n * - plugin table, spelled `plugins` in game.json and `gamePlugins` in\r\n * app-config.json.\r\n */\r\nexport interface GameManifest {\r\n deviceOrientation?: string;\r\n subPackages?: Array<{ name: string; root: string }>;\r\n subpackages?: Array<{ name: string; root: string }>;\r\n plugins?: Record<string, unknown>;\r\n gamePlugins?: Record<string, unknown>;\r\n [key: string]: unknown;\r\n}\r\n\r\n/** Cached manifest across callers within a single srcdoc iframe lifetime. */\r\nlet cachedManifest: GameManifest | null = null;\r\nlet manifestLoaded = false;\r\n\r\n/**\r\n * Synchronously load the game manifest. Tries in order:\r\n *\r\n * 1. `/app-config.json` \u2014 produced when a wxapkg is unpacked (either\r\n * preloaded into the VFS by the host, or unpacked client-side by\r\n * wxapkg-loader). This is the *canonical* manifest in wxapkg mode:\r\n * there is NO `game.json` in a decoded wxapkg \u2014 the information has\r\n * been split into `app-config.json` + `app-service.js`.\r\n * 2. `/game.json` \u2014 legacy source-directory mode where the game is\r\n * served straight out of an unpacked project (e.g. the static dev\r\n * server in demos/). Kept for backwards compatibility.\r\n *\r\n * Both paths go through `resolveGameUrl()`, so when the file is available\r\n * in the VFS (which it always is in wxapkg mode after preload), the\r\n * synchronous XHR is served directly from memory via the `wxvfs:` scheme.\r\n * Only when the VFS has neither does a real network request fire.\r\n *\r\n * Results (including \"not found\") are cached for the lifetime of the\r\n * srcdoc so plugin-compat and module-compat can call this freely.\r\n */\r\nexport function loadGameManifest(): GameManifest | null {\r\n if (manifestLoaded) return cachedManifest;\r\n manifestLoaded = true;\r\n\r\n const tryFetch = (path: string): GameManifest | null => {\r\n try {\r\n const xhr = new NativeXMLHttpRequest();\r\n xhr.open('GET', resolveGameUrl(path), false);\r\n xhr.send();\r\n if (xhr.status === 200) {\r\n return JSON.parse(xhr.responseText) as GameManifest;\r\n }\r\n } catch (e) {\r\n nativeConsole.warn(`[wx-compat] Failed to load ${path}:`, e);\r\n }\r\n return null;\r\n };\r\n\r\n // Prefer app-config.json: this is the file you actually have in wxapkg\r\n // mode. game.json only exists in legacy raw-source deployments.\r\n cachedManifest = tryFetch('/app-config.json');\r\n if (cachedManifest) {\r\n nativeConsole.log('[wx-compat] Loaded manifest from /app-config.json');\r\n return cachedManifest;\r\n }\r\n cachedManifest = tryFetch('/game.json');\r\n if (cachedManifest) {\r\n nativeConsole.log('[wx-compat] Loaded manifest from /game.json');\r\n return cachedManifest;\r\n }\r\n nativeConsole.warn('[wx-compat] No game manifest found (tried app-config.json and game.json)');\r\n return null;\r\n}\r\n\r\n/**\r\n * Reset the manifest cache. Called when the game is reloaded / swapped so\r\n * the next call re-fetches from the (possibly new) VFS.\r\n */\r\nexport function resetGameManifestCache(): void {\r\n cachedManifest = null;\r\n manifestLoaded = false;\r\n}\r\n", "/**\r\n * Shared constants for the wx-compat layer.\r\n *\r\n * Device dimensions are read from:\r\n * 1. window.__wxDevice* globals (injected by game-host.ts in srcdoc iframe mode)\r\n * 2. URL query params (?w=390&h=844&dpr=2) as fallback (legacy / standalone mode)\r\n * 3. Default: iPhone SE (375\u00D7667, dpr=2) if neither source provides valid values.\r\n *\r\n * DEVICE is a mutable object so that dimensions can be swapped at runtime\r\n * (e.g. when auto-detecting landscape orientation from game.json).\r\n */\r\n\r\nimport { nativeLocation, nativeDevicePixelRatio } from './native-globals';\r\n\r\n// Read from window.__wxDevice* globals first (set by game-host.ts before wx-compat loads)\r\nconst _win = window as unknown as Record<string, unknown>;\r\nconst _gw = typeof _win.__wxDeviceWidth === 'number' ? (_win.__wxDeviceWidth as number) : 0;\r\nconst _gh = typeof _win.__wxDeviceHeight === 'number' ? (_win.__wxDeviceHeight as number) : 0;\r\nconst _gdpr = typeof _win.__wxDevicePixelRatio === 'number' ? (_win.__wxDevicePixelRatio as number) : 0;\r\n\r\n// Fallback: URL query params (for standalone / legacy usage)\r\nconst _params = new URLSearchParams(nativeLocation.search);\r\nconst _pw = _gw || parseInt(_params.get('w') || '0', 10);\r\nconst _ph = _gh || parseInt(_params.get('h') || '0', 10);\r\nconst _pdpr = _gdpr || parseFloat(_params.get('dpr') || '0');\r\n\r\n/**\r\n * Mutable device configuration object.\r\n * All code should use DEVICE.width / DEVICE.height / DEVICE.pixelRatio\r\n * instead of the old DEVICE_WIDTH / DEVICE_HEIGHT / DEVICE_PIXEL_RATIO constants.\r\n *\r\n * Call DEVICE.swapDimensions() to swap width and height at runtime\r\n * (used by auto orientation detection when landscape is detected).\r\n */\r\nexport const DEVICE = {\r\n width: (_pw > 0 && _pw < 4096) ? _pw : 375,\r\n height: (_ph > 0 && _ph < 4096) ? _ph : 667,\r\n pixelRatio: (_pdpr > 0 && _pdpr <= 5) ? _pdpr : nativeDevicePixelRatio,\r\n\r\n /**\r\n * Swap width and height in-place.\r\n * Called when landscape orientation is detected in auto mode.\r\n */\r\n swapDimensions() {\r\n const tmp = this.width;\r\n this.width = this.height;\r\n this.height = tmp;\r\n },\r\n};\r\n\r\nexport const URL_PARAMS = _params;\r\n", "/**\r\n * Minimal, zero-dependency ZIP archive parser used by FileSystemManager.unzip().\r\n *\r\n * Supports:\r\n * - Method 0 (store, no compression)\r\n * - Method 8 (DEFLATE) via the browser's native DecompressionStream('deflate-raw')\r\n *\r\n * Not supported (will throw on encounter):\r\n * - ZIP64 (archives > 4 GiB, or > 65535 entries)\r\n * - Encrypted entries\r\n * - Other compression methods (bzip2, LZMA, \u2026) \u2014 rarely used in mini-game bundles.\r\n *\r\n * The parser is deliberately small and forgiving: it walks the End-of-Central-\r\n * Directory record \u2192 Central Directory \u2192 Local File Headers, exactly the path\r\n * that mini-game CDN-hosted resource packs follow. No CRC validation is\r\n * performed (matches the lenient behavior of WeChat's real unzip).\r\n *\r\n * Reference: PKWARE APPNOTE.TXT, section 4 (ZIP format).\r\n */\r\n\r\n// \u2500\u2500\u2500 Magic numbers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst EOCD_SIGNATURE = 0x06054b50; // \"PK\\5\\6\"\r\nconst CENTRAL_DIR_SIGNATURE = 0x02014b50; // \"PK\\1\\2\"\r\nconst LOCAL_FILE_SIGNATURE = 0x04034b50; // \"PK\\3\\4\"\r\n\r\nexport interface ZipEntry {\r\n /** Unix-style path from the archive (may include trailing \"/\" for directories). */\r\n name: string;\r\n /** True if this is a directory entry (no data, name ends with \"/\"). */\r\n isDir: boolean;\r\n /** Decompressed file bytes. Empty ArrayBuffer for directories. */\r\n data: ArrayBuffer;\r\n}\r\n\r\n/**\r\n * Read a little-endian 32-bit unsigned integer.\r\n */\r\nfunction readU32LE(view: DataView, offset: number): number {\r\n return view.getUint32(offset, true);\r\n}\r\n\r\n/**\r\n * Read a little-endian 16-bit unsigned integer.\r\n */\r\nfunction readU16LE(view: DataView, offset: number): number {\r\n return view.getUint16(offset, true);\r\n}\r\n\r\n/**\r\n * Locate the End-of-Central-Directory (EOCD) record. It lives at the tail of\r\n * the archive; the minimum EOCD is 22 bytes (no comment), and the optional\r\n * archive comment may extend it by up to 65535 bytes. We scan backwards from\r\n * the end looking for the signature.\r\n */\r\nfunction findEocd(view: DataView): number {\r\n const len = view.byteLength;\r\n const minEocd = 22;\r\n if (len < minEocd) {\r\n throw new Error('unzip:fail file too small to be a zip archive');\r\n }\r\n // Search the last 64 KiB + EOCD size\r\n const searchStart = Math.max(0, len - minEocd - 0xffff);\r\n for (let i = len - minEocd; i >= searchStart; i--) {\r\n if (readU32LE(view, i) === EOCD_SIGNATURE) {\r\n return i;\r\n }\r\n }\r\n throw new Error('unzip:fail end of central directory record not found');\r\n}\r\n\r\n/**\r\n * Decompress a DEFLATE-raw byte range using the browser's native\r\n * DecompressionStream. Throws a descriptive error if the platform lacks the\r\n * API (very old runtimes) \u2014 mini-game preview always runs in modern Chromium\r\n * so this should never happen in practice.\r\n */\r\nasync function inflateRaw(bytes: Uint8Array): Promise<Uint8Array> {\r\n const DS = (globalThis as unknown as {\r\n DecompressionStream?: typeof DecompressionStream;\r\n }).DecompressionStream;\r\n if (typeof DS !== 'function') {\r\n throw new Error(\r\n 'unzip:fail DecompressionStream is not available in this runtime; cannot decode DEFLATE entry',\r\n );\r\n }\r\n // Wrap in a Response so we can use arrayBuffer() to drain the stream.\r\n const stream = new DS('deflate-raw');\r\n const blob = new Blob([bytes]);\r\n const decompressed = blob.stream().pipeThrough(stream);\r\n const out = await new Response(decompressed).arrayBuffer();\r\n return new Uint8Array(out);\r\n}\r\n\r\n/**\r\n * Parse a ZIP archive and return all entries with their decompressed bytes.\r\n *\r\n * Implementation notes:\r\n * - We iterate the Central Directory (CD), which gives the authoritative\r\n * list of entries and where each Local File Header lives. The CD entries\r\n * also carry the compressed/uncompressed sizes, which are sometimes zero\r\n * in the Local File Header when the streaming \"data descriptor\" flag is\r\n * set (bit 3 of general purpose flag).\r\n * - For each entry we seek to its LFH, skip the variable-length name/extra\r\n * fields, then read `compressedSize` bytes starting at that offset.\r\n */\r\nexport async function unzipArchive(archive: ArrayBuffer): Promise<ZipEntry[]> {\r\n const view = new DataView(archive);\r\n const bytes = new Uint8Array(archive);\r\n\r\n const eocdOffset = findEocd(view);\r\n const totalEntries = readU16LE(view, eocdOffset + 10);\r\n const cdSize = readU32LE(view, eocdOffset + 12);\r\n const cdOffset = readU32LE(view, eocdOffset + 16);\r\n\r\n // Sanity \u2014 ZIP64 signals \"0xffff / 0xffffffff\" to mean \"look at zip64 EOCD\".\r\n if (totalEntries === 0xffff || cdSize === 0xffffffff || cdOffset === 0xffffffff) {\r\n throw new Error('unzip:fail zip64 archives are not supported in the preview runtime');\r\n }\r\n\r\n const entries: ZipEntry[] = [];\r\n let cursor = cdOffset;\r\n\r\n for (let i = 0; i < totalEntries; i++) {\r\n if (readU32LE(view, cursor) !== CENTRAL_DIR_SIGNATURE) {\r\n throw new Error(\r\n `unzip:fail invalid central directory record #${i} at offset ${cursor}`,\r\n );\r\n }\r\n const gpFlag = readU16LE(view, cursor + 8);\r\n const method = readU16LE(view, cursor + 10);\r\n const compressedSize = readU32LE(view, cursor + 20);\r\n const uncompressedSize = readU32LE(view, cursor + 24);\r\n const nameLen = readU16LE(view, cursor + 28);\r\n const extraLen = readU16LE(view, cursor + 30);\r\n const commentLen = readU16LE(view, cursor + 32);\r\n const localHeaderOffset = readU32LE(view, cursor + 42);\r\n\r\n if (gpFlag & 0x0001) {\r\n throw new Error(`unzip:fail encrypted entries are not supported`);\r\n }\r\n\r\n const nameStart = cursor + 46;\r\n // Archive filenames are UTF-8 when bit 11 of the GP flag is set, otherwise\r\n // CP437 in theory. Almost every modern producer writes UTF-8; we decode\r\n // as UTF-8 either way (mini-game packers always emit UTF-8).\r\n const name = new TextDecoder('utf-8', { fatal: false }).decode(\r\n bytes.subarray(nameStart, nameStart + nameLen),\r\n );\r\n\r\n cursor = nameStart + nameLen + extraLen + commentLen;\r\n\r\n // \u2500\u2500 Read the Local File Header to find where the file data starts \u2500\u2500\r\n if (readU32LE(view, localHeaderOffset) !== LOCAL_FILE_SIGNATURE) {\r\n throw new Error(\r\n `unzip:fail invalid local file header for \"${name}\" at offset ${localHeaderOffset}`,\r\n );\r\n }\r\n const lfhNameLen = readU16LE(view, localHeaderOffset + 26);\r\n const lfhExtraLen = readU16LE(view, localHeaderOffset + 28);\r\n const dataStart = localHeaderOffset + 30 + lfhNameLen + lfhExtraLen;\r\n\r\n const isDir = name.endsWith('/');\r\n let data: ArrayBuffer;\r\n if (isDir || uncompressedSize === 0) {\r\n data = new ArrayBuffer(0);\r\n } else if (method === 0) {\r\n // Store \u2014 no compression. Slice to get a standalone ArrayBuffer.\r\n data = archive.slice(dataStart, dataStart + compressedSize);\r\n } else if (method === 8) {\r\n // DEFLATE\r\n const raw = bytes.subarray(dataStart, dataStart + compressedSize);\r\n const inflated = await inflateRaw(raw);\r\n // Slice to get a fresh, standalone ArrayBuffer sized exactly to the\r\n // inflated bytes. `inflated.buffer` may have a larger backing store\r\n // (DecompressionStream often over-allocates), and Uint8Array.byteOffset\r\n // is not guaranteed to be 0, so we must clip with explicit bounds.\r\n // `ArrayBuffer.slice` performs a single copy internally \u2014 cheaper than\r\n // allocating a new Uint8Array and calling `set()` ourselves.\r\n data = inflated.buffer.slice(\r\n inflated.byteOffset,\r\n inflated.byteOffset + inflated.byteLength,\r\n );\r\n } else {\r\n throw new Error(\r\n `unzip:fail unsupported compression method ${method} for entry \"${name}\"`,\r\n );\r\n }\r\n\r\n entries.push({ name, isDir, data });\r\n }\r\n\r\n return entries;\r\n}\r\n", "/**\r\n * FileSystemManager \u2014 IndexedDB-backed virtual file system for WeChat Mini Games.\r\n *\r\n * Provides wx.getFileSystemManager() which returns a singleton FileSystemManager\r\n * instance supporting both sync and async versions of all file operations.\r\n *\r\n * Architecture:\r\n * - IndexedDB \"wx_fs\" database as persistent backend\r\n * - In-memory Map as synchronous cache (loaded from IDB on init)\r\n * - All sync methods operate on the memory cache\r\n * - All async methods operate on IDB and update the cache\r\n * - Root directories \"wxfile://usr\" and \"wxfile://tmp\" are pre-created\r\n *\r\n * Reference: WeChat Mini Game FileSystemManager documentation\r\n * https://developers.weixin.qq.com/minigame/dev/api/file/FileSystemManager.html\r\n */\r\n\r\nimport { NativeXMLHttpRequest, nativeFetch, nativeIndexedDB, wxResourceFetch } from './native-globals';\r\nimport { resolveGameUrl } from './url-utils';\r\nimport { decompressBrotli, decompressBrotliSync } from './brotli-decoder';\r\nimport { unzipArchive } from './zip-decoder';\r\nimport { has as vfsHas, listPaths as vfsListPaths, size as vfsSize } from './virtual-fs';\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype AnyCallback = (...args: any[]) => void;\r\n\r\ninterface CallbackOpts {\r\n success?: AnyCallback;\r\n fail?: AnyCallback;\r\n complete?: AnyCallback;\r\n [key: string]: unknown;\r\n}\r\n\r\n// \u2500\u2500\u2500 Constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst DB_NAME = 'wx_fs';\r\nconst DB_VERSION = 1;\r\nconst STORE_NAME = 'files';\r\n\r\nconst USR_ROOT = 'wxfile://usr';\r\nconst TMP_ROOT = 'wxfile://tmp';\r\nexport { TMP_ROOT };\r\n\r\n// \u2500\u2500\u2500 File Entry Type \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ninterface FileEntry {\r\n path: string;\r\n data: ArrayBuffer | null; // null for directories\r\n size: number;\r\n isDir: boolean;\r\n createTime: number;\r\n modifyTime: number;\r\n}\r\n\r\n// \u2500\u2500\u2500 Stats Object \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nclass Stats {\r\n mode: number;\r\n size: number;\r\n lastAccessedTime: number;\r\n lastModifiedTime: number;\r\n private _isDir: boolean;\r\n\r\n constructor(entry: FileEntry) {\r\n this._isDir = entry.isDir;\r\n this.mode = entry.isDir ? 0o40755 : 0o100644;\r\n this.size = entry.size;\r\n this.lastAccessedTime = entry.modifyTime;\r\n this.lastModifiedTime = entry.modifyTime;\r\n }\r\n\r\n isDirectory(): boolean { return this._isDir; }\r\n isFile(): boolean { return !this._isDir; }\r\n}\r\n\r\n// \u2500\u2500\u2500 Path Utilities \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Normalize path: remove trailing slash, resolve . and .. */\r\nfunction normalizePath(filePath: string): string {\r\n // Keep the wxfile:// prefix\r\n let p = filePath;\r\n if (p.endsWith('/') && p !== USR_ROOT && p !== TMP_ROOT) {\r\n p = p.slice(0, -1);\r\n }\r\n return p;\r\n}\r\n\r\n/** Get the parent directory path */\r\nfunction parentPath(filePath: string): string {\r\n const idx = filePath.lastIndexOf('/');\r\n if (idx <= 0) return '';\r\n const parent = filePath.slice(0, idx);\r\n // Don't go above root\r\n if (parent === 'wxfile:/' || parent === 'wxfile:') return '';\r\n return parent;\r\n}\r\n\r\n/** Get the filename from a path */\r\nfunction basename(filePath: string): string {\r\n const idx = filePath.lastIndexOf('/');\r\n return idx >= 0 ? filePath.slice(idx + 1) : filePath;\r\n}\r\n\r\n/** Check if path is under a valid root */\r\nfunction isValidPath(filePath: string): boolean {\r\n return filePath.startsWith(USR_ROOT) || filePath.startsWith(TMP_ROOT);\r\n}\r\n\r\n/** Check if a path refers to a package-internal file (not wxfile://) */\r\nfunction isPackagePath(filePath: string): boolean {\r\n return !filePath.startsWith('wxfile://') && !filePath.startsWith('blob:');\r\n}\r\n\r\n/**\r\n * Heuristic: does `buf` look like a raw brotli stream (i.e. still needs\r\n * decompression) rather than an already-decoded payload?\r\n *\r\n * Brotli itself has no fixed magic bytes \u2014 its header is a variable-length\r\n * bit field \u2014 so we detect by *exclusion*: if the prefix matches a known\r\n * plaintext / binary file magic (wasm, PNG, JPEG, JSON, XML, plain text,\r\n * UTF-8 BOM, \u2026) we assume the caller has already decompressed data. Any\r\n * buffer that slips past these filters is re-decoded; `decompressBrotli`\r\n * itself will throw if the input turns out not to be brotli, which the\r\n * caller swallows and falls back to the raw bytes.\r\n *\r\n * This is only used by readCompressedFile / readCompressedFileSync to guard\r\n * against double-decoding (the VFS already auto-decodes `.br` entries on\r\n * their first async read \u2014 see virtual-fs.ts).\r\n */\r\nfunction _looksLikeBrotli(buf: ArrayBuffer): boolean {\r\n if (!buf || buf.byteLength < 2) return false;\r\n const u = new Uint8Array(buf);\r\n const b0 = u[0];\r\n const b1 = u[1];\r\n const b2 = u[2];\r\n const b3 = u[3];\r\n\r\n // WebAssembly: 00 61 73 6d\r\n if (b0 === 0x00 && b1 === 0x61 && b2 === 0x73 && b3 === 0x6d) return false;\r\n // PNG: 89 50 4e 47\r\n if (b0 === 0x89 && b1 === 0x50 && b2 === 0x4e && b3 === 0x47) return false;\r\n // JPEG: ff d8 ff\r\n if (b0 === 0xff && b1 === 0xd8 && b2 === 0xff) return false;\r\n // GIF: 47 49 46 38\r\n if (b0 === 0x47 && b1 === 0x49 && b2 === 0x46 && b3 === 0x38) return false;\r\n // ZIP / DOCX / etc: 50 4b 03 04\r\n if (b0 === 0x50 && b1 === 0x4b && (b2 === 0x03 || b2 === 0x05 || b2 === 0x07)) return false;\r\n // UTF-8 BOM\r\n if (b0 === 0xef && b1 === 0xbb && b2 === 0xbf) return false;\r\n // Plain ASCII text / JSON / XML: first byte is printable ASCII or common whitespace\r\n if ((b0 >= 0x20 && b0 <= 0x7e) || b0 === 0x09 || b0 === 0x0a || b0 === 0x0d) return false;\r\n\r\n // Anything else \u2014 likely still a brotli stream. Typical first bytes are\r\n // 0x1b/0x8b/0xa1/0xc1/0xcb/0xce/0xd5 depending on window size & header,\r\n // which all fall through to here.\r\n return true;\r\n}\r\n\r\n/**\r\n * Fetch a package-internal file from the static server via synchronous XHR.\r\n * In the preview environment, all game files are served by the static server\r\n * at the root URL. For example, 'assets/internal/config.e6604.json' is\r\n * available at '/assets/internal/config.e6604.json'.\r\n */\r\nfunction fetchPackageFileSync(filePath: string): ArrayBuffer {\r\n // blob: URLs must be fetched directly, not prefixed with '/'.\r\n // For package paths, resolve against the game asset base URL so the request\r\n // goes to the local static server instead of the iframe's document origin\r\n // (which in srcdoc iframes is null / vscode-webview:// and returns 403).\r\n const normalizedForVfs = '/' + filePath.replace(/^\\/+/, '');\r\n const url = filePath.startsWith('blob:')\r\n ? filePath\r\n : resolveGameUrl(normalizedForVfs);\r\n const xhr = new NativeXMLHttpRequest();\r\n xhr.open('GET', url, false); // synchronous\r\n // NOTE: Cannot set responseType on synchronous XHR in browser environments.\r\n // Use overrideMimeType to prevent text encoding corruption, then manually\r\n // convert the binary string to ArrayBuffer.\r\n xhr.overrideMimeType('text/plain; charset=x-user-defined');\r\n xhr.send();\r\n if (xhr.status === 200) {\r\n const text = xhr.responseText;\r\n // \u2500\u2500 Defensive: static dev servers with SPA fallback return HTML 200 for\r\n // missing files. Treat ONLY real `text/html` responses from network\r\n // (http/https) as 404s \u2014 never touch VFS (`wxvfs:`) hits (whose payload\r\n // is authoritative: e.g. plist assets legitimately start with '<?xml').\r\n const isHttp = url.startsWith('http://') || url.startsWith('https://');\r\n if (isHttp) {\r\n const ctype = (xhr.getResponseHeader('content-type') || '').toLowerCase();\r\n if (ctype.includes('text/html') && text.length > 0 && text.charCodeAt(0) === 0x3c) {\r\n // eslint-disable-next-line no-console\r\n console.warn(\r\n `[wx-compat][fs-sync] HTML fallback from HTTP for \"${filePath}\" url=\"${url}\" ctype=\"${ctype}\"`,\r\n );\r\n throw new Error(`readFile:fail no such file or directory, open ${filePath}`);\r\n }\r\n }\r\n const buf = new ArrayBuffer(text.length);\r\n const view = new Uint8Array(buf);\r\n for (let i = 0; i < text.length; i++) {\r\n view[i] = text.charCodeAt(i) & 0xff;\r\n }\r\n // eslint-disable-next-line no-console\r\n console.log(\r\n `[wx-compat][fs-sync][DIAG] \"${filePath}\" url=\"${url}\" \u2192 ${buf.byteLength} bytes`,\r\n );\r\n return buf;\r\n }\r\n // eslint-disable-next-line no-console\r\n console.warn(\r\n `[wx-compat][fs-sync] failed \"${filePath}\" url=\"${url}\" status=${xhr.status}`,\r\n );\r\n throw new Error(`readFile:fail no such file or directory, open ${filePath}`);\r\n}\r\n\r\n/**\r\n * Fetch a package-internal file from the static server via async fetch.\r\n * Uses nativeFetch captured before cleanGlobals() removes window.fetch.\r\n */\r\nasync function fetchPackageFileAsync(filePath: string): Promise<ArrayBuffer> {\r\n // blob: URLs must be fetched directly, not prefixed with '/'.\r\n // For package paths, resolve against the game asset base URL (see sync variant).\r\n const normalizedForVfs = '/' + filePath.replace(/^\\/+/, '');\r\n const url = filePath.startsWith('blob:')\r\n ? filePath\r\n : resolveGameUrl(normalizedForVfs);\r\n // Use the VFS-aware resource fetcher: resolveGameUrl may return a `wxvfs:`\r\n // url when the file lives in the in-memory VFS, which the plain native\r\n // fetch cannot consume.\r\n const resp = await wxResourceFetch(url);\r\n if (!resp.ok) {\r\n // eslint-disable-next-line no-console\r\n console.warn(\r\n `[wx-compat][fs-async] failed \"${filePath}\" url=\"${url}\" status=${resp.status}`,\r\n );\r\n throw new Error(`readFile:fail no such file or directory, open ${filePath}`);\r\n }\r\n const buf = await resp.arrayBuffer();\r\n // \u2500\u2500 Defensive: SPA static servers return `<!DOCTYPE html>` with 200 +\r\n // text/html for missing files. Treat ONLY real `text/html` responses from\r\n // network (http/https) as 404s \u2014 VFS responses (`wxvfs:`) are\r\n // authoritative and must pass through unchanged (e.g. plist files\r\n // legitimately start with '<?xml').\r\n const isHttp = url.startsWith('http://') || url.startsWith('https://');\r\n if (isHttp && buf.byteLength > 0) {\r\n const ctype = (resp.headers.get('content-type') || '').toLowerCase();\r\n if (ctype.includes('text/html')) {\r\n const firstByte = new Uint8Array(buf, 0, 1)[0];\r\n if (firstByte === 0x3c /* '<' */) {\r\n // eslint-disable-next-line no-console\r\n console.warn(\r\n `[wx-compat][fs-async] HTML fallback from HTTP for \"${filePath}\" url=\"${url}\" ctype=\"${ctype}\"`,\r\n );\r\n throw new Error(`readFile:fail no such file or directory, open ${filePath}`);\r\n }\r\n }\r\n }\r\n // eslint-disable-next-line no-console\r\n console.log(\r\n `[wx-compat][fs-async][DIAG] \"${filePath}\" url=\"${url}\" \u2192 ${buf.byteLength} bytes`,\r\n );\r\n return buf;\r\n}\r\n\r\n// \u2500\u2500\u2500 IndexedDB Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction openDB(): Promise<IDBDatabase> {\r\n return new Promise((resolve, reject) => {\r\n const req = nativeIndexedDB.open(DB_NAME, DB_VERSION);\r\n req.onupgradeneeded = () => {\r\n const db = req.result;\r\n if (!db.objectStoreNames.contains(STORE_NAME)) {\r\n db.createObjectStore(STORE_NAME, { keyPath: 'path' });\r\n }\r\n };\r\n req.onsuccess = () => resolve(req.result);\r\n req.onerror = () => reject(req.error);\r\n });\r\n}\r\n\r\nfunction idbGet(db: IDBDatabase, key: string): Promise<FileEntry | undefined> {\r\n return new Promise((resolve, reject) => {\r\n const tx = db.transaction(STORE_NAME, 'readonly');\r\n const req = tx.objectStore(STORE_NAME).get(key);\r\n req.onsuccess = () => resolve(req.result as FileEntry | undefined);\r\n req.onerror = () => reject(req.error);\r\n });\r\n}\r\n\r\nfunction idbPut(db: IDBDatabase, entry: FileEntry): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const tx = db.transaction(STORE_NAME, 'readwrite');\r\n tx.objectStore(STORE_NAME).put(entry);\r\n tx.oncomplete = () => resolve();\r\n tx.onerror = () => reject(tx.error);\r\n });\r\n}\r\n\r\nfunction idbDelete(db: IDBDatabase, key: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const tx = db.transaction(STORE_NAME, 'readwrite');\r\n tx.objectStore(STORE_NAME).delete(key);\r\n tx.oncomplete = () => resolve();\r\n tx.onerror = () => reject(tx.error);\r\n });\r\n}\r\n\r\nfunction idbGetAll(db: IDBDatabase): Promise<FileEntry[]> {\r\n return new Promise((resolve, reject) => {\r\n const tx = db.transaction(STORE_NAME, 'readonly');\r\n const req = tx.objectStore(STORE_NAME).getAll();\r\n req.onsuccess = () => resolve(req.result as FileEntry[]);\r\n req.onerror = () => reject(req.error);\r\n });\r\n}\r\n\r\n// \u2500\u2500\u2500 Encoding Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction encodeString(str: string): ArrayBuffer {\r\n return new TextEncoder().encode(str).buffer;\r\n}\r\n\r\nfunction decodeBuffer(buf: ArrayBuffer, encoding: string): string {\r\n // Normalize common aliases that real WeChat accepts but TextDecoder may not:\r\n // \"utf8\" \u2192 \"utf-8\" (TextDecoder requires the hyphenated form on some engines)\r\n // \"UTF-8\" \u2192 \"utf-8\" (already fine, but normalize for consistency)\r\n // \"ascii\"/\"latin1\" \u2192 \"windows-1252\" fallback handled by TextDecoder itself\r\n const label = String(encoding || '').trim().toLowerCase();\r\n const normalized =\r\n label === 'utf8' || label === 'utf-8' || label === '' ? 'utf-8' :\r\n label;\r\n try {\r\n return new TextDecoder(normalized).decode(buf);\r\n } catch (e) {\r\n // Last-resort manual UTF-8 decode, so we never fail on valid bytes.\r\n // eslint-disable-next-line no-console\r\n console.warn(\r\n `[wx-compat][decodeBuffer] TextDecoder(\"${normalized}\") threw, falling back to manual UTF-8:`,\r\n e,\r\n );\r\n const bytes = new Uint8Array(buf);\r\n let s = '';\r\n for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);\r\n try { return decodeURIComponent(escape(s)); } catch { return s; }\r\n }\r\n}\r\n\r\nfunction dataToArrayBuffer(data: string | ArrayBuffer): ArrayBuffer {\r\n if (data instanceof ArrayBuffer) return data;\r\n return encodeString(data);\r\n}\r\n\r\nfunction toBase64(buf: ArrayBuffer): string {\r\n const bytes = new Uint8Array(buf);\r\n let binary = '';\r\n for (let i = 0; i < bytes.length; i++) {\r\n binary += String.fromCharCode(bytes[i]);\r\n }\r\n return btoa(binary);\r\n}\r\n\r\n// \u2500\u2500\u2500 FileSystemManager Class \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n//\r\n// IMPORTANT: On real WeChat devices, FileSystemManager methods are native\r\n// bridge functions \u2014 they are effectively standalone functions that do not\r\n// rely on JS `this` binding. Real-world game/plugin code (notably Cocos\r\n// plugin.js's `FileSystem_statSyncCatch` wrapper, and minigamefe `mgp`) often:\r\n// - destructures methods: `const { statSync } = wx.getFileSystemManager()`\r\n// - reassigns methods: `this.statSync = fs.statSync`\r\n// - re-invokes methods via `Function.prototype.apply` with a different\r\n// `this`, or copies the method onto a class instance that sits above\r\n// our prototype in the lookup chain.\r\n//\r\n// None of those patterns care about JS `this` on a real device. If our\r\n// methods access `cache` / `db`, they blow up with the infamous:\r\n// \"Cannot read properties of undefined (reading 'cache')\"\r\n//\r\n// The fix is structural, not a `bind()` patch: keep the single source of\r\n// truth (the in-memory cache and IDB handle) at **module scope** rather than\r\n// on the instance. Every method closes over these module-level variables\r\n// directly, so they work correctly regardless of how `this` is routed.\r\n// This mirrors the native bridge semantics \u2014 functions, not methods.\r\n\r\n// \u2500\u2500\u2500 Module-level singleton state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// Pre-populated with root directories so sync access works before IDB loads.\r\nconst cache: Map<string, FileEntry> = (() => {\r\n const m = new Map<string, FileEntry>();\r\n const now = Date.now();\r\n m.set(USR_ROOT, { path: USR_ROOT, data: null, size: 0, isDir: true, createTime: now, modifyTime: now });\r\n m.set(TMP_ROOT, { path: TMP_ROOT, data: null, size: 0, isDir: true, createTime: now, modifyTime: now });\r\n return m;\r\n})();\r\nlet db: IDBDatabase | null = null;\r\nlet initPromise: Promise<void> | null = null;\r\n\r\nfunction _makeDirEntry(path: string): FileEntry {\r\n const now = Date.now();\r\n return { path, data: null, size: 0, isDir: true, createTime: now, modifyTime: now };\r\n}\r\n\r\nfunction _makeFileEntry(path: string, data: ArrayBuffer): FileEntry {\r\n const now = Date.now();\r\n return { path, data, size: data.byteLength, isDir: false, createTime: now, modifyTime: now };\r\n}\r\n\r\n/** Persist an entry to IDB (fire-and-forget). */\r\nfunction _persist(entry: FileEntry): void {\r\n if (db) {\r\n idbPut(db, entry).catch(() => {});\r\n }\r\n}\r\n\r\n/** Delete from IDB (fire-and-forget). */\r\nfunction _removeFromDB(path: string): void {\r\n if (db) {\r\n idbDelete(db, path).catch(() => {});\r\n }\r\n}\r\n\r\nasync function _initFS(): Promise<void> {\r\n try {\r\n db = await openDB();\r\n const entries = await idbGetAll(db);\r\n for (const entry of entries) {\r\n cache.set(entry.path, entry);\r\n }\r\n // Ensure root dirs exist in IDB\r\n if (!cache.has(USR_ROOT)) {\r\n const entry = _makeDirEntry(USR_ROOT);\r\n cache.set(USR_ROOT, entry);\r\n await idbPut(db, entry);\r\n }\r\n if (!cache.has(TMP_ROOT)) {\r\n const entry = _makeDirEntry(TMP_ROOT);\r\n cache.set(TMP_ROOT, entry);\r\n await idbPut(db, entry);\r\n }\r\n } catch (e) {\r\n console.warn('[wx-compat] FileSystemManager: IndexedDB init failed, using memory-only mode:', e);\r\n }\r\n}\r\n\r\nclass FileSystemManager {\r\n // Proxy these on the instance so any legacy code reading `fs.cache`\r\n // / `fs.db` still sees the module-level singleton state. Methods below\r\n // never read through `this`; they close over the module-level variables.\r\n get cache(): Map<string, FileEntry> { return cache; }\r\n get db(): IDBDatabase | null { return db; }\r\n\r\n constructor() {\r\n // Kick off async IDB load on first construction.\r\n if (!initPromise) {\r\n initPromise = _initFS();\r\n }\r\n\r\n // Defensive: bind every prototype method to `this` and shadow it on the\r\n // instance. This handles legacy callers that destructure methods or\r\n // re-invoke them with a wrong `this`. Combined with the module-scope\r\n // state above, FS calls are robust to any `this` routing.\r\n const proto = Object.getPrototypeOf(this) as Record<string, unknown>;\r\n for (const name of Object.getOwnPropertyNames(proto)) {\r\n if (name === 'constructor') continue;\r\n const desc = Object.getOwnPropertyDescriptor(proto, name);\r\n // Skip getters (cache / db) \u2014 they already route through closure state.\r\n if (desc && typeof desc.value === 'function') {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (this as any)[name] = (desc.value as (...args: unknown[]) => unknown).bind(this);\r\n }\r\n }\r\n }\r\n\r\n // \u2500\u2500\u2500 Access \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n accessSync(path: string): void {\r\n const normalizedPath = normalizePath(path);\r\n // Check memory cache first\r\n if (cache.has(normalizedPath)) return;\r\n // For package-internal paths, check static server via sync HEAD request.\r\n // Resolve against the game asset base URL so srcdoc iframes don't hit\r\n // the document origin (which returns 403).\r\n if (isPackagePath(normalizedPath)) {\r\n const url = resolveGameUrl('/' + normalizedPath.replace(/^\\/+/, ''));\r\n const xhr = new NativeXMLHttpRequest();\r\n xhr.open('HEAD', url, false);\r\n xhr.send();\r\n if (xhr.status === 200) return;\r\n }\r\n throw new Error(`access:fail no such file or directory, access ${normalizedPath}`);\r\n }\r\n\r\n access(opts: CallbackOpts & { path: string }): void {\r\n const normalizedPath = normalizePath(opts.path);\r\n // Check memory cache first\r\n if (cache.has(normalizedPath)) {\r\n opts.success?.({ errMsg: 'access:ok' });\r\n opts.complete?.();\r\n return;\r\n }\r\n // For package-internal paths, check static server via async HEAD request.\r\n // Resolve against the game asset base URL (see sync variant).\r\n if (isPackagePath(normalizedPath)) {\r\n wxResourceFetch(resolveGameUrl('/' + normalizedPath.replace(/^\\/+/, '')), { method: 'HEAD' })\r\n .then(resp => {\r\n if (resp.ok) {\r\n opts.success?.({ errMsg: 'access:ok' });\r\n } else {\r\n opts.fail?.({ errMsg: `access:fail no such file or directory, access ${normalizedPath}` });\r\n }\r\n })\r\n .catch(() => {\r\n opts.fail?.({ errMsg: `access:fail no such file or directory, access ${normalizedPath}` });\r\n })\r\n .finally(() => {\r\n opts.complete?.();\r\n });\r\n return;\r\n }\r\n // Not in cache and not a package path\r\n opts.fail?.({ errMsg: `access:fail no such file or directory, access ${normalizedPath}` });\r\n opts.complete?.();\r\n }\r\n\r\n // \u2500\u2500\u2500 Stat \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n statSync(path: string, _recursive?: boolean): Stats {\r\n const normalizedPath = normalizePath(path);\r\n const entry = cache.get(normalizedPath);\r\n if (entry) {\r\n return new Stats(entry);\r\n }\r\n // Package-internal path: probe static server / VFS via sync HEAD to\r\n // discover whether the file exists and get its size. Real WeChat allows\r\n // stat() on package paths, and engines like Laya rely on this.\r\n if (isPackagePath(normalizedPath)) {\r\n const url = resolveGameUrl('/' + normalizedPath.replace(/^\\/+/, ''));\r\n try {\r\n const xhr = new NativeXMLHttpRequest();\r\n xhr.open('HEAD', url, false);\r\n xhr.send();\r\n if (xhr.status === 200) {\r\n const lenStr = xhr.getResponseHeader('content-length');\r\n const size = lenStr ? parseInt(lenStr, 10) || 0 : 0;\r\n const now = Date.now();\r\n return new Stats({\r\n path: normalizedPath,\r\n data: null,\r\n size,\r\n isDir: false,\r\n createTime: now,\r\n modifyTime: now,\r\n });\r\n }\r\n } catch {\r\n // fall through to throw below\r\n }\r\n }\r\n throw new Error(`stat:fail no such file or directory, stat ${normalizedPath}`);\r\n }\r\n\r\n stat(opts: CallbackOpts & { path: string; recursive?: boolean }): void {\r\n const normalizedPath = normalizePath(opts.path);\r\n // Fast path: memory cache hit \u2014 resolve synchronously.\r\n const entry = cache.get(normalizedPath);\r\n if (entry) {\r\n opts.success?.({ stats: new Stats(entry), errMsg: 'stat:ok' });\r\n opts.complete?.();\r\n return;\r\n }\r\n // Package-internal path: use async HEAD to avoid blocking the main\r\n // thread (esp. important for large assets that statSync would block on).\r\n if (isPackagePath(normalizedPath)) {\r\n wxResourceFetch(\r\n resolveGameUrl('/' + normalizedPath.replace(/^\\/+/, '')),\r\n { method: 'HEAD' },\r\n )\r\n .then((resp) => {\r\n if (!resp.ok) {\r\n opts.fail?.({\r\n errMsg: `stat:fail no such file or directory, stat ${normalizedPath}`,\r\n });\r\n return;\r\n }\r\n const lenStr = resp.headers.get('content-length');\r\n const size = lenStr ? parseInt(lenStr, 10) || 0 : 0;\r\n const now = Date.now();\r\n const stats = new Stats({\r\n path: normalizedPath,\r\n data: null,\r\n size,\r\n isDir: false,\r\n createTime: now,\r\n modifyTime: now,\r\n });\r\n opts.success?.({ stats, errMsg: 'stat:ok' });\r\n })\r\n .catch(() => {\r\n opts.fail?.({\r\n errMsg: `stat:fail no such file or directory, stat ${normalizedPath}`,\r\n });\r\n })\r\n .finally(() => {\r\n opts.complete?.();\r\n });\r\n return;\r\n }\r\n opts.fail?.({\r\n errMsg: `stat:fail no such file or directory, stat ${normalizedPath}`,\r\n });\r\n opts.complete?.();\r\n }\r\n\r\n // \u2500\u2500\u2500 Mkdir \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n mkdirSync(dirPath: string, recursive?: boolean): void {\r\n const normalizedPath = normalizePath(dirPath);\r\n if (!isValidPath(normalizedPath)) {\r\n throw new Error(`mkdir:fail invalid path ${normalizedPath}`);\r\n }\r\n\r\n if (cache.has(normalizedPath)) {\r\n throw new Error(`mkdir:fail file already exists, mkdir ${normalizedPath}`);\r\n }\r\n\r\n // Check parent exists\r\n const parent = parentPath(normalizedPath);\r\n if (parent && !cache.has(parent)) {\r\n if (recursive) {\r\n this.mkdirSync(parent, true);\r\n } else {\r\n throw new Error(`mkdir:fail no such file or directory, mkdir ${normalizedPath}`);\r\n }\r\n }\r\n\r\n const entry = _makeDirEntry(normalizedPath);\r\n cache.set(normalizedPath, entry);\r\n _persist(entry);\r\n }\r\n\r\n mkdir(opts: CallbackOpts & { dirPath: string; recursive?: boolean }): void {\r\n try {\r\n this.mkdirSync(opts.dirPath, opts.recursive);\r\n opts.success?.({ errMsg: 'mkdir:ok' });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String((e as Error).message) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n }\r\n\r\n // \u2500\u2500\u2500 Readdir \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n readdirSync(dirPath: string): string[] {\r\n const normalizedPath = normalizePath(dirPath);\r\n const entry = cache.get(normalizedPath);\r\n if (!entry) {\r\n throw new Error(`readdir:fail no such file or directory, readdir ${normalizedPath}`);\r\n }\r\n if (!entry.isDir) {\r\n throw new Error(`readdir:fail not a directory, readdir ${normalizedPath}`);\r\n }\r\n\r\n const prefix = normalizedPath + '/';\r\n const results: string[] = [];\r\n for (const key of cache.keys()) {\r\n if (key.startsWith(prefix)) {\r\n // Only direct children (no nested paths)\r\n const rest = key.slice(prefix.length);\r\n if (!rest.includes('/')) {\r\n results.push(rest);\r\n }\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n readdir(opts: CallbackOpts & { dirPath: string }): void {\r\n try {\r\n const files = this.readdirSync(opts.dirPath);\r\n opts.success?.({ files, errMsg: 'readdir:ok' });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String((e as Error).message) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n }\r\n\r\n // \u2500\u2500\u2500 WriteFile \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n writeFileSync(filePath: string, data: string | ArrayBuffer, encoding?: string): void {\r\n const normalizedPath = normalizePath(filePath);\r\n if (!isValidPath(normalizedPath)) {\r\n throw new Error(`writeFile:fail invalid path ${normalizedPath}`);\r\n }\r\n\r\n // Check parent directory exists\r\n const parent = parentPath(normalizedPath);\r\n if (parent && !cache.has(parent)) {\r\n throw new Error(`writeFile:fail no such file or directory, open ${normalizedPath}`);\r\n }\r\n\r\n const parentEntry = parent ? cache.get(parent) : null;\r\n if (parentEntry && !parentEntry.isDir) {\r\n throw new Error(`writeFile:fail not a directory ${parent}`);\r\n }\r\n\r\n let buf: ArrayBuffer;\r\n if (typeof data === 'string') {\r\n if (encoding === 'base64') {\r\n // Decode base64 string to ArrayBuffer\r\n const binary = atob(data);\r\n const bytes = new Uint8Array(binary.length);\r\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\r\n buf = bytes.buffer;\r\n } else {\r\n buf = encodeString(data);\r\n }\r\n } else {\r\n buf = data;\r\n }\r\n\r\n const entry = _makeFileEntry(normalizedPath, buf);\r\n // Preserve original createTime if file exists\r\n const existing = cache.get(normalizedPath);\r\n if (existing) {\r\n entry.createTime = existing.createTime;\r\n }\r\n cache.set(normalizedPath, entry);\r\n _persist(entry);\r\n }\r\n\r\n writeFile(opts: CallbackOpts & { filePath: string; data: string | ArrayBuffer; encoding?: string }): void {\r\n try {\r\n this.writeFileSync(opts.filePath, opts.data, opts.encoding);\r\n opts.success?.({ errMsg: 'writeFile:ok' });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String((e as Error).message) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n }\r\n\r\n // \u2500\u2500\u2500 ReadFile \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n readFileSync(filePath: string, encoding?: string): string | ArrayBuffer {\r\n const normalizedPath = normalizePath(filePath);\r\n\r\n // For package-internal paths (not wxfile://), fetch from static server\r\n if (isPackagePath(normalizedPath)) {\r\n const data = fetchPackageFileSync(normalizedPath);\r\n // eslint-disable-next-line no-console\r\n console.log(\r\n `[wx-compat][readFileSync][DIAG] path=\"${normalizedPath}\" encoding=\"${encoding ?? ''}\" \u2192 ${\r\n typeof data === 'string' ? `string(${(data as string).length})` : `ArrayBuffer(${(data as ArrayBuffer).byteLength})`\r\n }`,\r\n );\r\n if (encoding) {\r\n if (encoding === 'base64') {\r\n return toBase64(data);\r\n }\r\n return decodeBuffer(data, encoding);\r\n }\r\n return data;\r\n }\r\n\r\n const entry = cache.get(normalizedPath);\r\n if (!entry) {\r\n throw new Error(`readFile:fail no such file or directory, open ${normalizedPath}`);\r\n }\r\n if (entry.isDir) {\r\n throw new Error(`readFile:fail is a directory, open ${normalizedPath}`);\r\n }\r\n\r\n const data = entry.data!;\r\n if (encoding) {\r\n if (encoding === 'base64') {\r\n return toBase64(data);\r\n }\r\n return decodeBuffer(data, encoding);\r\n }\r\n return data;\r\n }\r\n\r\n readFile(opts: CallbackOpts & { filePath: string; encoding?: string }): void {\r\n const normalizedPath = normalizePath(opts.filePath);\r\n\r\n // For package-internal paths (not wxfile://), fetch from static server asynchronously\r\n if (isPackagePath(normalizedPath)) {\r\n fetchPackageFileAsync(normalizedPath)\r\n .then(data => {\r\n let result: string | ArrayBuffer = data;\r\n if (opts.encoding) {\r\n if (opts.encoding === 'base64') {\r\n result = toBase64(data);\r\n } else {\r\n result = decodeBuffer(data, opts.encoding);\r\n }\r\n }\r\n opts.success?.({ data: result, errMsg: 'readFile:ok' });\r\n })\r\n .catch(err => {\r\n // \u2500\u2500 DIAG \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Do NOT swallow the original error. Propagate it to opts.fail so\r\n // the caller (and the console) sees what actually went wrong\r\n // (TextDecoder label errors, brotli decode failure, etc.).\r\n const realMsg = err && (err.message || String(err));\r\n // eslint-disable-next-line no-console\r\n console.error(\r\n `[wx-compat][readFile][ERROR] path=\"${normalizedPath}\" encoding=\"${opts.encoding ?? ''}\" real=`,\r\n err,\r\n );\r\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n opts.fail?.({\r\n errMsg: `readFile:fail ${realMsg || `no such file or directory, open ${normalizedPath}`}`,\r\n });\r\n })\r\n .finally(() => {\r\n opts.complete?.();\r\n });\r\n return;\r\n }\r\n\r\n try {\r\n const data = this.readFileSync(opts.filePath, opts.encoding);\r\n opts.success?.({ data, errMsg: 'readFile:ok' });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String((e as Error).message) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n }\r\n\r\n // \u2500\u2500\u2500 ReadCompressedFile \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n //\r\n // WeChat Mini Game API (available since base library 2.21.1). Reads a\r\n // compressed asset and returns its *decompressed* bytes. The only\r\n // compression currently defined by the platform is brotli ('br').\r\n //\r\n // fs.readCompressedFile({\r\n // filePath: '...',\r\n // compressionAlgorithm: 'br',\r\n // success(res) { res.data /* ArrayBuffer, decompressed */ },\r\n // fail(res) { ... }\r\n // })\r\n //\r\n // const buf = fs.readCompressedFileSync({ filePath, compressionAlgorithm });\r\n //\r\n // Implementation note on the preview runtime\r\n // ------------------------------------------\r\n // The VFS layer (see virtual-fs.ts) already transparently decompresses\r\n // any `.br` entry on its first async read and caches the plain bytes\r\n // back into the entry. So by the time we call readFile() here the buffer\r\n // is usually already plain. We still run a defensive brotli sniff on the\r\n // result and decode a second time when the bytes still look compressed,\r\n // which covers two edge cases:\r\n // 1. The file was served from the plain HTTP static server (not VFS)\r\n // and the dev server did NOT set Content-Encoding: br, so the\r\n // browser never auto-decoded it.\r\n // 2. The caller is reading a user-stored `.br` in wxfile://usr that we\r\n // never preprocess.\r\n\r\n readCompressedFileSync(opts: { filePath: string; compressionAlgorithm: string }): ArrayBuffer {\r\n if (!opts || typeof opts !== 'object') {\r\n throw new Error('readCompressedFile:fail invalid options');\r\n }\r\n if (opts.compressionAlgorithm !== 'br') {\r\n throw new Error(\r\n `readCompressedFile:fail unsupported compressionAlgorithm '${opts.compressionAlgorithm}', only 'br' is supported`,\r\n );\r\n }\r\n const raw = this.readFileSync(opts.filePath) as ArrayBuffer;\r\n const rawBytes = raw.byteLength;\r\n const rawLooksBrotli = _looksLikeBrotli(raw);\r\n // eslint-disable-next-line no-console\r\n console.log(\r\n `[wx-compat][readCompressedFileSync][DIAG] path=\"${opts.filePath}\" algo=${opts.compressionAlgorithm} raw=${rawBytes} looksBrotli=${rawLooksBrotli}`,\r\n );\r\n // If the bytes still look like a brotli stream we try the synchronous\r\n // wasm decoder (warmed up at wx-compat install time). Only when that is\r\n // not yet ready \u2014 wasm instantiation hasn't resolved, or was never\r\n // attempted \u2014 do we surface the original error so the caller can fall\r\n // back to the async `readCompressedFile()` path. The async VFS decode\r\n // path will have run by now in the common case (subpackage preload,\r\n // preheat during installGlobalShims), but this is our last line of\r\n // defence for hosts that call `readCompressedFileSync` very early or\r\n // against files that never went through the async VFS accessor.\r\n if (rawLooksBrotli) {\r\n const decoded = decompressBrotliSync(raw);\r\n if (decoded) {\r\n const out = new Uint8Array(decoded.byteLength);\r\n out.set(decoded);\r\n // eslint-disable-next-line no-console\r\n console.log(\r\n `[wx-compat][readCompressedFileSync][DIAG] path=\"${opts.filePath}\" decoded ${rawBytes} \u2192 ${out.byteLength} bytes`,\r\n );\r\n return out.buffer;\r\n }\r\n throw new Error(\r\n 'readCompressedFileSync:fail brotli data not yet decoded, use readCompressedFile (async) instead',\r\n );\r\n }\r\n // eslint-disable-next-line no-console\r\n console.log(\r\n `[wx-compat][readCompressedFileSync][DIAG] path=\"${opts.filePath}\" returning raw ${rawBytes} bytes (not brotli-looking, pass-through)`,\r\n );\r\n return raw;\r\n }\r\n\r\n readCompressedFile(\r\n opts: CallbackOpts & { filePath: string; compressionAlgorithm: string },\r\n ): void {\r\n if (opts.compressionAlgorithm !== 'br') {\r\n const errMsg = `readCompressedFile:fail unsupported compressionAlgorithm '${opts.compressionAlgorithm}', only 'br' is supported`;\r\n opts.fail?.({ errMsg });\r\n opts.complete?.();\r\n return;\r\n }\r\n\r\n const normalizedPath = normalizePath(opts.filePath);\r\n const loadRaw: Promise<ArrayBuffer> = isPackagePath(normalizedPath)\r\n ? fetchPackageFileAsync(normalizedPath)\r\n : (() => {\r\n const entry = cache.get(normalizedPath);\r\n if (!entry) {\r\n return Promise.reject(\r\n new Error(`readCompressedFile:fail no such file or directory, open ${normalizedPath}`),\r\n );\r\n }\r\n if (entry.isDir) {\r\n return Promise.reject(\r\n new Error(`readCompressedFile:fail is a directory, open ${normalizedPath}`),\r\n );\r\n }\r\n return Promise.resolve(entry.data!);\r\n })();\r\n\r\n loadRaw\r\n .then(async (raw) => {\r\n const rawBytes = raw.byteLength;\r\n const rawLooksBrotli = _looksLikeBrotli(raw);\r\n // eslint-disable-next-line no-console\r\n console.log(\r\n `[wx-compat][readCompressedFile][DIAG] path=\"${normalizedPath}\" algo=${opts.compressionAlgorithm} raw=${rawBytes} looksBrotli=${rawLooksBrotli}`,\r\n );\r\n // Fast path: the VFS (or an earlier reader) already decompressed\r\n // this buffer \u2014 no magic bytes means no work.\r\n if (!rawLooksBrotli) {\r\n // eslint-disable-next-line no-console\r\n console.log(\r\n `[wx-compat][readCompressedFile][DIAG] path=\"${normalizedPath}\" returning raw ${rawBytes} bytes (not brotli-looking, pass-through)`,\r\n );\r\n return raw;\r\n }\r\n const decoded = await decompressBrotli(raw);\r\n // Return a fresh ArrayBuffer (not a view into a larger buffer) to\r\n // match what the WeChat runtime returns to game code.\r\n const out = new Uint8Array(decoded.byteLength);\r\n out.set(decoded);\r\n // eslint-disable-next-line no-console\r\n console.log(\r\n `[wx-compat][readCompressedFile][DIAG] path=\"${normalizedPath}\" decoded ${rawBytes} \u2192 ${out.byteLength} bytes`,\r\n );\r\n return out.buffer;\r\n })\r\n .then((data) => {\r\n opts.success?.({ data, errMsg: 'readCompressedFile:ok' });\r\n })\r\n .catch((e) => {\r\n opts.fail?.({ errMsg: String((e as Error).message || e) });\r\n })\r\n .finally(() => {\r\n opts.complete?.();\r\n });\r\n }\r\n\r\n // \u2500\u2500\u2500 AppendFile \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n appendFileSync(filePath: string, data: string | ArrayBuffer, encoding?: string): void {\r\n const normalizedPath = normalizePath(filePath);\r\n const existing = cache.get(normalizedPath);\r\n\r\n if (existing && existing.isDir) {\r\n throw new Error(`appendFile:fail is a directory, open ${normalizedPath}`);\r\n }\r\n\r\n const newBuf = typeof data === 'string'\r\n ? (encoding === 'base64'\r\n ? (() => { const b = atob(data); const u = new Uint8Array(b.length); for (let i = 0; i < b.length; i++) u[i] = b.charCodeAt(i); return u.buffer; })()\r\n : encodeString(data))\r\n : data;\r\n\r\n if (!existing) {\r\n // Create new file\r\n this.writeFileSync(filePath, newBuf, undefined);\r\n return;\r\n }\r\n\r\n // Append to existing data\r\n const oldBuf = existing.data!;\r\n const merged = new Uint8Array(oldBuf.byteLength + newBuf.byteLength);\r\n merged.set(new Uint8Array(oldBuf), 0);\r\n merged.set(new Uint8Array(newBuf), oldBuf.byteLength);\r\n\r\n const entry = _makeFileEntry(normalizedPath, merged.buffer);\r\n entry.createTime = existing.createTime;\r\n cache.set(normalizedPath, entry);\r\n _persist(entry);\r\n }\r\n\r\n appendFile(opts: CallbackOpts & { filePath: string; data: string | ArrayBuffer; encoding?: string }): void {\r\n try {\r\n this.appendFileSync(opts.filePath, opts.data, opts.encoding);\r\n opts.success?.({ errMsg: 'appendFile:ok' });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String((e as Error).message) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n }\r\n\r\n // \u2500\u2500\u2500 Unlink (delete file) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n unlinkSync(filePath: string): void {\r\n const normalizedPath = normalizePath(filePath);\r\n const entry = cache.get(normalizedPath);\r\n if (!entry) {\r\n throw new Error(`unlink:fail no such file or directory, unlink ${normalizedPath}`);\r\n }\r\n if (entry.isDir) {\r\n throw new Error(`unlink:fail is a directory, unlink ${normalizedPath}`);\r\n }\r\n cache.delete(normalizedPath);\r\n _removeFromDB(normalizedPath);\r\n }\r\n\r\n unlink(opts: CallbackOpts & { filePath: string }): void {\r\n try {\r\n this.unlinkSync(opts.filePath);\r\n opts.success?.({ errMsg: 'unlink:ok' });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String((e as Error).message) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n }\r\n\r\n // \u2500\u2500\u2500 Rmdir \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n rmdirSync(dirPath: string, recursive?: boolean): void {\r\n const normalizedPath = normalizePath(dirPath);\r\n if (normalizedPath === USR_ROOT || normalizedPath === TMP_ROOT) {\r\n throw new Error(`rmdir:fail cannot remove root directory ${normalizedPath}`);\r\n }\r\n\r\n const entry = cache.get(normalizedPath);\r\n if (!entry) {\r\n throw new Error(`rmdir:fail no such file or directory, rmdir ${normalizedPath}`);\r\n }\r\n if (!entry.isDir) {\r\n throw new Error(`rmdir:fail not a directory, rmdir ${normalizedPath}`);\r\n }\r\n\r\n const children = this.readdirSync(normalizedPath);\r\n if (children.length > 0 && !recursive) {\r\n throw new Error(`rmdir:fail directory not empty, rmdir ${normalizedPath}`);\r\n }\r\n\r\n if (recursive) {\r\n // Delete all descendants\r\n const prefix = normalizedPath + '/';\r\n const keysToDelete: string[] = [];\r\n for (const key of cache.keys()) {\r\n if (key.startsWith(prefix)) {\r\n keysToDelete.push(key);\r\n }\r\n }\r\n for (const key of keysToDelete) {\r\n cache.delete(key);\r\n _removeFromDB(key);\r\n }\r\n }\r\n\r\n cache.delete(normalizedPath);\r\n _removeFromDB(normalizedPath);\r\n }\r\n\r\n rmdir(opts: CallbackOpts & { dirPath: string; recursive?: boolean }): void {\r\n try {\r\n this.rmdirSync(opts.dirPath, opts.recursive);\r\n opts.success?.({ errMsg: 'rmdir:ok' });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String((e as Error).message) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n }\r\n\r\n // \u2500\u2500\u2500 Rename \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n renameSync(oldPath: string, newPath: string): void {\r\n const op = normalizePath(oldPath);\r\n const np = normalizePath(newPath);\r\n\r\n const entry = cache.get(op);\r\n if (!entry) {\r\n throw new Error(`rename:fail no such file or directory, rename ${op}`);\r\n }\r\n if (!isValidPath(np)) {\r\n throw new Error(`rename:fail invalid path ${np}`);\r\n }\r\n\r\n const newParent = parentPath(np);\r\n if (newParent && !cache.has(newParent)) {\r\n throw new Error(`rename:fail no such file or directory, rename ${np}`);\r\n }\r\n\r\n // Move entry\r\n const newEntry = { ...entry, path: np, modifyTime: Date.now() };\r\n cache.delete(op);\r\n _removeFromDB(op);\r\n cache.set(np, newEntry);\r\n _persist(newEntry);\r\n\r\n // If directory, move all descendants\r\n if (entry.isDir) {\r\n const prefix = op + '/';\r\n const moves: [string, string][] = [];\r\n for (const key of cache.keys()) {\r\n if (key.startsWith(prefix)) {\r\n const newKey = np + key.slice(op.length);\r\n moves.push([key, newKey]);\r\n }\r\n }\r\n for (const [oldKey, newKey] of moves) {\r\n const childEntry = cache.get(oldKey)!;\r\n const movedChild = { ...childEntry, path: newKey };\r\n cache.delete(oldKey);\r\n _removeFromDB(oldKey);\r\n cache.set(newKey, movedChild);\r\n _persist(movedChild);\r\n }\r\n }\r\n }\r\n\r\n rename(opts: CallbackOpts & { oldPath: string; newPath: string }): void {\r\n try {\r\n this.renameSync(opts.oldPath, opts.newPath);\r\n opts.success?.({ errMsg: 'rename:ok' });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String((e as Error).message) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n }\r\n\r\n // \u2500\u2500\u2500 CopyFile \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n //\r\n // Real WeChat allows `srcPath` to be EITHER a user-space wxfile:// path or\r\n // a code-package relative path (e.g. \"assets/xxx.zip\"). The preview\r\n // runtime must support both \u2014 Laya-based games, in particular, use\r\n // `copyFile({ srcPath: '<subpkg>/<resource>.zip', destPath: 'wxfile://usr/...' })`\r\n // right after `wx.loadSubpackage` success to stage compressed assets into\r\n // the user filesystem before unzipping them.\r\n //\r\n // - copyFileSync: cache miss + package path \u2192 sync XHR fetch (small files\r\n // like configs only; large zips should use the async variant).\r\n // - copyFile: cache miss + package path \u2192 async fetch to avoid blocking\r\n // the main thread on multi-MB archives.\r\n\r\n copyFileSync(srcPath: string, destPath: string): void {\r\n const sp = normalizePath(srcPath);\r\n const dp = normalizePath(destPath);\r\n\r\n if (!isValidPath(dp)) {\r\n throw new Error(`copyFile:fail invalid path ${dp}`);\r\n }\r\n const destParent = parentPath(dp);\r\n if (destParent && !cache.has(destParent)) {\r\n throw new Error(`copyFile:fail no such file or directory, copyFile ${dp}`);\r\n }\r\n\r\n let dataCopy: ArrayBuffer;\r\n const srcEntry = cache.get(sp);\r\n if (srcEntry) {\r\n if (srcEntry.isDir) {\r\n throw new Error(`copyFile:fail is a directory, copyFile ${sp}`);\r\n }\r\n dataCopy = srcEntry.data!.slice(0);\r\n } else if (isPackagePath(sp)) {\r\n // Fetch from VFS / static server. fetchPackageFileSync throws with a\r\n // readFile-prefixed message on miss \u2014 rewrite to copyFile semantics.\r\n try {\r\n dataCopy = fetchPackageFileSync(sp);\r\n } catch {\r\n throw new Error(`copyFile:fail no such file or directory, copyFile ${sp}`);\r\n }\r\n } else {\r\n throw new Error(`copyFile:fail no such file or directory, copyFile ${sp}`);\r\n }\r\n\r\n const newEntry = _makeFileEntry(dp, dataCopy);\r\n cache.set(dp, newEntry);\r\n _persist(newEntry);\r\n }\r\n\r\n copyFile(opts: CallbackOpts & { srcPath: string; destPath: string }): void {\r\n const sp = normalizePath(opts.srcPath);\r\n const dp = normalizePath(opts.destPath);\r\n\r\n // Fast path: src already in cache \u2014 defer to the sync impl.\r\n if (cache.has(sp) || !isPackagePath(sp)) {\r\n try {\r\n this.copyFileSync(opts.srcPath, opts.destPath);\r\n opts.success?.({ errMsg: 'copyFile:ok' });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String((e as Error).message) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n return;\r\n }\r\n\r\n // Package-internal source: fetch asynchronously so large archives don't\r\n // block the main thread. Validate destination eagerly so we surface the\r\n // same errors the sync path does.\r\n if (!isValidPath(dp)) {\r\n opts.fail?.({ errMsg: `copyFile:fail invalid path ${dp}` });\r\n opts.complete?.();\r\n return;\r\n }\r\n const destParent = parentPath(dp);\r\n if (destParent && !cache.has(destParent)) {\r\n opts.fail?.({\r\n errMsg: `copyFile:fail no such file or directory, copyFile ${dp}`,\r\n });\r\n opts.complete?.();\r\n return;\r\n }\r\n\r\n fetchPackageFileAsync(sp)\r\n .then((buf) => {\r\n const newEntry = _makeFileEntry(dp, buf);\r\n cache.set(dp, newEntry);\r\n _persist(newEntry);\r\n opts.success?.({ errMsg: 'copyFile:ok' });\r\n })\r\n .catch(() => {\r\n opts.fail?.({\r\n errMsg: `copyFile:fail no such file or directory, copyFile ${sp}`,\r\n });\r\n })\r\n .finally(() => {\r\n opts.complete?.();\r\n });\r\n }\r\n\r\n // \u2500\u2500\u2500 SaveFile \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n saveFileSync(tempFilePath: string, filePath?: string): string {\r\n const tp = normalizePath(tempFilePath);\r\n const entry = cache.get(tp);\r\n if (!entry) {\r\n throw new Error(`saveFile:fail no such file or directory, saveFile ${tp}`);\r\n }\r\n\r\n const dest = filePath ? normalizePath(filePath) : `${USR_ROOT}/${basename(tp)}`;\r\n if (!isValidPath(dest)) {\r\n throw new Error(`saveFile:fail invalid path ${dest}`);\r\n }\r\n\r\n const dataCopy = entry.data ? entry.data.slice(0) : new ArrayBuffer(0);\r\n const newEntry = _makeFileEntry(dest, dataCopy);\r\n cache.set(dest, newEntry);\r\n _persist(newEntry);\r\n\r\n return dest;\r\n }\r\n\r\n saveFile(opts: CallbackOpts & { tempFilePath: string; filePath?: string }): void {\r\n try {\r\n const savedFilePath = this.saveFileSync(opts.tempFilePath, opts.filePath);\r\n opts.success?.({ savedFilePath, errMsg: 'saveFile:ok' });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String((e as Error).message) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n }\r\n\r\n // \u2500\u2500\u2500 GetFileInfo \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n getFileInfo(opts: CallbackOpts & { filePath: string }): void {\r\n const normalizedPath = normalizePath(opts.filePath);\r\n const entry = cache.get(normalizedPath);\r\n if (entry) {\r\n opts.success?.({ size: entry.size, errMsg: 'getFileInfo:ok' });\r\n opts.complete?.();\r\n return;\r\n }\r\n // Package-internal path: async HEAD to the static server / VFS. Real\r\n // WeChat allows getFileInfo on package assets (docs list the digest\r\n // option for that exact use case).\r\n if (isPackagePath(normalizedPath)) {\r\n wxResourceFetch(\r\n resolveGameUrl('/' + normalizedPath.replace(/^\\/+/, '')),\r\n { method: 'HEAD' },\r\n )\r\n .then((resp) => {\r\n if (!resp.ok) {\r\n opts.fail?.({\r\n errMsg: `getFileInfo:fail no such file or directory, getFileInfo ${normalizedPath}`,\r\n });\r\n return;\r\n }\r\n const lenStr = resp.headers.get('content-length');\r\n const size = lenStr ? parseInt(lenStr, 10) || 0 : 0;\r\n opts.success?.({ size, errMsg: 'getFileInfo:ok' });\r\n })\r\n .catch(() => {\r\n opts.fail?.({\r\n errMsg: `getFileInfo:fail no such file or directory, getFileInfo ${normalizedPath}`,\r\n });\r\n })\r\n .finally(() => {\r\n opts.complete?.();\r\n });\r\n return;\r\n }\r\n opts.fail?.({\r\n errMsg: `getFileInfo:fail no such file or directory, getFileInfo ${normalizedPath}`,\r\n });\r\n opts.complete?.();\r\n }\r\n\r\n // \u2500\u2500\u2500 GetSavedFileList \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n getSavedFileList(opts?: CallbackOpts): void {\r\n const fileList: { filePath: string; size: number; createTime: number }[] = [];\r\n const prefix = USR_ROOT + '/';\r\n\r\n for (const [key, entry] of cache.entries()) {\r\n if (key.startsWith(prefix) && !entry.isDir) {\r\n fileList.push({\r\n filePath: key,\r\n size: entry.size,\r\n createTime: entry.createTime,\r\n });\r\n }\r\n }\r\n\r\n opts?.success?.({ fileList, errMsg: 'getSavedFileList:ok' });\r\n opts?.complete?.();\r\n }\r\n\r\n // \u2500\u2500\u2500 RemoveSavedFile \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n removeSavedFile(opts: CallbackOpts & { filePath: string }): void {\r\n try {\r\n this.unlinkSync(opts.filePath);\r\n opts.success?.({ errMsg: 'removeSavedFile:ok' });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String((e as Error).message) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n }\r\n\r\n // \u2500\u2500\u2500 Unzip \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n //\r\n // WeChat Mini Game API \u2014 fs.unzip({ zipFilePath, targetPath, success, fail })\r\n //\r\n // Extracts a .zip archive living at `zipFilePath` into the directory\r\n // `targetPath`. Both paths must resolve to readable/writable locations in\r\n // our virtual file system (usually under wxfile://usr or wxfile://tmp).\r\n //\r\n // Behaviour (matching the documented platform contract):\r\n // - `targetPath` must already exist and be a directory; otherwise fail.\r\n // - Each archive entry is written relative to `targetPath`. Nested\r\n // directories inside the archive are auto-created with `mkdirSync`\r\n // (recursive).\r\n // - Store (method 0) and DEFLATE (method 8) entries are supported;\r\n // encrypted / zip64 / other compression methods raise a clear error.\r\n //\r\n // This is async-only. WeChat's docs list no sync variant.\r\n unzip(\r\n opts: CallbackOpts & { zipFilePath: string; targetPath: string },\r\n ): void {\r\n const zipPath = normalizePath(opts.zipFilePath);\r\n const targetPath = normalizePath(opts.targetPath);\r\n\r\n // \u2500\u2500 Validate target directory up-front. The real platform reports\r\n // \"no such file or directory\" (1300002) when the parent is missing.\r\n const targetEntry = cache.get(targetPath);\r\n if (!targetEntry) {\r\n opts.fail?.({\r\n errMsg: `unzip:fail no such file or directory \"${targetPath}\"`,\r\n });\r\n opts.complete?.();\r\n return;\r\n }\r\n if (!targetEntry.isDir) {\r\n opts.fail?.({\r\n errMsg: `unzip:fail not a directory \"${targetPath}\"`,\r\n });\r\n opts.complete?.();\r\n return;\r\n }\r\n\r\n // \u2500\u2500 Load archive bytes. We support both wxfile:// (cache-backed) and\r\n // package paths (fetched from the dev server) even though the platform\r\n // only documents the former \u2014 games have been seen to pass either.\r\n const loadArchive: Promise<ArrayBuffer> = (async () => {\r\n if (isPackagePath(zipPath)) {\r\n return fetchPackageFileAsync(zipPath);\r\n }\r\n const entry = cache.get(zipPath);\r\n if (!entry) {\r\n throw new Error(\r\n `unzip:fail no such file or directory, open \"${zipPath}\"`,\r\n );\r\n }\r\n if (entry.isDir) {\r\n throw new Error(`unzip:fail is a directory, open \"${zipPath}\"`);\r\n }\r\n return entry.data!;\r\n })();\r\n\r\n loadArchive\r\n .then(async (archive) => {\r\n const entries = await unzipArchive(archive);\r\n\r\n // Ensure a directory exists, creating all missing parents.\r\n // Uses a local helper that routes through the class mkdirSync logic\r\n // so the in-memory cache + IndexedDB stay in sync.\r\n const mkdirp = (dir: string): void => {\r\n if (!dir || cache.has(dir)) return;\r\n const parent = parentPath(dir);\r\n if (parent && !cache.has(parent)) {\r\n mkdirp(parent);\r\n }\r\n // Guard against racing with a concurrent mkdir (unlikely, but safe).\r\n if (!cache.has(dir)) {\r\n const e = _makeDirEntry(dir);\r\n cache.set(dir, e);\r\n _persist(e);\r\n }\r\n };\r\n\r\n for (const e of entries) {\r\n // Disallow absolute / path-traversal entries. Real platforms\r\n // silently reject these; we err on the side of safety.\r\n if (\r\n e.name.startsWith('/') ||\r\n e.name.includes('..') ||\r\n e.name.includes('\\\\')\r\n ) {\r\n console.warn(\r\n `[wx-compat][unzip] skipping unsafe entry \"${e.name}\"`,\r\n );\r\n continue;\r\n }\r\n\r\n const fullPath = `${targetPath}/${e.name.replace(/\\/+$/, '')}`;\r\n\r\n if (e.isDir) {\r\n mkdirp(fullPath);\r\n continue;\r\n }\r\n\r\n // File entry \u2014 make sure parent directory exists.\r\n const parent = parentPath(fullPath);\r\n if (parent && !cache.has(parent)) {\r\n mkdirp(parent);\r\n }\r\n\r\n const fileEntry = _makeFileEntry(fullPath, e.data);\r\n const existing = cache.get(fullPath);\r\n if (existing) {\r\n fileEntry.createTime = existing.createTime;\r\n }\r\n cache.set(fullPath, fileEntry);\r\n _persist(fileEntry);\r\n }\r\n\r\n opts.success?.({ errMsg: 'unzip:ok' });\r\n })\r\n .catch((err) => {\r\n const msg = (err && (err as Error).message) || String(err);\r\n const errMsg = msg.startsWith('unzip:fail') ? msg : `unzip:fail ${msg}`;\r\n console.error('[wx-compat][unzip] failed:', err);\r\n opts.fail?.({ errMsg });\r\n })\r\n .finally(() => {\r\n opts.complete?.();\r\n });\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 Singleton \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nlet instance: FileSystemManager | null = null;\r\n\r\n/**\r\n * wx.getFileSystemManager() \u2014 returns the singleton FileSystemManager.\r\n */\r\nexport function getFileSystemManager(): FileSystemManager {\r\n if (!instance) {\r\n instance = new FileSystemManager();\r\n }\r\n return instance;\r\n}\r\n", "/**\r\n * Canvas creation and management module.\r\n *\r\n * Uses captured native document.createElement to avoid circular calls\r\n * when web-adapter replaces createElement or Canvas constructors.\r\n *\r\n * Key insight from WeChat Mini Game docs:\r\n * - wx.createCanvas(): First call returns the on-screen (main) canvas;\r\n * subsequent calls return new off-screen canvases.\r\n * - The main canvas is also referenced via `window.canvas` and\r\n * `GameGlobal.screencanvas` (set by web-adapter after the first call).\r\n * - Cocos web-adapter calls wx.createCanvas() via its Canvas constructor\r\n * and wraps the result with extra properties (style, clientWidth, etc.).\r\n */\r\n\r\nimport { DEVICE } from './constants';\r\nimport { nativeCreateElement, nativeDocument } from './native-globals';\r\nimport { getFileSystemManager, TMP_ROOT } from './file-system';\r\n\r\nlet mainCanvas: HTMLCanvasElement | null = null;\r\n\r\n// \u2500\u2500 preserveDrawingBuffer opt-in \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// The host page (wx-minigame-preview) writes `true` to\r\n// `window.__wxPreserveDrawingBuffer` when the caller wants every WebGL /\r\n// WebGL2 context produced by this compat layer to use\r\n// `preserveDrawingBuffer: true`, so the host can later call\r\n// `canvas.toDataURL()` / `canvas.toBlob()` and get a real frame rather\r\n// than a black image.\r\n//\r\n// The check is intentionally centralised here and done *per call* (not\r\n// cached into a module constant) so tests and hot-reloaded hosts can flip\r\n// the flag at runtime without reloading this module. The read is a single\r\n// property access on `window` \u2014 trivial cost even on the hot path.\r\n//\r\n// When the flag is absent / false, every helper below is a no-op and the\r\n// surrounding code paths are byte-for-byte identical to the previous\r\n// release: no getContext wrapper is installed on off-screen canvases, and\r\n// the main-canvas GL attrs object is passed through unchanged.\r\nfunction isPreserveDrawingBufferEnabled(): boolean {\r\n try {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n return (window as any).__wxPreserveDrawingBuffer === true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Merge `preserveDrawingBuffer: true` into a WebGL context attributes bag\r\n * when the opt-in flag is on. Returns the original options unchanged when\r\n * the flag is off, so callers pay zero cost in the default case.\r\n */\r\nfunction withPreserveDrawingBuffer(options: unknown): unknown {\r\n if (!isPreserveDrawingBufferEnabled()) return options;\r\n const base = (options && typeof options === 'object') ? options : {};\r\n return { ...(base as Record<string, unknown>), preserveDrawingBuffer: true };\r\n}\r\n\r\n/**\r\n * Wrap a freshly-created off-screen canvas so that any future\r\n * `getContext('webgl'|'webgl2'|'experimental-webgl', attrs)` call has\r\n * `preserveDrawingBuffer: true` merged into its attributes. 2D and other\r\n * context types pass through unchanged.\r\n *\r\n * Only installed when the opt-in flag is on at canvas-creation time; when\r\n * off, the canvas keeps its native `getContext` method and nothing is\r\n * patched. This is safer than a prototype patch because it only affects\r\n * canvases that wx-compat itself hands out to game code.\r\n */\r\nfunction installPreserveDrawingBufferWrapper(canvas: HTMLCanvasElement): void {\r\n if (!isPreserveDrawingBufferEnabled()) return;\r\n const original = canvas.getContext.bind(canvas);\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (canvas as any).getContext = function (contextId: string, attrs?: unknown) {\r\n if (contextId === 'webgl' || contextId === 'webgl2' || contextId === 'experimental-webgl') {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n return (original as any)(contextId, withPreserveDrawingBuffer(attrs));\r\n }\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n return (original as any)(contextId, attrs);\r\n };\r\n}\r\n\r\n\r\n\r\n\r\n/**\r\n * Returns (or creates) the main on-screen canvas singleton.\r\n *\r\n * Used internally by globals-compat.ts to set `window.canvas` and\r\n * `GameGlobal.screencanvas`. This is NOT the same as wx.createCanvas().\r\n */\r\nexport function getOrCreateMainCanvas(): HTMLCanvasElement {\r\n if (mainCanvas) {\r\n return mainCanvas;\r\n }\r\n\r\n // \u2500\u2500 PROBE: verify the browser/iframe can actually give us WebGL2/WebGL \u2500\u2500\u2500\u2500\r\n // This runs once, before Cocos ever asks for a context. Uses a throwaway\r\n // canvas so the main canvas isn't polluted.\r\n try {\r\n const probe = nativeCreateElement('canvas') as HTMLCanvasElement;\r\n probe.width = 16;\r\n probe.height = 16;\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const gl2 = (probe.getContext as any)('webgl2');\r\n if (gl2) {\r\n try { gl2.getExtension('WEBGL_lose_context')?.loseContext(); } catch { /* ignore */ }\r\n }\r\n\r\n const probe2 = nativeCreateElement('canvas') as HTMLCanvasElement;\r\n probe2.width = 16;\r\n probe2.height = 16;\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const gl1 = (probe2.getContext as any)('webgl');\r\n if (gl1) {\r\n try { gl1.getExtension('WEBGL_lose_context')?.loseContext(); } catch { /* ignore */ }\r\n }\r\n } catch (e) {\r\n console.error('[wx-compat][gl-probe] probe threw:', e);\r\n }\r\n\r\n mainCanvas = nativeCreateElement('canvas') as HTMLCanvasElement;\r\n // canvas.width/height = physical pixels = logical size \u00D7 DPR\r\n // canvas.style.width/height = CSS logical pixels (what the browser lays out)\r\n // This matches WeChat real device behaviour where the canvas buffer is\r\n // DPR times larger than the CSS display size.\r\n mainCanvas.width = Math.round(DEVICE.width * DEVICE.pixelRatio);\r\n mainCanvas.height = Math.round(DEVICE.height * DEVICE.pixelRatio);\r\n mainCanvas.style.width = DEVICE.width + 'px';\r\n mainCanvas.style.height = DEVICE.height + 'px';\r\n\r\n // \u2500\u2500 Intercept canvas.width / canvas.height writes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Trap any code (Cocos, web-adapter, game) that overwrites canvas dimensions\r\n // so we can see exactly who changes them and to what value.\r\n {\r\n const _proto = Object.getPrototypeOf(mainCanvas); // HTMLCanvasElement.prototype\r\n const _origWidthDesc = Object.getOwnPropertyDescriptor(_proto, 'width')!;\r\n const _origHeightDesc = Object.getOwnPropertyDescriptor(_proto, 'height')!;\r\n let _canvasWidth = mainCanvas.width;\r\n let _canvasHeight = mainCanvas.height;\r\n Object.defineProperty(mainCanvas, 'width', {\r\n configurable: true,\r\n enumerable: true,\r\n get() { return _canvasWidth; },\r\n set(v: number) {\r\n _canvasWidth = v;\r\n _origWidthDesc.set!.call(mainCanvas, v);\r\n // Always keep style.width = DEVICE_WIDTH (logical pixels).\r\n // Different engines set canvas.width to different values:\r\n // Cocos 3.x: canvas.width = windowWidth * pixelRatio (physical pixels)\r\n // Cocos 2.x: canvas.width = windowWidth (logical pixels)\r\n // We must NOT derive style from canvas.width.\r\n // Instead, pin style to the logical device size so the browser always\r\n // scales the canvas buffer to fill the preview window correctly.\r\n mainCanvas!.style.width = DEVICE.width + 'px';\r\n },\r\n });\r\n Object.defineProperty(mainCanvas, 'height', {\r\n configurable: true,\r\n enumerable: true,\r\n get() { return _canvasHeight; },\r\n set(v: number) {\r\n _canvasHeight = v;\r\n _origHeightDesc.set!.call(mainCanvas, v);\r\n // Always keep style.height = DEVICE_HEIGHT (logical pixels).\r\n mainCanvas!.style.height = DEVICE.height + 'px';\r\n },\r\n }); }\r\n\r\n // Pre-define clientWidth / clientHeight as configurable so that game\r\n // engines (e.g. Cocos web-adapter) can later redefine them via\r\n // Object.defineProperty without hitting \"Cannot redefine property\" errors.\r\n // clientWidth/clientHeight report the CSS logical size (not physical pixels)\r\n Object.defineProperty(mainCanvas, 'clientWidth', {\r\n configurable: true,\r\n enumerable: true,\r\n get() { return DEVICE.width; },\r\n });\r\n Object.defineProperty(mainCanvas, 'clientHeight', {\r\n configurable: true,\r\n enumerable: true,\r\n get() { return DEVICE.height; },\r\n });\r\n mainCanvas.style.display = 'block';\r\n mainCanvas.style.touchAction = 'none';\r\n mainCanvas.id = 'wx-main-canvas';\r\n\r\n // \u2500\u2500 WebGL variant binding (mirror real-device semantics) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Problem: WeChat canvases on real devices have NO WebGL-variant binding \u2014\r\n // a game can freely ask for either `webgl` or `webgl2` on the same canvas\r\n // and always get a usable context. Browsers are strict: once a canvas has\r\n // been bound to one variant, asking for the OTHER returns null, and\r\n // WEBGL_lose_context only releases GPU resources, not this binding.\r\n //\r\n // Missing abstraction: \"WebGL variant\" is an implementation detail of the\r\n // browser's canvas, NOT a concept in the WeChat canvas semantics we are\r\n // emulating. Our compat layer must present one canvas that behaves\r\n // variant-agnostic, the way real-device canvases do.\r\n //\r\n // Strategy \u2014 \"honour the caller's first request\":\r\n // \u2022 The very first GL request on the main canvas decides the binding.\r\n // If the caller asks for `webgl` / `experimental-webgl`, we bind\r\n // WebGL1. If the caller asks for `webgl2`, we bind WebGL2 (with a\r\n // graceful fallback to WebGL1 when the browser has no WebGL2).\r\n // \u2022 Subsequent GL requests are served from the bound context regardless\r\n // of which variant they ask for \u2014 matches WeChat's \"no variant\r\n // binding\" semantic. This is safe in practice because:\r\n // - bound webgl1 + caller asks webgl \u2192 exact match.\r\n // - bound webgl1 + caller asks webgl2 \u2192 return webgl1 context.\r\n // WebGL2 is an API superset, so this is technically wrong, but\r\n // the same engine never asks for both variants, and real WeChat\r\n // canvases also have a single underlying GL device.\r\n // - bound webgl2 + caller asks webgl \u2192 return webgl2 context\r\n // (API superset; valid WebGL1 calls are a subset of valid WebGL2\r\n // calls).\r\n // - bound webgl2 + caller asks webgl2 \u2192 exact match.\r\n //\r\n // Why not \"always bind the highest variant available\":\r\n // Some engines (notably Unity WebGL1 builds) detect the actual context\r\n // variant via `instanceof WebGL2RenderingContext` or `gl.VERSION`\r\n // string parsing and branch into incompatible code paths when they\r\n // discover a WebGL2 context, even if their renderer is WebGL1-only.\r\n // Always-upgrading silently broke Unity WebGL1 on this preview because\r\n // Unity's plugin took the \"WebGL2-is-here\" branch but its actual\r\n // shaders / GL calls were authored for WebGL1, producing a black\r\n // screen with no errors. Honouring the explicit request avoids this\r\n // class of breakage without affecting WebGL2-aware engines (Cocos 3.x\r\n // webgl2, Unity WebGL2 builds), because they explicitly request\r\n // `webgl2` and still get exactly that.\r\n //\r\n // Why not \"always bind the variant the caller asks for, every time\":\r\n // Browsers refuse to give a different context kind on a canvas that\r\n // has already been bound. Once we hand out webgl1, asking for webgl2\r\n // on the same canvas would return null no matter what we did; same in\r\n // the other direction. We have a single canvas to service all\r\n // subsequent requests, so we MUST share whichever was bound first.\r\n //\r\n // 2D requests on the main canvas get separate handling (see below):\r\n // browsers can NEVER return 2D on a canvas that has ever held GL, so\r\n // mixed 2D/GL usage is served via a pragmatic split between native\r\n // primary-2D (when nothing else has touched the canvas) and an off-DOM\r\n // sibling 2D canvas (when GL already owns the screen).\r\n {\r\n const _nativeGetContext = mainCanvas.getContext.bind(mainCanvas);\r\n // Mutable reference wrapper: when we do a variant upgrade (replace the\r\n // underlying canvas), we update .ref so all subsequent calls in this\r\n // closure use the new canvas's getContext.\r\n const _upgradeNativeGetContext = { ref: _nativeGetContext as (...args: unknown[]) => unknown };\r\n let _unifiedGL: WebGLRenderingContext | WebGL2RenderingContext | null = null;\r\n let _unifiedGLVariant: 'webgl' | 'webgl2' | null = null;\r\n let _primary2D: CanvasRenderingContext2D | null = null;\r\n let _fallback2DCanvas: HTMLCanvasElement | null = null;\r\n let _fallback2D: CanvasRenderingContext2D | null = null;\r\n\r\n // Capability probe: what does this browser actually let us have?\r\n // Cached at install time to avoid re-probing on every getContext call.\r\n // The result determines which variant we bind on first GL request.\r\n const _browserSupportsWebGL2: boolean = (() => {\r\n try {\r\n const probe = nativeCreateElement('canvas') as HTMLCanvasElement;\r\n probe.width = 1;\r\n probe.height = 1;\r\n const ctx = (probe as HTMLCanvasElement).getContext('webgl2') as WebGL2RenderingContext | null;\r\n if (ctx) {\r\n try { ctx.getExtension('WEBGL_lose_context')?.loseContext(); } catch { /* ignore */ }\r\n return true;\r\n }\r\n } catch { /* ignore */ }\r\n return false;\r\n })();\r\n\r\n (mainCanvas as HTMLCanvasElement & { getContext: typeof mainCanvas.getContext }).getContext = function(\r\n contextId: string,\r\n options?: unknown,\r\n ): RenderingContext | null {\r\n const isWebGL = contextId === 'webgl' || contextId === 'webgl2' || contextId === 'experimental-webgl';\r\n\r\n // \u2500\u2500 2D context on the main canvas \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Real-device semantics: a canvas can only ever hold ONE context kind\r\n // (the first caller wins). We mirror that, plus give a pragmatic\r\n // fallback for engines (Cocos / Unity web-adapter) that occasionally\r\n // ask for '2d' on the GL-bound main canvas for text measurement / UI.\r\n //\r\n // \u2022 mainCanvas clean \u2192 bind native 2D directly on mainCanvas.\r\n // This is the *only* path that puts pixels on\r\n // the user's screen for pure-2D games.\r\n // \u2022 mainCanvas 2D \u2192 return the cached 2D context (idempotent).\r\n // \u2022 mainCanvas on GL \u2192 return an off-DOM sibling 2D canvas so the\r\n // engine's ad-hoc 2D call doesn't throw; this\r\n // sibling isn't visible, matching the fact that\r\n // the GL engine owns the real screen output.\r\n if (contextId === '2d') {\r\n if (_primary2D) {\r\n return _primary2D;\r\n }\r\n if (!_unifiedGL) {\r\n // First context on mainCanvas is 2D \u2192 bind natively so pixels reach\r\n // the screen. This is the pure-2D minigame path.\r\n try {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const ctx2d = (_upgradeNativeGetContext.ref as any)(contextId, options) as CanvasRenderingContext2D | null;\r\n if (ctx2d) {\r\n _primary2D = ctx2d;\r\n return ctx2d;\r\n }\r\n } catch (e) {\r\n console.warn(`[wx-compat][canvas] getContext(\"2d\") native threw, falling back to sibling canvas:`, e);\r\n }\r\n // Fall through to sibling-canvas fallback below.\r\n }\r\n // mainCanvas is GL-bound (or native 2D failed) \u2192 use off-DOM sibling.\r\n if (!_fallback2D) {\r\n _fallback2DCanvas = nativeCreateElement('canvas') as HTMLCanvasElement;\r\n _fallback2DCanvas.width = mainCanvas!.width;\r\n _fallback2DCanvas.height = mainCanvas!.height;\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n _fallback2D = (_fallback2DCanvas.getContext as any)('2d', options) as CanvasRenderingContext2D | null;\r\n }\r\n return _fallback2D;\r\n }\r\n\r\n if (isWebGL) {\r\n // \u2500\u2500 Variant upgrade: webgl1 \u2192 webgl2 via canvas replacement \u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Scenario: game.js first-screen code binds webgl1 on the main canvas\r\n // for a splash screen, then the real engine (Cocos 3.x) later asks for\r\n // webgl2. On real WeChat devices this \"just works\" because there's no\r\n // variant binding. Browsers refuse to switch GL variant on the same\r\n // canvas, so we must replace the underlying DOM canvas with a fresh one\r\n // and bind webgl2 on it.\r\n //\r\n // This ONLY triggers for the webgl1\u2192webgl2 upgrade direction. The\r\n // reverse (webgl2\u2192webgl1) is safe to serve from the webgl2 context\r\n // since WebGL2 is an API superset of WebGL1.\r\n if (_unifiedGL && _unifiedGLVariant === 'webgl' && contextId === 'webgl2' && _browserSupportsWebGL2) {\r\n // 1. Release old GL resources\r\n try {\r\n const loseExt = _unifiedGL.getExtension('WEBGL_lose_context');\r\n if (loseExt) loseExt.loseContext();\r\n } catch { /* ignore */ }\r\n\r\n // 2. Create a new native canvas with the same dimensions and style\r\n const oldCanvas = mainCanvas as HTMLCanvasElement;\r\n const newCanvas = nativeCreateElement('canvas') as HTMLCanvasElement;\r\n newCanvas.width = oldCanvas.width;\r\n newCanvas.height = oldCanvas.height;\r\n newCanvas.style.cssText = oldCanvas.style.cssText;\r\n newCanvas.id = oldCanvas.id;\r\n\r\n // 3. Replace in DOM\r\n if (oldCanvas.parentNode) {\r\n oldCanvas.parentNode.replaceChild(newCanvas, oldCanvas);\r\n }\r\n\r\n // 4. Update module-level mainCanvas reference\r\n mainCanvas = newCanvas;\r\n\r\n // 5. Bind webgl2 on the fresh canvas (use its native getContext directly)\r\n const newNativeGetContext = newCanvas.getContext.bind(newCanvas);\r\n let ctx2: WebGL2RenderingContext | null = null;\r\n try {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const raw = (newNativeGetContext as any)('webgl2', withPreserveDrawingBuffer(options));\r\n ctx2 = raw ? (raw as WebGL2RenderingContext) : null;\r\n } catch (e) {\r\n console.error(`[wx-compat][canvas] variant-upgrade getContext(\"webgl2\") threw:`, e);\r\n }\r\n\r\n if (ctx2) {\r\n _unifiedGL = ctx2;\r\n _unifiedGLVariant = 'webgl2';\r\n // Update the nativeGetContext reference for future calls\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n _upgradeNativeGetContext.ref = newNativeGetContext as any;\r\n\r\n // 6. Re-install our getContext wrapper on the new canvas\r\n // (we're currently executing inside the wrapper on oldCanvas)\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (newCanvas as any).getContext = (oldCanvas as any).getContext;\r\n\r\n // 7. Re-install clientWidth/clientHeight on the new canvas\r\n Object.defineProperty(newCanvas, 'clientWidth', {\r\n configurable: true, enumerable: true,\r\n get() { return DEVICE.width; },\r\n });\r\n Object.defineProperty(newCanvas, 'clientHeight', {\r\n configurable: true, enumerable: true,\r\n get() { return DEVICE.height; },\r\n });\r\n\r\n return ctx2;\r\n } else {\r\n // Upgrade failed \u2014 revert: put old canvas back\r\n console.warn(`[wx-compat][canvas] variant upgrade webgl\u2192webgl2 FAILED, reverting`);\r\n if (newCanvas.parentNode) {\r\n newCanvas.parentNode.replaceChild(oldCanvas, newCanvas);\r\n }\r\n mainCanvas = oldCanvas;\r\n // Return the old webgl1 context as best-effort\r\n return _unifiedGL;\r\n }\r\n }\r\n\r\n // Reuse the already-bound context for compatible requests.\r\n // webgl2 bound + caller asks webgl \u2192 return webgl2 (API superset, safe).\r\n // webgl bound + caller asks webgl \u2192 exact match.\r\n // webgl2 bound + caller asks webgl2 \u2192 exact match.\r\n if (_unifiedGL) {\r\n return _unifiedGL;\r\n }\r\n\r\n // \u2500\u2500 First-time GL request \u2014 honour the caller's explicit variant \u2500\u2500\r\n // If the caller asks for \"webgl2\", try webgl2 first, then fall back\r\n // to webgl1 if the browser can't provide it.\r\n // If the caller asks for \"webgl\" or \"experimental-webgl\", bind\r\n // webgl1 directly \u2014 do NOT silently upgrade to webgl2, because some\r\n // engines (Unity WebGL1 builds) detect the context variant and enter\r\n // incompatible code paths when they discover WebGL2.\r\n let ctx: WebGLRenderingContext | WebGL2RenderingContext | null = null;\r\n let establishedVariant: 'webgl' | 'webgl2';\r\n const callerWantsWebGL2 = contextId === 'webgl2';\r\n\r\n if (callerWantsWebGL2) {\r\n // Caller explicitly asked for webgl2.\r\n establishedVariant = 'webgl2';\r\n if (_browserSupportsWebGL2) {\r\n try {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const raw = (_upgradeNativeGetContext.ref as any)('webgl2', withPreserveDrawingBuffer(options));\r\n ctx = raw ? (raw as WebGL2RenderingContext) : null;\r\n } catch (e) {\r\n console.warn(`[wx-compat][canvas] native getContext(\"webgl2\") threw:`, e);\r\n ctx = null;\r\n }\r\n }\r\n // Graceful degradation: caller wanted webgl2 but browser can't\r\n // provide it \u2014 fall back to webgl1.\r\n if (!ctx) {\r\n establishedVariant = 'webgl';\r\n try {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const raw = (_upgradeNativeGetContext.ref as any)('webgl', withPreserveDrawingBuffer(options));\r\n ctx = raw ? (raw as WebGLRenderingContext) : null;\r\n } catch (e) {\r\n console.error(`[wx-compat][canvas] native getContext(\"webgl\") threw:`, e);\r\n }\r\n }\r\n } else {\r\n // Caller asked for \"webgl\" or \"experimental-webgl\" \u2192 bind webgl1.\r\n establishedVariant = 'webgl';\r\n const gl1Name = contextId === 'experimental-webgl' ? 'experimental-webgl' : 'webgl';\r\n try {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const raw = (_upgradeNativeGetContext.ref as any)(gl1Name, withPreserveDrawingBuffer(options));\r\n ctx = raw ? (raw as WebGLRenderingContext) : null;\r\n } catch (e) {\r\n console.error(`[wx-compat][canvas] native getContext(\"${gl1Name}\") threw:`, e);\r\n }\r\n }\r\n\r\n if (ctx) {\r\n _unifiedGL = ctx;\r\n _unifiedGLVariant = establishedVariant;\r\n }\r\n return ctx;\r\n }\r\n\r\n // \u2500\u2500 Other context types (bitmaprenderer, etc.) \u2192 pass-through \u2500\u2500\r\n try {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n return (_upgradeNativeGetContext.ref as any)(contextId, options);\r\n } catch (e) {\r\n console.error(`[wx-compat][canvas] getContext(\"${contextId}\") THREW:`, e);\r\n return null;\r\n }\r\n } as typeof mainCanvas.getContext;\r\n }\r\n\r\n // Center canvas in body \u2014 use nativeDocument to access full DOM\r\n // since cleanGlobals may have stripped document properties.\r\n nativeDocument.body.style.margin = '0';\r\n nativeDocument.body.style.padding = '0';\r\n nativeDocument.body.style.display = 'flex';\r\n nativeDocument.body.style.justifyContent = 'center';\r\n nativeDocument.body.style.alignItems = 'center';\r\n nativeDocument.body.style.width = '100%';\r\n nativeDocument.body.style.height = '100%';\r\n nativeDocument.body.style.background = '#000';\r\n nativeDocument.body.style.overflow = 'hidden';\r\n\r\n // \u2500\u2500 Pointer Lock & Event Forwarding support \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // WeChat Mini Game SDK's weapp-adapter replaces canvas.addEventListener with\r\n // a function that registers handlers in a custom event system (not native DOM).\r\n // In our browser-based preview, all events are native DOM events, so the\r\n // adapter's custom event system never fires them.\r\n //\r\n // Solution: Intercept canvas.addEventListener so that ALL event handlers are\r\n // registered on nativeDocument instead of the adapter's custom system.\r\n // This ensures mousemove (during pointer lock), keyboard events, and mouse\r\n // click events all reach Unity's handlers via native DOM event propagation.\r\n //\r\n // We do NOT dual-register (adapter + nativeDocument) to avoid any risk of\r\n // duplicate event delivery.\r\n {\r\n let pointerLocked = false;\r\n\r\n // Intercept canvas.requestPointerLock \u2014 suppress redundant lock requests\r\n // when already locked (e.g. Unity re-requesting on every click).\r\n const _origRequestPointerLock = mainCanvas.requestPointerLock.bind(mainCanvas);\r\n mainCanvas.requestPointerLock = function() {\r\n if (nativeDocument.pointerLockElement === mainCanvas) {\r\n // Already locked \u2014 skip redundant request\r\n return Promise.resolve();\r\n }\r\n return _origRequestPointerLock();\r\n };\r\n\r\n // Events that should be registered on nativeDocument instead of the\r\n // adapter's custom event system.\r\n const NATIVE_DOC_EVENTS = new Set([\r\n 'mousemove', 'mousedown', 'mouseup',\r\n 'keydown', 'keyup', 'keypress',\r\n ]);\r\n\r\n // Track handlers registered on nativeDocument so we can remove them\r\n const nativeDocHandlers = new Map<string, Map<EventListener, EventListener>>();\r\n\r\n // Install interceptor for addEventListener via defineProperty.\r\n // When weapp-adapter does `canvas.addEventListener = fn`, our setter\r\n // silently absorbs it (we don't use the adapter's event system).\r\n // When Unity calls `canvas.addEventListener(type, handler)`, our getter\r\n // routes the handler to nativeDocument for native DOM delivery.\r\n Object.defineProperty(mainCanvas, 'addEventListener', {\r\n configurable: true,\r\n enumerable: true,\r\n get() {\r\n return function(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions) {\r\n if (NATIVE_DOC_EVENTS.has(type)) {\r\n // Register on nativeDocument \u2014 all mouse/keyboard events fire here\r\n if (!nativeDocHandlers.has(type)) {\r\n nativeDocHandlers.set(type, new Map());\r\n }\r\n // Avoid duplicate registration\r\n if (!nativeDocHandlers.get(type)!.has(listener)) {\r\n nativeDocHandlers.get(type)!.set(listener, listener);\r\n nativeDocument.addEventListener(type, listener, options);\r\n }\r\n }\r\n // For other event types (touch, wheel, etc.), silently ignore.\r\n // In our preview environment these are handled by other mechanisms.\r\n };\r\n },\r\n set() {\r\n // Absorb weapp-adapter's assignment silently \u2014 we don't use it\r\n },\r\n });\r\n\r\n Object.defineProperty(mainCanvas, 'removeEventListener', {\r\n configurable: true,\r\n enumerable: true,\r\n get() {\r\n return function(type: string, listener: EventListener, options?: boolean | EventListenerOptions) {\r\n if (NATIVE_DOC_EVENTS.has(type) && nativeDocHandlers.has(type)) {\r\n const map = nativeDocHandlers.get(type)!;\r\n if (map.has(listener)) {\r\n nativeDocument.removeEventListener(type, listener, options);\r\n map.delete(listener);\r\n }\r\n }\r\n };\r\n },\r\n set() {\r\n // Absorb weapp-adapter's assignment silently\r\n },\r\n });\r\n\r\n // React to pointer lock state changes\r\n nativeDocument.addEventListener('pointerlockchange', () => {\r\n const isLocked = nativeDocument.pointerLockElement === mainCanvas;\r\n\r\n if (isLocked && !pointerLocked) {\r\n pointerLocked = true;\r\n // Hide the mouse-touch simulation cursor via postMessage\r\n window.postMessage({ type: 'POINTER_LOCK_CHANGE', locked: true }, '*');\r\n } else if (!isLocked && pointerLocked) {\r\n pointerLocked = false;\r\n // Show the mouse-touch simulation cursor again\r\n window.postMessage({ type: 'POINTER_LOCK_CHANGE', locked: false }, '*');\r\n }\r\n });\r\n\r\n nativeDocument.addEventListener('pointerlockerror', () => {\r\n console.error('[wx-compat][pointerlock] pointerlockerror event fired');\r\n });\r\n }\r\n\r\n nativeDocument.body.appendChild(mainCanvas);\r\n\r\n return mainCanvas;\r\n}\r\n\r\n/**\r\n * wx.createCanvas() \u2014 mimics WeChat Mini Game behaviour:\r\n * - First call: returns the main (on-screen) canvas singleton.\r\n * - Subsequent calls: return a new independent (off-screen) canvas.\r\n *\r\n * The first call is consumed by web-adapter to initialise\r\n * GameGlobal.screencanvas (only when screencanvas wasn't pre-set).\r\n * All later calls produce fresh off-screen canvases for text measurement,\r\n * label rendering, etc.\r\n */\r\nlet _firstCreateCanvasCalled = false;\r\n\r\nexport function createCanvas(): HTMLCanvasElement {\r\n // First call \u2192 return the main on-screen canvas (same as WeChat behaviour).\r\n if (!_firstCreateCanvasCalled) {\r\n _firstCreateCanvasCalled = true;\r\n return getOrCreateMainCanvas();\r\n }\r\n\r\n // Subsequent calls \u2192 new independent off-screen canvas.\r\n // Off-screen canvases also use physical pixel dimensions.\r\n const canvas = nativeCreateElement('canvas') as HTMLCanvasElement;\r\n canvas.width = Math.round(DEVICE.width * DEVICE.pixelRatio);\r\n canvas.height = Math.round(DEVICE.height * DEVICE.pixelRatio);\r\n\r\n // Pre-define clientWidth / clientHeight as configurable so that game\r\n // adapters (e.g. Cocos web-adapter) can later redefine them via\r\n // Object.defineProperty without hitting \"Cannot redefine property\" errors.\r\n // In browsers, these are inherited from Element.prototype as non-configurable\r\n // getters, so defineProperty on the instance would fail without this.\r\n Object.defineProperty(canvas, 'clientWidth', {\r\n configurable: true,\r\n enumerable: true,\r\n get() { return DEVICE.width; },\r\n });\r\n Object.defineProperty(canvas, 'clientHeight', {\r\n configurable: true,\r\n enumerable: true,\r\n get() { return DEVICE.height; },\r\n });\r\n\r\n // Opt-in: force preserveDrawingBuffer on any future GL context this\r\n // off-screen canvas will produce. No-op when the flag is off.\r\n installPreserveDrawingBufferWrapper(canvas);\r\n\r\n return canvas;\r\n}\r\n\r\n/**\r\n * Creates an offscreen canvas for off-screen rendering.\r\n */\r\nexport function createOffscreenCanvas(width?: number, height?: number): HTMLCanvasElement {\r\n const canvas = nativeCreateElement('canvas') as HTMLCanvasElement;\r\n canvas.width = width ?? DEVICE.width;\r\n canvas.height = height ?? DEVICE.height;\r\n installPreserveDrawingBufferWrapper(canvas);\r\n return canvas;\r\n}\r\n\r\n/**\r\n * Returns the main canvas reference (used by touch events module).\r\n */\r\nexport function getMainCanvas(): HTMLCanvasElement | null {\r\n return mainCanvas;\r\n}\r\n\r\n// \u2500\u2500\u2500 Canvas Export (P1) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype AnyCallback = (...args: any[]) => void;\r\n\r\ninterface TempFilePathOptions {\r\n x?: number;\r\n y?: number;\r\n width?: number;\r\n height?: number;\r\n destWidth?: number;\r\n destHeight?: number;\r\n canvas?: HTMLCanvasElement;\r\n fileType?: 'jpg' | 'png';\r\n quality?: number;\r\n success?: (res: { tempFilePath: string }) => void;\r\n fail?: (res: { errMsg: string }) => void;\r\n complete?: AnyCallback;\r\n}\r\n\r\n/**\r\n * Core implementation for canvas-to-temp-file export.\r\n * Handles cropping, resizing, and format conversion.\r\n */\r\nfunction canvasToTempFilePathImpl(opts: TempFilePathOptions): void {\r\n try {\r\n const sourceCanvas = opts.canvas || mainCanvas;\r\n if (!sourceCanvas) {\r\n opts.fail?.({ errMsg: 'canvasToTempFilePath:fail no canvas' });\r\n opts.complete?.();\r\n return;\r\n }\r\n\r\n const fileType = opts.fileType || 'png';\r\n const quality = opts.quality ?? 1.0;\r\n const mimeType = fileType === 'jpg' ? 'image/jpeg' : 'image/png';\r\n\r\n // Determine source region\r\n const sx = opts.x ?? 0;\r\n const sy = opts.y ?? 0;\r\n const sw = opts.width ?? sourceCanvas.width;\r\n const sh = opts.height ?? sourceCanvas.height;\r\n\r\n // Determine destination dimensions\r\n const dw = opts.destWidth ?? sw;\r\n const dh = opts.destHeight ?? sh;\r\n\r\n // If cropping or resizing is needed, draw to a temp canvas first\r\n let exportCanvas: HTMLCanvasElement;\r\n const needsCrop = sx !== 0 || sy !== 0 || sw !== sourceCanvas.width || sh !== sourceCanvas.height;\r\n const needsResize = dw !== sw || dh !== sh;\r\n\r\n if (needsCrop || needsResize) {\r\n exportCanvas = nativeCreateElement('canvas') as HTMLCanvasElement;\r\n exportCanvas.width = dw;\r\n exportCanvas.height = dh;\r\n const ctx = exportCanvas.getContext('2d');\r\n if (!ctx) {\r\n opts.fail?.({ errMsg: 'canvasToTempFilePath:fail cannot get 2d context' });\r\n opts.complete?.();\r\n return;\r\n }\r\n ctx.drawImage(sourceCanvas, sx, sy, sw, sh, 0, 0, dw, dh);\r\n } else {\r\n exportCanvas = sourceCanvas;\r\n }\r\n\r\n // Export as blob \u2192 save to virtual FS \u2192 return wxfile://tmp/ path\r\n // This matches WeChat real-device behavior where tempFilePath is a\r\n // wxfile://tmp/xxx path, not a blob URL.\r\n exportCanvas.toBlob(\r\n async (blob) => {\r\n if (!blob) {\r\n opts.fail?.({ errMsg: 'canvasToTempFilePath:fail toBlob returned null' });\r\n opts.complete?.();\r\n return;\r\n }\r\n try {\r\n const arrayBuffer = await blob.arrayBuffer();\r\n const ext = fileType === 'jpg' ? '.jpg' : '.png';\r\n const tempFilePath = `${TMP_ROOT}/${Date.now()}_${Math.random().toString(36).slice(2)}${ext}`;\r\n const fs = getFileSystemManager();\r\n fs.writeFileSync(tempFilePath, arrayBuffer);\r\n opts.success?.({ tempFilePath });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: `canvasToTempFilePath:fail ${e}` });\r\n }\r\n opts.complete?.();\r\n },\r\n mimeType,\r\n quality,\r\n );\r\n } catch (e) {\r\n opts.fail?.({ errMsg: `canvasToTempFilePath:fail ${e}` });\r\n opts.complete?.();\r\n }\r\n}\r\n\r\n/**\r\n * wx.canvasToTempFilePath \u2014 export a canvas to a temporary file path.\r\n *\r\n * Returns a wxfile://tmp/ path (matching WeChat real-device behavior).\r\n * Supports cropping (x, y, width, height), resizing (destWidth, destHeight),\r\n * and format selection (png/jpg with quality).\r\n */\r\nexport function canvasToTempFilePath(opts: TempFilePathOptions): void {\r\n canvasToTempFilePathImpl(opts);\r\n}\r\n\r\n// \u2500\u2500\u2500 Canvas Pixel Operations (P2) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ninterface PixelOpts {\r\n canvasId?: string;\r\n canvas?: HTMLCanvasElement;\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n success?: AnyCallback;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: AnyCallback;\r\n}\r\n\r\n/**\r\n * wx.canvasGetImageData \u2014 read pixel data from a canvas region.\r\n */\r\nexport function canvasGetImageData(opts: PixelOpts): void {\r\n try {\r\n const cvs = opts.canvas || mainCanvas;\r\n if (!cvs) {\r\n opts.fail?.({ errMsg: 'canvasGetImageData:fail no canvas' });\r\n opts.complete?.();\r\n return;\r\n }\r\n const ctx = cvs.getContext('2d');\r\n if (!ctx) {\r\n opts.fail?.({ errMsg: 'canvasGetImageData:fail cannot get 2d context' });\r\n opts.complete?.();\r\n return;\r\n }\r\n const imageData = ctx.getImageData(opts.x, opts.y, opts.width, opts.height);\r\n opts.success?.({\r\n width: imageData.width,\r\n height: imageData.height,\r\n data: imageData.data,\r\n errMsg: 'canvasGetImageData:ok',\r\n });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: `canvasGetImageData:fail ${e}` });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n}\r\n\r\n/**\r\n * wx.canvasPutImageData \u2014 write pixel data to a canvas.\r\n */\r\nexport function canvasPutImageData(opts: PixelOpts & { data: Uint8ClampedArray }): void {\r\n try {\r\n const cvs = opts.canvas || mainCanvas;\r\n if (!cvs) {\r\n opts.fail?.({ errMsg: 'canvasPutImageData:fail no canvas' });\r\n opts.complete?.();\r\n return;\r\n }\r\n const ctx = cvs.getContext('2d');\r\n if (!ctx) {\r\n opts.fail?.({ errMsg: 'canvasPutImageData:fail cannot get 2d context' });\r\n opts.complete?.();\r\n return;\r\n }\r\n const imageData = new ImageData(new Uint8ClampedArray(opts.data.buffer as ArrayBuffer), opts.width, opts.height);\r\n ctx.putImageData(imageData, opts.x, opts.y);\r\n opts.success?.({ errMsg: 'canvasPutImageData:ok' });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: `canvasPutImageData:fail ${e}` });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n}\r\n", "/**\r\n * System information module.\r\n * Provides wx.getSystemInfo, wx.getSystemInfoSync, wx.getSystemInfoAsync,\r\n * and wx.getWindowInfo.\r\n */\r\n\r\nimport { DEVICE, URL_PARAMS } from './constants';\r\n\r\nexport interface SystemInfo {\r\n // Device\r\n brand: string;\r\n model: string;\r\n pixelRatio: number;\r\n screenWidth: number;\r\n screenHeight: number;\r\n windowWidth: number;\r\n windowHeight: number;\r\n statusBarHeight: number;\r\n language: string;\r\n version: string;\r\n system: string;\r\n platform: string;\r\n fontSizeSetting: number;\r\n SDKVersion: string;\r\n // Performance (Android-only semantically, but always present; -1 = unknown)\r\n benchmarkLevel: number;\r\n // Authorization switches (simulated \u2014 preview grants everything)\r\n albumAuthorized: boolean;\r\n cameraAuthorized: boolean;\r\n locationAuthorized: boolean;\r\n microphoneAuthorized: boolean;\r\n notificationAuthorized: boolean;\r\n notificationAlertAuthorized: boolean;\r\n notificationBadgeAuthorized: boolean;\r\n notificationSoundAuthorized: boolean;\r\n phoneCalendarAuthorized: boolean;\r\n // System switches\r\n bluetoothEnabled: boolean;\r\n locationEnabled: boolean;\r\n wifiEnabled: boolean;\r\n // Safe area\r\n safeArea: {\r\n left: number;\r\n right: number;\r\n top: number;\r\n bottom: number;\r\n width: number;\r\n height: number;\r\n };\r\n locationReducedAccuracy: boolean;\r\n // Theme (may be undefined if darkmode not configured; preview defaults to 'light')\r\n theme: string;\r\n // Host environment\r\n host: {\r\n appId: string;\r\n };\r\n enableDebug: boolean;\r\n deviceOrientation: string;\r\n}\r\n\r\nexport interface WindowInfo {\r\n windowWidth: number;\r\n windowHeight: number;\r\n screenWidth: number;\r\n screenHeight: number;\r\n pixelRatio: number;\r\n statusBarHeight: number;\r\n safeArea: {\r\n left: number;\r\n right: number;\r\n top: number;\r\n bottom: number;\r\n width: number;\r\n height: number;\r\n };\r\n}\r\n\r\n/**\r\n * Derive platform/system/brand from the device platform config.\r\n * Reads from window.__wxDevicePlatform (set by game-host.ts) or\r\n * the `devicePlatform` URL query param (legacy mode).\r\n * Possible values: \"ios\", \"android\", \"windows\", \"mac\", \"ipad\", \"huawei\".\r\n * Falls back to iOS when unset.\r\n */\r\nfunction getPlatformInfo(modelName: string): { platform: string; system: string; brand: string } {\r\n const _win = window as unknown as Record<string, unknown>;\r\n const dp = (typeof _win.__wxDevicePlatform === 'string' ? (_win.__wxDevicePlatform as string) : URL_PARAMS.get('devicePlatform') || '').toLowerCase();\r\n switch (dp) {\r\n case 'android':\r\n return { platform: 'android', system: 'Android 13', brand: 'Google' };\r\n case 'huawei':\r\n return { platform: 'android', system: 'HarmonyOS 4.0', brand: 'HUAWEI' };\r\n case 'windows':\r\n return { platform: 'windows', system: 'Windows 11', brand: 'PC' };\r\n case 'mac':\r\n return { platform: 'mac', system: 'macOS 14.0', brand: 'Apple' };\r\n case 'ipad':\r\n return { platform: 'ios', system: 'iPadOS 17.0', brand: 'Apple' };\r\n case 'ios':\r\n default:\r\n return { platform: 'ios', system: 'iOS 17.0', brand: 'Apple' };\r\n }\r\n}\r\n\r\nfunction buildSystemInfo(): SystemInfo {\r\n const _win = window as unknown as Record<string, unknown>;\r\n const modelName = (typeof _win.__wxDeviceModel === 'string' ? (_win.__wxDeviceModel as string) : null)\r\n || URL_PARAMS.get('model') || 'iPhone';\r\n const { platform, system, brand } = getPlatformInfo(modelName);\r\n const statusBarHeight = platform === 'windows' || platform === 'mac' ? 0 : 44;\r\n const appId = (typeof _win.__wxAppId === 'string' ? (_win.__wxAppId as string) : '') || '';\r\n const deviceOrientation = DEVICE.width > DEVICE.height ? 'landscape' : 'portrait';\r\n const info: SystemInfo = {\r\n brand,\r\n model: modelName,\r\n pixelRatio: DEVICE.pixelRatio,\r\n screenWidth: DEVICE.width,\r\n screenHeight: DEVICE.height,\r\n windowWidth: DEVICE.width,\r\n windowHeight: DEVICE.height,\r\n statusBarHeight,\r\n language: navigator.language || 'zh_CN',\r\n version: '8.0.54',\r\n system,\r\n platform,\r\n fontSizeSetting: 16,\r\n SDKVersion: '3.7.1',\r\n // Performance: -1 means \"unknown\" per official doc. Matches devtools default.\r\n benchmarkLevel: -1,\r\n // Authorization: preview environment grants all \u2014 games commonly read these\r\n // synchronously and short-circuit if any are false.\r\n albumAuthorized: true,\r\n cameraAuthorized: true,\r\n locationAuthorized: true,\r\n microphoneAuthorized: true,\r\n notificationAuthorized: true,\r\n notificationAlertAuthorized: true,\r\n notificationBadgeAuthorized: true,\r\n notificationSoundAuthorized: true,\r\n phoneCalendarAuthorized: true,\r\n bluetoothEnabled: false,\r\n locationEnabled: true,\r\n wifiEnabled: true,\r\n safeArea: {\r\n left: 0,\r\n right: DEVICE.width,\r\n top: statusBarHeight,\r\n bottom: DEVICE.height,\r\n width: DEVICE.width,\r\n height: DEVICE.height - statusBarHeight,\r\n },\r\n locationReducedAccuracy: false,\r\n theme: 'light',\r\n host: { appId },\r\n enableDebug: true,\r\n deviceOrientation,\r\n };\r\n return info;\r\n}\r\n\r\nexport function getSystemInfoSync(): SystemInfo {\r\n return buildSystemInfo();\r\n}\r\n\r\nexport function getSystemInfo(opts: {\r\n success?: (info: SystemInfo) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n try {\r\n const info = buildSystemInfo();\r\n opts.success?.(info);\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String(e) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n}\r\n\r\n/**\r\n * P0: wx.getSystemInfoAsync \u2014 async version of getSystemInfo.\r\n */\r\nexport function getSystemInfoAsync(opts: {\r\n success?: (info: SystemInfo) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n // Use Promise.resolve to make it truly asynchronous\r\n Promise.resolve().then(() => {\r\n try {\r\n const info = buildSystemInfo();\r\n opts.success?.(info);\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String(e) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * P0: wx.getWindowInfo \u2014 returns window-related information.\r\n */\r\nexport function getWindowInfo(): WindowInfo {\r\n const info = buildSystemInfo();\r\n return {\r\n windowWidth: info.windowWidth,\r\n windowHeight: info.windowHeight,\r\n screenWidth: info.screenWidth,\r\n screenHeight: info.screenHeight,\r\n pixelRatio: info.pixelRatio,\r\n statusBarHeight: info.statusBarHeight,\r\n safeArea: info.safeArea,\r\n };\r\n}\r\n\r\n// \u2500\u2500\u2500 P2: Additional System Info APIs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport interface DeviceInfo {\r\n brand: string;\r\n model: string;\r\n system: string;\r\n platform: string;\r\n deviceAbi: string;\r\n cpuType: string;\r\n memorySize: number;\r\n benchmarkLevel: number;\r\n}\r\n\r\n/**\r\n * P2: wx.getDeviceInfo \u2014 returns simulated device info.\r\n */\r\nexport function getDeviceInfo(): DeviceInfo {\r\n const info = buildSystemInfo();\r\n return {\r\n brand: info.brand,\r\n model: info.model,\r\n system: info.system,\r\n platform: info.platform,\r\n deviceAbi: '',\r\n cpuType: '',\r\n memorySize: (navigator as unknown as { deviceMemory?: number }).deviceMemory || 4,\r\n benchmarkLevel: info.benchmarkLevel,\r\n };\r\n}\r\n\r\nexport interface AppBaseInfo {\r\n SDKVersion: string;\r\n enableDebug: boolean;\r\n host: { appId: string };\r\n language: string;\r\n version: string;\r\n theme: string;\r\n}\r\n\r\n/**\r\n * P2: wx.getAppBaseInfo \u2014 returns simulated app base info.\r\n */\r\nexport function getAppBaseInfo(): AppBaseInfo {\r\n return {\r\n SDKVersion: '3.7.1',\r\n enableDebug: true,\r\n host: { appId: '' },\r\n language: navigator.language || 'zh_CN',\r\n version: '8.0.54',\r\n theme: 'light',\r\n };\r\n}\r\n\r\nexport interface SystemSetting {\r\n bluetoothEnabled: boolean;\r\n locationEnabled: boolean;\r\n wifiEnabled: boolean;\r\n deviceOrientation: string;\r\n}\r\n\r\n/**\r\n * P2: wx.getSystemSetting \u2014 returns simulated system setting.\r\n */\r\nexport function getSystemSetting(): SystemSetting {\r\n const info = buildSystemInfo();\r\n return {\r\n bluetoothEnabled: info.bluetoothEnabled,\r\n locationEnabled: info.locationEnabled,\r\n wifiEnabled: info.wifiEnabled,\r\n deviceOrientation: info.deviceOrientation,\r\n };\r\n}\r\n\r\n/**\r\n * P2: wx.getDeviceBenchmarkInfo \u2014 returns simulated benchmark info.\r\n */\r\nexport function getDeviceBenchmarkInfo(opts?: {\r\n success?: (res: { benchmarkLevel: number }) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n const info = buildSystemInfo();\r\n opts?.success?.({ benchmarkLevel: info.benchmarkLevel });\r\n opts?.complete?.();\r\n}\r\n", "/**\r\n * Storage module \u2014 localStorage-backed implementation of wx storage APIs.\r\n *\r\n * Uses nativeLocalStorage (captured before cleanGlobals runs) so the wx\r\n * storage shim keeps working even after the sandbox deletes window.localStorage.\r\n */\r\n\r\nimport { nativeLocalStorage } from './native-globals';\r\n\r\nconst STORAGE_PREFIX = 'wx_storage_';\r\n\r\nexport function setStorageSync(key: string, value: unknown): void {\r\n try {\r\n nativeLocalStorage.setItem(STORAGE_PREFIX + key, JSON.stringify(value));\r\n } catch (e) {\r\n throw new Error(`setStorageSync failed: ${e}`);\r\n }\r\n}\r\n\r\nexport function getStorageSync(key: string): unknown {\r\n try {\r\n const raw = nativeLocalStorage.getItem(STORAGE_PREFIX + key);\r\n if (raw === null) return '';\r\n return JSON.parse(raw);\r\n } catch {\r\n return '';\r\n }\r\n}\r\n\r\nexport function removeStorageSync(key: string): void {\r\n nativeLocalStorage.removeItem(STORAGE_PREFIX + key);\r\n}\r\n\r\nexport function clearStorageSync(): void {\r\n const keysToRemove: string[] = [];\r\n for (let i = 0; i < nativeLocalStorage.length; i++) {\r\n const k = nativeLocalStorage.key(i);\r\n if (k && k.startsWith(STORAGE_PREFIX)) {\r\n keysToRemove.push(k);\r\n }\r\n }\r\n keysToRemove.forEach((k) => nativeLocalStorage.removeItem(k));\r\n}\r\n\r\nexport function setStorage(opts: {\r\n key: string;\r\n data: unknown;\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n try {\r\n setStorageSync(opts.key, opts.data);\r\n opts.success?.();\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String(e) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n}\r\n\r\nexport function getStorage(opts: {\r\n key: string;\r\n success?: (res: { data: unknown }) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n try {\r\n const data = getStorageSync(opts.key);\r\n opts.success?.({ data });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String(e) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n}\r\n\r\nexport function removeStorage(opts: {\r\n key: string;\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n try {\r\n removeStorageSync(opts.key);\r\n opts.success?.();\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String(e) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n}\r\n\r\nexport function clearStorage(opts: {\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n try {\r\n clearStorageSync();\r\n opts.success?.();\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String(e) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 P2: Storage Info \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport interface StorageInfo {\r\n keys: string[];\r\n currentSize: number; // KB\r\n limitSize: number; // KB\r\n}\r\n\r\nexport function getStorageInfoSync(): StorageInfo {\r\n const keys: string[] = [];\r\n let totalSize = 0;\r\n for (let i = 0; i < nativeLocalStorage.length; i++) {\r\n const key = nativeLocalStorage.key(i);\r\n if (key && key.startsWith(STORAGE_PREFIX)) {\r\n const realKey = key.slice(STORAGE_PREFIX.length);\r\n keys.push(realKey);\r\n const val = nativeLocalStorage.getItem(key) || '';\r\n totalSize += key.length + val.length;\r\n }\r\n }\r\n return {\r\n keys,\r\n currentSize: Math.ceil(totalSize * 2 / 1024), // rough estimate (UTF-16)\r\n limitSize: 10240, // 10MB limit (similar to WeChat)\r\n };\r\n}\r\n\r\nexport function getStorageInfo(opts: {\r\n success?: (res: StorageInfo) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n try {\r\n const info = getStorageInfoSync();\r\n opts.success?.(info);\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String(e) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 P2: Buffer URL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * P2: wx.createBufferURL \u2014 creates a Blob URL from an ArrayBuffer.\r\n */\r\nexport function createBufferURL(buffer: ArrayBuffer): string {\r\n const blob = new Blob([buffer]);\r\n return URL.createObjectURL(blob);\r\n}\r\n\r\n/**\r\n * P2: wx.revokeBufferURL \u2014 revokes a previously created Blob URL.\r\n */\r\nexport function revokeBufferURL(url: string): void {\r\n URL.revokeObjectURL(url);\r\n}\r\n", "/**\r\n * Animation frame module with pause/resume support.\r\n *\r\n * Uses captured native references from native-globals to avoid infinite\r\n * recursion when our wrapper is installed on window.requestAnimationFrame.\r\n */\r\n\r\nimport { nativeRequestAnimationFrame, nativeCancelAnimationFrame } from './native-globals';\r\n\r\nlet isPaused = false;\r\nlet rafId = 0;\r\nconst pendingCallbacks: Array<(time: number) => void> = [];\r\n\r\n/**\r\n * Wrapped requestAnimationFrame that respects the pause state.\r\n * When paused, callbacks are queued but not executed.\r\n */\r\nexport function requestAnimationFrame(callback: (time: number) => void): number {\r\n if (isPaused) {\r\n pendingCallbacks.push(callback);\r\n return ++rafId;\r\n }\r\n return nativeRequestAnimationFrame(callback);\r\n}\r\n\r\nexport function cancelAnimationFrame(id: number): void {\r\n nativeCancelAnimationFrame(id);\r\n}\r\n\r\nexport function pauseAnimationFrames(): void {\r\n isPaused = true;\r\n}\r\n\r\nexport function resumeAnimationFrames(): void {\r\n isPaused = false;\r\n // Flush queued callbacks\r\n const queued = pendingCallbacks.splice(0);\r\n queued.forEach((cb) => nativeRequestAnimationFrame(cb));\r\n}\r\n", "/**\r\n * Audio module \u2014 InnerAudioContext implementation using HTML5 Audio.\r\n *\r\n * Uses captured native Audio/AudioContext constructors to avoid circular calls\r\n * when web-adapter replaces global Audio with a shim that calls wx APIs.\r\n */\r\n\r\nimport { NativeAudio, NativeAudioContext, nativeConsole, nativeFetch } from './native-globals';\r\nimport { getFileSystemManager } from './file-system';\r\nimport { resolveGameUrl } from './url-utils';\r\nimport { isVfsUrl, fromVfsUrl, getArrayBuffer as vfsGetArrayBuffer } from './virtual-fs';\r\n\r\n// \u2500\u2500\u2500 Audio src resolution (wxvfs / wxfile / relative) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n//\r\n// Cocos (and other engines) drive audio by doing `new Audio(); audio.src =\r\n// 'sfx/foo.mp3'` under the hood. In wxapkg-mode those assets live in the\r\n// in-memory VFS behind our `wxvfs:` pseudo-URL, which the browser refuses to\r\n// fetch \u2014 the <audio> element fires an `error` event, and Cocos reports\r\n// \"failed to load innerAudioContext\".\r\n//\r\n// We mirror the strategy image.ts uses for `<img>.src`: monkey-patch the\r\n// `src` descriptor on the captured NativeAudio prototype (which is\r\n// HTMLMediaElement.prototype). When the game assigns a pseudo-URL, we\r\n// materialise the bytes into a Blob URL on the fly and pass that to the\r\n// real setter. http(s) and data: URLs pass through unchanged.\r\n\r\n/** Guess MIME type from file extension (audio formats). */\r\nfunction guessAudioMimeType(path: string): string {\r\n const lower = path.toLowerCase();\r\n const dot = lower.lastIndexOf('.');\r\n const ext = dot >= 0 ? lower.substring(dot) : '';\r\n switch (ext) {\r\n case '.mp3': return 'audio/mpeg';\r\n case '.m4a': return 'audio/mp4';\r\n case '.aac': return 'audio/aac';\r\n case '.ogg': return 'audio/ogg';\r\n case '.oga': return 'audio/ogg';\r\n case '.opus': return 'audio/ogg';\r\n case '.wav': return 'audio/wav';\r\n case '.webm': return 'audio/webm';\r\n case '.flac': return 'audio/flac';\r\n default: return 'audio/mpeg';\r\n }\r\n}\r\n\r\n/**\r\n * Resolve a pseudo-URL that the browser cannot fetch directly (`wxfile://`,\r\n * `wxvfs:`) into a `blob:` URL backed by the in-memory bytes. Returns the\r\n * original value unchanged for schemes the browser can handle itself.\r\n */\r\nexport function resolveAudioSrc(value: string): string {\r\n if (!value) return value;\r\n\r\n if (value.startsWith('wxfile://')) {\r\n try {\r\n const fs = getFileSystemManager();\r\n const data = fs.readFileSync(value) as ArrayBuffer;\r\n const mime = guessAudioMimeType(value);\r\n const blob = new Blob([data], { type: mime });\r\n return URL.createObjectURL(blob);\r\n } catch (e) {\r\n nativeConsole.warn(`[wx-compat][resolveAudioSrc] Failed to read wxfile path: ${value}`, e);\r\n return '';\r\n }\r\n }\r\n\r\n if (isVfsUrl(value)) {\r\n const path = fromVfsUrl(value);\r\n const buf = vfsGetArrayBuffer(path);\r\n if (!buf) {\r\n nativeConsole.warn(`[wx-compat][resolveAudioSrc] wxvfs path not in VFS: ${path}`);\r\n return '';\r\n }\r\n const mime = guessAudioMimeType(path);\r\n const blob = new Blob([buf], { type: mime });\r\n return URL.createObjectURL(blob);\r\n }\r\n\r\n return value;\r\n}\r\n\r\n// \u2500\u2500\u2500 HTMLMediaElement.src prototype patch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n//\r\n// Installed once at module load. We look up the `src` descriptor by walking\r\n// the prototype chain of NativeAudio (Audio \u2192 HTMLAudioElement \u2192\r\n// HTMLMediaElement), patch the setter to route pseudo-URLs through\r\n// resolveAudioSrc, and keep a per-element blob URL so we can revoke it on\r\n// the next assignment. The getter still returns the original string that\r\n// game code assigned, matching WeChat real-device behaviour (and avoiding\r\n// surprises for engines that compare `audio.src` against their own cache\r\n// key).\r\n\r\n(() => {\r\n if (!NativeAudio) return;\r\n\r\n // Walk prototype chain to find the `src` descriptor (usually on\r\n // HTMLMediaElement.prototype). HTMLMediaElement may not be exposed as a\r\n // global inside the sandbox, so we walk via NativeAudio.prototype.\r\n let nativeSrcDescriptor: PropertyDescriptor | undefined;\r\n let proto: object | null = NativeAudio.prototype;\r\n while (proto && !nativeSrcDescriptor) {\r\n const d = Object.getOwnPropertyDescriptor(proto, 'src');\r\n if (d && d.get && d.set) nativeSrcDescriptor = d;\r\n proto = Object.getPrototypeOf(proto);\r\n }\r\n\r\n if (!nativeSrcDescriptor || !nativeSrcDescriptor.get || !nativeSrcDescriptor.set) {\r\n nativeConsole.warn('[wx-compat][audio] HTMLMediaElement.src descriptor not found; wxvfs audio disabled');\r\n return;\r\n }\r\n\r\n const nativeGet = nativeSrcDescriptor.get;\r\n const nativeSet = nativeSrcDescriptor.set;\r\n // Find the prototype that owns the descriptor so we can patch it in place.\r\n let ownerProto: object | null = NativeAudio.prototype;\r\n while (ownerProto && !Object.getOwnPropertyDescriptor(ownerProto, 'src')) {\r\n ownerProto = Object.getPrototypeOf(ownerProto);\r\n }\r\n if (!ownerProto) return;\r\n\r\n // Per-element state: the string the game last assigned, and the blob URL\r\n // we created for it (so we can revoke on reassignment / cleanup).\r\n const origSrcMap = new WeakMap<object, string>();\r\n const blobUrlMap = new WeakMap<object, string>();\r\n\r\n Object.defineProperty(ownerProto, 'src', {\r\n configurable: true,\r\n enumerable: true,\r\n get(this: HTMLMediaElement) {\r\n const stored = origSrcMap.get(this);\r\n if (stored !== undefined) return stored;\r\n return nativeGet.call(this);\r\n },\r\n set(this: HTMLMediaElement, value: string) {\r\n // Remember what game code assigned so the getter returns it verbatim.\r\n origSrcMap.set(this, value);\r\n\r\n // Revoke previous blob URL, if any, before creating a new one.\r\n const prevBlob = blobUrlMap.get(this);\r\n if (prevBlob) {\r\n try { URL.revokeObjectURL(prevBlob); } catch { /* noop */ }\r\n blobUrlMap.delete(this);\r\n }\r\n\r\n // Normalise: wxfile:// / wxvfs: are pass-through to resolveAudioSrc.\r\n // Other strings may still be relative \u2014 run through resolveGameUrl so\r\n // VFS-mounted assets (e.g. \"audio/foo.mp3\") get rewritten to wxvfs:.\r\n let resolved = value;\r\n if (\r\n typeof value === 'string' &&\r\n value &&\r\n !value.startsWith('wxfile://') &&\r\n !isVfsUrl(value) &&\r\n !value.startsWith('blob:') &&\r\n !value.startsWith('data:')\r\n ) {\r\n const r = resolveGameUrl(value);\r\n if (typeof r === 'string' && r) resolved = r;\r\n }\r\n\r\n if (typeof resolved === 'string' && (resolved.startsWith('wxfile://') || isVfsUrl(resolved))) {\r\n const blobUrl = resolveAudioSrc(resolved);\r\n if (blobUrl && blobUrl.startsWith('blob:')) {\r\n blobUrlMap.set(this, blobUrl);\r\n }\r\n nativeSet.call(this, blobUrl);\r\n return;\r\n }\r\n\r\n nativeSet.call(this, resolved);\r\n },\r\n });\r\n\r\n nativeConsole.log('[wx-compat][audio] HTMLMediaElement.src patched for wxvfs/wxfile support');\r\n})();\r\n\r\n// \u2500\u2500\u2500 decodeAudioData Server-side Fallback Patch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// VSCode Webview runs on Electron's stripped-down Chromium which lacks certain\r\n// audio codecs (notably AAC). When AudioContext.decodeAudioData() fails, we\r\n// POST the raw audio bytes to the local HTTP server's /api/decode-audio\r\n// endpoint, which decodes them server-side using Node.js (audio-decode package)\r\n// and returns raw PCM Float32 data. We then construct an AudioBuffer from it.\r\n//\r\n// This patch is installed at module load time so it takes effect before any\r\n// game code runs.\r\n(() => {\r\n if (!NativeAudioContext) return;\r\n\r\n const originalDecodeAudioData = NativeAudioContext.prototype.decodeAudioData;\r\n\r\n /**\r\n * Fallback: POST audio data to the server for decoding.\r\n *\r\n * The server endpoint /api/decode-audio accepts raw audio bytes and returns\r\n * a JSON response with PCM channel data (base64-encoded Float32Arrays),\r\n * sample rate, and number of channels.\r\n */\r\n async function decodeViaServer(\r\n ctx: AudioContext,\r\n audioData: ArrayBuffer,\r\n ): Promise<AudioBuffer> {\r\n // Determine the server origin from the current page URL\r\n const serverOrigin = window.location.origin;\r\n\r\n const response = await nativeFetch(`${serverOrigin}/api/decode-audio`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/octet-stream' },\r\n body: audioData,\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text().catch(() => 'unknown error');\r\n throw new DOMException(\r\n `Server-side audio decode failed (HTTP ${response.status}): ${errorText}`,\r\n 'EncodingError',\r\n );\r\n }\r\n\r\n const result = await response.json() as {\r\n sampleRate: number;\r\n numberOfChannels: number;\r\n length: number;\r\n channelData: string[]; // base64-encoded Float32Array per channel\r\n };\r\n\r\n // Construct AudioBuffer from server-decoded PCM data\r\n const audioBuffer = ctx.createBuffer(\r\n result.numberOfChannels,\r\n result.length,\r\n result.sampleRate,\r\n );\r\n\r\n for (let ch = 0; ch < result.numberOfChannels; ch++) {\r\n const base64 = result.channelData[ch];\r\n const binaryStr = atob(base64);\r\n const bytes = new Uint8Array(binaryStr.length);\r\n for (let i = 0; i < binaryStr.length; i++) {\r\n bytes[i] = binaryStr.charCodeAt(i);\r\n }\r\n const float32 = new Float32Array(bytes.buffer);\r\n audioBuffer.getChannelData(ch).set(float32);\r\n }\r\n\r\n nativeConsole.log(\r\n `[wx-compat][audio] Server-side decode succeeded: ` +\r\n `${result.length} samples, ${result.numberOfChannels}ch, ${result.sampleRate}Hz, ` +\r\n `${(result.length / result.sampleRate).toFixed(2)}s`,\r\n );\r\n\r\n return audioBuffer;\r\n }\r\n\r\n // Monkey-patch decodeAudioData on the prototype\r\n NativeAudioContext.prototype.decodeAudioData = function (\r\n audioData: ArrayBuffer,\r\n successCallback?: DecodeSuccessCallback | null,\r\n errorCallback?: DecodeErrorCallback | null,\r\n ): Promise<AudioBuffer> {\r\n const ctx = this as AudioContext;\r\n\r\n // Clone the ArrayBuffer before passing to the original decoder,\r\n // because it may detach the buffer on failure.\r\n const audioDataCopy = audioData.slice(0);\r\n\r\n // Call original first\r\n const promise = originalDecodeAudioData.call(ctx, audioData)\r\n .catch((originalError: DOMException) => {\r\n // Original decode failed \u2014 try server-side fallback\r\n nativeConsole.warn(\r\n '[wx-compat][audio] Native decodeAudioData failed, trying server-side fallback...',\r\n originalError.message,\r\n );\r\n return decodeViaServer(ctx, audioDataCopy);\r\n });\r\n\r\n // Support both callback and promise styles\r\n if (successCallback) {\r\n promise.then(successCallback).catch((err: DOMException) => {\r\n if (errorCallback) {\r\n errorCallback(err);\r\n }\r\n });\r\n }\r\n\r\n return promise;\r\n };\r\n\r\n nativeConsole.log('[wx-compat][audio] decodeAudioData server-side fallback patch installed');\r\n})();\r\n\r\nexport interface InnerAudioContext {\r\n src: string;\r\n loop: boolean;\r\n volume: number;\r\n autoplay: boolean;\r\n currentTime: number;\r\n duration: number;\r\n paused: boolean;\r\n play(): void;\r\n pause(): void;\r\n stop(): void;\r\n seek(position: number): void;\r\n destroy(): void;\r\n onPlay(callback: () => void): void;\r\n onPause(callback: () => void): void;\r\n onStop(callback: () => void): void;\r\n onEnded(callback: () => void): void;\r\n onError(callback: (res: { errMsg: string }) => void): void;\r\n onTimeUpdate(callback: () => void): void;\r\n onCanplay(callback: () => void): void;\r\n onWaiting(callback: () => void): void;\r\n onSeeked(callback: () => void): void;\r\n onSeeking(callback: () => void): void;\r\n offPlay(callback: () => void): void;\r\n offPause(callback: () => void): void;\r\n offStop(callback: () => void): void;\r\n offEnded(callback: () => void): void;\r\n offError(callback: (res: { errMsg: string }) => void): void;\r\n offTimeUpdate(callback: () => void): void;\r\n offCanplay(callback: () => void): void;\r\n offWaiting(callback: () => void): void;\r\n offSeeked(callback: () => void): void;\r\n offSeeking(callback: () => void): void;\r\n}\r\n\r\nexport function createInnerAudioContext(): InnerAudioContext {\r\n const audio = new NativeAudio();\r\n\r\n // Store callbacks for proper off* support\r\n const callbackMap = new Map<string, Set<Function>>();\r\n\r\n function addCb(event: string, cb: Function) {\r\n if (!callbackMap.has(event)) {\r\n callbackMap.set(event, new Set());\r\n }\r\n callbackMap.get(event)!.add(cb);\r\n audio.addEventListener(event, cb as EventListener);\r\n }\r\n\r\n function removeCb(event: string, cb: Function) {\r\n callbackMap.get(event)?.delete(cb);\r\n audio.removeEventListener(event, cb as EventListener);\r\n }\r\n\r\n return {\r\n get src() { return audio.src; },\r\n set src(v) { audio.src = v; },\r\n get loop() { return audio.loop; },\r\n set loop(v) { audio.loop = v; },\r\n get volume() { return audio.volume; },\r\n set volume(v) { audio.volume = Math.max(0, Math.min(1, v)); },\r\n get autoplay() { return audio.autoplay; },\r\n set autoplay(v) { audio.autoplay = v; },\r\n get currentTime() { return audio.currentTime; },\r\n get duration() { return audio.duration || 0; },\r\n get paused() { return audio.paused; },\r\n\r\n play() { audio.play().catch(() => { /* autoplay policy */ }); },\r\n pause() { audio.pause(); },\r\n stop() { audio.pause(); audio.currentTime = 0; },\r\n seek(pos) { audio.currentTime = pos; },\r\n destroy() {\r\n audio.pause();\r\n audio.src = '';\r\n // Remove all registered listeners\r\n callbackMap.forEach((cbs, event) => {\r\n cbs.forEach((cb) => audio.removeEventListener(event, cb as EventListener));\r\n });\r\n callbackMap.clear();\r\n },\r\n\r\n // on* methods\r\n onPlay(cb) { addCb('play', cb); },\r\n onPause(cb) { addCb('pause', cb); },\r\n onStop(cb) { addCb('ended', cb); },\r\n onEnded(cb) { addCb('ended', cb); },\r\n onError(cb) {\r\n const wrapper = () => cb({ errMsg: 'audio error' });\r\n (wrapper as any).__original = cb;\r\n addCb('error', wrapper);\r\n },\r\n onTimeUpdate(cb) { addCb('timeupdate', cb); },\r\n onCanplay(cb) { addCb('canplay', cb); },\r\n onWaiting(cb) { addCb('waiting', cb); },\r\n onSeeked(cb) { addCb('seeked', cb); },\r\n onSeeking(cb) { addCb('seeking', cb); },\r\n\r\n // off* methods\r\n offPlay(cb) { removeCb('play', cb); },\r\n offPause(cb) { removeCb('pause', cb); },\r\n offStop(cb) { removeCb('ended', cb); },\r\n offEnded(cb) { removeCb('ended', cb); },\r\n offError(cb) {\r\n // Find the wrapper by checking __original\r\n const cbs = callbackMap.get('error');\r\n if (cbs) {\r\n for (const wrapper of cbs) {\r\n if ((wrapper as any).__original === cb) {\r\n removeCb('error', wrapper);\r\n break;\r\n }\r\n }\r\n }\r\n },\r\n offTimeUpdate(cb) { removeCb('timeupdate', cb); },\r\n offCanplay(cb) { removeCb('canplay', cb); },\r\n offWaiting(cb) { removeCb('waiting', cb); },\r\n offSeeked(cb) { removeCb('seeked', cb); },\r\n offSeeking(cb) { removeCb('seeking', cb); },\r\n };\r\n}\r\n\r\n// \u2500\u2500\u2500 P2: Audio Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * P2: wx.setInnerAudioOption \u2014 sets global audio options (no-op in browser).\r\n */\r\nexport function setInnerAudioOption(opts: {\r\n mixWithOther?: boolean;\r\n obeyMuteSwitch?: boolean;\r\n speakerOn?: boolean;\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n // Browser audio does not have these concepts; no-op\r\n opts.success?.();\r\n opts.complete?.();\r\n}\r\n\r\n// \u2500\u2500\u2500 P2: WebAudioContext \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * P2: wx.createWebAudioContext \u2014 returns a browser-native AudioContext.\r\n * WeChat's WebAudioContext is essentially the Web Audio API, so we\r\n * return a native AudioContext directly.\r\n */\r\nexport function createWebAudioContext(): AudioContext {\r\n return new NativeAudioContext();\r\n}\r\n", "/**\r\n * Network Monitor \u2014 captures every outbound network request the game makes\r\n * (wx.request / wx.downloadFile / wx.uploadFile / wx.connectSocket / fetch /\r\n * XHR / WebSocket) so the host can score the cost of going fully offline.\r\n *\r\n * Activated by `window.__wxNetworkMonitorEnabled = true` (set by game-host.ts\r\n * from PreviewOptions.networkMonitor.enabled). When inactive, every public\r\n * function below is a cheap no-op so we add zero overhead in normal runs.\r\n *\r\n * Reports are aggregated by `<method> <url>` and posted to the parent frame\r\n * every `__wxNetworkMonitorInterval` ms (default 10s) plus once on\r\n * beforeunload. The schema is documented in `NetworkStatsReportPayload`.\r\n */\r\n\r\nimport { nativeLocation } from './native-globals';\r\n\r\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport type NetworkSource =\r\n | 'wx.request'\r\n | 'wx.downloadFile'\r\n | 'wx.uploadFile'\r\n | 'wx.connectSocket'\r\n | 'fetch'\r\n | 'xhr'\r\n | 'websocket';\r\n\r\nexport type NetworkCategory = 'static' | 'api' | 'websocket' | 'unknown';\r\n\r\nexport type ResourceKind =\r\n | 'image'\r\n | 'audio'\r\n | 'video'\r\n | 'font'\r\n | 'wasm'\r\n | 'wxapkg'\r\n | 'script'\r\n | 'json'\r\n | 'binary'\r\n | 'text'\r\n | 'other';\r\n\r\ninterface AggregatedRecord {\r\n source: NetworkSource;\r\n method: string;\r\n url: string;\r\n origin: string;\r\n category: NetworkCategory;\r\n resourceKind?: ResourceKind;\r\n count: number;\r\n bytes: number;\r\n // For ws: bytesIn/bytesOut split\r\n bytesIn?: number;\r\n bytesOut?: number;\r\n messages?: number;\r\n firstAt: number;\r\n lastAt: number;\r\n failedCount: number;\r\n status?: number;\r\n contentType?: string;\r\n errorMsg?: string;\r\n}\r\n\r\ninterface RequestHandle {\r\n key: string;\r\n startedAt: number;\r\n source: NetworkSource;\r\n method: string;\r\n url: string;\r\n category: NetworkCategory;\r\n origin: string;\r\n}\r\n\r\n// \u2500\u2500 State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nlet monitorEnabled = false;\r\nlet reportIntervalId: ReturnType<typeof setInterval> | null = null;\r\nconst records = new Map<string, AggregatedRecord>();\r\nconst skipped = {\r\n sameOrigin: 0,\r\n vfs: 0,\r\n pluginCdn: 0,\r\n cdnProxyResolved: 0,\r\n};\r\nconst monitorStartedAt = Date.now();\r\n\r\nconst DEFAULT_REPORT_INTERVAL_MS = 10_000;\r\n\r\n// \u2500\u2500 Public flags \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport function isNetworkMonitorEnabled(): boolean {\r\n return monitorEnabled;\r\n}\r\n\r\n// \u2500\u2500 Init \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport function initNetworkMonitor(): void {\r\n const win = window as unknown as Record<string, unknown>;\r\n monitorEnabled = !!win.__wxNetworkMonitorEnabled;\r\n if (!monitorEnabled) return;\r\n\r\n const intervalMs =\r\n typeof win.__wxNetworkMonitorInterval === 'number' &&\r\n (win.__wxNetworkMonitorInterval as number) > 0\r\n ? (win.__wxNetworkMonitorInterval as number)\r\n : DEFAULT_REPORT_INTERVAL_MS;\r\n\r\n console.log(\r\n `[wx-compat][network-monitor] Enabled. Report interval: ${intervalMs}ms`,\r\n );\r\n\r\n // Patch global fetch / XHR / WebSocket so non-wx.* requests are also\r\n // captured. We do this here (instead of in globals-compat.ts) so the patch\r\n // only happens when monitoring is actually on, and so the wiring stays\r\n // self-contained in this module.\r\n installGlobalNetworkHooks();\r\n\r\n reportIntervalId = setInterval(() => flushReport(), intervalMs);\r\n\r\n window.addEventListener('beforeunload', () => flushReport());\r\n}\r\n\r\nexport function stopNetworkMonitor(): void {\r\n if (reportIntervalId !== null) {\r\n clearInterval(reportIntervalId);\r\n reportIntervalId = null;\r\n }\r\n monitorEnabled = false;\r\n}\r\n\r\n// \u2500\u2500 Filtering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Decide whether a URL should be tracked. Returns the *resolved*\r\n * (cdn-proxy-unwrapped) URL when accepted, or null when skipped (and bumps\r\n * the corresponding `skipped.*` counter so the final report can show how\r\n * many same-origin / VFS / plugin-cdn requests were ignored).\r\n *\r\n * Rules:\r\n * 1. Non-http(s)/ws(s) protocols (wxvfs:, wxfile:, blob:, data:, file:) \u2192 skip.\r\n * 2. /cdn-proxy?url=<encoded> \u2192 unwrap the encoded URL and re-evaluate.\r\n * `skipped.cdnProxyResolved` tracks how many we unwrapped (purely for\r\n * diagnostics; the underlying request still gets tracked).\r\n * 3. Same-origin \u2192 skip (these are our static server's game files,\r\n * subpackages, plugin wxapkgs).\r\n * 4. Path matches /plugins-cdn/ or /api/wxapkg/ \u2192 skip (plugin packages\r\n * served by the static server itself).\r\n */\r\nfunction classifyAndAccept(rawUrl: string): {\r\n url: string;\r\n origin: string;\r\n isWs: boolean;\r\n} | null {\r\n if (!rawUrl) return null;\r\n\r\n // Strip `wxvfs:`, `wxfile:`, `blob:`, `data:`, `file:` early \u2014 none of\r\n // these touch the network.\r\n if (\r\n rawUrl.startsWith('wxvfs:') ||\r\n rawUrl.startsWith('wxfile:') ||\r\n rawUrl.startsWith('blob:') ||\r\n rawUrl.startsWith('data:') ||\r\n rawUrl.startsWith('file:')\r\n ) {\r\n skipped.vfs++;\r\n return null;\r\n }\r\n\r\n // Resolve relative \u2192 absolute against the page origin so we can inspect\r\n // origin / pathname uniformly.\r\n let parsed: URL;\r\n try {\r\n parsed = new URL(rawUrl, nativeLocation.origin);\r\n } catch {\r\n return null;\r\n }\r\n\r\n // Unwrap /cdn-proxy?url=<encoded> so we report the real downstream URL.\r\n if (parsed.pathname === '/cdn-proxy' && parsed.searchParams.has('url')) {\r\n const inner = parsed.searchParams.get('url') as string;\r\n skipped.cdnProxyResolved++;\r\n try {\r\n parsed = new URL(inner);\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n const protocol = parsed.protocol;\r\n const isHttp = protocol === 'http:' || protocol === 'https:';\r\n const isWs = protocol === 'ws:' || protocol === 'wss:';\r\n if (!isHttp && !isWs) {\r\n return null;\r\n }\r\n\r\n // Same-origin \u2192 game files served by our static server.\r\n if (parsed.origin === nativeLocation.origin) {\r\n skipped.sameOrigin++;\r\n return null;\r\n }\r\n\r\n // Plugin packages / static-server-hosted wxapkg endpoints \u2014 even if the\r\n // host configured a separate origin for them, we still treat them as\r\n // \"internal\" because they're served by infrastructure we control.\r\n const path = parsed.pathname.toLowerCase();\r\n if (\r\n path.startsWith('/plugins-cdn/') ||\r\n path.startsWith('/api/wxapkg/') ||\r\n path.startsWith('/api/wxapkg')\r\n ) {\r\n skipped.pluginCdn++;\r\n return null;\r\n }\r\n\r\n return { url: parsed.href, origin: parsed.origin, isWs };\r\n}\r\n\r\n// \u2500\u2500 Classification helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst STATIC_EXT_RE =\r\n /\\.(png|jpe?g|gif|webp|bmp|svg|ico|avif|heic|heif|mp3|m4a|wav|ogg|aac|opus|flac|mp4|webm|mov|m4v|ttf|otf|woff2?|eot|wasm|wxapkg|atlas|spine|skel|bin|dat|data|unityweb|bundle|pmtiles|ktx2|astc|basis|dds|ktx)(\\.br)?$/i;\r\n\r\nconst STATIC_CT_PREFIXES = [\r\n 'image/',\r\n 'audio/',\r\n 'video/',\r\n 'font/',\r\n 'application/wasm',\r\n 'application/font-',\r\n];\r\n\r\nfunction detectResourceKind(url: string, contentType?: string): ResourceKind {\r\n const ct = (contentType || '').toLowerCase();\r\n if (ct.startsWith('image/')) return 'image';\r\n if (ct.startsWith('audio/')) return 'audio';\r\n if (ct.startsWith('video/')) return 'video';\r\n if (ct.startsWith('font/') || ct.startsWith('application/font-')) return 'font';\r\n if (ct.includes('wasm')) return 'wasm';\r\n if (ct.includes('javascript')) return 'script';\r\n if (ct.includes('json')) return 'json';\r\n\r\n // Fall back to URL extension.\r\n const lower = url.toLowerCase().replace(/[?#].*$/, '');\r\n if (/\\.(png|jpe?g|gif|webp|bmp|svg|ico|avif|heic|heif)$/i.test(lower)) return 'image';\r\n if (/\\.(mp3|m4a|wav|ogg|aac|opus|flac)$/i.test(lower)) return 'audio';\r\n if (/\\.(mp4|webm|mov|m4v)$/i.test(lower)) return 'video';\r\n if (/\\.(ttf|otf|woff2?|eot)$/i.test(lower)) return 'font';\r\n if (/\\.wasm(\\.br)?$/i.test(lower)) return 'wasm';\r\n if (/\\.wxapkg$/i.test(lower)) return 'wxapkg';\r\n if (/\\.js$/i.test(lower)) return 'script';\r\n if (/\\.json$/i.test(lower)) return 'json';\r\n if (/\\.(bin|dat|data|unityweb|bundle|atlas|spine|skel|pmtiles|ktx2|astc|basis|dds|ktx)(\\.br)?$/i.test(lower)) {\r\n return 'binary';\r\n }\r\n if (ct.startsWith('text/')) return 'text';\r\n return 'other';\r\n}\r\n\r\nfunction classifyCategory(\r\n url: string,\r\n method: string,\r\n contentType: string | undefined,\r\n isWs: boolean,\r\n): { category: NetworkCategory; kind: ResourceKind } {\r\n if (isWs) return { category: 'websocket', kind: 'other' };\r\n\r\n const kind = detectResourceKind(url, contentType);\r\n const ct = (contentType || '').toLowerCase();\r\n\r\n // Strong signals for \"static asset\":\r\n const ctLooksStatic = STATIC_CT_PREFIXES.some((p) => ct.startsWith(p));\r\n const urlLooksStatic = STATIC_EXT_RE.test(url.replace(/[?#].*$/, ''));\r\n\r\n if (ctLooksStatic || urlLooksStatic) {\r\n return { category: 'static', kind };\r\n }\r\n\r\n // Anything that's not GET is almost certainly an API call.\r\n const m = (method || 'GET').toUpperCase();\r\n if (m !== 'GET' && m !== 'HEAD') {\r\n return { category: 'api', kind };\r\n }\r\n\r\n // GET with text/json content type \u2192 API. (Static JSON manifests slip\r\n // through here as `api` since we can't tell them apart without the URL\r\n // pattern; this is acceptable for cost evaluation \u2014 rare and small.)\r\n if (ct.includes('json') || ct.startsWith('text/')) {\r\n return { category: 'api', kind };\r\n }\r\n\r\n return { category: 'unknown', kind };\r\n}\r\n\r\n// \u2500\u2500 Recording \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction makeKey(source: NetworkSource, method: string, url: string): string {\r\n return `${source}|${method}|${url}`;\r\n}\r\n\r\n/**\r\n * Begin tracking a request. Returns a handle to be passed to\r\n * `recordResponse` (or null if the URL was filtered out).\r\n *\r\n * Safe to call when monitoring is disabled \u2014 returns null fast so callers\r\n * pay essentially nothing.\r\n */\r\nexport function recordRequest(\r\n source: NetworkSource,\r\n method: string,\r\n rawUrl: string,\r\n): RequestHandle | null {\r\n if (!monitorEnabled) return null;\r\n const accepted = classifyAndAccept(rawUrl);\r\n if (!accepted) return null;\r\n\r\n const upperMethod = (method || 'GET').toUpperCase();\r\n const key = makeKey(source, upperMethod, accepted.url);\r\n const now = Date.now();\r\n\r\n let rec = records.get(key);\r\n if (!rec) {\r\n // Initial classification with no contentType yet \u2014 this can be revised\r\n // when the response actually arrives via `recordResponse`.\r\n const c = classifyCategory(accepted.url, upperMethod, undefined, accepted.isWs);\r\n rec = {\r\n source,\r\n method: upperMethod,\r\n url: accepted.url,\r\n origin: accepted.origin,\r\n category: c.category,\r\n resourceKind: c.kind,\r\n count: 0,\r\n bytes: 0,\r\n firstAt: now,\r\n lastAt: now,\r\n failedCount: 0,\r\n };\r\n if (accepted.isWs) {\r\n rec.bytesIn = 0;\r\n rec.bytesOut = 0;\r\n rec.messages = 0;\r\n }\r\n records.set(key, rec);\r\n }\r\n rec.count += 1;\r\n rec.lastAt = now;\r\n\r\n return {\r\n key,\r\n startedAt: now,\r\n source,\r\n method: upperMethod,\r\n url: accepted.url,\r\n category: rec.category,\r\n origin: accepted.origin,\r\n };\r\n}\r\n\r\nexport function recordResponse(\r\n handle: RequestHandle | null | undefined,\r\n info: {\r\n status?: number;\r\n bytes?: number;\r\n contentType?: string;\r\n failed?: boolean;\r\n errorMsg?: string;\r\n },\r\n): void {\r\n if (!monitorEnabled || !handle) return;\r\n const rec = records.get(handle.key);\r\n if (!rec) return;\r\n\r\n if (typeof info.bytes === 'number' && info.bytes >= 0) {\r\n rec.bytes += info.bytes;\r\n }\r\n if (typeof info.status === 'number') {\r\n rec.status = info.status;\r\n }\r\n if (info.contentType) {\r\n rec.contentType = info.contentType;\r\n // Re-classify now that we know the real content type \u2014 this often\r\n // upgrades an \"unknown\" GET into a proper \"static\" or \"api\".\r\n const c = classifyCategory(rec.url, rec.method, info.contentType, false);\r\n rec.category = c.category;\r\n rec.resourceKind = c.kind;\r\n }\r\n if (info.failed) {\r\n rec.failedCount += 1;\r\n if (info.errorMsg) rec.errorMsg = info.errorMsg;\r\n }\r\n rec.lastAt = Date.now();\r\n}\r\n\r\n/** Record a single websocket message. Direction is 'in' for messages received,\r\n * 'out' for messages sent by the game. */\r\nexport function recordWebSocketEvent(\r\n handle: RequestHandle | null | undefined,\r\n direction: 'in' | 'out',\r\n bytes: number,\r\n): void {\r\n if (!monitorEnabled || !handle) return;\r\n const rec = records.get(handle.key);\r\n if (!rec) return;\r\n rec.messages = (rec.messages || 0) + 1;\r\n if (direction === 'in') {\r\n rec.bytesIn = (rec.bytesIn || 0) + bytes;\r\n } else {\r\n rec.bytesOut = (rec.bytesOut || 0) + bytes;\r\n }\r\n rec.lastAt = Date.now();\r\n}\r\n\r\n// \u2500\u2500 Reporting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ninterface KindStat {\r\n count: number;\r\n bytes: number;\r\n}\r\n\r\ninterface NetworkStatsSummary {\r\n total: { count: number; bytes: number };\r\n static: { count: number; bytes: number; byKind: Record<string, KindStat> };\r\n api: { count: number; bytes: number };\r\n websocket: {\r\n count: number;\r\n bytesIn: number;\r\n bytesOut: number;\r\n messages: number;\r\n };\r\n unknown: { count: number; bytes: number };\r\n}\r\n\r\nexport interface NetworkStatsReportPayload {\r\n type: '__wx_network_stats_report__';\r\n appId: string;\r\n generatedAt: number;\r\n windowMs: number;\r\n summary: NetworkStatsSummary;\r\n byOrigin: Record<string, { count: number; bytes: number }>;\r\n records: Array<{\r\n source: NetworkSource;\r\n method: string;\r\n url: string;\r\n origin: string;\r\n category: NetworkCategory;\r\n resourceKind?: ResourceKind;\r\n count: number;\r\n bytes: number;\r\n bytesIn?: number;\r\n bytesOut?: number;\r\n messages?: number;\r\n firstAt: number;\r\n lastAt: number;\r\n failedCount: number;\r\n status?: number;\r\n contentType?: string;\r\n errorMsg?: string;\r\n }>;\r\n skipped: {\r\n sameOrigin: number;\r\n vfs: number;\r\n pluginCdn: number;\r\n cdnProxyResolved: number;\r\n };\r\n notes: string[];\r\n}\r\n\r\nfunction buildSummary(): {\r\n summary: NetworkStatsSummary;\r\n byOrigin: Record<string, { count: number; bytes: number }>;\r\n} {\r\n const summary: NetworkStatsSummary = {\r\n total: { count: 0, bytes: 0 },\r\n static: { count: 0, bytes: 0, byKind: {} },\r\n api: { count: 0, bytes: 0 },\r\n websocket: { count: 0, bytesIn: 0, bytesOut: 0, messages: 0 },\r\n unknown: { count: 0, bytes: 0 },\r\n };\r\n const byOrigin: Record<string, { count: number; bytes: number }> = {};\r\n\r\n for (const rec of records.values()) {\r\n const totalBytes =\r\n rec.category === 'websocket'\r\n ? (rec.bytesIn || 0) + (rec.bytesOut || 0)\r\n : rec.bytes;\r\n summary.total.count += rec.count;\r\n summary.total.bytes += totalBytes;\r\n\r\n if (!byOrigin[rec.origin]) byOrigin[rec.origin] = { count: 0, bytes: 0 };\r\n byOrigin[rec.origin].count += rec.count;\r\n byOrigin[rec.origin].bytes += totalBytes;\r\n\r\n if (rec.category === 'static') {\r\n summary.static.count += rec.count;\r\n summary.static.bytes += rec.bytes;\r\n const kind = rec.resourceKind || 'other';\r\n const slot =\r\n summary.static.byKind[kind] || (summary.static.byKind[kind] = { count: 0, bytes: 0 });\r\n slot.count += rec.count;\r\n slot.bytes += rec.bytes;\r\n } else if (rec.category === 'api') {\r\n summary.api.count += rec.count;\r\n summary.api.bytes += rec.bytes;\r\n } else if (rec.category === 'websocket') {\r\n summary.websocket.count += rec.count;\r\n summary.websocket.bytesIn += rec.bytesIn || 0;\r\n summary.websocket.bytesOut += rec.bytesOut || 0;\r\n summary.websocket.messages += rec.messages || 0;\r\n } else {\r\n summary.unknown.count += rec.count;\r\n summary.unknown.bytes += rec.bytes;\r\n }\r\n }\r\n return { summary, byOrigin };\r\n}\r\n\r\n/**\r\n * Build the cumulative report and post it to the parent frame. The local\r\n * record store is intentionally NOT cleared after flush \u2014 this is a\r\n * \"session-cumulative\" report (host overwrites the on-disk JSON every time),\r\n * which is much more useful for offline-cost evaluation than fragmentary\r\n * deltas.\r\n */\r\nexport function flushReport(): void {\r\n if (!monitorEnabled) return;\r\n if (records.size === 0) return;\r\n\r\n const win = window as unknown as Record<string, unknown>;\r\n const appId =\r\n (win.__wxAppid as string) ||\r\n (win.__wxAppId as string) ||\r\n (win.__wxMonitorAppId as string) ||\r\n 'unknown';\r\n\r\n const { summary, byOrigin } = buildSummary();\r\n\r\n const payload: NetworkStatsReportPayload = {\r\n type: '__wx_network_stats_report__',\r\n appId,\r\n generatedAt: Date.now(),\r\n windowMs: Date.now() - monitorStartedAt,\r\n summary,\r\n byOrigin,\r\n records: [...records.values()].map((r) => ({\r\n source: r.source,\r\n method: r.method,\r\n url: r.url,\r\n origin: r.origin,\r\n category: r.category,\r\n resourceKind: r.resourceKind,\r\n count: r.count,\r\n bytes: r.bytes,\r\n bytesIn: r.bytesIn,\r\n bytesOut: r.bytesOut,\r\n messages: r.messages,\r\n firstAt: r.firstAt,\r\n lastAt: r.lastAt,\r\n failedCount: r.failedCount,\r\n status: r.status,\r\n contentType: r.contentType,\r\n errorMsg: r.errorMsg,\r\n })),\r\n skipped: { ...skipped },\r\n notes: [\r\n '<audio>/<video> stream loading is not intercepted at byte level.',\r\n 'Web Worker network calls inside dedicated workers may not be captured.',\r\n 'Bytes are derived from response Content-Length when available; otherwise the actual payload size after read.',\r\n ],\r\n };\r\n\r\n try {\r\n window.parent.postMessage(payload, '*');\r\n } catch (e) {\r\n console.warn('[wx-compat][network-monitor] Failed to post report:', e);\r\n }\r\n}\r\n\r\n// \u2500\u2500 Global hooks: fetch / XHR / WebSocket \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Patch window.fetch / XMLHttpRequest / WebSocket so requests issued\r\n * outside of wx.* APIs are still captured. Idempotent \u2014 if `monitorEnabled`\r\n * is false we do nothing.\r\n *\r\n * This must run AFTER globals-compat.installGlobalShims() has installed its\r\n * own patched fetch / ProxiedXMLHttpRequest, so we wrap *those* (which\r\n * means cdn-proxy URL rewriting still happens before we record). We\r\n * re-read window.fetch / window.XMLHttpRequest at patch time to get the\r\n * already-installed versions.\r\n */\r\nfunction installGlobalNetworkHooks(): void {\r\n const win = window as unknown as Record<string, unknown>;\r\n\r\n // \u2500\u2500 fetch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n const originalFetch = win.fetch as typeof fetch | undefined;\r\n if (typeof originalFetch === 'function') {\r\n const patched: typeof fetch = function monitoredFetch(\r\n input: RequestInfo | URL,\r\n init?: RequestInit,\r\n ): Promise<Response> {\r\n let url = '';\r\n let method = 'GET';\r\n try {\r\n if (typeof input === 'string') {\r\n url = input;\r\n } else if (input instanceof URL) {\r\n url = input.toString();\r\n } else {\r\n url = (input as Request).url;\r\n method = (input as Request).method || 'GET';\r\n }\r\n if (init && init.method) method = init.method;\r\n } catch {\r\n /* ignore \u2014 fall through to plain fetch */\r\n }\r\n const handle = recordRequest('fetch', method, url);\r\n const promise = originalFetch(input as RequestInfo, init);\r\n if (!handle) return promise;\r\n return promise.then(\r\n (resp) => {\r\n // Use Content-Length when available \u2014 avoids cloning huge bodies.\r\n const ct = resp.headers.get('content-type') || undefined;\r\n const lenHeader = resp.headers.get('content-length');\r\n const bytes = lenHeader ? parseInt(lenHeader, 10) || 0 : -1;\r\n if (bytes >= 0) {\r\n recordResponse(handle, {\r\n status: resp.status,\r\n bytes,\r\n contentType: ct,\r\n failed: !resp.ok,\r\n });\r\n return resp;\r\n }\r\n // No Content-Length \u2192 clone + read to learn the size, but only\r\n // for small responses to avoid doubling memory for assets.\r\n const clone = resp.clone();\r\n clone\r\n .arrayBuffer()\r\n .then((buf) => {\r\n recordResponse(handle, {\r\n status: resp.status,\r\n bytes: buf.byteLength,\r\n contentType: ct,\r\n failed: !resp.ok,\r\n });\r\n })\r\n .catch(() => {\r\n recordResponse(handle, {\r\n status: resp.status,\r\n contentType: ct,\r\n failed: !resp.ok,\r\n });\r\n });\r\n return resp;\r\n },\r\n (err) => {\r\n recordResponse(handle, {\r\n failed: true,\r\n errorMsg: err instanceof Error ? err.message : String(err),\r\n });\r\n throw err;\r\n },\r\n );\r\n };\r\n win.fetch = patched;\r\n }\r\n\r\n // \u2500\u2500 XMLHttpRequest \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n const OrigXHR = win.XMLHttpRequest as typeof XMLHttpRequest | undefined;\r\n if (typeof OrigXHR === 'function') {\r\n class MonitoredXHR extends OrigXHR {\r\n private __wxNmHandle: RequestHandle | null = null;\r\n private __wxNmMethod = 'GET';\r\n private __wxNmUrl = '';\r\n\r\n open(\r\n method: string,\r\n url: string | URL,\r\n async?: boolean,\r\n username?: string | null,\r\n password?: string | null,\r\n ): void {\r\n this.__wxNmMethod = method || 'GET';\r\n this.__wxNmUrl = String(url);\r\n if (async === undefined) {\r\n super.open(method, url);\r\n } else {\r\n super.open(\r\n method,\r\n url,\r\n async,\r\n username ?? undefined,\r\n password ?? undefined,\r\n );\r\n }\r\n }\r\n\r\n send(body?: Document | XMLHttpRequestBodyInit | null): void {\r\n this.__wxNmHandle = recordRequest('xhr', this.__wxNmMethod, this.__wxNmUrl);\r\n const handle = this.__wxNmHandle;\r\n if (handle) {\r\n const onLoadEnd = (): void => {\r\n try {\r\n const status = this.status;\r\n const ct = this.getResponseHeader && this.getResponseHeader('content-type');\r\n let bytes = 0;\r\n try {\r\n const resp: unknown = (this as XMLHttpRequest).response;\r\n if (resp instanceof ArrayBuffer) bytes = resp.byteLength;\r\n else if (resp instanceof Blob) bytes = resp.size;\r\n else if (typeof resp === 'string') bytes = resp.length;\r\n else if (this.responseText) bytes = this.responseText.length;\r\n } catch {\r\n /* responseType=='document' / 'json' may throw on some browsers */\r\n }\r\n recordResponse(handle, {\r\n status,\r\n bytes,\r\n contentType: ct || undefined,\r\n failed: status >= 400 || status === 0,\r\n });\r\n } catch {\r\n recordResponse(handle, { failed: true });\r\n }\r\n this.removeEventListener('loadend', onLoadEnd);\r\n this.removeEventListener('error', onError);\r\n };\r\n const onError = (): void => {\r\n recordResponse(handle, { failed: true, errorMsg: 'xhr error' });\r\n };\r\n this.addEventListener('loadend', onLoadEnd);\r\n this.addEventListener('error', onError);\r\n }\r\n super.send(body as XMLHttpRequestBodyInit | Document | null);\r\n }\r\n }\r\n win.XMLHttpRequest = MonitoredXHR as unknown as typeof XMLHttpRequest;\r\n }\r\n\r\n // \u2500\u2500 WebSocket \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n const OrigWS = win.WebSocket as typeof WebSocket | undefined;\r\n if (typeof OrigWS === 'function') {\r\n const Monitored = function MonitoredWebSocket(\r\n this: WebSocket,\r\n url: string | URL,\r\n protocols?: string | string[],\r\n ): WebSocket {\r\n const ws = new OrigWS(url, protocols);\r\n const handle = recordRequest('websocket', 'WS', String(url));\r\n if (handle) {\r\n ws.addEventListener('message', (e) => {\r\n let bytes = 0;\r\n const data = (e as MessageEvent).data;\r\n if (typeof data === 'string') bytes = data.length;\r\n else if (data instanceof ArrayBuffer) bytes = data.byteLength;\r\n else if (data instanceof Blob) bytes = data.size;\r\n recordWebSocketEvent(handle, 'in', bytes);\r\n });\r\n const origSend = ws.send.bind(ws);\r\n ws.send = (data: string | ArrayBufferLike | Blob | ArrayBufferView): void => {\r\n let bytes = 0;\r\n if (typeof data === 'string') bytes = data.length;\r\n else if (data instanceof Blob) bytes = data.size;\r\n else if (data && typeof (data as ArrayBuffer).byteLength === 'number') {\r\n bytes = (data as ArrayBuffer).byteLength;\r\n }\r\n recordWebSocketEvent(handle, 'out', bytes);\r\n return origSend(data);\r\n };\r\n ws.addEventListener('error', () => {\r\n recordResponse(handle, { failed: true, errorMsg: 'websocket error' });\r\n });\r\n }\r\n return ws;\r\n } as unknown as typeof WebSocket;\r\n // Preserve static constants so feature checks like WebSocket.OPEN keep\r\n // working. The constants are declared `readonly` on the WebSocket type,\r\n // so we go through `as unknown as Record<string, number>` to bypass the\r\n // readonly check while keeping the rest of the cast statically typed.\r\n const consts = Monitored as unknown as Record<string, number>;\r\n consts.CONNECTING = OrigWS.CONNECTING;\r\n consts.OPEN = OrigWS.OPEN;\r\n consts.CLOSING = OrigWS.CLOSING;\r\n consts.CLOSED = OrigWS.CLOSED;\r\n Monitored.prototype = OrigWS.prototype;\r\n win.WebSocket = Monitored;\r\n }\r\n}\r\n", "/**\r\n * Network module \u2014 wx.request, wx.connectSocket, wx.downloadFile, wx.uploadFile.\r\n *\r\n * Uses captured native fetch/WebSocket to avoid circular calls with web-adapter.\r\n */\r\n\r\nimport { NativeWebSocket, nativeFetch, nativeLocation, wxResourceFetch } from './native-globals';\r\nimport { getFileSystemManager, TMP_ROOT } from './file-system';\r\nimport { resolveGameUrl } from './url-utils';\r\nimport {\r\n recordRequest as nmRecordRequest,\r\n recordResponse as nmRecordResponse,\r\n recordWebSocketEvent as nmRecordWsEvent,\r\n} from './network-monitor';\r\n\r\n// \u2500\u2500\u2500 Concurrency limiter \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n//\r\n// Native WeChat caps wx.request to 10 concurrent requests per process and\r\n// enforces a similar limit on wx.downloadFile / wx.uploadFile (5 each).\r\n// Browsers already cap connections per origin, but a runaway game can still\r\n// blow up our memory by enqueueing thousands of in-flight fetches with large\r\n// arrayBuffer responses. We mirror the native cap so misbehaving code surfaces\r\n// the same back-pressure in preview as it would on a real device.\r\n//\r\n// `MAX_CONCURRENT_*` can be overridden via window globals before wx-compat\r\n// loads (the host page may want to relax limits during stress tests). We read\r\n// them lazily so the override always wins regardless of script ordering.\r\n//\r\n// IMPORTANT: the queue *gates entry* into nativeFetch / blob fetching, but the\r\n// abort / progress / error handling below stays unchanged. Once a slot is\r\n// granted we call the original implementation; the slot is released exactly\r\n// once via the .finally() hook on every code path.\r\n\r\ninterface QueueEntry {\r\n run: () => void;\r\n}\r\n\r\nclass ConcurrencyLimiter {\r\n private active = 0;\r\n private queue: QueueEntry[] = [];\r\n constructor(private readonly defaultMax: number, private readonly globalKey: string) {}\r\n private get max(): number {\r\n const override = (window as unknown as Record<string, unknown>)[this.globalKey];\r\n if (typeof override === 'number' && override > 0 && override < 1000) return override;\r\n return this.defaultMax;\r\n }\r\n /**\r\n * Schedule `task`. Returns a Promise that resolves when the task itself\r\n * resolves (or rejects). Each task MUST eventually settle so the slot can\r\n * be released; we guard with .finally() on the inner promise.\r\n */\r\n schedule<T>(task: () => Promise<T>): Promise<T> {\r\n return new Promise<T>((resolve, reject) => {\r\n const run = (): void => {\r\n this.active++;\r\n Promise.resolve()\r\n .then(task)\r\n .then(resolve, reject)\r\n .finally(() => {\r\n this.active--;\r\n this.drain();\r\n });\r\n };\r\n if (this.active < this.max) run();\r\n else this.queue.push({ run });\r\n });\r\n }\r\n private drain(): void {\r\n while (this.active < this.max && this.queue.length > 0) {\r\n this.queue.shift()!.run();\r\n }\r\n }\r\n}\r\n\r\n// Native WeChat documented caps: request=10, downloadFile=5, uploadFile=5.\r\nconst requestLimiter = new ConcurrencyLimiter(10, '__wxMaxConcurrentRequest');\r\nconst downloadLimiter = new ConcurrencyLimiter(5, '__wxMaxConcurrentDownload');\r\nconst uploadLimiter = new ConcurrencyLimiter(5, '__wxMaxConcurrentUpload');\r\n\r\nexport interface RequestOptions {\r\n url: string;\r\n method?: string;\r\n data?: unknown;\r\n header?: Record<string, string>;\r\n dataType?: string;\r\n responseType?: string;\r\n success?: (res: { data: unknown; statusCode: number; header: Record<string, string> }) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}\r\n\r\n/**\r\n * P2: RequestTask \u2014 request task with abort support.\r\n */\r\nexport interface RequestTask {\r\n abort(): void;\r\n onHeadersReceived(callback: (res: { header: Record<string, string> }) => void): void;\r\n offHeadersReceived(callback: Function): void;\r\n}\r\n\r\n/**\r\n * Rewrite a URL to go through the server-side CDN proxy if it's a cross-origin\r\n * request. In WeChat, wx.request has no CORS restrictions, but in browser\r\n * preview, fetch/XHR to a different origin gets blocked by CORS.\r\n *\r\n * The static server exposes GET /cdn-proxy?url=<encoded-url> which forwards\r\n * the request server-side, bypassing browser CORS restrictions.\r\n *\r\n * Only rewrites URLs whose origin differs from the current page origin.\r\n * Same-origin and relative URLs are returned unchanged.\r\n */\r\nfunction cdnProxyUrl(url: string): string {\r\n // Internal pseudo-schemes must NEVER be routed through the CDN proxy \u2014\r\n // they're served entirely from memory / the local runtime and would\r\n // otherwise get URL-encoded into `/cdn-proxy?url=wxvfs%3A...` and hit\r\n // the real network (which fails, confusingly, with \"Network request\r\n // failed\" on RN WebView).\r\n //\r\n // `blob:` and `data:` are same-document resources; proxying them is\r\n // equally nonsensical. Bail out early for all four.\r\n if (\r\n url.startsWith('wxvfs:') ||\r\n url.startsWith('wxfile://') ||\r\n url.startsWith('blob:') ||\r\n url.startsWith('data:')\r\n ) {\r\n return url;\r\n }\r\n try {\r\n const currentOrigin = nativeLocation.origin;\r\n const parsed = new URL(url, currentOrigin);\r\n // Only proxy absolute URLs that are cross-origin.\r\n // Guard against `parsed.origin === 'null'` (opaque origins from e.g.\r\n // srcdoc iframes in some WebViews), which would otherwise match the\r\n // cross-origin branch even for same-document URLs.\r\n if (parsed.origin && parsed.origin !== 'null' && parsed.origin !== currentOrigin) {\r\n return `/cdn-proxy?url=${encodeURIComponent(parsed.href)}`;\r\n }\r\n } catch {\r\n // Invalid URL \u2014 return as-is\r\n }\r\n return url;\r\n}\r\n\r\n/** Expose cdnProxyUrl for use by other modules (e.g. globals-compat XMLHttpRequest proxy) */\r\nexport { cdnProxyUrl };\r\n\r\nexport function request(opts: RequestOptions): RequestTask {\r\n const method = (opts.method || 'GET').toUpperCase();\r\n const headers: Record<string, string> = opts.header || {};\r\n const controller = new AbortController();\r\n\r\n const fetchOpts: RequestInit = {\r\n method,\r\n headers,\r\n signal: controller.signal,\r\n };\r\n\r\n if (method !== 'GET' && method !== 'HEAD' && opts.data !== undefined) {\r\n if (typeof opts.data === 'string') {\r\n fetchOpts.body = opts.data;\r\n } else {\r\n fetchOpts.body = JSON.stringify(opts.data);\r\n if (!headers['content-type'] && !headers['Content-Type']) {\r\n (fetchOpts.headers as Record<string, string>)['Content-Type'] = 'application/json';\r\n }\r\n }\r\n }\r\n\r\n const headersReceivedCallbacks: Set<(res: { header: Record<string, string> }) => void> = new Set();\r\n\r\n // Resolve relative URLs against the game asset base URL first, then proxy\r\n // cross-origin absolute URLs through the server to bypass CORS.\r\n const resolvedUrl = resolveGameUrl(opts.url);\r\n const fetchUrl = cdnProxyUrl(resolvedUrl);\r\n\r\n // Network-monitor: hand the resolver the *real* (un-proxied) URL so the\r\n // report records the actual downstream origin instead of our same-origin\r\n // /cdn-proxy wrapper. Filtering of same-origin / vfs / plugin-cdn happens\r\n // inside the monitor.\r\n const nmHandle = nmRecordRequest('wx.request', method, resolvedUrl);\r\n\r\n // Gate the actual nativeFetch through the request limiter so a runaway\r\n // game cannot exceed native's 10-concurrent-request budget. Aborts before\r\n // the slot is granted are honored: the queued task checks `signal.aborted`\r\n // and short-circuits with the same AbortError that fetch would have raised.\r\n requestLimiter\r\n .schedule(() => {\r\n if (controller.signal.aborted) {\r\n return Promise.reject(Object.assign(new Error('aborted'), { name: 'AbortError' }));\r\n }\r\n return nativeFetch(fetchUrl, fetchOpts);\r\n })\r\n .then(async (response) => {\r\n const responseHeaders: Record<string, string> = {};\r\n response.headers.forEach((value, key) => {\r\n responseHeaders[key] = value;\r\n });\r\n\r\n // Fire headers received callbacks\r\n headersReceivedCallbacks.forEach((cb) => cb({ header: responseHeaders }));\r\n\r\n let data: unknown;\r\n const ct = responseHeaders['content-type'] || '';\r\n let bytes = 0;\r\n if (opts.responseType === 'arraybuffer') {\r\n const buf = await response.arrayBuffer();\r\n bytes = buf.byteLength;\r\n data = buf;\r\n } else if (ct.includes('application/json') || opts.dataType === 'json') {\r\n const text = await response.text().catch(() => '');\r\n bytes = text.length;\r\n try { data = JSON.parse(text); } catch { data = null; }\r\n } else {\r\n const text = await response.text();\r\n bytes = text.length;\r\n data = text;\r\n }\r\n\r\n // Prefer Content-Length header when present (more accurate than the\r\n // post-decode length above for compressed responses).\r\n const lenHeader = responseHeaders['content-length'];\r\n const headerBytes = lenHeader ? parseInt(lenHeader, 10) || -1 : -1;\r\n nmRecordResponse(nmHandle, {\r\n status: response.status,\r\n bytes: headerBytes >= 0 ? headerBytes : bytes,\r\n contentType: ct,\r\n failed: !response.ok,\r\n });\r\n\r\n opts.success?.({\r\n data,\r\n statusCode: response.status,\r\n header: responseHeaders,\r\n });\r\n })\r\n .catch((err) => {\r\n nmRecordResponse(nmHandle, {\r\n failed: true,\r\n errorMsg: err instanceof Error ? err.message : String(err),\r\n });\r\n if (err.name !== 'AbortError') {\r\n opts.fail?.({ errMsg: String(err) });\r\n } else {\r\n opts.fail?.({ errMsg: 'request:fail abort' });\r\n }\r\n })\r\n .finally(() => {\r\n opts.complete?.();\r\n });\r\n\r\n return {\r\n abort() {\r\n controller.abort();\r\n },\r\n onHeadersReceived(callback) {\r\n headersReceivedCallbacks.add(callback);\r\n },\r\n offHeadersReceived(callback) {\r\n headersReceivedCallbacks.delete(callback as any);\r\n },\r\n };\r\n}\r\n\r\n// \u2500\u2500\u2500 WebSocket (P1) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n// Track the last created SocketTask for global WebSocket API compatibility\r\nlet _lastSocketTask: SocketTask | null = null;\r\n\r\n/**\r\n * SocketTask wraps a native WebSocket with WeChat-compatible API.\r\n */\r\nexport class SocketTask {\r\n private ws: WebSocket;\r\n private _onOpenCbs: Set<Function> = new Set();\r\n private _onMessageCbs: Set<Function> = new Set();\r\n private _onErrorCbs: Set<Function> = new Set();\r\n private _onCloseCbs: Set<Function> = new Set();\r\n\r\n constructor(ws: WebSocket) {\r\n this.ws = ws;\r\n ws.addEventListener('open', () => {\r\n this._onOpenCbs.forEach((cb) => (cb as Function)({ header: {} }));\r\n });\r\n ws.addEventListener('message', (e) => {\r\n this._onMessageCbs.forEach((cb) => (cb as Function)({ data: e.data }));\r\n });\r\n ws.addEventListener('error', () => {\r\n this._onErrorCbs.forEach((cb) => (cb as Function)({ errMsg: 'WebSocket error' }));\r\n });\r\n ws.addEventListener('close', (e) => {\r\n this._onCloseCbs.forEach((cb) => (cb as Function)({ code: e.code, reason: e.reason }));\r\n });\r\n }\r\n\r\n send(opts: {\r\n data: string | ArrayBuffer;\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n }): void {\r\n try {\r\n this.ws.send(opts.data);\r\n opts.success?.();\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String(e) });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n }\r\n\r\n close(opts?: {\r\n code?: number;\r\n reason?: string;\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n }): void {\r\n try {\r\n this.ws.close(opts?.code ?? 1000, opts?.reason ?? '');\r\n opts?.success?.();\r\n } catch (e) {\r\n opts?.fail?.({ errMsg: String(e) });\r\n } finally {\r\n opts?.complete?.();\r\n }\r\n }\r\n\r\n onOpen(callback: Function): void { this._onOpenCbs.add(callback); }\r\n onMessage(callback: Function): void { this._onMessageCbs.add(callback); }\r\n onError(callback: Function): void { this._onErrorCbs.add(callback); }\r\n onClose(callback: Function): void { this._onCloseCbs.add(callback); }\r\n}\r\n\r\nexport function connectSocket(opts: {\r\n url: string;\r\n header?: Record<string, string>;\r\n protocols?: string[];\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): SocketTask {\r\n try {\r\n const ws = new NativeWebSocket(opts.url, opts.protocols);\r\n // Network-monitor: register the socket up-front so we count the\r\n // connect attempt even when no message is ever exchanged.\r\n const nmHandle = nmRecordRequest('wx.connectSocket', 'WS', opts.url);\r\n if (nmHandle) {\r\n ws.addEventListener('message', (e) => {\r\n let b = 0;\r\n const d = e.data;\r\n if (typeof d === 'string') b = d.length;\r\n else if (d instanceof ArrayBuffer) b = d.byteLength;\r\n else if (d instanceof Blob) b = d.size;\r\n nmRecordWsEvent(nmHandle, 'in', b);\r\n });\r\n const origSend = ws.send.bind(ws);\r\n ws.send = (data: string | ArrayBufferLike | Blob | ArrayBufferView): void => {\r\n let b = 0;\r\n if (typeof data === 'string') b = data.length;\r\n else if (data instanceof Blob) b = data.size;\r\n else if (data && typeof (data as ArrayBuffer).byteLength === 'number') {\r\n b = (data as ArrayBuffer).byteLength;\r\n }\r\n nmRecordWsEvent(nmHandle, 'out', b);\r\n return origSend(data);\r\n };\r\n ws.addEventListener('error', () => {\r\n nmRecordResponse(nmHandle, { failed: true, errorMsg: 'wx.connectSocket error' });\r\n });\r\n }\r\n const task = new SocketTask(ws);\r\n _lastSocketTask = task;\r\n opts.success?.();\r\n opts.complete?.();\r\n return task;\r\n } catch (e) {\r\n opts.fail?.({ errMsg: String(e) });\r\n opts.complete?.();\r\n // Return a dummy SocketTask that does nothing\r\n const dummyWs = { addEventListener: () => {}, send: () => {}, close: () => {} } as unknown as WebSocket;\r\n return new SocketTask(dummyWs);\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 Download File (P1) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * DownloadTask \u2014 returned by wx.downloadFile, supports abort and progress callbacks.\r\n */\r\nexport interface DownloadTask {\r\n abort(): void;\r\n onProgressUpdate(callback: (res: { progress: number; totalBytesWritten: number; totalBytesExpectedToWrite: number }) => void): void;\r\n offProgressUpdate(callback: Function): void;\r\n onHeadersReceived(callback: (res: { header: Record<string, string> }) => void): void;\r\n offHeadersReceived(callback: Function): void;\r\n}\r\n\r\nexport function downloadFile(opts: {\r\n url: string;\r\n header?: Record<string, string>;\r\n filePath?: string;\r\n success?: (res: { tempFilePath: string; filePath?: string; statusCode: number }) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): DownloadTask {\r\n const controller = new AbortController();\r\n const progressCallbacks: Set<Function> = new Set();\r\n const headersReceivedCallbacks: Set<Function> = new Set();\r\n\r\n const task: DownloadTask = {\r\n abort() { controller.abort(); },\r\n onProgressUpdate(cb) { progressCallbacks.add(cb); },\r\n offProgressUpdate(cb) { progressCallbacks.delete(cb); },\r\n onHeadersReceived(cb) { headersReceivedCallbacks.add(cb); },\r\n offHeadersReceived(cb) { headersReceivedCallbacks.delete(cb); },\r\n };\r\n\r\n console.log(`[wx-compat][downloadFile] url=${opts.url}, filePath=${opts.filePath || '(none)'}`);\r\n // Resolve relative URLs against the game asset base URL first, then proxy\r\n // cross-origin absolute URLs through the server to bypass CORS.\r\n const resolvedUrl = resolveGameUrl(opts.url);\r\n const fetchUrl = cdnProxyUrl(resolvedUrl);\r\n const nmHandle = nmRecordRequest('wx.downloadFile', 'GET', resolvedUrl);\r\n downloadLimiter\r\n .schedule(() => {\r\n if (controller.signal.aborted) {\r\n return Promise.reject(Object.assign(new Error('aborted'), { name: 'AbortError' }));\r\n }\r\n return nativeFetch(fetchUrl, { headers: opts.header || {}, signal: controller.signal });\r\n })\r\n .then(async (response) => {\r\n console.log(`[wx-compat][downloadFile] response status=${response.status}, ok=${response.ok}, url=${opts.url}`);\r\n // Fire headers received callbacks\r\n const responseHeaders: Record<string, string> = {};\r\n response.headers.forEach((value, key) => { responseHeaders[key] = value; });\r\n headersReceivedCallbacks.forEach((cb) => cb({ header: responseHeaders }));\r\n if (!response.ok) {\r\n opts.fail?.({ errMsg: `downloadFile:fail server returned ${response.status}` });\r\n return;\r\n }\r\n const arrayBuffer = await response.arrayBuffer();\r\n console.log(`[wx-compat][downloadFile] downloaded ${arrayBuffer.byteLength} bytes, url=${opts.url}`);\r\n nmRecordResponse(nmHandle, {\r\n status: response.status,\r\n bytes: arrayBuffer.byteLength,\r\n contentType: responseHeaders['content-type'],\r\n failed: !response.ok,\r\n });\r\n\r\n if (opts.filePath) {\r\n // When filePath is specified, save the downloaded data to the virtual FS\r\n // and return filePath (matching WeChat behavior).\r\n try {\r\n const fs = getFileSystemManager();\r\n // Ensure parent directories exist using recursive creation\r\n const parentDir = opts.filePath.substring(0, opts.filePath.lastIndexOf('/'));\r\n if (parentDir) {\r\n try { fs.mkdirSync(parentDir, true); } catch { /* already exists */ }\r\n }\r\n fs.writeFileSync(opts.filePath, arrayBuffer);\r\n opts.success?.({\r\n tempFilePath: opts.filePath,\r\n filePath: opts.filePath,\r\n statusCode: response.status,\r\n });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: `downloadFile:fail ${e}` });\r\n }\r\n } else {\r\n // No filePath specified \u2014 save to a temp path in the virtual FS.\r\n // WeChat returns a wxfile://tmp/xxx path; game code later reads it\r\n // via fs.readFile(tempFilePath). Using blob URLs would break because\r\n // the virtual FS doesn't understand blob: protocol.\r\n try {\r\n const fs = getFileSystemManager();\r\n // Extract file extension from URL, stripping query params and hash\r\n let ext = '';\r\n try {\r\n const pathname = new URL(opts.url).pathname;\r\n const dotIdx = pathname.lastIndexOf('.');\r\n if (dotIdx >= 0) ext = pathname.substring(dotIdx);\r\n } catch {\r\n const dotIdx = opts.url.lastIndexOf('.');\r\n if (dotIdx >= 0) ext = opts.url.substring(dotIdx).replace(/[?#].*$/, '');\r\n }\r\n const tempFilePath = `${TMP_ROOT}/${Date.now()}_${Math.random().toString(36).slice(2)}${ext}`;\r\n fs.writeFileSync(tempFilePath, arrayBuffer);\r\n opts.success?.({\r\n tempFilePath,\r\n statusCode: response.status,\r\n });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: `downloadFile:fail ${e}` });\r\n }\r\n }\r\n })\r\n .catch((err) => {\r\n nmRecordResponse(nmHandle, {\r\n failed: true,\r\n errorMsg: err instanceof Error ? err.message : String(err),\r\n });\r\n opts.fail?.({ errMsg: `downloadFile:fail ${err}` });\r\n })\r\n .finally(() => {\r\n opts.complete?.();\r\n });\r\n\r\n return task;\r\n}\r\n\r\n// \u2500\u2500\u2500 Upload File (P1) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport function uploadFile(opts: {\r\n url: string;\r\n filePath: string;\r\n name: string;\r\n header?: Record<string, string>;\r\n formData?: Record<string, string>;\r\n success?: (res: { data: string; statusCode: number }) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n // In browser preview, filePath is typically a blob URL or data URL\r\n const formData = new FormData();\r\n\r\n // Add form data fields\r\n if (opts.formData) {\r\n Object.entries(opts.formData).forEach(([key, value]) => {\r\n formData.append(key, value);\r\n });\r\n }\r\n\r\n // Fetch the file from filePath and append to form data.\r\n // resolveGameUrl is a no-op for blob:/data:/wxfile:/absolute URLs, and rewrites\r\n // relative paths to the game asset base URL (or a wxvfs: URL when the file\r\n // lives in the in-memory VFS).\r\n const resolvedUploadUrl = resolveGameUrl(opts.url);\r\n const nmHandle = nmRecordRequest('wx.uploadFile', 'POST', resolvedUploadUrl);\r\n uploadLimiter\r\n .schedule(async () => {\r\n const blobRes = await wxResourceFetch(resolveGameUrl(opts.filePath));\r\n const blob = await blobRes.blob();\r\n formData.append(opts.name, blob);\r\n return nativeFetch(cdnProxyUrl(resolvedUploadUrl), {\r\n method: 'POST',\r\n headers: opts.header || {},\r\n body: formData,\r\n });\r\n })\r\n .then(async (response) => {\r\n const data = await response.text();\r\n nmRecordResponse(nmHandle, {\r\n status: response.status,\r\n bytes: data.length,\r\n contentType: response.headers.get('content-type') || undefined,\r\n failed: !response.ok,\r\n });\r\n opts.success?.({\r\n data,\r\n statusCode: response.status,\r\n });\r\n })\r\n .catch((err) => {\r\n nmRecordResponse(nmHandle, {\r\n failed: true,\r\n errorMsg: err instanceof Error ? err.message : String(err),\r\n });\r\n opts.fail?.({ errMsg: `uploadFile:fail ${err}` });\r\n })\r\n .finally(() => {\r\n opts.complete?.();\r\n });\r\n}\r\n\r\n// \u2500\u2500\u2500 Global WebSocket API (P2 \u2014 legacy compatibility) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// Older games use wx.sendSocketMessage / wx.onSocketOpen instead of SocketTask.\r\n// These global APIs proxy to the most recently created SocketTask.\r\n\r\nexport function sendSocketMessage(opts: {\r\n data: string | ArrayBuffer;\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if (!_lastSocketTask) {\r\n opts.fail?.({ errMsg: 'sendSocketMessage:fail no socket connection' });\r\n opts.complete?.();\r\n return;\r\n }\r\n _lastSocketTask.send(opts);\r\n}\r\n\r\nexport function closeSocket(opts?: {\r\n code?: number;\r\n reason?: string;\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if (!_lastSocketTask) {\r\n opts?.fail?.({ errMsg: 'closeSocket:fail no socket connection' });\r\n opts?.complete?.();\r\n return;\r\n }\r\n _lastSocketTask.close(opts);\r\n}\r\n\r\nexport function onSocketOpen(callback: Function): void {\r\n if (_lastSocketTask) _lastSocketTask.onOpen(callback);\r\n}\r\n\r\nexport function onSocketClose(callback: Function): void {\r\n if (_lastSocketTask) _lastSocketTask.onClose(callback);\r\n}\r\n\r\nexport function onSocketMessage(callback: Function): void {\r\n if (_lastSocketTask) _lastSocketTask.onMessage(callback);\r\n}\r\n\r\nexport function onSocketError(callback: Function): void {\r\n if (_lastSocketTask) _lastSocketTask.onError(callback);\r\n}\r\n", "/**\r\n * Device module \u2014 vibration + P0 touch event APIs.\r\n *\r\n * Implements:\r\n * wx.vibrateShort, wx.vibrateLong\r\n * wx.onTouchStart, wx.onTouchMove, wx.onTouchEnd, wx.onTouchCancel\r\n * wx.offTouchStart, wx.offTouchMove, wx.offTouchEnd, wx.offTouchCancel\r\n */\r\n\r\nimport { getMainCanvas } from './canvas';\r\nimport { nativeDocAddEventListener, nativeHead } from './native-globals';\r\n\r\n// \u2500\u2500\u2500 Vibration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Keyframes for a 2-bounce visual shake simulation.\r\n * The animation oscillates left-right twice (~2 full cycles), then settles.\r\n * Desktops don't have real haptic motors, so this gives a visual hint that\r\n * vibrateShort/vibrateLong was invoked.\r\n *\r\n * Duration is set via animation-duration so the same keyframe works for\r\n * short (200\u202Fms) and long (400\u202Fms) vibrations.\r\n */\r\nconst SHAKE_CSS = `\r\n@keyframes wx-vibrate-shake {\r\n 0%, 100% { transform: translateX(0); }\r\n 13% { transform: translateX(-4px); }\r\n 38% { transform: translateX(4px); }\r\n 63% { transform: translateX(-4px); }\r\n 88% { transform: translateX(4px); }\r\n}\r\n`;\r\n\r\nlet shakeStyleEl: HTMLStyleElement | null = null;\r\nlet shakeTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\nfunction ensureShakeStyle(): void {\r\n if (shakeStyleEl) return;\r\n const style = document.createElement('style');\r\n style.textContent = SHAKE_CSS;\r\n nativeHead.appendChild(style);\r\n shakeStyleEl = style;\r\n}\r\n\r\n/**\r\n * Apply a brief visual shake to the game viewport and automatically\r\n * remove it after `duration` ms. Cancels any previous running shake\r\n * so repeated calls don't stack.\r\n */\r\nfunction triggerVisualShake(duration: number): void {\r\n ensureShakeStyle();\r\n\r\n const body = document.body;\r\n if (!body) return;\r\n\r\n // Cancel any in-flight shake so stacked vibrate calls don't prolong it.\r\n if (shakeTimer) {\r\n clearTimeout(shakeTimer);\r\n shakeTimer = null;\r\n body.classList.remove('wx-vibrate-shaking');\r\n }\r\n\r\n // Force reflow so re-adding the class restarts the animation from frame 0.\r\n void body.offsetWidth;\r\n\r\n body.classList.add('wx-vibrate-shaking');\r\n body.style.animation = `wx-vibrate-shake ${duration}ms ease`;\r\n\r\n shakeTimer = setTimeout(() => {\r\n body.classList.remove('wx-vibrate-shaking');\r\n body.style.animation = '';\r\n shakeTimer = null;\r\n }, duration);\r\n}\r\n\r\n/**\r\n * `wx.vibrateShort` \u2014 short vibration. Supports the WeChat-documented\r\n * `type` parameter:\r\n * - 'heavy' \u2192 ~30ms (matches Apple's UIImpactFeedbackStyleHeavy)\r\n * - 'medium' \u2192 ~20ms\r\n * - 'light' \u2192 ~10ms (default)\r\n *\r\n * Calling `navigator.vibrate(0)` cancels any previous vibration; we\r\n * intentionally do NOT do that here because games may issue rapid\r\n * back-to-back short vibrations and we want each one to fire.\r\n */\r\nexport function vibrateShort(opts?: { type?: 'heavy' | 'medium' | 'light'; success?: () => void; fail?: (e: { errMsg: string }) => void; complete?: () => void }): void {\r\n const type = opts?.type || 'light';\r\n const ms = type === 'heavy' ? 30 : type === 'medium' ? 20 : 10;\r\n if (typeof navigator !== 'undefined' && typeof navigator.vibrate === 'function') {\r\n try {\r\n navigator.vibrate(ms);\r\n } catch {\r\n // Some Safari builds throw on vibrate() even though the function exists.\r\n }\r\n }\r\n\r\n // Visual shake: two quick bounces (~200\u202Fms).\r\n triggerVisualShake(200);\r\n\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * `wx.vibrateLong` \u2014 long (~400ms) vibration.\r\n */\r\nexport function vibrateLong(opts?: { success?: () => void; fail?: (e: { errMsg: string }) => void; complete?: () => void }): void {\r\n if (typeof navigator !== 'undefined' && typeof navigator.vibrate === 'function') {\r\n try {\r\n navigator.vibrate(400);\r\n } catch {\r\n // see above\r\n }\r\n }\r\n\r\n // Visual shake: slower bounce (~400\u202Fms).\r\n triggerVisualShake(400);\r\n\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n// \u2500\u2500\u2500 Touch Events (P0) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * WeChat Touch object structure.\r\n */\r\ninterface WxTouch {\r\n identifier: number;\r\n pageX: number;\r\n pageY: number;\r\n clientX: number;\r\n clientY: number;\r\n}\r\n\r\ninterface WxTouchEvent {\r\n touches: WxTouch[];\r\n changedTouches: WxTouch[];\r\n timeStamp: number;\r\n}\r\n\r\ntype TouchCallback = (event: WxTouchEvent) => void;\r\n\r\nconst touchStartCallbacks: Set<TouchCallback> = new Set();\r\nconst touchMoveCallbacks: Set<TouchCallback> = new Set();\r\nconst touchEndCallbacks: Set<TouchCallback> = new Set();\r\nconst touchCancelCallbacks: Set<TouchCallback> = new Set();\r\n\r\n/**\r\n * Convert a browser TouchList to WeChat-style touch array,\r\n * adjusting coordinates relative to the canvas element.\r\n */\r\nfunction convertTouchList(touchList: TouchList, canvas: HTMLCanvasElement | null): WxTouch[] {\r\n const result: WxTouch[] = [];\r\n const rect = canvas?.getBoundingClientRect();\r\n const offsetX = rect?.left ?? 0;\r\n const offsetY = rect?.top ?? 0;\r\n\r\n for (let i = 0; i < touchList.length; i++) {\r\n const t = touchList[i];\r\n result.push({\r\n identifier: t.identifier,\r\n pageX: t.pageX - offsetX,\r\n pageY: t.pageY - offsetY,\r\n clientX: t.clientX - offsetX,\r\n clientY: t.clientY - offsetY,\r\n });\r\n }\r\n return result;\r\n}\r\n\r\nfunction buildWxTouchEvent(e: TouchEvent, canvas: HTMLCanvasElement | null): WxTouchEvent {\r\n return {\r\n touches: convertTouchList(e.touches, canvas),\r\n changedTouches: convertTouchList(e.changedTouches, canvas),\r\n timeStamp: e.timeStamp,\r\n };\r\n}\r\n\r\n// Mouse fallback for desktop \u2014 simulate single-touch with mouse events\r\nlet mouseDown = false;\r\nlet mouseIdentifier = 0;\r\n\r\nfunction buildWxTouchEventFromMouse(\r\n e: MouseEvent,\r\n canvas: HTMLCanvasElement | null,\r\n isTouchEnd: boolean\r\n): WxTouchEvent {\r\n const rect = canvas?.getBoundingClientRect();\r\n const offsetX = rect?.left ?? 0;\r\n const offsetY = rect?.top ?? 0;\r\n const touch: WxTouch = {\r\n identifier: mouseIdentifier,\r\n pageX: e.pageX - offsetX,\r\n pageY: e.pageY - offsetY,\r\n clientX: e.clientX - offsetX,\r\n clientY: e.clientY - offsetY,\r\n };\r\n return {\r\n touches: isTouchEnd ? [] : [touch],\r\n changedTouches: [touch],\r\n timeStamp: e.timeStamp,\r\n };\r\n}\r\n\r\n// Track whether native touch events have been setup\r\nlet touchListenersSetup = false;\r\nlet mouseListenersSetup = false;\r\n\r\nfunction ensureTouchListeners(): void {\r\n if (touchListenersSetup) return;\r\n touchListenersSetup = true;\r\n\r\n // Use document-level listeners \u2014 canvas may not exist yet at registration time\r\n nativeDocAddEventListener('touchstart', (e: TouchEvent) => {\r\n const canvas = getMainCanvas();\r\n const evt = buildWxTouchEvent(e, canvas);\r\n touchStartCallbacks.forEach((cb) => cb(evt));\r\n }, { passive: true });\r\n\r\n nativeDocAddEventListener('touchmove', (e: TouchEvent) => {\r\n const canvas = getMainCanvas();\r\n const evt = buildWxTouchEvent(e, canvas);\r\n touchMoveCallbacks.forEach((cb) => cb(evt));\r\n }, { passive: true });\r\n\r\n nativeDocAddEventListener('touchend', (e: TouchEvent) => {\r\n const canvas = getMainCanvas();\r\n const evt = buildWxTouchEvent(e, canvas);\r\n touchEndCallbacks.forEach((cb) => cb(evt));\r\n }, { passive: true });\r\n\r\n nativeDocAddEventListener('touchcancel', (e: TouchEvent) => {\r\n const canvas = getMainCanvas();\r\n const evt = buildWxTouchEvent(e, canvas);\r\n touchCancelCallbacks.forEach((cb) => cb(evt));\r\n }, { passive: true });\r\n}\r\n\r\nfunction ensureMouseListeners(): void {\r\n if (mouseListenersSetup) return;\r\n mouseListenersSetup = true;\r\n\r\n nativeDocAddEventListener('mousedown', (e: MouseEvent) => {\r\n mouseDown = true;\r\n mouseIdentifier++;\r\n const canvas = getMainCanvas();\r\n const evt = buildWxTouchEventFromMouse(e, canvas, false);\r\n touchStartCallbacks.forEach((cb) => cb(evt));\r\n });\r\n\r\n nativeDocAddEventListener('mousemove', (e: MouseEvent) => {\r\n if (!mouseDown) return;\r\n const canvas = getMainCanvas();\r\n const evt = buildWxTouchEventFromMouse(e, canvas, false);\r\n touchMoveCallbacks.forEach((cb) => cb(evt));\r\n });\r\n\r\n nativeDocAddEventListener('mouseup', (e: MouseEvent) => {\r\n if (!mouseDown) return;\r\n mouseDown = false;\r\n const canvas = getMainCanvas();\r\n const evt = buildWxTouchEventFromMouse(e, canvas, true);\r\n touchEndCallbacks.forEach((cb) => cb(evt));\r\n });\r\n}\r\n\r\nfunction ensureInputListeners(): void {\r\n ensureTouchListeners();\r\n ensureMouseListeners();\r\n}\r\n\r\n// \u2500\u2500\u2500 Public Touch API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport function onTouchStart(callback: TouchCallback): void {\r\n ensureInputListeners();\r\n touchStartCallbacks.add(callback);\r\n}\r\n\r\nexport function onTouchMove(callback: TouchCallback): void {\r\n ensureInputListeners();\r\n touchMoveCallbacks.add(callback);\r\n}\r\n\r\nexport function onTouchEnd(callback: TouchCallback): void {\r\n ensureInputListeners();\r\n touchEndCallbacks.add(callback);\r\n}\r\n\r\nexport function onTouchCancel(callback: TouchCallback): void {\r\n ensureInputListeners();\r\n touchCancelCallbacks.add(callback);\r\n}\r\n\r\nexport function offTouchStart(callback: TouchCallback): void {\r\n touchStartCallbacks.delete(callback);\r\n}\r\n\r\nexport function offTouchMove(callback: TouchCallback): void {\r\n touchMoveCallbacks.delete(callback);\r\n}\r\n\r\nexport function offTouchEnd(callback: TouchCallback): void {\r\n touchEndCallbacks.delete(callback);\r\n}\r\n\r\nexport function offTouchCancel(callback: TouchCallback): void {\r\n touchCancelCallbacks.delete(callback);\r\n}\r\n", "/**\r\n * Image module.\r\n *\r\n * Uses the captured native Image constructor to avoid circular calls:\r\n * web-adapter replaces global Image with a shim that calls wx.createImage(),\r\n * so using `new Image()` after adapter loads would recurse infinitely.\r\n *\r\n * The returned Image has its `src` property overridden via Object.defineProperty:\r\n * when a wxfile:// path is assigned, the file data is read from the virtual\r\n * file system, converted to a Blob URL, and set as the real src. This allows\r\n * game code to load images stored in the virtual FS (e.g. downloaded via\r\n * wx.downloadFile) without the browser complaining about unknown protocols.\r\n *\r\n * NOTE: We use Object.defineProperty instead of Proxy because WebGL's\r\n * texImage2D requires a genuine HTMLImageElement \u2014 Proxy objects fail with\r\n * \"Overload resolution failed\".\r\n *\r\n * NOTE: We reference NativeImage.prototype (captured window.Image) instead of\r\n * HTMLImageElement directly, because game code runs in a sandbox where\r\n * HTMLImageElement is not defined.\r\n *\r\n * WeChat real-device alignment (wx.createImage()):\r\n * - Returns an Image object with: src, width, height, onload, onerror\r\n * - Setting src to wxfile:// path loads the image from virtual FS via blob URL\r\n * - Reading src back returns the original wxfile:// path (not the blob URL)\r\n * - Previous blob URLs are revoked to prevent memory leaks\r\n */\r\n\r\nimport { NativeImage } from './native-globals';\r\nimport { getFileSystemManager } from './file-system';\r\nimport { resolveGameUrl } from './url-utils';\r\nimport { isVfsUrl, fromVfsUrl, getArrayBuffer as vfsGetArrayBuffer } from './virtual-fs';\r\n\r\n/**\r\n * Guess MIME type from file extension.\r\n */\r\nfunction guessMimeType(path: string): string {\r\n const lower = path.toLowerCase();\r\n if (lower.endsWith('.png')) return 'image/png';\r\n if (lower.endsWith('.jpg') || lower.endsWith('.jpeg')) return 'image/jpeg';\r\n if (lower.endsWith('.gif')) return 'image/gif';\r\n if (lower.endsWith('.webp')) return 'image/webp';\r\n if (lower.endsWith('.svg')) return 'image/svg+xml';\r\n if (lower.endsWith('.bmp')) return 'image/bmp';\r\n // Default to octet-stream; browsers can usually sniff image type from content\r\n return 'application/octet-stream';\r\n}\r\n\r\n/**\r\n * Resolve a pseudo-URL that the browser cannot fetch directly (`wxfile://`,\r\n * `wxvfs:`) into a `blob:` URL backed by the in-memory bytes. Returns the\r\n * original value unchanged for schemes the browser can handle itself\r\n * (http/https/data/blob/\u2026).\r\n *\r\n * This is the single funnel that converts our private schemes into something\r\n * `<img>.src`, CSS `background-image`, or WebGL `texImage2D` can consume \u2014\r\n * those APIs bypass the XHR/fetch interceptors, so they need real bytes.\r\n */\r\nexport function resolveImageSrc(value: string): string {\r\n if (!value) return value;\r\n\r\n // wxfile:// \u2014 user files written via FileSystemManager\r\n if (value.startsWith('wxfile://')) {\r\n try {\r\n const fs = getFileSystemManager();\r\n const data = fs.readFileSync(value) as ArrayBuffer;\r\n const mime = guessMimeType(value);\r\n const blob = new Blob([data], { type: mime });\r\n return URL.createObjectURL(blob);\r\n } catch (e) {\r\n console.warn(`[wx-compat][resolveImageSrc] Failed to read wxfile path: ${value}`, e);\r\n return '';\r\n }\r\n }\r\n\r\n // wxvfs: \u2014 game assets mounted in the in-memory VFS (wxapkg unpack etc.)\r\n if (isVfsUrl(value)) {\r\n const path = fromVfsUrl(value);\r\n const buf = vfsGetArrayBuffer(path);\r\n if (!buf) {\r\n console.warn(`[wx-compat][resolveImageSrc] wxvfs path not in VFS: ${path}`);\r\n return '';\r\n }\r\n const mime = guessMimeType(path);\r\n const blob = new Blob([buf], { type: mime });\r\n return URL.createObjectURL(blob);\r\n }\r\n\r\n return value;\r\n}\r\n\r\nexport function createImage(): unknown {\r\n const img = new NativeImage();\r\n\r\n // Instead of wrapping with Proxy (which breaks WebGL's texImage2D type\r\n // checking \u2014 \"Overload resolution failed\"), we override the `src` property\r\n // directly on the instance using Object.defineProperty. This way the\r\n // returned object is still a genuine HTMLImageElement that WebGL accepts.\r\n\r\n // Capture the native src descriptor from the prototype chain.\r\n // Use NativeImage.prototype (captured window.Image before sandbox cleanup)\r\n // instead of HTMLImageElement.prototype, because HTMLImageElement is not\r\n // available inside the sandbox.\r\n // Walk up the prototype chain to find 'src' descriptor \u2014 in most browsers\r\n // Image.prototype === HTMLImageElement.prototype, but we walk just in case.\r\n let nativeSrcDescriptor: PropertyDescriptor | undefined;\r\n let proto: object | null = NativeImage.prototype;\r\n while (proto && !nativeSrcDescriptor) {\r\n nativeSrcDescriptor = Object.getOwnPropertyDescriptor(proto, 'src');\r\n proto = Object.getPrototypeOf(proto);\r\n }\r\n\r\n if (!nativeSrcDescriptor || !nativeSrcDescriptor.get || !nativeSrcDescriptor.set) {\r\n // Fallback: if we can't find the native descriptor, return the raw image\r\n console.warn('[wx-compat][createImage] Could not find native src descriptor, returning raw Image');\r\n return img;\r\n }\r\n\r\n // Track the original src value set by game code, so reading `src` back\r\n // returns the wxfile:// path instead of the internal blob URL.\r\n let originalSrc = '';\r\n // Track the current blob URL so we can revoke it when src changes\r\n let currentBlobUrl: string | null = null;\r\n\r\n Object.defineProperty(img, 'src', {\r\n get() {\r\n // Return the original path assigned by game code, matching WeChat\r\n // real-device behavior (game code sees its own url, not our blob).\r\n if (originalSrc) {\r\n return originalSrc;\r\n }\r\n return nativeSrcDescriptor.get!.call(img);\r\n },\r\n set(value: string) {\r\n originalSrc = value;\r\n\r\n // Resolve relative paths. resolveGameUrl may return:\r\n // - a `wxvfs:` pseudo-URL when the asset is in the in-memory VFS\r\n // - an http(s) URL built from assetBaseUrl\r\n // - the original value when neither applies\r\n // wxfile:// and existing wxvfs: values are passed through unchanged.\r\n if (typeof value === 'string' && value && !value.startsWith('wxfile://') && !isVfsUrl(value)) {\r\n const resolved = resolveGameUrl(value);\r\n if (resolved !== value) {\r\n value = resolved;\r\n }\r\n }\r\n\r\n // Revoke the previous blob URL (if any) before we potentially create\r\n // a new one or switch to a network URL.\r\n if (currentBlobUrl) {\r\n URL.revokeObjectURL(currentBlobUrl);\r\n currentBlobUrl = null;\r\n }\r\n\r\n // Pseudo-URLs the browser cannot fetch directly (wxfile://, wxvfs:)\r\n // must be materialised into a blob URL. resolveImageSrc handles both.\r\n if (typeof value === 'string' && (value.startsWith('wxfile://') || isVfsUrl(value))) {\r\n const blobUrl = resolveImageSrc(value);\r\n if (blobUrl && blobUrl.startsWith('blob:')) {\r\n currentBlobUrl = blobUrl;\r\n }\r\n // Blob URLs are same-origin; no CORS needed.\r\n nativeSrcDescriptor.set!.call(img, blobUrl);\r\n return;\r\n }\r\n\r\n // Absolute http(s) URLs (CDN / assetBaseUrl rewrites) \u2014 opt into CORS\r\n // so WebGL texImage2D can use the resulting image as a texture source.\r\n if (typeof value === 'string' && (value.startsWith('http://') || value.startsWith('https://'))) {\r\n img.crossOrigin = 'anonymous';\r\n }\r\n\r\n nativeSrcDescriptor.set!.call(img, value);\r\n },\r\n enumerable: true,\r\n configurable: true,\r\n });\r\n\r\n return img;\r\n}\r\n", "/**\r\n * Performance module \u2014 performance APIs and log managers.\r\n *\r\n * Uses captured native performance object to avoid issues with adapters.\r\n */\r\n\r\nimport { nativePerformance } from './native-globals';\r\n\r\nexport function getPerformance(): Performance {\r\n return nativePerformance;\r\n}\r\n\r\nexport function setPreferredFramesPerSecond(_fps: number): void {\r\n // No-op in browser \u2014 browser uses 60fps by default\r\n}\r\n\r\n// \u2500\u2500\u2500 P2: Performance Reporting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * P2: wx.reportPerformance \u2014 logs performance data (no-op in browser).\r\n */\r\nexport function reportPerformance(id: number, value: number, dimensions?: string | string[]): void {\r\n // No-op \u2014 WeChat-specific performance reporting\r\n}\r\n\r\n/**\r\n * P2: wx.triggerGC \u2014 triggers garbage collection (no-op in browser).\r\n */\r\nexport function triggerGC(): void {\r\n // No-op \u2014 cannot trigger GC in browser\r\n}\r\n\r\n// \u2500\u2500\u2500 P2: Log Manager \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ninterface LogManager {\r\n debug(...args: unknown[]): void;\r\n info(...args: unknown[]): void;\r\n log(...args: unknown[]): void;\r\n warn(...args: unknown[]): void;\r\n}\r\n\r\n/**\r\n * P2: wx.getLogManager \u2014 returns a console-based log manager.\r\n */\r\nexport function getLogManager(opts?: { level?: number }): LogManager {\r\n return {\r\n debug: console.debug.bind(console),\r\n info: console.info.bind(console),\r\n log: console.log.bind(console),\r\n warn: console.warn.bind(console),\r\n };\r\n}\r\n\r\ninterface RealtimeLogManager {\r\n addFilterMsg(msg: string): void;\r\n error(...args: unknown[]): void;\r\n info(...args: unknown[]): void;\r\n warn(...args: unknown[]): void;\r\n setFilterMsg(msg: string): void;\r\n in(pagePath: string): RealtimeLogManager;\r\n}\r\n\r\n/**\r\n * P2: wx.getRealtimeLogManager \u2014 returns a console-based realtime log manager.\r\n */\r\nexport function getRealtimeLogManager(): RealtimeLogManager {\r\n const mgr: RealtimeLogManager = {\r\n addFilterMsg(_msg: string) {},\r\n error: console.error.bind(console),\r\n info: console.info.bind(console),\r\n warn: console.warn.bind(console),\r\n setFilterMsg(_msg: string) {},\r\n in(_pagePath: string) { return mgr; },\r\n };\r\n return mgr;\r\n}\r\n", "/**\r\n * Lifecycle events module.\r\n *\r\n * Implements:\r\n * wx.onShow, wx.offShow (P0)\r\n * wx.onHide, wx.offHide (P0)\r\n * wx.onError, wx.offError (P0)\r\n */\r\n\r\nimport { nativeDocument, nativeLocation } from './native-globals';\r\n\r\n// \u2500\u2500\u2500 Show / Hide \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ntype VoidCallback = () => void;\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype ShowCallback = (res: any) => void;\r\n\r\nconst showCallbacks: Set<ShowCallback> = new Set();\r\nconst hideCallbacks: Set<VoidCallback> = new Set();\r\n\r\n/**\r\n * Build the result object passed to onShow callbacks.\r\n * Matches the real WeChat wx.onShow callback signature:\r\n * { scene, query, shareTicket, referrerInfo, ... }\r\n */\r\nfunction buildShowResult() {\r\n const query: Record<string, string> = {};\r\n const params = new URLSearchParams(nativeLocation.search);\r\n params.forEach((value, key) => {\r\n query[key] = value;\r\n });\r\n return {\r\n scene: 1001,\r\n query,\r\n shareTicket: '',\r\n referrerInfo: {\r\n appId: '',\r\n extraData: {},\r\n },\r\n };\r\n}\r\n\r\n// Setup visibility change listener once \u2014 use nativeDocument since\r\n// cleanGlobals strips visibilitychange-related properties from document.\r\n//\r\n// NOTE: we intentionally gate the first dispatch behind a \"ready\" flag that\r\n// flips to true after the current tick (and only if the tab is currently\r\n// visible). This mirrors real-device semantics where wx.onShow / wx.onHide\r\n// only fire when the mini-game is *backgrounded and resumed*, not during\r\n// its initial launch. Some browsers fire a transient `visibilitychange`\r\n// event while the host page (or webview) is still initializing; without\r\n// this gate, the mini-game receives a spurious onHide/onShow during cold\r\n// start and may emit game-level \"resumed from background\" flows that then\r\n// wait on user-driven signals that never arrive, leaving the game stuck.\r\nlet lifecycleReady = false;\r\nif (typeof nativeDocument !== 'undefined' && !nativeDocument.hidden) {\r\n // Flip the flag on the next macrotask so any synchronous visibility churn\r\n // during module init / wasm loading is swallowed.\r\n setTimeout(() => { lifecycleReady = true; }, 0);\r\n} else {\r\n // If we cold-started while hidden, only arm the listener once the tab\r\n // becomes visible for the first time, then treat that as the \"baseline\"\r\n // (no onShow fire for the baseline transition).\r\n const armOnce = () => {\r\n if (!nativeDocument.hidden) {\r\n lifecycleReady = true;\r\n nativeDocument.removeEventListener('visibilitychange', armOnce);\r\n }\r\n };\r\n nativeDocument.addEventListener('visibilitychange', armOnce);\r\n}\r\n\r\nnativeDocument.addEventListener('visibilitychange', () => {\r\n if (!lifecycleReady) return;\r\n if (nativeDocument.hidden) {\r\n hideCallbacks.forEach((cb) => cb());\r\n } else {\r\n const result = buildShowResult();\r\n showCallbacks.forEach((cb) => cb(result));\r\n }\r\n});\r\n\r\nexport function onShow(callback: ShowCallback): void {\r\n showCallbacks.add(callback);\r\n}\r\n\r\nexport function offShow(callback: ShowCallback): void {\r\n showCallbacks.delete(callback);\r\n}\r\n\r\nexport function onHide(callback: VoidCallback): void {\r\n hideCallbacks.add(callback);\r\n}\r\n\r\nexport function offHide(callback: VoidCallback): void {\r\n hideCallbacks.delete(callback);\r\n}\r\n\r\n// \u2500\u2500\u2500 Error \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ntype ErrorCallback = (err: { message: string; stack: string }) => void;\r\n\r\nconst errorCallbacks: Set<ErrorCallback> = new Set();\r\nlet errorListenerSetup = false;\r\n\r\nfunction ensureErrorListener(): void {\r\n if (errorListenerSetup) return;\r\n errorListenerSetup = true;\r\n\r\n window.addEventListener('error', (e: ErrorEvent) => {\r\n const payload = { message: e.message, stack: e.error?.stack || '' };\r\n errorCallbacks.forEach((cb) => cb(payload));\r\n });\r\n}\r\n\r\nexport function onError(callback: ErrorCallback): void {\r\n ensureErrorListener();\r\n errorCallbacks.add(callback);\r\n}\r\n\r\nexport function offError(callback: ErrorCallback): void {\r\n errorCallbacks.delete(callback);\r\n}\r\n\r\n// \u2500\u2500\u2500 Unhandled Promise Rejection (P1) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ntype RejectionCallback = (res: { reason: string }) => void;\r\n\r\nconst rejectionCallbacks: Set<RejectionCallback> = new Set();\r\nlet rejectionListenerSetup = false;\r\n\r\nfunction ensureRejectionListener(): void {\r\n if (rejectionListenerSetup) return;\r\n rejectionListenerSetup = true;\r\n\r\n window.addEventListener('unhandledrejection', (e: PromiseRejectionEvent) => {\r\n const payload = { reason: String(e.reason) };\r\n rejectionCallbacks.forEach((cb) => cb(payload));\r\n });\r\n}\r\n\r\nexport function onUnhandledRejection(callback: RejectionCallback): void {\r\n ensureRejectionListener();\r\n rejectionCallbacks.add(callback);\r\n}\r\n\r\nexport function offUnhandledRejection(callback: RejectionCallback): void {\r\n rejectionCallbacks.delete(callback);\r\n}\r\n\r\n// \u2500\u2500\u2500 Audio Interruption (P1, no-op stubs) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst audioInterruptionBeginCallbacks: Set<VoidCallback> = new Set();\r\nconst audioInterruptionEndCallbacks: Set<VoidCallback> = new Set();\r\n\r\nexport function onAudioInterruptionBegin(callback: VoidCallback): void {\r\n audioInterruptionBeginCallbacks.add(callback);\r\n}\r\n\r\nexport function offAudioInterruptionBegin(callback: VoidCallback): void {\r\n audioInterruptionBeginCallbacks.delete(callback);\r\n}\r\n\r\nexport function onAudioInterruptionEnd(callback: VoidCallback): void {\r\n audioInterruptionEndCallbacks.add(callback);\r\n}\r\n\r\nexport function offAudioInterruptionEnd(callback: VoidCallback): void {\r\n audioInterruptionEndCallbacks.delete(callback);\r\n}\r\n\r\n// \u2500\u2500\u2500 Launch / Enter Options (P1) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ninterface LaunchOptions {\r\n scene: number;\r\n query: Record<string, string>;\r\n referrerInfo: { appId: string; extraData: Record<string, unknown> };\r\n}\r\n\r\nfunction buildMockLaunchOptions(): LaunchOptions {\r\n // Parse URL query params as launch query\r\n const query: Record<string, string> = {};\r\n const params = new URLSearchParams(nativeLocation.search);\r\n params.forEach((value, key) => {\r\n query[key] = value;\r\n });\r\n\r\n return {\r\n scene: 1001, // scene 1001 = search in WeChat\r\n query,\r\n referrerInfo: {\r\n appId: '',\r\n extraData: {},\r\n },\r\n };\r\n}\r\n\r\nexport function getLaunchOptionsSync(): LaunchOptions {\r\n return buildMockLaunchOptions();\r\n}\r\n\r\nexport function getEnterOptionsSync(): LaunchOptions {\r\n return buildMockLaunchOptions();\r\n}\r\n", "/**\r\n * Log interception module.\r\n * Patches console.log/warn/error to forward messages to the parent frame.\r\n */\r\n\r\ninterface LogEntry {\r\n type: '__wx_log__';\r\n ts: number;\r\n level: 'log' | 'info' | 'debug' | 'warn' | 'error';\r\n msg: string;\r\n}\r\n\r\nconst LOG_BUFFER_MAX = 500;\r\nconst logBuffer: LogEntry[] = [];\r\n\r\n/**\r\n * Check if a value is a browser Event object that only serializes to {\"isTrusted\":true}.\r\n * These are typically fired by DOM element onerror callbacks (e.g. img.onerror, script.onerror)\r\n * and are not useful error information \u2014 just noise in the console.\r\n */\r\nfunction isBrowserEventObject(value: unknown): boolean {\r\n if (!value || typeof value !== 'object') return false;\r\n // Check for the Event interface: isTrusted is a hallmark of native browser Events\r\n if ('isTrusted' in (value as Record<string, unknown>) && (value as Record<string, unknown>).isTrusted === true) {\r\n // Verify it's actually an Event (has type, target, etc.) or serializes to just {isTrusted:true}\r\n try {\r\n const json = JSON.stringify(value);\r\n if (json === '{\"isTrusted\":true}') return true;\r\n } catch { /* not serializable, not a plain Event */ }\r\n }\r\n return false;\r\n}\r\n\r\nfunction forwardLog(level: 'log' | 'info' | 'debug' | 'warn' | 'error', args: unknown[]): void {\r\n const msg = args\r\n .map((a) => {\r\n if (a instanceof Error) {\r\n // Error properties (message, stack) are non-enumerable \u2014 JSON.stringify\r\n // would produce '{}'. Format them explicitly instead.\r\n return a.stack ? a.stack : `${a.name}: ${a.message}`;\r\n }\r\n if (typeof a === 'object' && a !== null) {\r\n try { return JSON.stringify(a); } catch { return String(a); }\r\n }\r\n return String(a);\r\n })\r\n .join(' ');\r\n\r\n const entry: LogEntry = { type: '__wx_log__', ts: Date.now(), level, msg };\r\n logBuffer.push(entry);\r\n if (logBuffer.length > LOG_BUFFER_MAX) {\r\n logBuffer.shift();\r\n }\r\n\r\n try {\r\n // The parent frame is always the same http://localhost:PORT origin;\r\n // using '*' here is safe in this controlled localhost-only context.\r\n window.parent?.postMessage(entry, '*');\r\n } catch {\r\n // Cross-origin parent; silently ignore\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Setup console interception and global error forwarding.\r\n * Must be called once during initialization.\r\n */\r\nexport function setupLogInterception(): void {\r\n // Patch console to intercept logs\r\n const _origLog = console.log.bind(console);\r\n const _origInfo = console.info.bind(console);\r\n const _origDebug = console.debug.bind(console);\r\n const _origWarn = console.warn.bind(console);\r\n const _origError = console.error.bind(console);\r\n\r\n console.log = (...args: unknown[]) => {\r\n _origLog(...args);\r\n forwardLog('log', args);\r\n };\r\n console.info = (...args: unknown[]) => {\r\n _origInfo(...args);\r\n forwardLog('info', args);\r\n };\r\n console.debug = (...args: unknown[]) => {\r\n _origDebug(...args);\r\n forwardLog('debug', args);\r\n };\r\n console.warn = (...args: unknown[]) => {\r\n _origWarn(...args);\r\n forwardLog('warn', args);\r\n };\r\n console.error = (...args: unknown[]) => {\r\n // Filter out pure browser Event objects (e.g. from img.onerror / script.onerror).\r\n // These serialize to just {\"isTrusted\":true} and provide no useful error info.\r\n // Cocos 3.x engine sets element.onerror = console.error, which passes the\r\n // native Event object directly \u2014 we downgrade these to warnings instead.\r\n const filteredArgs = args.filter(a => !isBrowserEventObject(a));\r\n if (filteredArgs.length === 0) {\r\n // All args were Event objects \u2014 downgrade to a warning instead of error\r\n _origWarn('[wx-compat] Suppressed Event-only console.error (likely a non-critical resource load failure)');\r\n forwardLog('warn', ['[wx-compat] Suppressed Event-only console.error (likely a non-critical resource load failure)']);\r\n return;\r\n }\r\n _origError(...args);\r\n forwardLog('error', args);\r\n };\r\n\r\n // Forward uncaught errors and unhandled rejections\r\n window.addEventListener('error', (e) => {\r\n const msg = `[Uncaught] ${e.message} (${e.filename}:${e.lineno}:${e.colno})`;\r\n // Print to the original (pre-patch) console so the error is visible in\r\n // the iframe's DevTools even if something swallowed the native event.\r\n // Crucially, include the real Error object so DevTools renders the full\r\n // stack trace \u2014 the message/filename fields in ErrorEvent are often the\r\n // minified artifact, not the true source location.\r\n _origError(msg, e.error || '');\r\n forwardLog('error', [msg]);\r\n });\r\n window.addEventListener('unhandledrejection', (e) => {\r\n const msg = `[UnhandledPromise] ${e.reason}`;\r\n _origError(msg, e.reason instanceof Error ? e.reason : '');\r\n forwardLog('error', [msg]);\r\n });\r\n}\r\n\r\nexport { logBuffer };\r\n", "/**\r\n * Environment variables module (P0).\r\n *\r\n * Implements wx.env with USER_DATA_PATH and other environment variables.\r\n * In browser preview, USER_DATA_PATH points to a virtual path.\r\n */\r\n\r\nexport const env = {\r\n /**\r\n * User data path \u2014 in browser we use a virtual prefix.\r\n * Games that use wx.getFileSystemManager() to read/write this path\r\n * will fail, but the path string itself is available for reference.\r\n */\r\n USER_DATA_PATH: 'wxfile://usr',\r\n};\r\n", "/**\r\n * Render helpers module (P1).\r\n *\r\n * Implements:\r\n * wx.createPath2D \u2014 Path2D object creation\r\n * wx.createImageData \u2014 ImageData object creation\r\n * wx.loadFont \u2014 font loading via FontFace API\r\n * wx.getTextLineHeight \u2014 text line height measurement via Canvas\r\n */\r\n\r\nimport { nativeCreateElement, nativeDocFonts } from './native-globals';\r\n\r\n/**\r\n * P1: wx.createPath2D \u2014 returns a browser-native Path2D object.\r\n */\r\nexport function createPath2D(): Path2D {\r\n return new Path2D();\r\n}\r\n\r\n/**\r\n * P1: wx.createImageData \u2014 returns a new ImageData object.\r\n *\r\n * Two calling conventions (matching WeChat docs):\r\n * wx.createImageData(width, height) \u2014 create empty ImageData\r\n * wx.createImageData(data, width, height) \u2014 create ImageData from existing pixel data\r\n *\r\n * @example\r\n * const imageData1 = wx.createImageData(100, 100)\r\n * const imageData2 = wx.createImageData(imageData1.data, 100, 100)\r\n */\r\nexport function createImageData(\r\n widthOrData: number | Uint8ClampedArray,\r\n heightOrWidth: number,\r\n heightIfData?: number,\r\n): ImageData {\r\n if (widthOrData instanceof Uint8ClampedArray) {\r\n // createImageData(data, width, height)\r\n const data = widthOrData;\r\n const width = heightOrWidth;\r\n const height = heightIfData!;\r\n return new ImageData(data as unknown as Uint8ClampedArray<ArrayBuffer>, width, height);\r\n }\r\n // createImageData(width, height)\r\n const width = widthOrData;\r\n const height = heightOrWidth;\r\n return new ImageData(width, height);\r\n}\r\n\r\n/**\r\n * P1: wx.loadFont \u2014 loads a custom font using FontFace API.\r\n * @param path The font file path/URL\r\n * @returns The font family name to use in Canvas\r\n */\r\nexport function loadFont(path: string): string {\r\n // Generate a font family name from the path\r\n const familyName = 'wxFont_' + path.replace(/[^a-zA-Z0-9]/g, '_').slice(-32);\r\n\r\n try {\r\n const fontFace = new FontFace(familyName, `url(${path})`);\r\n fontFace.load().then((loaded) => {\r\n (nativeDocFonts as FontFaceSet).add(loaded);\r\n }).catch((err) => {\r\n console.warn(`[wx-compat] loadFont failed for \"${path}\":`, err);\r\n });\r\n } catch (err) {\r\n console.warn(`[wx-compat] loadFont not supported or failed:`, err);\r\n }\r\n\r\n return familyName;\r\n}\r\n\r\n/**\r\n * P1: wx.getTextLineHeight \u2014 measure text line height using a temporary Canvas.\r\n * @param opts Options including text, fontStyle, fontWeight, fontSize, fontFamily\r\n * @returns The line height in pixels\r\n */\r\nexport function getTextLineHeight(opts: {\r\n text?: string;\r\n fontStyle?: string;\r\n fontWeight?: string;\r\n fontSize?: number;\r\n fontFamily?: string;\r\n}): number {\r\n const fontSize = opts.fontSize || 16;\r\n const fontFamily = opts.fontFamily || 'sans-serif';\r\n const fontStyle = opts.fontStyle || 'normal';\r\n const fontWeight = opts.fontWeight || 'normal';\r\n\r\n const canvas = nativeCreateElement('canvas') as HTMLCanvasElement;\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) return fontSize * 1.2;\r\n\r\n ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`;\r\n const metrics = ctx.measureText(opts.text || 'M');\r\n\r\n // Use actualBoundingBoxAscent + actualBoundingBoxDescent if available\r\n if (metrics.actualBoundingBoxAscent !== undefined && metrics.actualBoundingBoxDescent !== undefined) {\r\n return metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;\r\n }\r\n\r\n // Fallback: approximate line height as 1.2x font size\r\n return fontSize * 1.2;\r\n}\r\n", "/**\r\n * UI module (P1) \u2014 Toast, Modal, Loading, ActionSheet, MenuButton.\r\n *\r\n * Implements:\r\n * wx.showToast / wx.hideToast\r\n * wx.showModal\r\n * wx.showLoading / wx.hideLoading\r\n * wx.showActionSheet\r\n * wx.getMenuButtonBoundingClientRect\r\n * wx.onWindowResize / wx.offWindowResize\r\n */\r\n\r\nimport { DEVICE } from './constants';\r\nimport { nativeCreateElement, nativeHead, nativeBody } from './native-globals';\r\n\r\n// \u2500\u2500\u2500 Shared CSS Injection \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nlet styleInjected = false;\r\n\r\nfunction ensureStyles(): void {\r\n if (styleInjected) return;\r\n styleInjected = true;\r\n\r\n const style = nativeCreateElement('style') as HTMLStyleElement;\r\n style.textContent = `\r\n .wx-compat-overlay {\r\n position: fixed; top: 0; left: 0; right: 0; bottom: 0;\r\n display: flex; align-items: center; justify-content: center;\r\n z-index: 99999; pointer-events: auto;\r\n }\r\n .wx-compat-overlay-bg {\r\n background: rgba(0,0,0,0.5);\r\n }\r\n .wx-compat-toast {\r\n background: rgba(0,0,0,0.76); color: #fff;\r\n padding: 12px 24px; border-radius: 8px;\r\n font-size: 14px; text-align: center;\r\n max-width: 70%; word-break: break-word;\r\n pointer-events: none;\r\n }\r\n .wx-compat-toast-icon {\r\n font-size: 36px; margin-bottom: 8px;\r\n }\r\n .wx-compat-modal {\r\n background: #fff; border-radius: 12px;\r\n width: 280px; overflow: hidden;\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\r\n }\r\n .wx-compat-modal-title {\r\n font-size: 17px; font-weight: 600; text-align: center;\r\n padding: 24px 24px 8px;\r\n }\r\n .wx-compat-modal-content {\r\n font-size: 14px; color: #666; text-align: center;\r\n padding: 0 24px 24px; word-break: break-word;\r\n }\r\n .wx-compat-modal-btns {\r\n display: flex; border-top: 1px solid #e5e5e5;\r\n }\r\n .wx-compat-modal-btn {\r\n flex: 1; padding: 12px 0; text-align: center;\r\n font-size: 17px; cursor: pointer; border: none;\r\n background: transparent; outline: none;\r\n }\r\n .wx-compat-modal-btn:active { background: #f0f0f0; }\r\n .wx-compat-modal-btn-cancel { color: #333; }\r\n .wx-compat-modal-btn-confirm { color: #576B95; font-weight: 600; }\r\n .wx-compat-modal-btn + .wx-compat-modal-btn {\r\n border-left: 1px solid #e5e5e5;\r\n }\r\n .wx-compat-loading-spinner {\r\n width: 36px; height: 36px; margin-bottom: 8px;\r\n border: 3px solid rgba(255,255,255,0.3);\r\n border-top-color: #fff; border-radius: 50%;\r\n animation: wx-compat-spin 0.8s linear infinite;\r\n }\r\n @keyframes wx-compat-spin { to { transform: rotate(360deg); } }\r\n .wx-compat-action-sheet {\r\n position: fixed; bottom: 0; left: 0; right: 0;\r\n background: #f7f7f7; border-radius: 12px 12px 0 0;\r\n z-index: 100000; overflow: hidden;\r\n animation: wx-compat-slide-up 0.2s ease;\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\r\n }\r\n @keyframes wx-compat-slide-up {\r\n from { transform: translateY(100%); }\r\n to { transform: translateY(0); }\r\n }\r\n .wx-compat-action-item {\r\n padding: 14px 0; text-align: center; font-size: 17px;\r\n background: #fff; cursor: pointer; border: none;\r\n width: 100%; outline: none; color: #333;\r\n }\r\n .wx-compat-action-item:active { background: #f0f0f0; }\r\n .wx-compat-action-item + .wx-compat-action-item {\r\n border-top: 1px solid #e5e5e5;\r\n }\r\n .wx-compat-action-cancel {\r\n margin-top: 8px; color: #333; font-weight: 500;\r\n }\r\n `;\r\n nativeHead.appendChild(style);\r\n}\r\n\r\n// \u2500\u2500\u2500 Toast \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nlet toastTimer: ReturnType<typeof setTimeout> | null = null;\r\nlet toastOverlay: HTMLElement | null = null;\r\n\r\nexport function showToast(opts: {\r\n title: string;\r\n icon?: 'success' | 'error' | 'loading' | 'none';\r\n duration?: number;\r\n mask?: boolean;\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n ensureStyles();\r\n hideToast();\r\n\r\n const duration = opts.duration ?? 1500;\r\n const icon = opts.icon ?? 'success';\r\n\r\n const overlay = nativeCreateElement('div') as HTMLDivElement;\r\n overlay.className = 'wx-compat-overlay';\r\n if (opts.mask) overlay.classList.add('wx-compat-overlay-bg');\r\n\r\n const toast = nativeCreateElement('div') as HTMLDivElement;\r\n toast.className = 'wx-compat-toast';\r\n\r\n if (icon === 'success') {\r\n toast.innerHTML = `<div class=\"wx-compat-toast-icon\">\u2713</div>${opts.title}`;\r\n } else if (icon === 'error') {\r\n toast.innerHTML = `<div class=\"wx-compat-toast-icon\">\u2715</div>${opts.title}`;\r\n } else if (icon === 'loading') {\r\n toast.innerHTML = `<div class=\"wx-compat-loading-spinner\"></div>${opts.title}`;\r\n } else {\r\n toast.textContent = opts.title;\r\n }\r\n\r\n overlay.appendChild(toast);\r\n nativeBody.appendChild(overlay);\r\n toastOverlay = overlay;\r\n\r\n toastTimer = setTimeout(() => {\r\n hideToast();\r\n }, duration);\r\n\r\n opts.success?.();\r\n opts.complete?.();\r\n}\r\n\r\nexport function hideToast(opts?: {\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if (toastTimer) {\r\n clearTimeout(toastTimer);\r\n toastTimer = null;\r\n }\r\n if (toastOverlay && toastOverlay.parentNode) {\r\n toastOverlay.parentNode.removeChild(toastOverlay);\r\n toastOverlay = null;\r\n }\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\n// \u2500\u2500\u2500 Modal \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport function showModal(opts: {\r\n title?: string;\r\n content?: string;\r\n showCancel?: boolean;\r\n cancelText?: string;\r\n cancelColor?: string;\r\n confirmText?: string;\r\n confirmColor?: string;\r\n success?: (res: { confirm: boolean; cancel: boolean }) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n ensureStyles();\r\n\r\n const showCancel = opts.showCancel !== false;\r\n const overlay = nativeCreateElement('div') as HTMLDivElement;\r\n overlay.className = 'wx-compat-overlay wx-compat-overlay-bg';\r\n\r\n const modal = nativeCreateElement('div') as HTMLDivElement;\r\n modal.className = 'wx-compat-modal';\r\n\r\n if (opts.title) {\r\n const title = nativeCreateElement('div') as HTMLDivElement;\r\n title.className = 'wx-compat-modal-title';\r\n title.textContent = opts.title;\r\n modal.appendChild(title);\r\n }\r\n\r\n if (opts.content) {\r\n const content = nativeCreateElement('div') as HTMLDivElement;\r\n content.className = 'wx-compat-modal-content';\r\n content.textContent = opts.content;\r\n modal.appendChild(content);\r\n }\r\n\r\n const btns = nativeCreateElement('div') as HTMLDivElement;\r\n btns.className = 'wx-compat-modal-btns';\r\n\r\n function cleanup(confirm: boolean): void {\r\n if (overlay.parentNode) overlay.parentNode.removeChild(overlay);\r\n opts.success?.({ confirm, cancel: !confirm });\r\n opts.complete?.();\r\n }\r\n\r\n if (showCancel) {\r\n const cancelBtn = nativeCreateElement('button') as HTMLButtonElement;\r\n cancelBtn.className = 'wx-compat-modal-btn wx-compat-modal-btn-cancel';\r\n cancelBtn.textContent = opts.cancelText || '\u53D6\u6D88';\r\n if (opts.cancelColor) cancelBtn.style.color = opts.cancelColor;\r\n cancelBtn.addEventListener('click', () => cleanup(false));\r\n btns.appendChild(cancelBtn);\r\n }\r\n\r\n const confirmBtn = nativeCreateElement('button') as HTMLButtonElement;\r\n confirmBtn.className = 'wx-compat-modal-btn wx-compat-modal-btn-confirm';\r\n confirmBtn.textContent = opts.confirmText || '\u786E\u5B9A';\r\n if (opts.confirmColor) confirmBtn.style.color = opts.confirmColor;\r\n confirmBtn.addEventListener('click', () => cleanup(true));\r\n btns.appendChild(confirmBtn);\r\n\r\n modal.appendChild(btns);\r\n overlay.appendChild(modal);\r\n nativeBody.appendChild(overlay);\r\n}\r\n\r\n// \u2500\u2500\u2500 Loading \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\nlet loadingOverlay: HTMLElement | null = null;\r\n\r\nexport function showLoading(opts: {\r\n title?: string;\r\n mask?: boolean;\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n ensureStyles();\r\n hideLoading();\r\n\r\n const overlay = nativeCreateElement('div') as HTMLDivElement;\r\n overlay.className = 'wx-compat-overlay';\r\n if (opts.mask !== false) overlay.classList.add('wx-compat-overlay-bg');\r\n\r\n const toast = nativeCreateElement('div') as HTMLDivElement;\r\n toast.className = 'wx-compat-toast';\r\n toast.innerHTML = `<div class=\"wx-compat-loading-spinner\"></div>${opts.title || ''}`;\r\n\r\n overlay.appendChild(toast);\r\n nativeBody.appendChild(overlay);\r\n loadingOverlay = overlay;\r\n\r\n opts.success?.();\r\n opts.complete?.();\r\n}\r\n\r\nexport function hideLoading(opts?: {\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if (loadingOverlay && loadingOverlay.parentNode) {\r\n loadingOverlay.parentNode.removeChild(loadingOverlay);\r\n loadingOverlay = null;\r\n }\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\n// \u2500\u2500\u2500 ActionSheet \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport function showActionSheet(opts: {\r\n itemList: string[];\r\n itemColor?: string;\r\n success?: (res: { tapIndex: number }) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n ensureStyles();\r\n\r\n const bgOverlay = nativeCreateElement('div') as HTMLDivElement;\r\n bgOverlay.className = 'wx-compat-overlay wx-compat-overlay-bg';\r\n bgOverlay.style.alignItems = 'flex-end';\r\n\r\n const sheet = nativeCreateElement('div') as HTMLDivElement;\r\n sheet.className = 'wx-compat-action-sheet';\r\n\r\n function cleanup(tapIndex: number): void {\r\n if (bgOverlay.parentNode) bgOverlay.parentNode.removeChild(bgOverlay);\r\n if (tapIndex >= 0) {\r\n opts.success?.({ tapIndex });\r\n } else {\r\n opts.fail?.({ errMsg: 'showActionSheet:fail cancel' });\r\n }\r\n opts.complete?.();\r\n }\r\n\r\n opts.itemList.forEach((item, index) => {\r\n const btn = nativeCreateElement('button') as HTMLButtonElement;\r\n btn.className = 'wx-compat-action-item';\r\n btn.textContent = item;\r\n if (opts.itemColor) btn.style.color = opts.itemColor;\r\n btn.addEventListener('click', () => cleanup(index));\r\n sheet.appendChild(btn);\r\n });\r\n\r\n const cancelBtn = nativeCreateElement('button') as HTMLButtonElement;\r\n cancelBtn.className = 'wx-compat-action-item wx-compat-action-cancel';\r\n cancelBtn.textContent = '\u53D6\u6D88';\r\n cancelBtn.addEventListener('click', () => cleanup(-1));\r\n sheet.appendChild(cancelBtn);\r\n\r\n bgOverlay.addEventListener('click', (e) => {\r\n if (e.target === bgOverlay) cleanup(-1);\r\n });\r\n\r\n bgOverlay.appendChild(sheet);\r\n nativeBody.appendChild(bgOverlay);\r\n}\r\n\r\n// \u2500\u2500\u2500 MenuButton \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * P1: wx.getMenuButtonBoundingClientRect\r\n * Returns a simulated bounding rect for the capsule menu button,\r\n * allowing games to properly layout around the safe area.\r\n */\r\nexport function getMenuButtonBoundingClientRect(): {\r\n top: number;\r\n right: number;\r\n bottom: number;\r\n left: number;\r\n width: number;\r\n height: number;\r\n} {\r\n // Simulate iPhone capsule button position\r\n const top = 48;\r\n const height = 32;\r\n const width = 87;\r\n const right = DEVICE.width - 10;\r\n const left = right - width;\r\n return {\r\n top,\r\n right,\r\n bottom: top + height,\r\n left,\r\n width,\r\n height,\r\n };\r\n}\r\n\r\n// \u2500\u2500\u2500 Window Resize \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ntype WindowResizeCallback = (res: { windowWidth: number; windowHeight: number }) => void;\r\n\r\nconst windowResizeCallbacks: Set<WindowResizeCallback> = new Set();\r\nlet windowResizeListenerSetup = false;\r\n\r\nfunction ensureWindowResizeListener(): void {\r\n if (windowResizeListenerSetup) return;\r\n windowResizeListenerSetup = true;\r\n\r\n window.addEventListener('resize', () => {\r\n const payload = {\r\n windowWidth: DEVICE.width,\r\n windowHeight: DEVICE.height,\r\n };\r\n windowResizeCallbacks.forEach((cb) => cb(payload));\r\n });\r\n}\r\n\r\nexport function onWindowResize(callback: WindowResizeCallback): void {\r\n ensureWindowResizeListener();\r\n windowResizeCallbacks.add(callback);\r\n}\r\n\r\nexport function offWindowResize(callback: WindowResizeCallback): void {\r\n windowResizeCallbacks.delete(callback);\r\n}\r\n\r\n// \u2500\u2500\u2500 Window State Change (P2) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ntype WindowStateCallback = (res: { windowState: string }) => void;\r\n\r\nconst windowStateCallbacks: Set<WindowStateCallback> = new Set();\r\nlet windowStateListenerSetup = false;\r\n\r\nfunction ensureWindowStateListener(): void {\r\n if (windowStateListenerSetup) return;\r\n windowStateListenerSetup = true;\r\n\r\n window.addEventListener('focus', () => {\r\n windowStateCallbacks.forEach((cb) => cb({ windowState: 'focus' }));\r\n });\r\n window.addEventListener('blur', () => {\r\n windowStateCallbacks.forEach((cb) => cb({ windowState: 'blur' }));\r\n });\r\n}\r\n\r\nexport function onWindowStateChange(callback: WindowStateCallback): void {\r\n ensureWindowStateListener();\r\n windowStateCallbacks.add(callback);\r\n}\r\n\r\nexport function offWindowStateChange(callback: WindowStateCallback): void {\r\n windowStateCallbacks.delete(callback);\r\n}\r\n", "/**\r\n * Input events module (P1) \u2014 Mouse, Wheel, Keyboard events for PC support.\r\n *\r\n * Implements:\r\n * wx.onMouseDown / wx.offMouseDown\r\n * wx.onMouseMove / wx.offMouseMove\r\n * wx.onMouseUp / wx.offMouseUp\r\n * wx.onWheel / wx.offWheel\r\n * wx.onKeyDown / wx.offKeyDown\r\n * wx.onKeyUp / wx.offKeyUp\r\n */\r\n\r\nimport { getMainCanvas } from './canvas';\r\nimport { nativeDocAddEventListener } from './native-globals';\r\n\r\n// \u2500\u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ninterface WxMouseEvent {\r\n x: number;\r\n y: number;\r\n button: number;\r\n timeStamp: number;\r\n}\r\n\r\ninterface WxWheelEvent {\r\n x: number;\r\n y: number;\r\n deltaX: number;\r\n deltaY: number;\r\n deltaZ: number;\r\n timeStamp: number;\r\n}\r\n\r\ninterface WxKeyEvent {\r\n key: string;\r\n code: string;\r\n timeStamp: number;\r\n}\r\n\r\ntype MouseCallback = (event: WxMouseEvent) => void;\r\ntype WheelCallback = (event: WxWheelEvent) => void;\r\ntype KeyCallback = (event: WxKeyEvent) => void;\r\n\r\n// \u2500\u2500\u2500 Mouse Events \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst mouseDownCallbacks: Set<MouseCallback> = new Set();\r\nconst mouseMoveCallbacks: Set<MouseCallback> = new Set();\r\nconst mouseUpCallbacks: Set<MouseCallback> = new Set();\r\n\r\nlet mouseListenersSetup = false;\r\n\r\nfunction buildWxMouseEvent(e: MouseEvent): WxMouseEvent {\r\n const canvas = getMainCanvas();\r\n const rect = canvas?.getBoundingClientRect();\r\n const offsetX = rect?.left ?? 0;\r\n const offsetY = rect?.top ?? 0;\r\n return {\r\n x: e.clientX - offsetX,\r\n y: e.clientY - offsetY,\r\n button: e.button,\r\n timeStamp: e.timeStamp,\r\n };\r\n}\r\n\r\nfunction ensureMouseListeners(): void {\r\n if (mouseListenersSetup) return;\r\n mouseListenersSetup = true;\r\n\r\n nativeDocAddEventListener('mousedown', (e: MouseEvent) => {\r\n const evt = buildWxMouseEvent(e);\r\n mouseDownCallbacks.forEach((cb) => cb(evt));\r\n });\r\n\r\n nativeDocAddEventListener('mousemove', (e: MouseEvent) => {\r\n const evt = buildWxMouseEvent(e);\r\n mouseMoveCallbacks.forEach((cb) => cb(evt));\r\n });\r\n\r\n nativeDocAddEventListener('mouseup', (e: MouseEvent) => {\r\n const evt = buildWxMouseEvent(e);\r\n mouseUpCallbacks.forEach((cb) => cb(evt));\r\n });\r\n}\r\n\r\nexport function onMouseDown(callback: MouseCallback): void {\r\n ensureMouseListeners();\r\n mouseDownCallbacks.add(callback);\r\n}\r\n\r\nexport function offMouseDown(callback: MouseCallback): void {\r\n mouseDownCallbacks.delete(callback);\r\n}\r\n\r\nexport function onMouseMove(callback: MouseCallback): void {\r\n ensureMouseListeners();\r\n mouseMoveCallbacks.add(callback);\r\n}\r\n\r\nexport function offMouseMove(callback: MouseCallback): void {\r\n mouseMoveCallbacks.delete(callback);\r\n}\r\n\r\nexport function onMouseUp(callback: MouseCallback): void {\r\n ensureMouseListeners();\r\n mouseUpCallbacks.add(callback);\r\n}\r\n\r\nexport function offMouseUp(callback: MouseCallback): void {\r\n mouseUpCallbacks.delete(callback);\r\n}\r\n\r\n// \u2500\u2500\u2500 Wheel Events \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst wheelCallbacks: Set<WheelCallback> = new Set();\r\nlet wheelListenerSetup = false;\r\n\r\nfunction ensureWheelListener(): void {\r\n if (wheelListenerSetup) return;\r\n wheelListenerSetup = true;\r\n\r\n nativeDocAddEventListener('wheel', (e: WheelEvent) => {\r\n const canvas = getMainCanvas();\r\n const rect = canvas?.getBoundingClientRect();\r\n const offsetX = rect?.left ?? 0;\r\n const offsetY = rect?.top ?? 0;\r\n const evt: WxWheelEvent = {\r\n x: e.clientX - offsetX,\r\n y: e.clientY - offsetY,\r\n deltaX: e.deltaX,\r\n deltaY: e.deltaY,\r\n deltaZ: e.deltaZ,\r\n timeStamp: e.timeStamp,\r\n };\r\n wheelCallbacks.forEach((cb) => cb(evt));\r\n }, { passive: true });\r\n}\r\n\r\nexport function onWheel(callback: WheelCallback): void {\r\n ensureWheelListener();\r\n wheelCallbacks.add(callback);\r\n}\r\n\r\nexport function offWheel(callback: WheelCallback): void {\r\n wheelCallbacks.delete(callback);\r\n}\r\n\r\n// \u2500\u2500\u2500 Keyboard Events \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst keyDownCallbacks: Set<KeyCallback> = new Set();\r\nconst keyUpCallbacks: Set<KeyCallback> = new Set();\r\n\r\nlet keyboardListenersSetup = false;\r\n\r\nfunction buildWxKeyEvent(e: KeyboardEvent): WxKeyEvent {\r\n return {\r\n key: e.key,\r\n code: e.code,\r\n timeStamp: e.timeStamp,\r\n };\r\n}\r\n\r\nfunction ensureKeyboardListeners(): void {\r\n if (keyboardListenersSetup) return;\r\n keyboardListenersSetup = true;\r\n\r\n nativeDocAddEventListener('keydown', (e: KeyboardEvent) => {\r\n const evt = buildWxKeyEvent(e);\r\n keyDownCallbacks.forEach((cb) => cb(evt));\r\n });\r\n\r\n nativeDocAddEventListener('keyup', (e: KeyboardEvent) => {\r\n const evt = buildWxKeyEvent(e);\r\n keyUpCallbacks.forEach((cb) => cb(evt));\r\n });\r\n}\r\n\r\nexport function onKeyDown(callback: KeyCallback): void {\r\n ensureKeyboardListeners();\r\n keyDownCallbacks.add(callback);\r\n}\r\n\r\nexport function offKeyDown(callback: KeyCallback): void {\r\n keyDownCallbacks.delete(callback);\r\n}\r\n\r\nexport function onKeyUp(callback: KeyCallback): void {\r\n ensureKeyboardListeners();\r\n keyUpCallbacks.add(callback);\r\n}\r\n\r\nexport function offKeyUp(callback: KeyCallback): void {\r\n keyUpCallbacks.delete(callback);\r\n}\r\n", "/**\r\n * Cursor module (P2) \u2014 mouse cursor, pointer lock.\r\n *\r\n * Implements:\r\n * wx.setCursor \u2014 set mouse cursor style\r\n * wx.requestPointerLock \u2014 request pointer lock\r\n * wx.exitPointerLock \u2014 exit pointer lock\r\n * wx.isPointerLocked \u2014 check if pointer is locked\r\n */\r\n\r\nimport { getMainCanvas } from './canvas';\r\nimport { nativeDocument } from './native-globals';\r\n\r\n/**\r\n * P2: wx.setCursor \u2014 sets the CSS cursor style on the canvas.\r\n */\r\nexport function setCursor(opts: {\r\n cursor: string;\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n try {\r\n const canvas = getMainCanvas();\r\n if (canvas) {\r\n canvas.style.cursor = opts.cursor;\r\n }\r\n opts.success?.();\r\n } catch (e) {\r\n opts.fail?.({ errMsg: `setCursor:fail ${e}` });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n}\r\n\r\n/**\r\n * P2: wx.requestPointerLock \u2014 requests pointer lock via Pointer Lock API.\r\n */\r\nexport function requestPointerLock(opts?: {\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n try {\r\n const canvas = getMainCanvas();\r\n if (canvas) {\r\n canvas.requestPointerLock();\r\n }\r\n opts?.success?.();\r\n } catch (e) {\r\n opts?.fail?.({ errMsg: `requestPointerLock:fail ${e}` });\r\n } finally {\r\n opts?.complete?.();\r\n }\r\n}\r\n\r\n/**\r\n * P2: wx.exitPointerLock \u2014 exits pointer lock.\r\n */\r\nexport function exitPointerLock(opts?: {\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n try {\r\n nativeDocument.exitPointerLock();\r\n opts?.success?.();\r\n } catch (e) {\r\n opts?.fail?.({ errMsg: `exitPointerLock:fail ${e}` });\r\n } finally {\r\n opts?.complete?.();\r\n }\r\n}\r\n\r\n/**\r\n * P2: wx.isPointerLocked \u2014 checks if pointer is currently locked.\r\n */\r\nexport function isPointerLocked(): boolean {\r\n return nativeDocument.pointerLockElement !== null;\r\n}\r\n", "/**\r\n * Sensors module (P2) \u2014 Accelerometer, Gyroscope, Compass, Device Orientation, Device Motion.\r\n *\r\n * These APIs are used by sensor-based games (tilt controls, compass, etc.).\r\n * Browser implementations use DeviceMotionEvent and DeviceOrientationEvent.\r\n *\r\n * Permissions Policy note:\r\n * In browser iframes, sensor events (devicemotion / deviceorientation) require\r\n * explicit Permissions Policy grants on the <iframe allow=\"...\"> attribute.\r\n * Without them the browser fires a [Violation] and the events never arrive.\r\n *\r\n * We handle this in two layers:\r\n * 1. The outer preview.html iframe carries allow=\"accelerometer; gyroscope; ...\"\r\n * so the game-host iframe is granted the necessary permissions.\r\n * 2. Here we use the Permissions API (where available) to detect denial early\r\n * and call the fail/complete callbacks instead of silently registering a\r\n * listener that will never fire.\r\n *\r\n * On WeChat real device these are native OS sensor APIs \u2014 no permission model.\r\n */\r\n\r\n// \u2500\u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ntype AccelCallback = (res: { x: number; y: number; z: number }) => void;\r\ntype GyroCallback = (res: { x: number; y: number; z: number }) => void;\r\ntype CompassCallback = (res: { direction: number; accuracy: number }) => void;\r\ntype DeviceOrientationCallback = (res: { alpha: number; beta: number; gamma: number }) => void;\r\ntype DeviceMotionCallback = (res: {\r\n acceleration: { x: number; y: number; z: number };\r\n accelerationIncludingGravity: { x: number; y: number; z: number };\r\n rotationRate: { alpha: number; beta: number; gamma: number };\r\n interval: number;\r\n}) => void;\r\n\r\n// \u2500\u2500\u2500 Permission helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Sensor permission names recognised by the Permissions API.\r\n * `device-motion` and `device-orientation` are the W3C names used by Chrome/Edge.\r\n * Safari does not support querying these via the Permissions API at all.\r\n */\r\ntype SensorPermissionName = 'accelerometer' | 'gyroscope' | 'magnetometer';\r\n\r\n/**\r\n * Check whether a sensor permission is granted via the Permissions API.\r\n * Returns:\r\n * 'granted' \u2014 permission is explicitly granted (safe to use)\r\n * 'denied' \u2014 permission is explicitly denied (will not work)\r\n * 'prompt' \u2014 not yet decided (may work; browser will prompt on first use)\r\n * 'unknown' \u2014 Permissions API not available or name not recognised\r\n */\r\nasync function querySensorPermission(name: SensorPermissionName): Promise<'granted' | 'denied' | 'prompt' | 'unknown'> {\r\n try {\r\n if (!navigator.permissions) return 'unknown';\r\n const status = await navigator.permissions.query({ name: name as PermissionName });\r\n return status.state as 'granted' | 'denied' | 'prompt';\r\n } catch {\r\n // PermissionName not recognised by this browser (e.g. Firefox, Safari)\r\n return 'unknown';\r\n }\r\n}\r\n\r\n/**\r\n * Safely add a window event listener for sensor events.\r\n * Some browsers throw synchronously when Permissions Policy blocks the event.\r\n * Returns true if the listener was added successfully.\r\n */\r\nfunction safeAddSensorListener<K extends keyof WindowEventMap>(\r\n type: K,\r\n handler: (e: WindowEventMap[K]) => void\r\n): boolean {\r\n try {\r\n window.addEventListener(type, handler);\r\n return true;\r\n } catch (e) {\r\n console.warn(`[wx-compat][sensors] Failed to add ${type} listener (Permissions Policy?):`, e);\r\n return false;\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 Accelerometer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst accelCallbacks: Set<AccelCallback> = new Set();\r\nlet accelHandler: ((e: DeviceMotionEvent) => void) | null = null;\r\n\r\nexport function startAccelerometer(opts?: {\r\n interval?: string;\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if (!accelHandler) {\r\n // Check permission asynchronously; register listener optimistically so that\r\n // games that have the iframe allow attribute work without waiting.\r\n querySensorPermission('accelerometer').then((state) => {\r\n if (state === 'denied') {\r\n console.warn('[wx-compat][sensors] accelerometer permission denied (Permissions Policy)');\r\n opts?.fail?.({ errMsg: 'startAccelerometer:fail permission denied' });\r\n opts?.complete?.();\r\n return;\r\n }\r\n if (!accelHandler) {\r\n accelHandler = (e: DeviceMotionEvent) => {\r\n const a = e.accelerationIncludingGravity;\r\n if (!a) return;\r\n const payload = {\r\n x: (a.x || 0) / 9.8,\r\n y: (a.y || 0) / 9.8,\r\n z: (a.z || 0) / 9.8,\r\n };\r\n accelCallbacks.forEach((cb) => cb(payload));\r\n };\r\n const ok = safeAddSensorListener('devicemotion', accelHandler);\r\n if (!ok) {\r\n accelHandler = null;\r\n opts?.fail?.({ errMsg: 'startAccelerometer:fail not supported' });\r\n opts?.complete?.();\r\n return;\r\n }\r\n }\r\n opts?.success?.();\r\n opts?.complete?.();\r\n });\r\n // Return immediately (async permission check happens in background)\r\n return;\r\n }\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\nexport function stopAccelerometer(opts?: {\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if (accelHandler) {\r\n window.removeEventListener('devicemotion', accelHandler);\r\n accelHandler = null;\r\n }\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\nexport function onAccelerometerChange(callback: AccelCallback): void {\r\n accelCallbacks.add(callback);\r\n}\r\n\r\nexport function offAccelerometerChange(callback: AccelCallback): void {\r\n accelCallbacks.delete(callback);\r\n}\r\n\r\n// \u2500\u2500\u2500 Gyroscope \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst gyroCallbacks: Set<GyroCallback> = new Set();\r\nlet gyroHandler: ((e: DeviceMotionEvent) => void) | null = null;\r\n\r\nexport function startGyroscope(opts?: {\r\n interval?: string;\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if (!gyroHandler) {\r\n querySensorPermission('gyroscope').then((state) => {\r\n if (state === 'denied') {\r\n console.warn('[wx-compat][sensors] gyroscope permission denied (Permissions Policy)');\r\n opts?.fail?.({ errMsg: 'startGyroscope:fail permission denied' });\r\n opts?.complete?.();\r\n return;\r\n }\r\n if (!gyroHandler) {\r\n gyroHandler = (e: DeviceMotionEvent) => {\r\n const r = e.rotationRate;\r\n if (!r) return;\r\n const payload = {\r\n x: r.beta || 0,\r\n y: r.gamma || 0,\r\n z: r.alpha || 0,\r\n };\r\n gyroCallbacks.forEach((cb) => cb(payload));\r\n };\r\n const ok = safeAddSensorListener('devicemotion', gyroHandler);\r\n if (!ok) {\r\n gyroHandler = null;\r\n opts?.fail?.({ errMsg: 'startGyroscope:fail not supported' });\r\n opts?.complete?.();\r\n return;\r\n }\r\n }\r\n opts?.success?.();\r\n opts?.complete?.();\r\n });\r\n return;\r\n }\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\nexport function stopGyroscope(opts?: {\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if (gyroHandler) {\r\n window.removeEventListener('devicemotion', gyroHandler);\r\n gyroHandler = null;\r\n }\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\nexport function onGyroscopeChange(callback: GyroCallback): void {\r\n gyroCallbacks.add(callback);\r\n}\r\n\r\nexport function offGyroscopeChange(callback: GyroCallback): void {\r\n gyroCallbacks.delete(callback);\r\n}\r\n\r\n// \u2500\u2500\u2500 Compass \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst compassCallbacks: Set<CompassCallback> = new Set();\r\nlet compassHandler: ((e: DeviceOrientationEvent) => void) | null = null;\r\n\r\nexport function startCompass(opts?: {\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if (!compassHandler) {\r\n querySensorPermission('magnetometer').then((state) => {\r\n if (state === 'denied') {\r\n console.warn('[wx-compat][sensors] magnetometer/compass permission denied (Permissions Policy)');\r\n opts?.fail?.({ errMsg: 'startCompass:fail permission denied' });\r\n opts?.complete?.();\r\n return;\r\n }\r\n if (!compassHandler) {\r\n compassHandler = (e: DeviceOrientationEvent) => {\r\n const direction = e.alpha != null ? 360 - e.alpha : 0;\r\n const payload = { direction, accuracy: 0 };\r\n compassCallbacks.forEach((cb) => cb(payload));\r\n };\r\n const ok = safeAddSensorListener('deviceorientation', compassHandler);\r\n if (!ok) {\r\n compassHandler = null;\r\n opts?.fail?.({ errMsg: 'startCompass:fail not supported' });\r\n opts?.complete?.();\r\n return;\r\n }\r\n }\r\n opts?.success?.();\r\n opts?.complete?.();\r\n });\r\n return;\r\n }\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\nexport function stopCompass(opts?: {\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if (compassHandler) {\r\n window.removeEventListener('deviceorientation', compassHandler);\r\n compassHandler = null;\r\n }\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\nexport function onCompassChange(callback: CompassCallback): void {\r\n compassCallbacks.add(callback);\r\n}\r\n\r\nexport function offCompassChange(callback: CompassCallback): void {\r\n compassCallbacks.delete(callback);\r\n}\r\n\r\n// \u2500\u2500\u2500 Device Orientation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst deviceOrientationCallbacks: Set<DeviceOrientationCallback> = new Set();\r\nlet deviceOrientationHandler: ((e: DeviceOrientationEvent) => void) | null = null;\r\n\r\nfunction ensureDeviceOrientationHandler(): void {\r\n if (deviceOrientationHandler) return;\r\n deviceOrientationHandler = (e: DeviceOrientationEvent) => {\r\n const payload = {\r\n alpha: e.alpha || 0,\r\n beta: e.beta || 0,\r\n gamma: e.gamma || 0,\r\n };\r\n deviceOrientationCallbacks.forEach((cb) => cb(payload));\r\n };\r\n safeAddSensorListener('deviceorientation', deviceOrientationHandler);\r\n}\r\n\r\nexport function onDeviceOrientationChange(callback: DeviceOrientationCallback): void {\r\n ensureDeviceOrientationHandler();\r\n deviceOrientationCallbacks.add(callback);\r\n}\r\n\r\nexport function offDeviceOrientationChange(callback: DeviceOrientationCallback): void {\r\n deviceOrientationCallbacks.delete(callback);\r\n if (deviceOrientationCallbacks.size === 0 && deviceOrientationHandler) {\r\n window.removeEventListener('deviceorientation', deviceOrientationHandler);\r\n deviceOrientationHandler = null;\r\n }\r\n}\r\n\r\nexport function setDeviceOrientation(opts: {\r\n value: string; // 'portrait' | 'landscape' | 'landscapeReverse'\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n // Browser cannot programmatically set orientation, no-op\r\n console.warn('[wx-compat] setDeviceOrientation is not supported in browser');\r\n opts.success?.();\r\n opts.complete?.();\r\n}\r\n\r\n// \u2500\u2500\u2500 Device Motion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst deviceMotionCallbacks: Set<DeviceMotionCallback> = new Set();\r\nlet deviceMotionHandler: ((e: DeviceMotionEvent) => void) | null = null;\r\n\r\nexport function startDeviceMotionListening(opts?: {\r\n interval?: string;\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if (!deviceMotionHandler) {\r\n // devicemotion requires both accelerometer + gyroscope permissions\r\n querySensorPermission('accelerometer').then((state) => {\r\n if (state === 'denied') {\r\n console.warn('[wx-compat][sensors] devicemotion permission denied (Permissions Policy)');\r\n opts?.fail?.({ errMsg: 'startDeviceMotionListening:fail permission denied' });\r\n opts?.complete?.();\r\n return;\r\n }\r\n if (!deviceMotionHandler) {\r\n deviceMotionHandler = (e: DeviceMotionEvent) => {\r\n const payload = {\r\n acceleration: {\r\n x: e.acceleration?.x || 0,\r\n y: e.acceleration?.y || 0,\r\n z: e.acceleration?.z || 0,\r\n },\r\n accelerationIncludingGravity: {\r\n x: e.accelerationIncludingGravity?.x || 0,\r\n y: e.accelerationIncludingGravity?.y || 0,\r\n z: e.accelerationIncludingGravity?.z || 0,\r\n },\r\n rotationRate: {\r\n alpha: e.rotationRate?.alpha || 0,\r\n beta: e.rotationRate?.beta || 0,\r\n gamma: e.rotationRate?.gamma || 0,\r\n },\r\n interval: e.interval || 0,\r\n };\r\n deviceMotionCallbacks.forEach((cb) => cb(payload));\r\n };\r\n const ok = safeAddSensorListener('devicemotion', deviceMotionHandler);\r\n if (!ok) {\r\n deviceMotionHandler = null;\r\n opts?.fail?.({ errMsg: 'startDeviceMotionListening:fail not supported' });\r\n opts?.complete?.();\r\n return;\r\n }\r\n }\r\n opts?.success?.();\r\n opts?.complete?.();\r\n });\r\n return;\r\n }\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\nexport function stopDeviceMotionListening(opts?: {\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if (deviceMotionHandler) {\r\n window.removeEventListener('devicemotion', deviceMotionHandler);\r\n deviceMotionHandler = null;\r\n }\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\nexport function onDeviceMotionChange(callback: DeviceMotionCallback): void {\r\n deviceMotionCallbacks.add(callback);\r\n}\r\n\r\nexport function offDeviceMotionChange(callback: DeviceMotionCallback): void {\r\n deviceMotionCallbacks.delete(callback);\r\n}\r\n", "/**\r\n * Device extras module (P2) \u2014 Battery, Clipboard, Network Status, Screen, Memory, Gamepad.\r\n *\r\n * These APIs extend device capabilities for browser preview.\r\n */\r\n\r\nimport { nativeDocument, nativeCreateElement } from './native-globals';\r\n\r\n// \u2500\u2500\u2500 Battery (P2) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport function getBatteryInfo(opts: {\r\n success?: (res: { level: number; isCharging: boolean }) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if ('getBattery' in navigator) {\r\n (navigator as any).getBattery().then((battery: any) => {\r\n opts.success?.({ level: Math.round(battery.level * 100), isCharging: battery.charging });\r\n opts.complete?.();\r\n }).catch(() => {\r\n opts.success?.({ level: 100, isCharging: false });\r\n opts.complete?.();\r\n });\r\n } else {\r\n opts.success?.({ level: 100, isCharging: false });\r\n opts.complete?.();\r\n }\r\n}\r\n\r\nexport function getBatteryInfoSync(): { level: number; isCharging: boolean } {\r\n // Battery API is async, return mock for sync version\r\n return { level: 100, isCharging: false };\r\n}\r\n\r\n// \u2500\u2500\u2500 Clipboard (P2) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport function setClipboardData(opts: {\r\n data: string;\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if (navigator.clipboard) {\r\n navigator.clipboard.writeText(opts.data).then(() => {\r\n opts.success?.();\r\n }).catch((e) => {\r\n opts.fail?.({ errMsg: `setClipboardData:fail ${e}` });\r\n }).finally(() => {\r\n opts.complete?.();\r\n });\r\n } else {\r\n // Fallback: execCommand \u2014 use nativeDocument since cleanGlobals\r\n // strips execCommand from the sandboxed document\r\n try {\r\n const ta = nativeCreateElement('textarea') as HTMLTextAreaElement;\r\n ta.value = opts.data;\r\n ta.style.position = 'fixed';\r\n ta.style.left = '-9999px';\r\n nativeDocument.body.appendChild(ta);\r\n ta.select();\r\n nativeDocument.execCommand('copy');\r\n nativeDocument.body.removeChild(ta);\r\n opts.success?.();\r\n } catch (e) {\r\n opts.fail?.({ errMsg: `setClipboardData:fail ${e}` });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n }\r\n}\r\n\r\nexport function getClipboardData(opts: {\r\n success?: (res: { data: string }) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if (navigator.clipboard) {\r\n navigator.clipboard.readText().then((text) => {\r\n opts.success?.({ data: text });\r\n }).catch((e) => {\r\n opts.fail?.({ errMsg: `getClipboardData:fail ${e}` });\r\n }).finally(() => {\r\n opts.complete?.();\r\n });\r\n } else {\r\n opts.fail?.({ errMsg: 'getClipboardData:fail clipboard API not available' });\r\n opts.complete?.();\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 Network Status (P2) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ntype NetworkStatusCallback = (res: { isConnected: boolean; networkType: string }) => void;\r\n\r\nconst networkStatusCallbacks: Set<NetworkStatusCallback> = new Set();\r\nlet networkListenerSetup = false;\r\n\r\nfunction getNetworkTypeString(): string {\r\n const conn = (navigator as any).connection;\r\n if (conn) {\r\n const type = conn.effectiveType || conn.type || '';\r\n if (type === '4g') return '4g';\r\n if (type === '3g') return '3g';\r\n if (type === '2g') return '2g';\r\n if (type === 'wifi') return 'wifi';\r\n }\r\n return navigator.onLine ? 'wifi' : 'none';\r\n}\r\n\r\n// Build the standard getNetworkType result per WeChat docs. The same object\r\n// is passed to both `success` and `complete` (WeChat semantics: complete\r\n// receives the success/fail result).\r\nfunction buildNetworkTypeResult(): {\r\n networkType: string;\r\n signalStrength: number;\r\n hasSystemProxy: boolean;\r\n weakNet: boolean;\r\n errMsg: string;\r\n} {\r\n const networkType = getNetworkTypeString();\r\n const conn = (navigator as any).connection;\r\n const effectiveType = conn?.effectiveType || '';\r\n const weakNet = effectiveType === '2g' || effectiveType === 'slow-2g';\r\n return {\r\n networkType,\r\n signalStrength: 0,\r\n hasSystemProxy: false,\r\n weakNet,\r\n errMsg: 'getNetworkType:ok',\r\n };\r\n}\r\n\r\nfunction ensureNetworkListener(): void {\r\n if (networkListenerSetup) return;\r\n networkListenerSetup = true;\r\n\r\n const fire = () => {\r\n const payload = {\r\n isConnected: navigator.onLine,\r\n networkType: getNetworkTypeString(),\r\n };\r\n networkStatusCallbacks.forEach((cb) => cb(payload));\r\n };\r\n\r\n window.addEventListener('online', fire);\r\n window.addEventListener('offline', fire);\r\n}\r\n\r\nexport function getNetworkType(opts?: {\r\n success?: (res: {\r\n networkType: string;\r\n signalStrength: number;\r\n hasSystemProxy: boolean;\r\n weakNet: boolean;\r\n errMsg: string;\r\n }) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: (res: {\r\n networkType: string;\r\n signalStrength: number;\r\n hasSystemProxy: boolean;\r\n weakNet: boolean;\r\n errMsg: string;\r\n }) => void;\r\n}): void {\r\n const res = buildNetworkTypeResult();\r\n opts?.success?.(res);\r\n // Per WeChat docs: `complete` is called on both success and failure, and\r\n // receives the same result object as `success` / `fail`. Games commonly\r\n // rely on this (e.g. `complete(n) { ... n.networkType ... }`). Passing\r\n // undefined here would crash such games.\r\n opts?.complete?.(res);\r\n}\r\n\r\nexport function onNetworkStatusChange(callback: NetworkStatusCallback): void {\r\n ensureNetworkListener();\r\n networkStatusCallbacks.add(callback);\r\n}\r\n\r\nexport function offNetworkStatusChange(callback: NetworkStatusCallback): void {\r\n networkStatusCallbacks.delete(callback);\r\n}\r\n\r\ntype WeakNetCallback = (res: { weakNet: boolean; networkType: string }) => void;\r\nconst weakNetCallbacks: Set<WeakNetCallback> = new Set();\r\n\r\nexport function onNetworkWeakChange(callback: WeakNetCallback): void {\r\n weakNetCallbacks.add(callback);\r\n // In browser, we approximate weak network by checking effectiveType\r\n const conn = (navigator as any).connection;\r\n if (conn && conn.addEventListener) {\r\n conn.addEventListener('change', () => {\r\n const type = conn.effectiveType || '';\r\n const isWeak = type === '2g' || type === 'slow-2g';\r\n callback({ weakNet: isWeak, networkType: getNetworkTypeString() });\r\n });\r\n }\r\n}\r\n\r\nexport function offNetworkWeakChange(callback: WeakNetCallback): void {\r\n weakNetCallbacks.delete(callback);\r\n}\r\n\r\n// \u2500\u2500\u2500 Screen (P2) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nlet wakeLock: any = null;\r\n\r\nexport function setKeepScreenOn(opts: {\r\n keepScreenOn: boolean;\r\n success?: () => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n if ('wakeLock' in navigator) {\r\n if (opts.keepScreenOn) {\r\n (navigator as any).wakeLock.request('screen').then((lock: any) => {\r\n wakeLock = lock;\r\n opts.success?.();\r\n }).catch((e: Error) => {\r\n opts.fail?.({ errMsg: `setKeepScreenOn:fail ${e}` });\r\n }).finally(() => {\r\n opts.complete?.();\r\n });\r\n } else {\r\n if (wakeLock) {\r\n wakeLock.release();\r\n wakeLock = null;\r\n }\r\n opts.success?.();\r\n opts.complete?.();\r\n }\r\n } else {\r\n // Wake Lock API not available, no-op\r\n opts.success?.();\r\n opts.complete?.();\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 Memory Warning (P2) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ntype MemoryCallback = (res: { level: number }) => void;\r\nconst memoryWarningCallbacks: Set<MemoryCallback> = new Set();\r\n\r\nexport function onMemoryWarning(callback: MemoryCallback): void {\r\n memoryWarningCallbacks.add(callback);\r\n // Browser doesn't have memory warning events; this is a no-op registration\r\n}\r\n\r\nexport function offMemoryWarning(callback: MemoryCallback): void {\r\n memoryWarningCallbacks.delete(callback);\r\n}\r\n\r\n// \u2500\u2500\u2500 Gamepad (P2) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ntype GamepadCallback = (res: { gamepad: Gamepad }) => void;\r\n\r\nconst gamepadConnectedCallbacks: Set<GamepadCallback> = new Set();\r\nconst gamepadDisconnectedCallbacks: Set<GamepadCallback> = new Set();\r\nlet gamepadListenerSetup = false;\r\n\r\nfunction ensureGamepadListeners(): void {\r\n if (gamepadListenerSetup) return;\r\n gamepadListenerSetup = true;\r\n\r\n window.addEventListener('gamepadconnected', (e: GamepadEvent) => {\r\n gamepadConnectedCallbacks.forEach((cb) => cb({ gamepad: e.gamepad }));\r\n });\r\n window.addEventListener('gamepaddisconnected', (e: GamepadEvent) => {\r\n gamepadDisconnectedCallbacks.forEach((cb) => cb({ gamepad: e.gamepad }));\r\n });\r\n}\r\n\r\nexport function getGamepads(): (Gamepad | null)[] {\r\n return Array.from(navigator.getGamepads());\r\n}\r\n\r\nexport function onGamepadConnected(callback: GamepadCallback): void {\r\n ensureGamepadListeners();\r\n gamepadConnectedCallbacks.add(callback);\r\n}\r\n\r\nexport function onGamepadDisconnected(callback: GamepadCallback): void {\r\n ensureGamepadListeners();\r\n gamepadDisconnectedCallbacks.add(callback);\r\n}\r\n", "/**\r\n * Data analysis module (P2) \u2014 reporting, experiments, game log.\r\n *\r\n * Implements:\r\n * wx.reportEvent / wx.reportMonitor / wx.reportScene \u2014 no-op (log to console)\r\n * wx.getExptInfoSync / wx.getGameExptInfo \u2014 return empty data\r\n * wx.getGameLogManager / GameLogManager \u2014 console-based mock\r\n * wx.getMiniReportManager / MiniReportManager \u2014 no-op mock\r\n */\r\n\r\n/**\r\n * P2: wx.reportAnalytics \u2014 logs analytics data to console (no-op in browser).\r\n * Stores reported data for potential later inspection.\r\n */\r\nconst _analyticsData: Array<{ eventName: string; data: Record<string, unknown> }> = [];\r\n\r\nexport function reportAnalytics(eventName: string, data?: Record<string, unknown>): void {\r\n const entry = { eventName, data: data || {} };\r\n _analyticsData.push(entry);\r\n console.log(`[wx-compat] reportAnalytics: ${eventName}`, data || '');\r\n}\r\n\r\n/**\r\n * P2: wx.reportEvent \u2014 logs event to console (no-op in browser).\r\n */\r\nexport function reportEvent(eventId: string, data?: Record<string, unknown>): void {\r\n console.log(`[wx-compat] reportEvent: ${eventId}`, data || '');\r\n}\r\n\r\n/**\r\n * P2: wx.reportMonitor \u2014 logs monitor data to console.\r\n */\r\nexport function reportMonitor(name: string, value: number): void {\r\n console.log(`[wx-compat] reportMonitor: ${name} = ${value}`);\r\n}\r\n\r\n/**\r\n * P2: wx.reportScene \u2014 logs scene data to console.\r\n */\r\nexport function reportScene(opts: {\r\n sceneId: number;\r\n dimensionValues?: Record<string, string>;\r\n metricValues?: Record<string, number>;\r\n}): void {\r\n console.log(`[wx-compat] reportScene: ${opts.sceneId}`, opts);\r\n}\r\n\r\n/**\r\n * P2: wx.getExptInfoSync \u2014 returns empty experiment info.\r\n */\r\nexport function getExptInfoSync(keys?: string[]): Record<string, unknown> {\r\n return {};\r\n}\r\n\r\n/**\r\n * P2: wx.getGameExptInfo \u2014 returns empty experiment info via callback.\r\n */\r\nexport function getGameExptInfo(opts: {\r\n keys: string[];\r\n success?: (res: { data: Record<string, unknown> }) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n opts.success?.({ data: {} });\r\n opts.complete?.();\r\n}\r\n\r\n/**\r\n * Tagged logger returned by GameLogManager.tag().\r\n * Provides info/warn/error/debug methods that prefix output with the tag name.\r\n */\r\ninterface TaggedGameLogManager {\r\n info(...args: unknown[]): void;\r\n warn(...args: unknown[]): void;\r\n error(...args: unknown[]): void;\r\n debug(...args: unknown[]): void;\r\n tag(tagName: string): TaggedGameLogManager;\r\n}\r\n\r\n/**\r\n * GameLogManager \u2014 console-based mock.\r\n * Matches the WeChat GameLogManager API including tag() for sub-loggers.\r\n */\r\ninterface GameLogManager {\r\n addFilterMsg(msg: string): void;\r\n addUnionIdFilterMsg(msg: string): void;\r\n info(...args: unknown[]): void;\r\n warn(...args: unknown[]): void;\r\n error(...args: unknown[]): void;\r\n debug(...args: unknown[]): void;\r\n tag(tagName: string): TaggedGameLogManager;\r\n}\r\n\r\n/**\r\n * Create a tagged logger instance (returned by GameLogManager.tag()).\r\n */\r\nfunction createTaggedLogger(tagName: string): TaggedGameLogManager {\r\n return {\r\n info(...args: unknown[]) { console.info(`[GameLog][${tagName}]`, ...args); },\r\n warn(...args: unknown[]) { console.warn(`[GameLog][${tagName}]`, ...args); },\r\n error(...args: unknown[]) { console.error(`[GameLog][${tagName}]`, ...args); },\r\n debug(...args: unknown[]) { console.debug(`[GameLog][${tagName}]`, ...args); },\r\n tag(newTag: string) { return createTaggedLogger(newTag); },\r\n };\r\n}\r\n\r\n/**\r\n * P2: wx.getGameLogManager \u2014 returns a console-based log manager.\r\n * Supports the tag() method used by Unity and other engine plugins\r\n * to create sub-loggers with prefixed output.\r\n */\r\nexport function getGameLogManager(opts?: { commonInfo?: Record<string, unknown> }): GameLogManager {\r\n return {\r\n addFilterMsg(msg: string) {\r\n console.log(`[GameLog filter] ${msg}`);\r\n },\r\n addUnionIdFilterMsg(msg: string) {\r\n console.log(`[GameLog unionId filter] ${msg}`);\r\n },\r\n info(...args: unknown[]) { console.info('[GameLog]', ...args); },\r\n warn(...args: unknown[]) { console.warn('[GameLog]', ...args); },\r\n error(...args: unknown[]) { console.error('[GameLog]', ...args); },\r\n debug(...args: unknown[]) { console.debug('[GameLog]', ...args); },\r\n tag(tagName: string) { return createTaggedLogger(tagName); },\r\n };\r\n}\r\n\r\n/**\r\n * MiniReportManager \u2014 no-op mock.\r\n */\r\ninterface MiniReportManager {\r\n reportEvent(eventId: string, data?: Record<string, unknown>): void;\r\n}\r\n\r\n/**\r\n * P2: wx.getMiniReportManager \u2014 returns a no-op report manager.\r\n */\r\nexport function getMiniReportManager(): MiniReportManager {\r\n return {\r\n reportEvent(eventId: string, data?: Record<string, unknown>) {\r\n console.log(`[MiniReport] ${eventId}`, data || '');\r\n },\r\n };\r\n}\r\n", "/**\r\n * Worker compatibility module (P2) \u2014 wx.createWorker shim.\r\n *\r\n * In WeChat, wx.createWorker takes a script path relative to the mini game root\r\n * and spawns a separate thread. Inside that thread, the runtime injects a global\r\n * `worker` object with `onMessage`, `postMessage`, `getFileSystemManager`,\r\n * `createSharedArrayBuffer`, etc.\r\n *\r\n * In browser preview we use a real Web Worker for true multi-threading, but\r\n * bridge the API difference by injecting a bootstrap script that defines a\r\n * global `worker` object inside the Worker scope. This mock `worker` object\r\n * translates WeChat-style calls (`worker.onMessage`, `worker.postMessage`)\r\n * into standard Web Worker messaging (`self.onmessage`, `self.postMessage`).\r\n *\r\n * Flow:\r\n * 1. Fetch the original worker script source code.\r\n * 2. Prepend a bootstrap snippet that defines `self.worker` with WeChat-\r\n * compatible APIs (onMessage, postMessage, getFileSystemManager, etc.).\r\n * 3. Create a Blob URL from the combined code and spawn a real Web Worker.\r\n * 4. Main-thread WxWorker handle translates between WeChat API and standard\r\n * Web Worker messaging.\r\n */\r\n\r\nimport { wxResourceFetch } from './native-globals';\r\nimport { resolveGameUrl, loadGameManifest } from './url-utils';\r\n\r\ninterface WxWorker {\r\n postMessage(message: unknown): void;\r\n onMessage(callback: (res: { message: unknown }) => void): void;\r\n /** Receives uncaught errors from the worker thread (P1 protocol). */\r\n onError?(callback: (res: { message: string; filename?: string; lineno?: number; colno?: number }) => void): void;\r\n /** Native protocol: track when the worker has actually booted up. */\r\n onProcessKilled?(callback: () => void): void;\r\n terminate(): void;\r\n}\r\n\r\n/**\r\n * Per-worker bootstrap timeout (ms). If the worker script has not signalled\r\n * `ready` within this window, we surface an error to the host and free the\r\n * Worker object. Configurable via `window.__wxWorkerBootTimeoutMs` so stress\r\n * tests / large bundles can opt into a longer budget.\r\n *\r\n * Default 15s mirrors the native limit on PC (Windows/Mac) WeChat which\r\n * kills workers that fail to bind within ~12-20s of `wx.createWorker()`.\r\n */\r\nfunction getBootTimeoutMs(): number {\r\n const v = (window as unknown as Record<string, unknown>).__wxWorkerBootTimeoutMs;\r\n if (typeof v === 'number' && v > 0 && v < 600_000) return v;\r\n return 15_000;\r\n}\r\n\r\n/**\r\n * Hard run budget (ms) for a single message handler inside the worker.\r\n * We cannot truly limit JS execution time without `Atomics.wait` style\r\n * watchdogs running on a parallel Worker, but we *can* notice when a\r\n * worker has been silent for too long after we sent a message and surface\r\n * a console warning so games don't appear to hang silently.\r\n *\r\n * 0 disables the watchdog entirely.\r\n */\r\nfunction getWorkerWatchdogMs(): number {\r\n const v = (window as unknown as Record<string, unknown>).__wxWorkerWatchdogMs;\r\n if (typeof v === 'number' && v >= 0 && v < 600_000) return v;\r\n return 0; // off by default \u2014 most games legitimately stall on long FFTs\r\n}\r\n\r\n/**\r\n * Bootstrap code injected at the top of the Worker script.\r\n *\r\n * Defines `self.worker` (also accessible as bare `worker`) with:\r\n * - onMessage(cb) \u2014 registers a listener; bridges from self.onmessage\r\n * - postMessage(msg) \u2014 sends to main thread via self.postMessage\r\n * - getFileSystemManager() \u2014 stub (FS not available in Worker thread)\r\n * - createSharedArrayBuffer(size) \u2014 SharedArrayBuffer with fallback\r\n *\r\n * Native protocol envelopes (B-style, mirroring WMPFWorker / PCWebWorker):\r\n * - { type: 'wx-worker-init', payload: { ... env ... } } main \u2192 worker\r\n * - { type: 'wx-worker-ready', payload: null } worker \u2192 main\r\n * - { type: 'wx-worker-message', payload: <user message> } both directions\r\n * - { type: 'wx-worker-error', payload: { message, ... } } worker \u2192 main\r\n *\r\n * `init` runs first and lets us pass environment hints (e.g. game appId,\r\n * deviceWidth) into the worker before any user code runs. `ready` lets the\r\n * main thread know the worker scope is set up (used to clear the boot\r\n * timeout watchdog). User messages keep using the `wx-worker-message`\r\n * envelope unchanged so existing call sites stay compatible.\r\n */\r\nconst WORKER_BOOTSTRAP = `\r\n// \u2500\u2500 WeChat worker global shim \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n(function() {\r\n var _callbacks = [];\r\n var _errorCallbacks = [];\r\n\r\n // Forward uncaught errors to the main thread under a dedicated envelope.\r\n // Without this, self.onerror swallows errors silently and the host has\r\n // no way to surface them on the wx.createWorker handle onError callback.\r\n self.addEventListener('error', function(e) { try {\r\n self.postMessage({\r\n type: 'wx-worker-error',\r\n payload: {\r\n message: (e && e.message) || String(e),\r\n filename: e && e.filename,\r\n lineno: e && e.lineno,\r\n colno: e && e.colno,\r\n },\r\n });\r\n } catch (_) { /* ignore */ }\r\n });\r\n self.addEventListener('unhandledrejection', function(e) {\r\n try {\r\n var reason = e && (e.reason && (e.reason.stack || e.reason.message)) || String(e);\r\n self.postMessage({\r\n type: 'wx-worker-error',\r\n payload: { message: 'unhandledrejection: ' + reason },\r\n });\r\n } catch (_) { /* ignore */ }\r\n });\r\n\r\n self.worker = {\r\n onMessage: function(cb) {\r\n _callbacks.push(cb);\r\n },\r\n postMessage: function(msg) {\r\n self.postMessage({ type: 'wx-worker-message', payload: msg });\r\n },\r\n /**\r\n * onError matches the WeChat-documented surface (added in 2.27+).\r\n * Errors are *also* forwarded to the main thread for the wx.createWorker\r\n * handle's onError callback; this hook lets in-worker code observe them\r\n * locally too (rarely used, but cheap to expose).\r\n */\r\n onError: function(cb) {\r\n _errorCallbacks.push(cb);\r\n },\r\n getFileSystemManager: function() {\r\n // FileSystemManager is not available inside a real Web Worker thread.\r\n // Return a minimal stub that logs warnings for any operation.\r\n console.warn('[wx-compat][worker] getFileSystemManager is not supported inside Web Worker. File operations should be delegated to the main thread.');\r\n return null;\r\n },\r\n createSharedArrayBuffer: function(size) {\r\n try {\r\n return new SharedArrayBuffer(size);\r\n } catch(e) {\r\n console.warn('[wx-compat][worker] SharedArrayBuffer not available, falling back to ArrayBuffer');\r\n return new ArrayBuffer(size);\r\n }\r\n }\r\n };\r\n\r\n // Bridge: main \u2192 worker traffic on the protocol envelopes.\r\n self.onmessage = function(e) {\r\n var data = e.data;\r\n if (!data || typeof data !== 'object') return;\r\n if (data.type === 'wx-worker-message') {\r\n for (var i = 0; i < _callbacks.length; i++) {\r\n try {\r\n _callbacks[i](data.payload);\r\n } catch(err) {\r\n console.error('[wx-compat][worker] Error in worker onMessage callback:', err);\r\n // Forward as a structured error so the host's onError fires too.\r\n try {\r\n self.postMessage({\r\n type: 'wx-worker-error',\r\n payload: { message: 'onMessage threw: ' + (err && err.message || String(err)) },\r\n });\r\n } catch (_) { /* ignore */ }\r\n }\r\n }\r\n } else if (data.type === 'wx-worker-init') {\r\n // Stash env hints; user code can read them off self.__wxWorkerEnv\r\n // (e.g. appId, devicePixelRatio, debug flag).\r\n self.__wxWorkerEnv = data.payload || {};\r\n }\r\n };\r\n\r\n // Announce readiness so the main thread can clear its boot timeout.\r\n // Posted at the END of the bootstrap so any synchronous setup above is\r\n // already done; user-script execution still happens after this frame.\r\n try {\r\n self.postMessage({ type: 'wx-worker-ready' });\r\n } catch (_) { /* ignore */ }\r\n})();\r\n// \u2500\u2500 End WeChat worker global shim \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n`;\r\n\r\n/**\r\n * Minimal AMD-style define/require shim executed INSIDE the Worker scope when\r\n * the game packs its workers as a bundle (see `workers.js` with\r\n * `define(\"workers/xxx/index.js\", function(require, module, exports, ...) { ... })`).\r\n *\r\n * Why not reuse main-thread module-compat.ts? The Worker is a separate JS\r\n * realm with no access to the main window/moduleFactories. We only need a\r\n * tiny subset: register factories via `define(id, fn)`, resolve them via\r\n * `require(id)` once to execute the chosen entry module. Everything else\r\n * (wx, wx-compat APIs) is unused by these AMD-packed worker modules \u2014 they\r\n * only touch the injected `worker` global already provided by\r\n * WORKER_BOOTSTRAP above.\r\n *\r\n * The shim also accepts the extra WeChat-style argument list\r\n * `(require, module, exports, window, document, frames, self, location,\r\n * navigator, localStorage, history, Caches, screen, alert, confirm, prompt,\r\n * XMLHttpRequest, WebSocket, Reporter, webkit, WeixinJSCore)` \u2014 passing\r\n * undefined for the ones that don't make sense inside a Worker.\r\n */\r\nconst WORKER_BUNDLE_MODULE_SHIM = `\r\n// \u2500\u2500 workers.js bundle module shim \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n(function() {\r\n var factories = Object.create(null);\r\n var cache = Object.create(null);\r\n\r\n self.define = function(id, factory) {\r\n factories[id] = factory;\r\n };\r\n\r\n function _require(id) {\r\n if (cache[id]) return cache[id].exports;\r\n var factory = factories[id];\r\n if (!factory) {\r\n throw new Error('[wx-compat][worker] module not registered: ' + id);\r\n }\r\n var mod = { exports: {} };\r\n cache[id] = mod;\r\n // WeChat's define() receives a long argument list. Inside a Web Worker\r\n // most of these globals are absent or irrelevant \u2014 pass the few we have\r\n // and let the rest be undefined. The worker-global shim (self.worker)\r\n // is already installed by WORKER_BOOTSTRAP above.\r\n factory(\r\n _require,\r\n mod,\r\n mod.exports,\r\n /* window */ undefined,\r\n /* document */ undefined,\r\n /* frames */ undefined,\r\n /* self */ self,\r\n /* location */ self.location,\r\n /* navigator */ self.navigator,\r\n /* localStorage */ undefined,\r\n /* history */ undefined,\r\n /* Caches */ undefined,\r\n /* screen */ undefined,\r\n /* alert */ undefined,\r\n /* confirm */ undefined,\r\n /* prompt */ undefined,\r\n /* XMLHttpRequest */ self.XMLHttpRequest,\r\n /* WebSocket */ self.WebSocket,\r\n /* Reporter */ undefined,\r\n /* webkit */ undefined,\r\n /* WeixinJSCore */ undefined\r\n );\r\n return mod.exports;\r\n }\r\n\r\n self.require = _require;\r\n self.__wxWorkerRequire = _require;\r\n})();\r\n// \u2500\u2500 End workers.js bundle module shim \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n`;\r\n\r\n/**\r\n * Resolve which bundle file (if any) packages the worker module at\r\n * `scriptPath`. Per the WeChat docs:\r\n *\r\n * game.json.workers = \"workers\" // string form, <= 1 root\r\n * game.json.workers = { \"name\": \"...\", // object form (less common)\r\n * \"workers\": [...] }\r\n *\r\n * Every worker script under `<workersRoot>/**` is bundled into the single\r\n * file `<workersRoot>.js` alongside a top-level `workers.js` manifest. The\r\n * runtime loads that bundle, then calls the registered factory for the\r\n * requested sub-path.\r\n *\r\n * We support the common case: if `scriptPath` starts with the workers root\r\n * and a `<root>.js` exists in the VFS / on disk, return that path.\r\n * Otherwise return null so the caller falls back to loading the raw script\r\n * as a single file (the legacy / directory-mode path).\r\n */\r\n/**\r\n * Type guard for the `workers` field of a game.json manifest.\r\n *\r\n * Accepts the two documented shapes:\r\n * - string form: `\"workers\": \"workers\"`\r\n * - object form: `\"workers\": { \"name\": \"...\", \"workers\": [...] }`\r\n *\r\n * Using a proper type guard (instead of scattered `as` casts) lets the\r\n * compiler narrow `workersField` automatically at the call site and\r\n * removes the `any` / `unknown`-escape-hatch casts from the main flow.\r\n */\r\ninterface WorkersObjectConfig {\r\n name?: string;\r\n workers?: unknown;\r\n}\r\ntype WorkersConfig = string | WorkersObjectConfig;\r\n\r\nfunction isWorkersConfig(value: unknown): value is WorkersConfig {\r\n if (typeof value === 'string') return true;\r\n if (value === null || typeof value !== 'object') return false;\r\n const name = (value as { name?: unknown }).name;\r\n return name === undefined || typeof name === 'string';\r\n}\r\n\r\nfunction resolveWorkersBundlePath(scriptPath: string): string | null {\r\n const manifest = loadGameManifest();\r\n if (!manifest) return null;\r\n\r\n // Extract the workers root. String form: \"workers\"; object form: take\r\n // the `name` field if present. We deliberately ignore the full sub-list\r\n // because the bundle name is always `<root>.js`, regardless of how many\r\n // scripts live inside.\r\n const workersField: unknown = (manifest as Record<string, unknown>).workers;\r\n let workersRoot: string | null = null;\r\n if (isWorkersConfig(workersField)) {\r\n if (typeof workersField === 'string') {\r\n const trimmed = workersField.trim();\r\n if (trimmed) workersRoot = trimmed;\r\n } else if (typeof workersField.name === 'string') {\r\n const trimmed = workersField.name.trim();\r\n if (trimmed) workersRoot = trimmed;\r\n }\r\n }\r\n\r\n if (!workersRoot) return null;\r\n\r\n // Normalise: strip leading/trailing slashes so \"/workers/\" and \"workers\"\r\n // both match.\r\n const normRoot = workersRoot.replace(/^\\/+|\\/+$/g, '');\r\n const normScript = scriptPath.replace(/^\\/+/, '');\r\n\r\n // Must live under the declared workers root. If the game passes an\r\n // absolute path that doesn't start with the root (unusual but legal in\r\n // directory-mode source projects), fall back to single-file loading.\r\n if (!normScript.startsWith(normRoot + '/') && normScript !== normRoot + '.js') {\r\n return null;\r\n }\r\n\r\n // The bundle itself sits next to the workers directory, one level up.\r\n return normRoot + '.js';\r\n}\r\n\r\n/**\r\n * P2: wx.createWorker \u2014 creates a real Web Worker with an injected `worker`\r\n * global that mimics WeChat's worker runtime environment.\r\n *\r\n * @param scriptPath Path to the worker script (relative to game root)\r\n * @param opts Options (currently unused)\r\n */\r\nexport function createWorker(\r\n scriptPath: string,\r\n opts?: { useExperimentalWorker?: boolean }\r\n): WxWorker {\r\n const messageCallbacks: Set<(res: { message: unknown }) => void> = new Set();\r\n const errorCallbacks: Set<(res: { message: string; filename?: string; lineno?: number; colno?: number }) => void> = new Set();\r\n const killedCallbacks: Set<() => void> = new Set();\r\n let nativeWorker: Worker | null = null;\r\n let blobUrl: string | null = null;\r\n let terminated = false;\r\n let bootResolved = false;\r\n let pendingMessages: unknown[] = [];\r\n\r\n // Boot watchdog: if the worker scope never posts `wx-worker-ready` within\r\n // the configured budget, log loudly and terminate the worker so the main\r\n // thread doesn't hold a zombie reference. Without this, a worker script\r\n // with a top-level syntax error stays silently broken, and every\r\n // subsequent `worker.postMessage` is just a slow leak.\r\n const bootTimeoutMs = getBootTimeoutMs();\r\n const bootTimer = setTimeout(() => {\r\n if (bootResolved || terminated) return;\r\n const msg = `[wx-compat][worker] Boot timeout (${bootTimeoutMs}ms): \"${scriptPath}\" never posted ready`;\r\n console.error(msg);\r\n errorCallbacks.forEach((cb) => {\r\n try { cb({ message: 'worker boot timeout' }); } catch { /* ignore */ }\r\n });\r\n // Terminate so the host can hot-swap the worker if it wants.\r\n try { nativeWorker?.terminate(); } catch { /* ignore */ }\r\n nativeWorker = null;\r\n bootResolved = true;\r\n }, bootTimeoutMs);\r\n\r\n // Optional per-message watchdog: warn if the worker hasn't replied within\r\n // the configured window. Off by default \u2014 many real games legitimately\r\n // perform multi-second computations without intermediate messages.\r\n const watchdogMs = getWorkerWatchdogMs();\r\n let watchdogTimer: ReturnType<typeof setTimeout> | null = null;\r\n function bumpWatchdog(): void {\r\n if (!watchdogMs) return;\r\n if (watchdogTimer) clearTimeout(watchdogTimer);\r\n watchdogTimer = setTimeout(() => {\r\n console.warn(\r\n `[wx-compat][worker] \"${scriptPath}\" silent for ${watchdogMs}ms after main\u2192worker message \u2014 possible deadlock or runaway loop.`,\r\n );\r\n }, watchdogMs);\r\n }\r\n\r\n // Fetch the worker script, prepend bootstrap, and spawn a real Web Worker\r\n // Use the VFS-aware fetcher: worker scripts packaged inside a wxapkg live in\r\n // the in-memory VFS (wxvfs: url) and cannot be served by the plain native fetch.\r\n // resolveGameUrl rewrites relative paths to either a wxvfs: or an http(s) URL,\r\n // and wxResourceFetch handles both.\r\n //\r\n // Bundle-awareness: WeChat packs all scripts under the declared `workers`\r\n // root (e.g. \"workers/response/index.js\") into a single `<root>.js`\r\n // AMD-style bundle that calls `define(id, factory)` once per source file.\r\n // When such a bundle exists we must load *that* file instead of the\r\n // virtual per-module path (which would 404 / fall through to the remote\r\n // server and return HTML, producing the classic\r\n // \"Uncaught SyntaxError: Unexpected token '<'\"\r\n // inside the Worker). After loading, a tiny define/require shim inside\r\n // the Worker resolves the intended entry module.\r\n const bundlePath = resolveWorkersBundlePath(scriptPath);\r\n const fetchPath = bundlePath ?? scriptPath;\r\n const entryModuleId = bundlePath ? scriptPath.replace(/^\\/+/, '') : null;\r\n\r\n wxResourceFetch(resolveGameUrl(fetchPath))\r\n .then((res) => {\r\n if (!res.ok) {\r\n throw new Error(`HTTP ${res.status} ${res.statusText}`);\r\n }\r\n return res.text();\r\n })\r\n .then((code) => {\r\n if (terminated) return;\r\n\r\n // Combine bootstrap + (optional AMD shim) + original script.\r\n // - Single-file mode: BOOTSTRAP + code\r\n // - Bundle mode: BOOTSTRAP + AMD shim + bundle-source + entry\r\n // `require(entryModuleId)` that executes the intended factory.\r\n let fullSource: string;\r\n if (entryModuleId) {\r\n const entryRequire =\r\n `\\n;try { self.__wxWorkerRequire(${JSON.stringify(entryModuleId)}); } ` +\r\n `catch (e) { console.error('[wx-compat][worker] failed to start entry module ' + ${JSON.stringify(entryModuleId)} + ':', e); }\\n`;\r\n fullSource =\r\n WORKER_BOOTSTRAP +\r\n WORKER_BUNDLE_MODULE_SHIM +\r\n code +\r\n entryRequire +\r\n `//# sourceURL=${fetchPath}`;\r\n } else {\r\n fullSource = `${WORKER_BOOTSTRAP}${code}\\n//# sourceURL=${scriptPath}`;\r\n }\r\n const blob = new Blob([fullSource], { type: 'application/javascript' });\r\n blobUrl = URL.createObjectURL(blob);\r\n\r\n nativeWorker = new Worker(blobUrl);\r\n\r\n // Send `init` envelope with environment hints. User code reads them\r\n // off `self.__wxWorkerEnv` if it cares; most workers ignore them.\r\n // We do this BEFORE wiring the message listener so the init message\r\n // is the very first thing the worker scope sees on its event queue.\r\n try {\r\n const win = window as unknown as Record<string, unknown>;\r\n nativeWorker.postMessage({\r\n type: 'wx-worker-init',\r\n payload: {\r\n appId: win.__wxAppid || 'preview',\r\n deviceWidth: win.__wxDeviceWidth,\r\n deviceHeight: win.__wxDeviceHeight,\r\n devicePixelRatio: win.__wxDevicePixelRatio,\r\n platform: win.__wxDevicePlatform,\r\n scriptPath,\r\n },\r\n });\r\n } catch (e) {\r\n // Non-fatal \u2014 init payload is best-effort.\r\n console.warn('[wx-compat][worker] init payload post failed:', e);\r\n }\r\n\r\n // Listen for messages from the Worker and dispatch on the protocol envelope.\r\n nativeWorker.addEventListener('message', (e: MessageEvent) => {\r\n const data = e.data;\r\n if (!data || typeof data !== 'object') return;\r\n if (watchdogTimer) { clearTimeout(watchdogTimer); watchdogTimer = null; }\r\n if (data.type === 'wx-worker-ready') {\r\n if (!bootResolved) {\r\n bootResolved = true;\r\n clearTimeout(bootTimer);\r\n // Flush any messages queued before the worker booted.\r\n if (pendingMessages.length > 0) {\r\n const queued = pendingMessages;\r\n pendingMessages = [];\r\n for (const m of queued) {\r\n try { nativeWorker!.postMessage({ type: 'wx-worker-message', payload: m }); } catch (err) {\r\n console.warn('[wx-compat][worker] post failed during flush:', err);\r\n }\r\n }\r\n }\r\n }\r\n return;\r\n }\r\n if (data.type === 'wx-worker-error') {\r\n const payload = data.payload || { message: 'unknown worker error' };\r\n errorCallbacks.forEach((cb) => {\r\n try { cb(payload); } catch (err) {\r\n console.error('[wx-compat][worker] Error in main onError callback:', err);\r\n }\r\n });\r\n return;\r\n }\r\n if (data.type === 'wx-worker-message') {\r\n messageCallbacks.forEach((cb) => {\r\n try {\r\n cb({ message: data.payload });\r\n } catch (err) {\r\n console.error('[wx-compat][worker] Error in main onMessage callback:', err);\r\n }\r\n });\r\n }\r\n });\r\n\r\n nativeWorker.addEventListener('error', (e: ErrorEvent) => {\r\n // Native worker-level error (script-load failure / uncaught at the\r\n // event-loop boundary). Surface to onError callbacks so the host\r\n // sees a unified error stream.\r\n console.error(`[wx-compat][worker] Worker error in \"${scriptPath}\":`, e.message);\r\n errorCallbacks.forEach((cb) => {\r\n try { cb({ message: e.message, filename: e.filename, lineno: e.lineno, colno: e.colno }); } catch { /* ignore */ }\r\n });\r\n });\r\n })\r\n .catch((err) => {\r\n console.warn(`[wx-compat] createWorker failed for \"${scriptPath}\":`, err);\r\n });\r\n\r\n // Return the WxWorker handle for the main thread\r\n return {\r\n /**\r\n * Main thread sends a message to the worker script.\r\n * Wraps in protocol envelope so the bootstrap shim can dispatch it.\r\n *\r\n * If the worker hasn't reached `ready` yet (still booting / fetching\r\n * its bundle), the message is queued and flushed once the\r\n * `wx-worker-ready` envelope arrives. This eliminates the legacy\r\n * 10ms-poll-and-retry path which could lose messages on slow networks.\r\n */\r\n postMessage(message: unknown): void {\r\n if (terminated) return;\r\n bumpWatchdog();\r\n if (nativeWorker && bootResolved) {\r\n nativeWorker.postMessage({ type: 'wx-worker-message', payload: message });\r\n } else {\r\n pendingMessages.push(message);\r\n }\r\n },\r\n\r\n /**\r\n * Main thread registers a callback to receive messages from the worker.\r\n */\r\n onMessage(callback: (res: { message: unknown }) => void): void {\r\n messageCallbacks.add(callback);\r\n },\r\n\r\n /**\r\n * Subscribe to errors raised inside the worker thread (uncaught\r\n * exceptions, unhandled rejections, post-bootstrap throws). Mirrors\r\n * the WeChat 2.27+ `worker.onError` API.\r\n */\r\n onError(callback: (res: { message: string; filename?: string; lineno?: number; colno?: number }) => void): void {\r\n errorCallbacks.add(callback);\r\n },\r\n\r\n /**\r\n * Subscribe to the synthetic \"process killed\" event we fire on\r\n * terminate(). Native exposes this for OS-killed worker processes;\r\n * in preview every kill is voluntary, but exposing the hook lets\r\n * games keep their reload logic identical between native and web.\r\n */\r\n onProcessKilled(callback: () => void): void {\r\n killedCallbacks.add(callback);\r\n },\r\n\r\n /**\r\n * Terminate the worker and clean up resources.\r\n */\r\n terminate(): void {\r\n if (terminated) return;\r\n terminated = true;\r\n clearTimeout(bootTimer);\r\n if (watchdogTimer) { clearTimeout(watchdogTimer); watchdogTimer = null; }\r\n try { nativeWorker?.terminate(); } catch { /* ignore */ }\r\n nativeWorker = null;\r\n // Notify killed listeners after teardown so handlers see a clean state.\r\n killedCallbacks.forEach((cb) => { try { cb(); } catch { /* ignore */ } });\r\n messageCallbacks.clear();\r\n errorCallbacks.clear();\r\n killedCallbacks.clear();\r\n pendingMessages = [];\r\n if (blobUrl) {\r\n URL.revokeObjectURL(blobUrl);\r\n blobUrl = null;\r\n }\r\n },\r\n };\r\n}\r\n", "/**\r\n * Utils module (P2) \u2014 encode/decode and image compression.\r\n *\r\n * Uses captured native constructors to avoid circular calls with web-adapter.\r\n *\r\n * Implements:\r\n * wx.encode \u2014 encode string to ArrayBuffer using TextEncoder\r\n * wx.decode \u2014 decode ArrayBuffer to string using TextDecoder\r\n * wx.compressImage \u2014 compress image via Canvas (quality reduction)\r\n */\r\n\r\nimport { NativeImage, nativeCreateElement } from './native-globals';\r\n\r\n// \u2500\u2500\u2500 Base64 \u2194 ArrayBuffer (P2) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * wx.arrayBufferToBase64 \u2014 convert ArrayBuffer to base64 string.\r\n * Widely used by games for save-data serialization.\r\n */\r\nexport function arrayBufferToBase64(buffer: ArrayBuffer): string {\r\n const bytes = new Uint8Array(buffer);\r\n let binary = '';\r\n for (let i = 0; i < bytes.length; i++) {\r\n binary += String.fromCharCode(bytes[i]);\r\n }\r\n return btoa(binary);\r\n}\r\n\r\n/**\r\n * wx.base64ToArrayBuffer \u2014 convert base64 string to ArrayBuffer.\r\n */\r\nexport function base64ToArrayBuffer(base64: string): ArrayBuffer {\r\n const binary = atob(base64);\r\n const bytes = new Uint8Array(binary.length);\r\n for (let i = 0; i < binary.length; i++) {\r\n bytes[i] = binary.charCodeAt(i);\r\n }\r\n return bytes.buffer;\r\n}\r\n\r\n/**\r\n * P2: wx.encode \u2014 encodes a string to ArrayBuffer.\r\n */\r\nexport function encode(opts: {\r\n data: string;\r\n format?: string; // default 'utf8'\r\n}): ArrayBuffer {\r\n const encoder = new TextEncoder();\r\n return encoder.encode(opts.data).buffer;\r\n}\r\n\r\n/**\r\n * P2: wx.decode \u2014 decodes ArrayBuffer to string.\r\n */\r\nexport function decode(opts: {\r\n data: ArrayBuffer;\r\n format?: string; // default 'utf8'\r\n}): string {\r\n const decoder = new TextDecoder(opts.format || 'utf-8');\r\n return decoder.decode(opts.data);\r\n}\r\n\r\n/**\r\n * P2: wx.compressImage \u2014 compress an image via Canvas re-encoding.\r\n */\r\nexport function compressImage(opts: {\r\n src: string;\r\n quality?: number; // 0-100, default 80\r\n success?: (res: { tempFilePath: string }) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: () => void;\r\n}): void {\r\n const quality = (opts.quality ?? 80) / 100;\r\n const img = new NativeImage();\r\n img.crossOrigin = 'anonymous';\r\n img.onload = () => {\r\n try {\r\n const canvas = nativeCreateElement('canvas') as HTMLCanvasElement;\r\n canvas.width = img.naturalWidth;\r\n canvas.height = img.naturalHeight;\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) {\r\n opts.fail?.({ errMsg: 'compressImage:fail canvas context error' });\r\n opts.complete?.();\r\n return;\r\n }\r\n ctx.drawImage(img, 0, 0);\r\n canvas.toBlob(\r\n (blob) => {\r\n if (blob) {\r\n const tempFilePath = URL.createObjectURL(blob);\r\n opts.success?.({ tempFilePath });\r\n } else {\r\n opts.fail?.({ errMsg: 'compressImage:fail blob creation failed' });\r\n }\r\n opts.complete?.();\r\n },\r\n 'image/jpeg',\r\n quality\r\n );\r\n } catch (e) {\r\n opts.fail?.({ errMsg: `compressImage:fail ${e}` });\r\n opts.complete?.();\r\n }\r\n };\r\n img.onerror = () => {\r\n opts.fail?.({ errMsg: `compressImage:fail load image error` });\r\n opts.complete?.();\r\n };\r\n img.src = opts.src;\r\n}\r\n", "var F = {}, V = {};\nV.byteLength = Lt;\nV.toByteArray = kt;\nV.fromByteArray = $t;\nvar L = [], C = [], Ct = typeof Uint8Array < \"u\" ? Uint8Array : Array, q = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nfor (var P = 0, Rt = q.length; P < Rt; ++P)\n L[P] = q[P], C[q.charCodeAt(P)] = P;\nC[\"-\".charCodeAt(0)] = 62;\nC[\"_\".charCodeAt(0)] = 63;\nfunction ft(f) {\n var h = f.length;\n if (h % 4 > 0)\n throw new Error(\"Invalid string. Length must be a multiple of 4\");\n var l = f.indexOf(\"=\");\n l === -1 && (l = h);\n var s = l === h ? 0 : 4 - l % 4;\n return [l, s];\n}\nfunction Lt(f) {\n var h = ft(f), l = h[0], s = h[1];\n return (l + s) * 3 / 4 - s;\n}\nfunction St(f, h, l) {\n return (h + l) * 3 / 4 - l;\n}\nfunction kt(f) {\n var h, l = ft(f), s = l[0], w = l[1], a = new Ct(St(f, s, w)), p = 0, o = w > 0 ? s - 4 : s, y;\n for (y = 0; y < o; y += 4)\n h = C[f.charCodeAt(y)] << 18 | C[f.charCodeAt(y + 1)] << 12 | C[f.charCodeAt(y + 2)] << 6 | C[f.charCodeAt(y + 3)], a[p++] = h >> 16 & 255, a[p++] = h >> 8 & 255, a[p++] = h & 255;\n return w === 2 && (h = C[f.charCodeAt(y)] << 2 | C[f.charCodeAt(y + 1)] >> 4, a[p++] = h & 255), w === 1 && (h = C[f.charCodeAt(y)] << 10 | C[f.charCodeAt(y + 1)] << 4 | C[f.charCodeAt(y + 2)] >> 2, a[p++] = h >> 8 & 255, a[p++] = h & 255), a;\n}\nfunction Ot(f) {\n return L[f >> 18 & 63] + L[f >> 12 & 63] + L[f >> 6 & 63] + L[f & 63];\n}\nfunction Dt(f, h, l) {\n for (var s, w = [], a = h; a < l; a += 3)\n s = (f[a] << 16 & 16711680) + (f[a + 1] << 8 & 65280) + (f[a + 2] & 255), w.push(Ot(s));\n return w.join(\"\");\n}\nfunction $t(f) {\n for (var h, l = f.length, s = l % 3, w = [], a = 16383, p = 0, o = l - s; p < o; p += a)\n w.push(Dt(f, p, p + a > o ? o : p + a));\n return s === 1 ? (h = f[l - 1], w.push(\n L[h >> 2] + L[h << 4 & 63] + \"==\"\n )) : s === 2 && (h = (f[l - 2] << 8) + f[l - 1], w.push(\n L[h >> 10] + L[h >> 4 & 63] + L[h << 2 & 63] + \"=\"\n )), w.join(\"\");\n}\nvar z = {};\n/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */\nz.read = function(f, h, l, s, w) {\n var a, p, o = w * 8 - s - 1, y = (1 << o) - 1, _ = y >> 1, m = -7, I = l ? w - 1 : 0, T = l ? -1 : 1, U = f[h + I];\n for (I += T, a = U & (1 << -m) - 1, U >>= -m, m += o; m > 0; a = a * 256 + f[h + I], I += T, m -= 8)\n ;\n for (p = a & (1 << -m) - 1, a >>= -m, m += s; m > 0; p = p * 256 + f[h + I], I += T, m -= 8)\n ;\n if (a === 0)\n a = 1 - _;\n else {\n if (a === y)\n return p ? NaN : (U ? -1 : 1) * (1 / 0);\n p = p + Math.pow(2, s), a = a - _;\n }\n return (U ? -1 : 1) * p * Math.pow(2, a - s);\n};\nz.write = function(f, h, l, s, w, a) {\n var p, o, y, _ = a * 8 - w - 1, m = (1 << _) - 1, I = m >> 1, T = w === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0, U = s ? 0 : a - 1, S = s ? 1 : -1, k = h < 0 || h === 0 && 1 / h < 0 ? 1 : 0;\n for (h = Math.abs(h), isNaN(h) || h === 1 / 0 ? (o = isNaN(h) ? 1 : 0, p = m) : (p = Math.floor(Math.log(h) / Math.LN2), h * (y = Math.pow(2, -p)) < 1 && (p--, y *= 2), p + I >= 1 ? h += T / y : h += T * Math.pow(2, 1 - I), h * y >= 2 && (p++, y /= 2), p + I >= m ? (o = 0, p = m) : p + I >= 1 ? (o = (h * y - 1) * Math.pow(2, w), p = p + I) : (o = h * Math.pow(2, I - 1) * Math.pow(2, w), p = 0)); w >= 8; f[l + U] = o & 255, U += S, o /= 256, w -= 8)\n ;\n for (p = p << w | o, _ += w; _ > 0; f[l + U] = p & 255, U += S, p /= 256, _ -= 8)\n ;\n f[l + U - S] |= k * 128;\n};\n/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh <https://feross.org>\n * @license MIT\n */\n(function(f) {\n const h = V, l = z, s = typeof Symbol == \"function\" && typeof Symbol.for == \"function\" ? Symbol.for(\"nodejs.util.inspect.custom\") : null;\n f.Buffer = o, f.SlowBuffer = ht, f.INSPECT_MAX_BYTES = 50;\n const w = 2147483647;\n f.kMaxLength = w, o.TYPED_ARRAY_SUPPORT = a(), !o.TYPED_ARRAY_SUPPORT && typeof console < \"u\" && typeof console.error == \"function\" && console.error(\n \"This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support.\"\n );\n function a() {\n try {\n const n = new Uint8Array(1), t = { foo: function() {\n return 42;\n } };\n return Object.setPrototypeOf(t, Uint8Array.prototype), Object.setPrototypeOf(n, t), n.foo() === 42;\n } catch {\n return !1;\n }\n }\n Object.defineProperty(o.prototype, \"parent\", {\n enumerable: !0,\n get: function() {\n if (!!o.isBuffer(this))\n return this.buffer;\n }\n }), Object.defineProperty(o.prototype, \"offset\", {\n enumerable: !0,\n get: function() {\n if (!!o.isBuffer(this))\n return this.byteOffset;\n }\n });\n function p(n) {\n if (n > w)\n throw new RangeError('The value \"' + n + '\" is invalid for option \"size\"');\n const t = new Uint8Array(n);\n return Object.setPrototypeOf(t, o.prototype), t;\n }\n function o(n, t, r) {\n if (typeof n == \"number\") {\n if (typeof t == \"string\")\n throw new TypeError(\n 'The \"string\" argument must be of type string. Received type number'\n );\n return I(n);\n }\n return y(n, t, r);\n }\n o.poolSize = 8192;\n function y(n, t, r) {\n if (typeof n == \"string\")\n return T(n, t);\n if (ArrayBuffer.isView(n))\n return S(n);\n if (n == null)\n throw new TypeError(\n \"The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type \" + typeof n\n );\n if (R(n, ArrayBuffer) || n && R(n.buffer, ArrayBuffer) || typeof SharedArrayBuffer < \"u\" && (R(n, SharedArrayBuffer) || n && R(n.buffer, SharedArrayBuffer)))\n return k(n, t, r);\n if (typeof n == \"number\")\n throw new TypeError(\n 'The \"value\" argument must not be of type number. Received type number'\n );\n const e = n.valueOf && n.valueOf();\n if (e != null && e !== n)\n return o.from(e, t, r);\n const i = G(n);\n if (i)\n return i;\n if (typeof Symbol < \"u\" && Symbol.toPrimitive != null && typeof n[Symbol.toPrimitive] == \"function\")\n return o.from(n[Symbol.toPrimitive](\"string\"), t, r);\n throw new TypeError(\n \"The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type \" + typeof n\n );\n }\n o.from = function(n, t, r) {\n return y(n, t, r);\n }, Object.setPrototypeOf(o.prototype, Uint8Array.prototype), Object.setPrototypeOf(o, Uint8Array);\n function _(n) {\n if (typeof n != \"number\")\n throw new TypeError('\"size\" argument must be of type number');\n if (n < 0)\n throw new RangeError('The value \"' + n + '\" is invalid for option \"size\"');\n }\n function m(n, t, r) {\n return _(n), n <= 0 ? p(n) : t !== void 0 ? typeof r == \"string\" ? p(n).fill(t, r) : p(n).fill(t) : p(n);\n }\n o.alloc = function(n, t, r) {\n return m(n, t, r);\n };\n function I(n) {\n return _(n), p(n < 0 ? 0 : Y(n) | 0);\n }\n o.allocUnsafe = function(n) {\n return I(n);\n }, o.allocUnsafeSlow = function(n) {\n return I(n);\n };\n function T(n, t) {\n if ((typeof t != \"string\" || t === \"\") && (t = \"utf8\"), !o.isEncoding(t))\n throw new TypeError(\"Unknown encoding: \" + t);\n const r = J(n, t) | 0;\n let e = p(r);\n const i = e.write(n, t);\n return i !== r && (e = e.slice(0, i)), e;\n }\n function U(n) {\n const t = n.length < 0 ? 0 : Y(n.length) | 0, r = p(t);\n for (let e = 0; e < t; e += 1)\n r[e] = n[e] & 255;\n return r;\n }\n function S(n) {\n if (R(n, Uint8Array)) {\n const t = new Uint8Array(n);\n return k(t.buffer, t.byteOffset, t.byteLength);\n }\n return U(n);\n }\n function k(n, t, r) {\n if (t < 0 || n.byteLength < t)\n throw new RangeError('\"offset\" is outside of buffer bounds');\n if (n.byteLength < t + (r || 0))\n throw new RangeError('\"length\" is outside of buffer bounds');\n let e;\n return t === void 0 && r === void 0 ? e = new Uint8Array(n) : r === void 0 ? e = new Uint8Array(n, t) : e = new Uint8Array(n, t, r), Object.setPrototypeOf(e, o.prototype), e;\n }\n function G(n) {\n if (o.isBuffer(n)) {\n const t = Y(n.length) | 0, r = p(t);\n return r.length === 0 || n.copy(r, 0, 0, t), r;\n }\n if (n.length !== void 0)\n return typeof n.length != \"number\" || j(n.length) ? p(0) : U(n);\n if (n.type === \"Buffer\" && Array.isArray(n.data))\n return U(n.data);\n }\n function Y(n) {\n if (n >= w)\n throw new RangeError(\"Attempt to allocate Buffer larger than maximum size: 0x\" + w.toString(16) + \" bytes\");\n return n | 0;\n }\n function ht(n) {\n return +n != n && (n = 0), o.alloc(+n);\n }\n o.isBuffer = function(t) {\n return t != null && t._isBuffer === !0 && t !== o.prototype;\n }, o.compare = function(t, r) {\n if (R(t, Uint8Array) && (t = o.from(t, t.offset, t.byteLength)), R(r, Uint8Array) && (r = o.from(r, r.offset, r.byteLength)), !o.isBuffer(t) || !o.isBuffer(r))\n throw new TypeError(\n 'The \"buf1\", \"buf2\" arguments must be one of type Buffer or Uint8Array'\n );\n if (t === r)\n return 0;\n let e = t.length, i = r.length;\n for (let u = 0, c = Math.min(e, i); u < c; ++u)\n if (t[u] !== r[u]) {\n e = t[u], i = r[u];\n break;\n }\n return e < i ? -1 : i < e ? 1 : 0;\n }, o.isEncoding = function(t) {\n switch (String(t).toLowerCase()) {\n case \"hex\":\n case \"utf8\":\n case \"utf-8\":\n case \"ascii\":\n case \"latin1\":\n case \"binary\":\n case \"base64\":\n case \"ucs2\":\n case \"ucs-2\":\n case \"utf16le\":\n case \"utf-16le\":\n return !0;\n default:\n return !1;\n }\n }, o.concat = function(t, r) {\n if (!Array.isArray(t))\n throw new TypeError('\"list\" argument must be an Array of Buffers');\n if (t.length === 0)\n return o.alloc(0);\n let e;\n if (r === void 0)\n for (r = 0, e = 0; e < t.length; ++e)\n r += t[e].length;\n const i = o.allocUnsafe(r);\n let u = 0;\n for (e = 0; e < t.length; ++e) {\n let c = t[e];\n if (R(c, Uint8Array))\n u + c.length > i.length ? (o.isBuffer(c) || (c = o.from(c)), c.copy(i, u)) : Uint8Array.prototype.set.call(\n i,\n c,\n u\n );\n else if (o.isBuffer(c))\n c.copy(i, u);\n else\n throw new TypeError('\"list\" argument must be an Array of Buffers');\n u += c.length;\n }\n return i;\n };\n function J(n, t) {\n if (o.isBuffer(n))\n return n.length;\n if (ArrayBuffer.isView(n) || R(n, ArrayBuffer))\n return n.byteLength;\n if (typeof n != \"string\")\n throw new TypeError(\n 'The \"string\" argument must be one of type string, Buffer, or ArrayBuffer. Received type ' + typeof n\n );\n const r = n.length, e = arguments.length > 2 && arguments[2] === !0;\n if (!e && r === 0)\n return 0;\n let i = !1;\n for (; ; )\n switch (t) {\n case \"ascii\":\n case \"latin1\":\n case \"binary\":\n return r;\n case \"utf8\":\n case \"utf-8\":\n return X(n).length;\n case \"ucs2\":\n case \"ucs-2\":\n case \"utf16le\":\n case \"utf-16le\":\n return r * 2;\n case \"hex\":\n return r >>> 1;\n case \"base64\":\n return ct(n).length;\n default:\n if (i)\n return e ? -1 : X(n).length;\n t = (\"\" + t).toLowerCase(), i = !0;\n }\n }\n o.byteLength = J;\n function st(n, t, r) {\n let e = !1;\n if ((t === void 0 || t < 0) && (t = 0), t > this.length || ((r === void 0 || r > this.length) && (r = this.length), r <= 0) || (r >>>= 0, t >>>= 0, r <= t))\n return \"\";\n for (n || (n = \"utf8\"); ; )\n switch (n) {\n case \"hex\":\n return gt(this, t, r);\n case \"utf8\":\n case \"utf-8\":\n return Q(this, t, r);\n case \"ascii\":\n return xt(this, t, r);\n case \"latin1\":\n case \"binary\":\n return It(this, t, r);\n case \"base64\":\n return yt(this, t, r);\n case \"ucs2\":\n case \"ucs-2\":\n case \"utf16le\":\n case \"utf-16le\":\n return dt(this, t, r);\n default:\n if (e)\n throw new TypeError(\"Unknown encoding: \" + n);\n n = (n + \"\").toLowerCase(), e = !0;\n }\n }\n o.prototype._isBuffer = !0;\n function D(n, t, r) {\n const e = n[t];\n n[t] = n[r], n[r] = e;\n }\n o.prototype.swap16 = function() {\n const t = this.length;\n if (t % 2 !== 0)\n throw new RangeError(\"Buffer size must be a multiple of 16-bits\");\n for (let r = 0; r < t; r += 2)\n D(this, r, r + 1);\n return this;\n }, o.prototype.swap32 = function() {\n const t = this.length;\n if (t % 4 !== 0)\n throw new RangeError(\"Buffer size must be a multiple of 32-bits\");\n for (let r = 0; r < t; r += 4)\n D(this, r, r + 3), D(this, r + 1, r + 2);\n return this;\n }, o.prototype.swap64 = function() {\n const t = this.length;\n if (t % 8 !== 0)\n throw new RangeError(\"Buffer size must be a multiple of 64-bits\");\n for (let r = 0; r < t; r += 8)\n D(this, r, r + 7), D(this, r + 1, r + 6), D(this, r + 2, r + 5), D(this, r + 3, r + 4);\n return this;\n }, o.prototype.toString = function() {\n const t = this.length;\n return t === 0 ? \"\" : arguments.length === 0 ? Q(this, 0, t) : st.apply(this, arguments);\n }, o.prototype.toLocaleString = o.prototype.toString, o.prototype.equals = function(t) {\n if (!o.isBuffer(t))\n throw new TypeError(\"Argument must be a Buffer\");\n return this === t ? !0 : o.compare(this, t) === 0;\n }, o.prototype.inspect = function() {\n let t = \"\";\n const r = f.INSPECT_MAX_BYTES;\n return t = this.toString(\"hex\", 0, r).replace(/(.{2})/g, \"$1 \").trim(), this.length > r && (t += \" ... \"), \"<Buffer \" + t + \">\";\n }, s && (o.prototype[s] = o.prototype.inspect), o.prototype.compare = function(t, r, e, i, u) {\n if (R(t, Uint8Array) && (t = o.from(t, t.offset, t.byteLength)), !o.isBuffer(t))\n throw new TypeError(\n 'The \"target\" argument must be one of type Buffer or Uint8Array. Received type ' + typeof t\n );\n if (r === void 0 && (r = 0), e === void 0 && (e = t ? t.length : 0), i === void 0 && (i = 0), u === void 0 && (u = this.length), r < 0 || e > t.length || i < 0 || u > this.length)\n throw new RangeError(\"out of range index\");\n if (i >= u && r >= e)\n return 0;\n if (i >= u)\n return -1;\n if (r >= e)\n return 1;\n if (r >>>= 0, e >>>= 0, i >>>= 0, u >>>= 0, this === t)\n return 0;\n let c = u - i, B = e - r;\n const g = Math.min(c, B), x = this.slice(i, u), d = t.slice(r, e);\n for (let E = 0; E < g; ++E)\n if (x[E] !== d[E]) {\n c = x[E], B = d[E];\n break;\n }\n return c < B ? -1 : B < c ? 1 : 0;\n };\n function K(n, t, r, e, i) {\n if (n.length === 0)\n return -1;\n if (typeof r == \"string\" ? (e = r, r = 0) : r > 2147483647 ? r = 2147483647 : r < -2147483648 && (r = -2147483648), r = +r, j(r) && (r = i ? 0 : n.length - 1), r < 0 && (r = n.length + r), r >= n.length) {\n if (i)\n return -1;\n r = n.length - 1;\n } else if (r < 0)\n if (i)\n r = 0;\n else\n return -1;\n if (typeof t == \"string\" && (t = o.from(t, e)), o.isBuffer(t))\n return t.length === 0 ? -1 : Z(n, t, r, e, i);\n if (typeof t == \"number\")\n return t = t & 255, typeof Uint8Array.prototype.indexOf == \"function\" ? i ? Uint8Array.prototype.indexOf.call(n, t, r) : Uint8Array.prototype.lastIndexOf.call(n, t, r) : Z(n, [t], r, e, i);\n throw new TypeError(\"val must be string, number or Buffer\");\n }\n function Z(n, t, r, e, i) {\n let u = 1, c = n.length, B = t.length;\n if (e !== void 0 && (e = String(e).toLowerCase(), e === \"ucs2\" || e === \"ucs-2\" || e === \"utf16le\" || e === \"utf-16le\")) {\n if (n.length < 2 || t.length < 2)\n return -1;\n u = 2, c /= 2, B /= 2, r /= 2;\n }\n function g(d, E) {\n return u === 1 ? d[E] : d.readUInt16BE(E * u);\n }\n let x;\n if (i) {\n let d = -1;\n for (x = r; x < c; x++)\n if (g(n, x) === g(t, d === -1 ? 0 : x - d)) {\n if (d === -1 && (d = x), x - d + 1 === B)\n return d * u;\n } else\n d !== -1 && (x -= x - d), d = -1;\n } else\n for (r + B > c && (r = c - B), x = r; x >= 0; x--) {\n let d = !0;\n for (let E = 0; E < B; E++)\n if (g(n, x + E) !== g(t, E)) {\n d = !1;\n break;\n }\n if (d)\n return x;\n }\n return -1;\n }\n o.prototype.includes = function(t, r, e) {\n return this.indexOf(t, r, e) !== -1;\n }, o.prototype.indexOf = function(t, r, e) {\n return K(this, t, r, e, !0);\n }, o.prototype.lastIndexOf = function(t, r, e) {\n return K(this, t, r, e, !1);\n };\n function pt(n, t, r, e) {\n r = Number(r) || 0;\n const i = n.length - r;\n e ? (e = Number(e), e > i && (e = i)) : e = i;\n const u = t.length;\n e > u / 2 && (e = u / 2);\n let c;\n for (c = 0; c < e; ++c) {\n const B = parseInt(t.substr(c * 2, 2), 16);\n if (j(B))\n return c;\n n[r + c] = B;\n }\n return c;\n }\n function lt(n, t, r, e) {\n return H(X(t, n.length - r), n, r, e);\n }\n function at(n, t, r, e) {\n return H(Ut(t), n, r, e);\n }\n function wt(n, t, r, e) {\n return H(ct(t), n, r, e);\n }\n function Bt(n, t, r, e) {\n return H(_t(t, n.length - r), n, r, e);\n }\n o.prototype.write = function(t, r, e, i) {\n if (r === void 0)\n i = \"utf8\", e = this.length, r = 0;\n else if (e === void 0 && typeof r == \"string\")\n i = r, e = this.length, r = 0;\n else if (isFinite(r))\n r = r >>> 0, isFinite(e) ? (e = e >>> 0, i === void 0 && (i = \"utf8\")) : (i = e, e = void 0);\n else\n throw new Error(\n \"Buffer.write(string, encoding, offset[, length]) is no longer supported\"\n );\n const u = this.length - r;\n if ((e === void 0 || e > u) && (e = u), t.length > 0 && (e < 0 || r < 0) || r > this.length)\n throw new RangeError(\"Attempt to write outside buffer bounds\");\n i || (i = \"utf8\");\n let c = !1;\n for (; ; )\n switch (i) {\n case \"hex\":\n return pt(this, t, r, e);\n case \"utf8\":\n case \"utf-8\":\n return lt(this, t, r, e);\n case \"ascii\":\n case \"latin1\":\n case \"binary\":\n return at(this, t, r, e);\n case \"base64\":\n return wt(this, t, r, e);\n case \"ucs2\":\n case \"ucs-2\":\n case \"utf16le\":\n case \"utf-16le\":\n return Bt(this, t, r, e);\n default:\n if (c)\n throw new TypeError(\"Unknown encoding: \" + i);\n i = (\"\" + i).toLowerCase(), c = !0;\n }\n }, o.prototype.toJSON = function() {\n return {\n type: \"Buffer\",\n data: Array.prototype.slice.call(this._arr || this, 0)\n };\n };\n function yt(n, t, r) {\n return t === 0 && r === n.length ? h.fromByteArray(n) : h.fromByteArray(n.slice(t, r));\n }\n function Q(n, t, r) {\n r = Math.min(n.length, r);\n const e = [];\n let i = t;\n for (; i < r; ) {\n const u = n[i];\n let c = null, B = u > 239 ? 4 : u > 223 ? 3 : u > 191 ? 2 : 1;\n if (i + B <= r) {\n let g, x, d, E;\n switch (B) {\n case 1:\n u < 128 && (c = u);\n break;\n case 2:\n g = n[i + 1], (g & 192) === 128 && (E = (u & 31) << 6 | g & 63, E > 127 && (c = E));\n break;\n case 3:\n g = n[i + 1], x = n[i + 2], (g & 192) === 128 && (x & 192) === 128 && (E = (u & 15) << 12 | (g & 63) << 6 | x & 63, E > 2047 && (E < 55296 || E > 57343) && (c = E));\n break;\n case 4:\n g = n[i + 1], x = n[i + 2], d = n[i + 3], (g & 192) === 128 && (x & 192) === 128 && (d & 192) === 128 && (E = (u & 15) << 18 | (g & 63) << 12 | (x & 63) << 6 | d & 63, E > 65535 && E < 1114112 && (c = E));\n }\n }\n c === null ? (c = 65533, B = 1) : c > 65535 && (c -= 65536, e.push(c >>> 10 & 1023 | 55296), c = 56320 | c & 1023), e.push(c), i += B;\n }\n return Et(e);\n }\n const v = 4096;\n function Et(n) {\n const t = n.length;\n if (t <= v)\n return String.fromCharCode.apply(String, n);\n let r = \"\", e = 0;\n for (; e < t; )\n r += String.fromCharCode.apply(\n String,\n n.slice(e, e += v)\n );\n return r;\n }\n function xt(n, t, r) {\n let e = \"\";\n r = Math.min(n.length, r);\n for (let i = t; i < r; ++i)\n e += String.fromCharCode(n[i] & 127);\n return e;\n }\n function It(n, t, r) {\n let e = \"\";\n r = Math.min(n.length, r);\n for (let i = t; i < r; ++i)\n e += String.fromCharCode(n[i]);\n return e;\n }\n function gt(n, t, r) {\n const e = n.length;\n (!t || t < 0) && (t = 0), (!r || r < 0 || r > e) && (r = e);\n let i = \"\";\n for (let u = t; u < r; ++u)\n i += Nt[n[u]];\n return i;\n }\n function dt(n, t, r) {\n const e = n.slice(t, r);\n let i = \"\";\n for (let u = 0; u < e.length - 1; u += 2)\n i += String.fromCharCode(e[u] + e[u + 1] * 256);\n return i;\n }\n o.prototype.slice = function(t, r) {\n const e = this.length;\n t = ~~t, r = r === void 0 ? e : ~~r, t < 0 ? (t += e, t < 0 && (t = 0)) : t > e && (t = e), r < 0 ? (r += e, r < 0 && (r = 0)) : r > e && (r = e), r < t && (r = t);\n const i = this.subarray(t, r);\n return Object.setPrototypeOf(i, o.prototype), i;\n };\n function A(n, t, r) {\n if (n % 1 !== 0 || n < 0)\n throw new RangeError(\"offset is not uint\");\n if (n + t > r)\n throw new RangeError(\"Trying to access beyond buffer length\");\n }\n o.prototype.readUintLE = o.prototype.readUIntLE = function(t, r, e) {\n t = t >>> 0, r = r >>> 0, e || A(t, r, this.length);\n let i = this[t], u = 1, c = 0;\n for (; ++c < r && (u *= 256); )\n i += this[t + c] * u;\n return i;\n }, o.prototype.readUintBE = o.prototype.readUIntBE = function(t, r, e) {\n t = t >>> 0, r = r >>> 0, e || A(t, r, this.length);\n let i = this[t + --r], u = 1;\n for (; r > 0 && (u *= 256); )\n i += this[t + --r] * u;\n return i;\n }, o.prototype.readUint8 = o.prototype.readUInt8 = function(t, r) {\n return t = t >>> 0, r || A(t, 1, this.length), this[t];\n }, o.prototype.readUint16LE = o.prototype.readUInt16LE = function(t, r) {\n return t = t >>> 0, r || A(t, 2, this.length), this[t] | this[t + 1] << 8;\n }, o.prototype.readUint16BE = o.prototype.readUInt16BE = function(t, r) {\n return t = t >>> 0, r || A(t, 2, this.length), this[t] << 8 | this[t + 1];\n }, o.prototype.readUint32LE = o.prototype.readUInt32LE = function(t, r) {\n return t = t >>> 0, r || A(t, 4, this.length), (this[t] | this[t + 1] << 8 | this[t + 2] << 16) + this[t + 3] * 16777216;\n }, o.prototype.readUint32BE = o.prototype.readUInt32BE = function(t, r) {\n return t = t >>> 0, r || A(t, 4, this.length), this[t] * 16777216 + (this[t + 1] << 16 | this[t + 2] << 8 | this[t + 3]);\n }, o.prototype.readBigUInt64LE = O(function(t) {\n t = t >>> 0, M(t, \"offset\");\n const r = this[t], e = this[t + 7];\n (r === void 0 || e === void 0) && b(t, this.length - 8);\n const i = r + this[++t] * 2 ** 8 + this[++t] * 2 ** 16 + this[++t] * 2 ** 24, u = this[++t] + this[++t] * 2 ** 8 + this[++t] * 2 ** 16 + e * 2 ** 24;\n return BigInt(i) + (BigInt(u) << BigInt(32));\n }), o.prototype.readBigUInt64BE = O(function(t) {\n t = t >>> 0, M(t, \"offset\");\n const r = this[t], e = this[t + 7];\n (r === void 0 || e === void 0) && b(t, this.length - 8);\n const i = r * 2 ** 24 + this[++t] * 2 ** 16 + this[++t] * 2 ** 8 + this[++t], u = this[++t] * 2 ** 24 + this[++t] * 2 ** 16 + this[++t] * 2 ** 8 + e;\n return (BigInt(i) << BigInt(32)) + BigInt(u);\n }), o.prototype.readIntLE = function(t, r, e) {\n t = t >>> 0, r = r >>> 0, e || A(t, r, this.length);\n let i = this[t], u = 1, c = 0;\n for (; ++c < r && (u *= 256); )\n i += this[t + c] * u;\n return u *= 128, i >= u && (i -= Math.pow(2, 8 * r)), i;\n }, o.prototype.readIntBE = function(t, r, e) {\n t = t >>> 0, r = r >>> 0, e || A(t, r, this.length);\n let i = r, u = 1, c = this[t + --i];\n for (; i > 0 && (u *= 256); )\n c += this[t + --i] * u;\n return u *= 128, c >= u && (c -= Math.pow(2, 8 * r)), c;\n }, o.prototype.readInt8 = function(t, r) {\n return t = t >>> 0, r || A(t, 1, this.length), this[t] & 128 ? (255 - this[t] + 1) * -1 : this[t];\n }, o.prototype.readInt16LE = function(t, r) {\n t = t >>> 0, r || A(t, 2, this.length);\n const e = this[t] | this[t + 1] << 8;\n return e & 32768 ? e | 4294901760 : e;\n }, o.prototype.readInt16BE = function(t, r) {\n t = t >>> 0, r || A(t, 2, this.length);\n const e = this[t + 1] | this[t] << 8;\n return e & 32768 ? e | 4294901760 : e;\n }, o.prototype.readInt32LE = function(t, r) {\n return t = t >>> 0, r || A(t, 4, this.length), this[t] | this[t + 1] << 8 | this[t + 2] << 16 | this[t + 3] << 24;\n }, o.prototype.readInt32BE = function(t, r) {\n return t = t >>> 0, r || A(t, 4, this.length), this[t] << 24 | this[t + 1] << 16 | this[t + 2] << 8 | this[t + 3];\n }, o.prototype.readBigInt64LE = O(function(t) {\n t = t >>> 0, M(t, \"offset\");\n const r = this[t], e = this[t + 7];\n (r === void 0 || e === void 0) && b(t, this.length - 8);\n const i = this[t + 4] + this[t + 5] * 2 ** 8 + this[t + 6] * 2 ** 16 + (e << 24);\n return (BigInt(i) << BigInt(32)) + BigInt(r + this[++t] * 2 ** 8 + this[++t] * 2 ** 16 + this[++t] * 2 ** 24);\n }), o.prototype.readBigInt64BE = O(function(t) {\n t = t >>> 0, M(t, \"offset\");\n const r = this[t], e = this[t + 7];\n (r === void 0 || e === void 0) && b(t, this.length - 8);\n const i = (r << 24) + this[++t] * 2 ** 16 + this[++t] * 2 ** 8 + this[++t];\n return (BigInt(i) << BigInt(32)) + BigInt(this[++t] * 2 ** 24 + this[++t] * 2 ** 16 + this[++t] * 2 ** 8 + e);\n }), o.prototype.readFloatLE = function(t, r) {\n return t = t >>> 0, r || A(t, 4, this.length), l.read(this, t, !0, 23, 4);\n }, o.prototype.readFloatBE = function(t, r) {\n return t = t >>> 0, r || A(t, 4, this.length), l.read(this, t, !1, 23, 4);\n }, o.prototype.readDoubleLE = function(t, r) {\n return t = t >>> 0, r || A(t, 8, this.length), l.read(this, t, !0, 52, 8);\n }, o.prototype.readDoubleBE = function(t, r) {\n return t = t >>> 0, r || A(t, 8, this.length), l.read(this, t, !1, 52, 8);\n };\n function N(n, t, r, e, i, u) {\n if (!o.isBuffer(n))\n throw new TypeError('\"buffer\" argument must be a Buffer instance');\n if (t > i || t < u)\n throw new RangeError('\"value\" argument is out of bounds');\n if (r + e > n.length)\n throw new RangeError(\"Index out of range\");\n }\n o.prototype.writeUintLE = o.prototype.writeUIntLE = function(t, r, e, i) {\n if (t = +t, r = r >>> 0, e = e >>> 0, !i) {\n const B = Math.pow(2, 8 * e) - 1;\n N(this, t, r, e, B, 0);\n }\n let u = 1, c = 0;\n for (this[r] = t & 255; ++c < e && (u *= 256); )\n this[r + c] = t / u & 255;\n return r + e;\n }, o.prototype.writeUintBE = o.prototype.writeUIntBE = function(t, r, e, i) {\n if (t = +t, r = r >>> 0, e = e >>> 0, !i) {\n const B = Math.pow(2, 8 * e) - 1;\n N(this, t, r, e, B, 0);\n }\n let u = e - 1, c = 1;\n for (this[r + u] = t & 255; --u >= 0 && (c *= 256); )\n this[r + u] = t / c & 255;\n return r + e;\n }, o.prototype.writeUint8 = o.prototype.writeUInt8 = function(t, r, e) {\n return t = +t, r = r >>> 0, e || N(this, t, r, 1, 255, 0), this[r] = t & 255, r + 1;\n }, o.prototype.writeUint16LE = o.prototype.writeUInt16LE = function(t, r, e) {\n return t = +t, r = r >>> 0, e || N(this, t, r, 2, 65535, 0), this[r] = t & 255, this[r + 1] = t >>> 8, r + 2;\n }, o.prototype.writeUint16BE = o.prototype.writeUInt16BE = function(t, r, e) {\n return t = +t, r = r >>> 0, e || N(this, t, r, 2, 65535, 0), this[r] = t >>> 8, this[r + 1] = t & 255, r + 2;\n }, o.prototype.writeUint32LE = o.prototype.writeUInt32LE = function(t, r, e) {\n return t = +t, r = r >>> 0, e || N(this, t, r, 4, 4294967295, 0), this[r + 3] = t >>> 24, this[r + 2] = t >>> 16, this[r + 1] = t >>> 8, this[r] = t & 255, r + 4;\n }, o.prototype.writeUint32BE = o.prototype.writeUInt32BE = function(t, r, e) {\n return t = +t, r = r >>> 0, e || N(this, t, r, 4, 4294967295, 0), this[r] = t >>> 24, this[r + 1] = t >>> 16, this[r + 2] = t >>> 8, this[r + 3] = t & 255, r + 4;\n };\n function tt(n, t, r, e, i) {\n ut(t, e, i, n, r, 7);\n let u = Number(t & BigInt(4294967295));\n n[r++] = u, u = u >> 8, n[r++] = u, u = u >> 8, n[r++] = u, u = u >> 8, n[r++] = u;\n let c = Number(t >> BigInt(32) & BigInt(4294967295));\n return n[r++] = c, c = c >> 8, n[r++] = c, c = c >> 8, n[r++] = c, c = c >> 8, n[r++] = c, r;\n }\n function rt(n, t, r, e, i) {\n ut(t, e, i, n, r, 7);\n let u = Number(t & BigInt(4294967295));\n n[r + 7] = u, u = u >> 8, n[r + 6] = u, u = u >> 8, n[r + 5] = u, u = u >> 8, n[r + 4] = u;\n let c = Number(t >> BigInt(32) & BigInt(4294967295));\n return n[r + 3] = c, c = c >> 8, n[r + 2] = c, c = c >> 8, n[r + 1] = c, c = c >> 8, n[r] = c, r + 8;\n }\n o.prototype.writeBigUInt64LE = O(function(t, r = 0) {\n return tt(this, t, r, BigInt(0), BigInt(\"0xffffffffffffffff\"));\n }), o.prototype.writeBigUInt64BE = O(function(t, r = 0) {\n return rt(this, t, r, BigInt(0), BigInt(\"0xffffffffffffffff\"));\n }), o.prototype.writeIntLE = function(t, r, e, i) {\n if (t = +t, r = r >>> 0, !i) {\n const g = Math.pow(2, 8 * e - 1);\n N(this, t, r, e, g - 1, -g);\n }\n let u = 0, c = 1, B = 0;\n for (this[r] = t & 255; ++u < e && (c *= 256); )\n t < 0 && B === 0 && this[r + u - 1] !== 0 && (B = 1), this[r + u] = (t / c >> 0) - B & 255;\n return r + e;\n }, o.prototype.writeIntBE = function(t, r, e, i) {\n if (t = +t, r = r >>> 0, !i) {\n const g = Math.pow(2, 8 * e - 1);\n N(this, t, r, e, g - 1, -g);\n }\n let u = e - 1, c = 1, B = 0;\n for (this[r + u] = t & 255; --u >= 0 && (c *= 256); )\n t < 0 && B === 0 && this[r + u + 1] !== 0 && (B = 1), this[r + u] = (t / c >> 0) - B & 255;\n return r + e;\n }, o.prototype.writeInt8 = function(t, r, e) {\n return t = +t, r = r >>> 0, e || N(this, t, r, 1, 127, -128), t < 0 && (t = 255 + t + 1), this[r] = t & 255, r + 1;\n }, o.prototype.writeInt16LE = function(t, r, e) {\n return t = +t, r = r >>> 0, e || N(this, t, r, 2, 32767, -32768), this[r] = t & 255, this[r + 1] = t >>> 8, r + 2;\n }, o.prototype.writeInt16BE = function(t, r, e) {\n return t = +t, r = r >>> 0, e || N(this, t, r, 2, 32767, -32768), this[r] = t >>> 8, this[r + 1] = t & 255, r + 2;\n }, o.prototype.writeInt32LE = function(t, r, e) {\n return t = +t, r = r >>> 0, e || N(this, t, r, 4, 2147483647, -2147483648), this[r] = t & 255, this[r + 1] = t >>> 8, this[r + 2] = t >>> 16, this[r + 3] = t >>> 24, r + 4;\n }, o.prototype.writeInt32BE = function(t, r, e) {\n return t = +t, r = r >>> 0, e || N(this, t, r, 4, 2147483647, -2147483648), t < 0 && (t = 4294967295 + t + 1), this[r] = t >>> 24, this[r + 1] = t >>> 16, this[r + 2] = t >>> 8, this[r + 3] = t & 255, r + 4;\n }, o.prototype.writeBigInt64LE = O(function(t, r = 0) {\n return tt(this, t, r, -BigInt(\"0x8000000000000000\"), BigInt(\"0x7fffffffffffffff\"));\n }), o.prototype.writeBigInt64BE = O(function(t, r = 0) {\n return rt(this, t, r, -BigInt(\"0x8000000000000000\"), BigInt(\"0x7fffffffffffffff\"));\n });\n function nt(n, t, r, e, i, u) {\n if (r + e > n.length)\n throw new RangeError(\"Index out of range\");\n if (r < 0)\n throw new RangeError(\"Index out of range\");\n }\n function et(n, t, r, e, i) {\n return t = +t, r = r >>> 0, i || nt(n, t, r, 4), l.write(n, t, r, e, 23, 4), r + 4;\n }\n o.prototype.writeFloatLE = function(t, r, e) {\n return et(this, t, r, !0, e);\n }, o.prototype.writeFloatBE = function(t, r, e) {\n return et(this, t, r, !1, e);\n };\n function it(n, t, r, e, i) {\n return t = +t, r = r >>> 0, i || nt(n, t, r, 8), l.write(n, t, r, e, 52, 8), r + 8;\n }\n o.prototype.writeDoubleLE = function(t, r, e) {\n return it(this, t, r, !0, e);\n }, o.prototype.writeDoubleBE = function(t, r, e) {\n return it(this, t, r, !1, e);\n }, o.prototype.copy = function(t, r, e, i) {\n if (!o.isBuffer(t))\n throw new TypeError(\"argument should be a Buffer\");\n if (e || (e = 0), !i && i !== 0 && (i = this.length), r >= t.length && (r = t.length), r || (r = 0), i > 0 && i < e && (i = e), i === e || t.length === 0 || this.length === 0)\n return 0;\n if (r < 0)\n throw new RangeError(\"targetStart out of bounds\");\n if (e < 0 || e >= this.length)\n throw new RangeError(\"Index out of range\");\n if (i < 0)\n throw new RangeError(\"sourceEnd out of bounds\");\n i > this.length && (i = this.length), t.length - r < i - e && (i = t.length - r + e);\n const u = i - e;\n return this === t && typeof Uint8Array.prototype.copyWithin == \"function\" ? this.copyWithin(r, e, i) : Uint8Array.prototype.set.call(\n t,\n this.subarray(e, i),\n r\n ), u;\n }, o.prototype.fill = function(t, r, e, i) {\n if (typeof t == \"string\") {\n if (typeof r == \"string\" ? (i = r, r = 0, e = this.length) : typeof e == \"string\" && (i = e, e = this.length), i !== void 0 && typeof i != \"string\")\n throw new TypeError(\"encoding must be a string\");\n if (typeof i == \"string\" && !o.isEncoding(i))\n throw new TypeError(\"Unknown encoding: \" + i);\n if (t.length === 1) {\n const c = t.charCodeAt(0);\n (i === \"utf8\" && c < 128 || i === \"latin1\") && (t = c);\n }\n } else\n typeof t == \"number\" ? t = t & 255 : typeof t == \"boolean\" && (t = Number(t));\n if (r < 0 || this.length < r || this.length < e)\n throw new RangeError(\"Out of range index\");\n if (e <= r)\n return this;\n r = r >>> 0, e = e === void 0 ? this.length : e >>> 0, t || (t = 0);\n let u;\n if (typeof t == \"number\")\n for (u = r; u < e; ++u)\n this[u] = t;\n else {\n const c = o.isBuffer(t) ? t : o.from(t, i), B = c.length;\n if (B === 0)\n throw new TypeError('The value \"' + t + '\" is invalid for argument \"value\"');\n for (u = 0; u < e - r; ++u)\n this[u + r] = c[u % B];\n }\n return this;\n };\n const $ = {};\n function W(n, t, r) {\n $[n] = class extends r {\n constructor() {\n super(), Object.defineProperty(this, \"message\", {\n value: t.apply(this, arguments),\n writable: !0,\n configurable: !0\n }), this.name = `${this.name} [${n}]`, this.stack, delete this.name;\n }\n get code() {\n return n;\n }\n set code(i) {\n Object.defineProperty(this, \"code\", {\n configurable: !0,\n enumerable: !0,\n value: i,\n writable: !0\n });\n }\n toString() {\n return `${this.name} [${n}]: ${this.message}`;\n }\n };\n }\n W(\n \"ERR_BUFFER_OUT_OF_BOUNDS\",\n function(n) {\n return n ? `${n} is outside of buffer bounds` : \"Attempt to access memory outside buffer bounds\";\n },\n RangeError\n ), W(\n \"ERR_INVALID_ARG_TYPE\",\n function(n, t) {\n return `The \"${n}\" argument must be of type number. Received type ${typeof t}`;\n },\n TypeError\n ), W(\n \"ERR_OUT_OF_RANGE\",\n function(n, t, r) {\n let e = `The value of \"${n}\" is out of range.`, i = r;\n return Number.isInteger(r) && Math.abs(r) > 2 ** 32 ? i = ot(String(r)) : typeof r == \"bigint\" && (i = String(r), (r > BigInt(2) ** BigInt(32) || r < -(BigInt(2) ** BigInt(32))) && (i = ot(i)), i += \"n\"), e += ` It must be ${t}. Received ${i}`, e;\n },\n RangeError\n );\n function ot(n) {\n let t = \"\", r = n.length;\n const e = n[0] === \"-\" ? 1 : 0;\n for (; r >= e + 4; r -= 3)\n t = `_${n.slice(r - 3, r)}${t}`;\n return `${n.slice(0, r)}${t}`;\n }\n function mt(n, t, r) {\n M(t, \"offset\"), (n[t] === void 0 || n[t + r] === void 0) && b(t, n.length - (r + 1));\n }\n function ut(n, t, r, e, i, u) {\n if (n > r || n < t) {\n const c = typeof t == \"bigint\" ? \"n\" : \"\";\n let B;\n throw u > 3 ? t === 0 || t === BigInt(0) ? B = `>= 0${c} and < 2${c} ** ${(u + 1) * 8}${c}` : B = `>= -(2${c} ** ${(u + 1) * 8 - 1}${c}) and < 2 ** ${(u + 1) * 8 - 1}${c}` : B = `>= ${t}${c} and <= ${r}${c}`, new $.ERR_OUT_OF_RANGE(\"value\", B, n);\n }\n mt(e, i, u);\n }\n function M(n, t) {\n if (typeof n != \"number\")\n throw new $.ERR_INVALID_ARG_TYPE(t, \"number\", n);\n }\n function b(n, t, r) {\n throw Math.floor(n) !== n ? (M(n, r), new $.ERR_OUT_OF_RANGE(r || \"offset\", \"an integer\", n)) : t < 0 ? new $.ERR_BUFFER_OUT_OF_BOUNDS() : new $.ERR_OUT_OF_RANGE(\n r || \"offset\",\n `>= ${r ? 1 : 0} and <= ${t}`,\n n\n );\n }\n const Ft = /[^+/0-9A-Za-z-_]/g;\n function At(n) {\n if (n = n.split(\"=\")[0], n = n.trim().replace(Ft, \"\"), n.length < 2)\n return \"\";\n for (; n.length % 4 !== 0; )\n n = n + \"=\";\n return n;\n }\n function X(n, t) {\n t = t || 1 / 0;\n let r;\n const e = n.length;\n let i = null;\n const u = [];\n for (let c = 0; c < e; ++c) {\n if (r = n.charCodeAt(c), r > 55295 && r < 57344) {\n if (!i) {\n if (r > 56319) {\n (t -= 3) > -1 && u.push(239, 191, 189);\n continue;\n } else if (c + 1 === e) {\n (t -= 3) > -1 && u.push(239, 191, 189);\n continue;\n }\n i = r;\n continue;\n }\n if (r < 56320) {\n (t -= 3) > -1 && u.push(239, 191, 189), i = r;\n continue;\n }\n r = (i - 55296 << 10 | r - 56320) + 65536;\n } else\n i && (t -= 3) > -1 && u.push(239, 191, 189);\n if (i = null, r < 128) {\n if ((t -= 1) < 0)\n break;\n u.push(r);\n } else if (r < 2048) {\n if ((t -= 2) < 0)\n break;\n u.push(\n r >> 6 | 192,\n r & 63 | 128\n );\n } else if (r < 65536) {\n if ((t -= 3) < 0)\n break;\n u.push(\n r >> 12 | 224,\n r >> 6 & 63 | 128,\n r & 63 | 128\n );\n } else if (r < 1114112) {\n if ((t -= 4) < 0)\n break;\n u.push(\n r >> 18 | 240,\n r >> 12 & 63 | 128,\n r >> 6 & 63 | 128,\n r & 63 | 128\n );\n } else\n throw new Error(\"Invalid code point\");\n }\n return u;\n }\n function Ut(n) {\n const t = [];\n for (let r = 0; r < n.length; ++r)\n t.push(n.charCodeAt(r) & 255);\n return t;\n }\n function _t(n, t) {\n let r, e, i;\n const u = [];\n for (let c = 0; c < n.length && !((t -= 2) < 0); ++c)\n r = n.charCodeAt(c), e = r >> 8, i = r % 256, u.push(i), u.push(e);\n return u;\n }\n function ct(n) {\n return h.toByteArray(At(n));\n }\n function H(n, t, r, e) {\n let i;\n for (i = 0; i < e && !(i + r >= t.length || i >= n.length); ++i)\n t[i + r] = n[i];\n return i;\n }\n function R(n, t) {\n return n instanceof t || n != null && n.constructor != null && n.constructor.name != null && n.constructor.name === t.name;\n }\n function j(n) {\n return n !== n;\n }\n const Nt = function() {\n const n = \"0123456789abcdef\", t = new Array(256);\n for (let r = 0; r < 16; ++r) {\n const e = r * 16;\n for (let i = 0; i < 16; ++i)\n t[e + i] = n[r] + n[i];\n }\n return t;\n }();\n function O(n) {\n return typeof BigInt > \"u\" ? Tt : n;\n }\n function Tt() {\n throw new Error(\"BigInt not supported\");\n }\n})(F);\nconst Mt = 0, Pt = 1, bt = 2, Gt = 3, Ht = 4;\nfunction Vt(f) {\n const h = [\n new F.Buffer(1),\n new F.Buffer(4),\n new F.Buffer(4),\n new F.Buffer(4),\n new F.Buffer(1)\n ];\n h[Mt].writeUIntLE(190, 0, 1), h[Pt].writeInt32BE(1, 0), h[Ht].writeUIntLE(237, 0, 1);\n const l = f.length, s = [], w = [];\n f.forEach(({ path: I, data: T }) => {\n s.push(new F.Buffer(I)), w.push(T);\n });\n let a = 14 + 4 + 12 * l + F.Buffer.concat(s).length;\n const p = s.map((I, T) => {\n const U = new F.Buffer(4);\n U.writeInt32BE(I.length, 0);\n const S = w[T].length, k = new F.Buffer(4);\n k.writeInt32BE(a, 0), a += S;\n const G = new F.Buffer(4);\n return G.writeInt32BE(S, 0), F.Buffer.concat([U, I, k, G]);\n }), o = new F.Buffer(4);\n o.writeInt32BE(l, 0), p.unshift(o);\n const y = F.Buffer.concat(p), _ = F.Buffer.concat(w);\n h[bt].writeInt32BE(y.length, 0), h[Gt].writeInt32BE(_.length, 0);\n const m = F.Buffer.concat(h);\n return F.Buffer.concat([m, y, _]);\n}\nconst Yt = 14, Wt = 18, Xt = 18;\nfunction jt(f) {\n return f.slice(Yt, Wt).readInt32BE(0);\n}\nfunction qt(f) {\n const h = jt(f), l = [];\n let s = Xt;\n for (let w = 0; w < h; w++) {\n const a = f.slice(s, s + 4).readInt32BE(0);\n s += 4;\n const p = f.slice(s, s + a).toString();\n s += a;\n const o = f.slice(s, s + 4).readInt32BE(0);\n s += 4;\n const y = f.slice(s, s + 4).readInt32BE(0);\n s += 4, l.push({\n name: p,\n offset: o,\n length: y\n });\n }\n return l;\n}\nfunction zt(f) {\n try {\n const h = qt(f), l = [];\n for (const s of h) {\n const { name: w, offset: a, length: p } = s;\n l.push({\n path: w,\n data: f.slice(a, a + p)\n });\n }\n return l;\n } catch (h) {\n throw new Error(`unpack wxvpkg catch error ${h}`);\n }\n}\nconst Jt = 5, Kt = 9, Zt = 9, Qt = 13, vt = 18, tr = 22, rr = 22;\nfunction nr(f) {\n return f.slice(Jt, Kt).readInt32BE(0);\n}\nfunction er(f) {\n return f.slice(Zt, Qt).readInt32BE(0);\n}\nfunction ir(f) {\n return f.slice(vt, tr).readInt32BE(0);\n}\nfunction or(f) {\n const h = ir(f), l = [];\n let s = rr;\n for (let w = 0; w < h; w++) {\n const a = f.slice(s, s + 4).readInt32BE(0);\n s += 4;\n const p = f.slice(s, s + a).toString();\n s += a;\n const o = f.slice(s, s + 1).readIntBE(0, 1, !1);\n s += 1;\n const y = f.slice(s, s + 2).readIntBE(0, 2, !1);\n s += 2;\n const _ = f.slice(s, s + 4).readInt32BE(0);\n s += 4;\n const m = f.slice(s, s + 4).readInt32BE(0);\n s += 4, l.push({\n name: p,\n encType: o,\n mode: y,\n offset: _,\n length: m\n });\n }\n return l;\n}\nfunction ur(f, h) {\n try {\n const l = or(f), s = [], w = 18 + nr(f) + er(f);\n for (const a of l) {\n const { name: p, offset: o, length: y } = a;\n s.push({\n path: p,\n data: f.slice(\n o + w,\n o + w + y\n )\n });\n }\n return s;\n } catch (l) {\n throw new Error(`unpack wxvpkg catch error ${l}`);\n }\n}\nconst cr = {\n 0: zt,\n 10: ur\n};\nfunction fr(f) {\n const h = pr(f), l = cr[h];\n if (!l)\n throw new Error(`wxvpkg unrecognized version: ${h}`);\n return l(f);\n}\nconst hr = 1, sr = 5;\nfunction pr(f) {\n let h = f.slice(hr, sr).readInt32BE(0);\n if (h === 1) {\n const l = f.slice(13, 14);\n (l[0] === 14 || l[0] === 237) && (h = 0);\n }\n return h;\n}\nfunction ar(f) {\n let h = F.Buffer.from(f);\n return fr(h);\n}\nfunction wr(f) {\n return Vt(f);\n}\nfunction Br(f) {\n return f.buffer.slice(\n f.byteOffset,\n f.byteOffset + f.byteLength\n );\n}\nconst yr = F.Buffer;\nexport {\n yr as Buffer,\n Br as bufferToArrayBuffer,\n wr as pack,\n ar as unpack\n};\n", "/**\r\n * wxapkg-loader.ts \u2014 unified \"resolve CDN url \u2192 download wxapkg \u2192 unpack \u2192\r\n * register files into VFS\" helper, shared by all three wxapkg flavours:\r\n *\r\n * \u2022 main package (bootstrapped by wx-compat before game.js runs)\r\n * \u2022 subpackages (lazy-loaded via wx.loadSubpackage)\r\n * \u2022 plugin packages (preloaded by plugin-compat before game.js runs)\r\n *\r\n * The npm package is solely responsible for unpacking. The outside world\r\n * only has to:\r\n * 1. Expose an HTTP endpoint that returns a CDN url for a given\r\n * (appid, path) pair, OR\r\n * 2. Hand us the wxapkg ArrayBuffer directly (bypassing the resolver).\r\n *\r\n * There is deliberately NO support for \"server-side unpacked\" main packages\r\n * here \u2014 that pre-existing directory-serving flow stays untouched and lives\r\n * entirely outside this file.\r\n */\r\n\r\nimport { unpack } from '@tencent/wxapkg-browser';\r\nimport { nativeConsole, nativeFetch } from './native-globals';\r\nimport { resolveGameUrl } from './url-utils';\r\nimport * as vfs from './virtual-fs';\r\n\r\n// \u2500\u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Configuration for resolving a wxapkg CDN url via a host-side HTTP API.\r\n *\r\n * The historical endpoint used for plugins is:\r\n * GET /api/wxapkg/:provider?version=<version> \u2192 { cdnUrl }\r\n *\r\n * For the unified RN / multi-package flow we generalise to:\r\n * GET <baseAPI>/api/<appid>/version?path=<path>&version=<version> \u2192 { cdnUrl }\r\n *\r\n * `path` is the subpackage root (e.g. \"subpackages/internal\") \u2014 empty string\r\n * means the main package. `version` is optional and only meaningful for\r\n * plugins today.\r\n */\r\nexport interface CdnResolverConfig {\r\n /**\r\n * Base URL for the resolver API. Trailing slash is optional.\r\n * Example: \"https://api.example.com\"\r\n *\r\n * When omitted, the resolver falls back to same-origin requests against\r\n * the historical `/api/wxapkg/:provider` endpoint so that the legacy\r\n * VSCode preview flow keeps working.\r\n */\r\n baseAPI?: string;\r\n\r\n /** Mini-game appid. Required for the unified flow; ignored for legacy flow. */\r\n appid?: string;\r\n\r\n /**\r\n * URL template. Supports `${baseAPI}`, `${appid}`, `${path}`, `${version}`\r\n * placeholders. Default:\r\n * ${baseAPI}/api/${appid}/version?path=${path}&version=${version}\r\n *\r\n * An empty `path` (main package) renders as `path=` \u2014 resolver servers are\r\n * expected to treat that as \"give me the main package\".\r\n */\r\n urlTemplate?: string;\r\n\r\n /**\r\n * Extract the CDN URL from the resolver response body. Default extractor:\r\n * (body) => body.cdnUrl ?? body.url ?? body.data?.cdnUrl\r\n */\r\n pickCdnUrl?: (body: unknown) => string | null | undefined;\r\n}\r\n\r\nexport interface WxapkgDownloadOptions {\r\n /**\r\n * CDN url resolver \u2014 either the already-resolved URL, or a config that\r\n * the loader will POST to the resolver API with.\r\n */\r\n resolver: CdnResolverConfig | null;\r\n\r\n /** Mini-game appid (duplicated here for logging / legacy path). */\r\n appid?: string;\r\n\r\n /** Logical path of the package being downloaded ('' for main). */\r\n path: string;\r\n\r\n /** Optional version tag (only meaningful for plugins today). */\r\n version?: string;\r\n\r\n /**\r\n * Directory under which unpacked files get mounted in the VFS.\r\n * \"\" \u2014 main package, files unpacked at /<filename>\r\n * \"subpackages/a\" \u2014 subpackage, files unpacked at /subpackages/a/<filename>\r\n * \"__plugin__/<provider>\"\r\n * \u2014 plugin, files unpacked at /__plugin__/<provider>/<filename>\r\n */\r\n mountRoot: string;\r\n\r\n /**\r\n * If true, request the wxapkg via the host-side `/cdn-proxy?url=` endpoint\r\n * (same-origin, bypasses CORS). If false, fetch the CDN url directly.\r\n * Default: true \u2014 the RN use-case uses a bridge-style proxy on the native\r\n * side, and the existing VSCode preview uses a true HTTP proxy.\r\n */\r\n useProxy?: boolean;\r\n\r\n /**\r\n * Progress callback (0-100). Called with actual network bytes transferred.\r\n * Wired up from `wx.loadSubpackage({ onProgressUpdate })`.\r\n */\r\n onProgress?: (progress: number, written: number, expected: number) => void;\r\n\r\n /**\r\n * Short-circuit: if the bytes are already available locally, skip the\r\n * resolver+download steps entirely. Mostly used by callers that have\r\n * pre-staged the wxapkg via `preloadFiles()`.\r\n */\r\n preloadedWxapkgData?: ArrayBuffer | Uint8Array;\r\n\r\n /**\r\n * Optional label used in log messages. Falls back to `${mountRoot || '/'}`.\r\n */\r\n label?: string;\r\n}\r\n\r\nexport interface WxapkgLoadResult {\r\n /** Number of files unpacked and mounted into the VFS. */\r\n fileCount: number;\r\n /** Paths (absolute, VFS-normalised) of the mounted files. */\r\n mountedPaths: string[];\r\n}\r\n\r\n// \u2500\u2500\u2500 Resolver \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction renderUrlTemplate(tpl: string, vars: Record<string, string>): string {\r\n return tpl.replace(/\\$\\{(\\w+)\\}/g, (_, k) => vars[k] ?? '');\r\n}\r\n\r\nconst DEFAULT_URL_TEMPLATE =\r\n '${baseAPI}/api/${appid}/version?path=${path}&version=${version}';\r\n\r\nfunction defaultPickCdnUrl(body: unknown): string | null {\r\n if (!body || typeof body !== 'object') return null;\r\n const b = body as Record<string, unknown>;\r\n if (typeof b.cdnUrl === 'string') return b.cdnUrl;\r\n if (typeof b.url === 'string') return b.url;\r\n if (b.data && typeof b.data === 'object') {\r\n const d = b.data as Record<string, unknown>;\r\n if (typeof d.cdnUrl === 'string') return d.cdnUrl;\r\n if (typeof d.url === 'string') return d.url;\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Resolve a wxapkg CDN URL. Two shapes are supported:\r\n *\r\n * (a) `resolver.baseAPI` is provided \u2192 render `urlTemplate` and hit the\r\n * unified endpoint. This is the RN use-case.\r\n *\r\n * (b) `resolver.baseAPI` is absent \u2192 fall back to the legacy\r\n * `/api/wxapkg/:provider?version=` (provider = `path` or `appid`) which\r\n * is what the existing plugin-compat code used. This keeps the VSCode\r\n * plugin / dev server path working after the refactor.\r\n */\r\nasync function resolveCdnUrl(opts: WxapkgDownloadOptions): Promise<string | null> {\r\n const { resolver, appid, path, version, label } = opts;\r\n const tag = label || (path || 'main');\r\n\r\n // Path (b): legacy endpoint.\r\n if (!resolver || !resolver.baseAPI) {\r\n const provider = path || appid || '';\r\n if (!provider) {\r\n nativeConsole.error(\r\n `[wx-compat][wxapkg-loader] Cannot resolve CDN url for \"${tag}\": ` +\r\n `no resolver.baseAPI and no provider/appid available.`,\r\n );\r\n return null;\r\n }\r\n const v = version || '';\r\n // Relative URL must be resolved against the game's assetBaseUrl \u2014 inside\r\n // a srcdoc iframe, the document origin is the host page (e.g.\r\n // vscode-webview://\u2026) which would otherwise hijack relative paths and\r\n // produce requests like `vscode-webview://\u2026/api/wxapkg/\u2026`. Using the\r\n // shared resolver keeps this aligned with every other relative fetch in\r\n // wx-compat (file-system, network, globals-compat, etc.).\r\n const url = resolveGameUrl(\r\n `/api/wxapkg/${encodeURIComponent(provider)}?version=${encodeURIComponent(v)}`,\r\n );\r\n try {\r\n const res = await nativeFetch(url);\r\n if (!res.ok) {\r\n nativeConsole.error(\r\n `[wx-compat][wxapkg-loader] Legacy resolver returned HTTP ${res.status} for ${tag}`,\r\n );\r\n return null;\r\n }\r\n const body = await res.json();\r\n const pick = resolver?.pickCdnUrl ?? defaultPickCdnUrl;\r\n return pick(body) ?? null;\r\n } catch (e) {\r\n nativeConsole.error(\r\n `[wx-compat][wxapkg-loader] Legacy resolver failed for ${tag}:`, e,\r\n );\r\n return null;\r\n }\r\n }\r\n\r\n // Path (a): unified endpoint via configurable template.\r\n const baseAPI = resolver.baseAPI.replace(/\\/+$/, '');\r\n const effectiveAppid = resolver.appid || appid || '';\r\n const tpl = resolver.urlTemplate || DEFAULT_URL_TEMPLATE;\r\n const rendered = renderUrlTemplate(tpl, {\r\n baseAPI,\r\n appid: encodeURIComponent(effectiveAppid),\r\n path: encodeURIComponent(path || ''),\r\n version: encodeURIComponent(version || ''),\r\n });\r\n // If the template produced a relative URL (empty baseAPI, or a template\r\n // that starts with '/'), funnel it through resolveGameUrl so the srcdoc\r\n // iframe doesn't hijack it. Absolute http(s) URLs are left untouched by\r\n // resolveGameUrl.\r\n const url = resolveGameUrl(rendered);\r\n\r\n try {\r\n const res = await nativeFetch(url);\r\n if (!res.ok) {\r\n nativeConsole.error(\r\n `[wx-compat][wxapkg-loader] Resolver returned HTTP ${res.status} for ${tag}: ${url}`,\r\n );\r\n return null;\r\n }\r\n const body = await res.json();\r\n const pick = resolver.pickCdnUrl ?? defaultPickCdnUrl;\r\n const cdn = pick(body) ?? null;\r\n if (!cdn) {\r\n nativeConsole.error(\r\n `[wx-compat][wxapkg-loader] Resolver body missing cdn url for ${tag}:`, body,\r\n );\r\n }\r\n return cdn;\r\n } catch (e) {\r\n nativeConsole.error(\r\n `[wx-compat][wxapkg-loader] Resolver request failed for ${tag}: ${url}`, e,\r\n );\r\n return null;\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 Download \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Fetch a CDN url as an ArrayBuffer. When `useProxy` is true (default), route\r\n * through the same-origin `/cdn-proxy?url=` endpoint to bypass CORS \u2014 this\r\n * is the behaviour both the VSCode dev server and the RN WebView bridge\r\n * follow (the RN side registers a `/cdn-proxy` handler on its own local\r\n * HTTP bridge).\r\n *\r\n * Streams chunks via `response.body.getReader()` so we can emit a real\r\n * progress number to `wx.loadSubpackage({ onProgressUpdate })`.\r\n */\r\nasync function downloadWxapkg(\r\n cdnUrl: string,\r\n useProxy: boolean,\r\n onProgress?: (progress: number, written: number, expected: number) => void,\r\n label = 'wxapkg',\r\n): Promise<ArrayBuffer | null> {\r\n // The `/cdn-proxy` route is served by the host dev server / RN bridge, so\r\n // it MUST be resolved against the same origin as the other relative URLs\r\n // (otherwise srcdoc iframes would rewrite it to vscode-webview://\u2026).\r\n const fetchUrl = useProxy\r\n ? resolveGameUrl(`/cdn-proxy?url=${encodeURIComponent(cdnUrl)}`)\r\n : cdnUrl;\r\n\r\n let res: Response;\r\n try {\r\n res = await nativeFetch(fetchUrl);\r\n } catch (e) {\r\n nativeConsole.error(`[wx-compat][wxapkg-loader] fetch(${label}) failed:`, e);\r\n return null;\r\n }\r\n if (!res.ok) {\r\n nativeConsole.error(\r\n `[wx-compat][wxapkg-loader] fetch(${label}) HTTP ${res.status}: ${fetchUrl}`,\r\n );\r\n return null;\r\n }\r\n\r\n // Fast path: no progress callback, just consume the body in one shot.\r\n if (!onProgress || !res.body || typeof res.body.getReader !== 'function') {\r\n try {\r\n return await res.arrayBuffer();\r\n } catch (e) {\r\n nativeConsole.error(`[wx-compat][wxapkg-loader] body read failed for ${label}:`, e);\r\n return null;\r\n }\r\n }\r\n\r\n // Streaming path: read chunks and update progress.\r\n const total = Number(res.headers.get('content-length') || 0);\r\n const reader = res.body.getReader();\r\n const chunks: Uint8Array[] = [];\r\n let received = 0;\r\n try {\r\n // Loop until reader is done \u2014 typed so biome doesn't complain.\r\n for (;;) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n if (value) {\r\n chunks.push(value);\r\n received += value.byteLength;\r\n const pct = total > 0\r\n ? Math.min(99, Math.floor((received / total) * 100))\r\n : 0;\r\n try {\r\n onProgress(pct, received, total || received);\r\n } catch { /* swallow user callback errors */ }\r\n }\r\n }\r\n } catch (e) {\r\n nativeConsole.error(`[wx-compat][wxapkg-loader] stream read failed for ${label}:`, e);\r\n return null;\r\n }\r\n\r\n // Concatenate.\r\n const out = new Uint8Array(received);\r\n let off = 0;\r\n for (const c of chunks) {\r\n out.set(c, off);\r\n off += c.byteLength;\r\n }\r\n try { onProgress(100, received, total || received); } catch { /* noop */ }\r\n return out.buffer;\r\n}\r\n\r\n// \u2500\u2500\u2500 Unpack + mount \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Unpack a wxapkg ArrayBuffer and mount every file into the VFS.\r\n *\r\n * \u2500\u2500\u2500 The only invariant: match manifest-declared mountRoot \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n *\r\n * A wxapkg carries each entry's path as \"/subpackages/<realRoot>/file\" for\r\n * subpackages, \"/<file>\" for the main package, and \"/<file>\" or nested\r\n * paths for plugin packages. These paths are the package's own authoritative\r\n * description of where its files live \u2014 we treat them as ground truth.\r\n *\r\n * The transformation rule during mount depends on how `mountRoot` relates\r\n * to the archive's own path namespace:\r\n *\r\n * (1) Main package \u2014 `mountRoot === \"\"`.\r\n * VFS root IS the archive root. Paths are mounted verbatim.\r\n *\r\n * (2) Subpackage \u2014 `mountRoot` comes from the manifest's `subPackages[].root`\r\n * and MUST match the archive's internal prefix for the subpackage to\r\n * be intact. Archives store entries as \"/subpackages/<root>/...\", so\r\n * we strip that leading \"<mountRoot>/\" to avoid doubling it when we\r\n * re-prepend mountRoot during mount.\r\n * archive entry : \"/subpackages/main/game.js\"\r\n * mountRoot : \"subpackages/main\"\r\n * desired VFS : \"/subpackages/main/game.js\"\r\n * If the prefix does NOT match (e.g. CDN delivered a package keyed to\r\n * a different subpackage root), that is a *data-source* error we\r\n * deliberately surface rather than silently paper over. Renaming\r\n * internal paths to match the declared root breaks engines (notably\r\n * Cocos) that rely on the archive's layout for their own relative\r\n * resolution.\r\n *\r\n * (3) Plugin package \u2014 `mountRoot` is \"__plugin__/<provider>\", a namespace\r\n * invented by wx-compat; it is NOT present in the archive's own path\r\n * space. We simply prepend mountRoot to every entry's full relative\r\n * path without any stripping \u2014 \"mismatch\" here is the expected and\r\n * correct behaviour, not a data error.\r\n *\r\n * Callers signal which case they are via the `mountKind` parameter.\r\n */\r\nexport type WxapkgMountKind = 'main' | 'subpackage' | 'plugin';\r\n\r\nexport function unpackAndMount(\r\n data: ArrayBuffer | Uint8Array,\r\n mountRoot: string,\r\n label = 'wxapkg',\r\n mountKind: WxapkgMountKind = inferMountKind(mountRoot),\r\n): WxapkgLoadResult {\r\n const buf = data instanceof Uint8Array ? data.buffer : data;\r\n const files = unpack(buf) as Array<{ path: string; data: string | Uint8Array }>;\r\n const root = (mountRoot || '').replace(/^\\/+|\\/+$/g, '');\r\n const mounted: string[] = [];\r\n let mismatchCount = 0;\r\n\r\n for (const f of files) {\r\n // wxapkg paths typically start with '/'; strip leading slashes for\r\n // uniform handling.\r\n let rel = f.path.replace(/^\\/+/, '');\r\n\r\n if (mountKind === 'subpackage' && root) {\r\n const expectedPrefix = root + '/';\r\n if (rel === root) {\r\n // Edge case: a directory entry that exactly equals mountRoot.\r\n // Nothing meaningful to mount.\r\n rel = '';\r\n } else if (rel.startsWith(expectedPrefix)) {\r\n // Normal case: archive embeds the manifest-declared subpackage\r\n // root in every path. Strip it before re-prepending mountRoot.\r\n rel = rel.substring(expectedPrefix.length);\r\n } else {\r\n // Archive's real prefix differs from mountRoot \u2014 preserve the\r\n // archive's identity. The resulting VFS path will NOT sit under\r\n // mountRoot, which is exactly what we want: downstream will\r\n // fail to locate it under the expected path, making the\r\n // misdelivery visible rather than silently masked.\r\n mismatchCount++;\r\n }\r\n }\r\n // For 'main' (root === \"\") and 'plugin' (namespace not present in\r\n // archive) we do NOT touch the internal path: just prepend mountRoot.\r\n\r\n const full = root\r\n ? (rel ? `/${root}/${rel}` : `/${root}`)\r\n : `/${rel}`;\r\n if (typeof f.data === 'string') {\r\n vfs.putText(full, f.data);\r\n } else {\r\n vfs.put(full, f.data);\r\n }\r\n mounted.push(full);\r\n }\r\n\r\n if (mismatchCount > 0) {\r\n const sampleBadPath = files.find(f => {\r\n const r = f.path.replace(/^\\/+/, '');\r\n return !(r === root || r.startsWith(root + '/'));\r\n })?.path;\r\n nativeConsole.warn(\r\n `[wx-compat][wxapkg-loader] ${label}: ${mismatchCount}/${files.length} ` +\r\n `entries did NOT start with mountRoot=\"${root}/\". This means the CDN ` +\r\n `returned a wxapkg whose internal subpackage prefix differs from the ` +\r\n `subpackage root declared in app-config.json. ` +\r\n `Example mismatched path: ${sampleBadPath ?? '(none)'}. ` +\r\n `Fix the resolver / CDN mapping \u2014 wx-compat will not silently rewrite ` +\r\n `the archive's internal paths.`,\r\n );\r\n }\r\n nativeConsole.log(\r\n `[wx-compat][wxapkg-loader] Unpacked ${label}: ` +\r\n `${files.length} files \u2192 mountRoot=\"${root || '/'}\" kind=${mountKind} ` +\r\n `sample=${mounted.slice(0, 3).join(',')}`,\r\n );\r\n return { fileCount: files.length, mountedPaths: mounted };\r\n}\r\n\r\n/**\r\n * Best-effort fallback when the caller didn't pass `mountKind` explicitly.\r\n * The `__plugin__/...` convention is the one discriminator we can rely on\r\n * without additional context. Main vs subpackage is disambiguated by\r\n * whether `mountRoot` is empty.\r\n */\r\nfunction inferMountKind(mountRoot: string): WxapkgMountKind {\r\n const r = (mountRoot || '').replace(/^\\/+|\\/+$/g, '');\r\n if (!r) return 'main';\r\n if (r.startsWith('__plugin__/') || r === '__plugin__') return 'plugin';\r\n return 'subpackage';\r\n}\r\n\r\n// \u2500\u2500\u2500 Orchestration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * One-shot: (optionally resolve + download) \u2192 unpack \u2192 mount into VFS.\r\n *\r\n * Returns null if any step fails; callers should log contextually and decide\r\n * whether failure is fatal.\r\n */\r\nexport async function loadWxapkg(\r\n opts: WxapkgDownloadOptions,\r\n): Promise<WxapkgLoadResult | null> {\r\n const tag = opts.label || opts.path || 'main';\r\n\r\n // Short-circuit: caller handed us the bytes.\r\n if (opts.preloadedWxapkgData) {\r\n return unpackAndMount(opts.preloadedWxapkgData, opts.mountRoot, tag);\r\n }\r\n\r\n const cdnUrl = await resolveCdnUrl(opts);\r\n if (!cdnUrl) return null;\r\n nativeConsole.log(\r\n `[wx-compat][wxapkg-loader] Resolved CDN url for ${tag}: ${cdnUrl}`,\r\n );\r\n\r\n const useProxy = opts.useProxy !== false;\r\n const buf = await downloadWxapkg(cdnUrl, useProxy, opts.onProgress, tag);\r\n if (!buf) return null;\r\n nativeConsole.log(\r\n `[wx-compat][wxapkg-loader] Downloaded ${tag}: ${(buf.byteLength / 1024).toFixed(1)} KB`,\r\n );\r\n\r\n try {\r\n return unpackAndMount(buf, opts.mountRoot, tag);\r\n } catch (e) {\r\n nativeConsole.error(`[wx-compat][wxapkg-loader] unpack(${tag}) failed:`, e);\r\n return null;\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 Config access \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Snapshot of the resolver configuration seen on window at startup. Populated\r\n * from `window.__wxCdnResolver` (installed by the host page).\r\n */\r\nlet globalResolver: CdnResolverConfig | null = null;\r\nlet globalAppid: string | undefined;\r\nlet globalUseProxy = true;\r\n\r\nexport function configureFromWindow(): void {\r\n const win = window as unknown as {\r\n __wxCdnResolver?: CdnResolverConfig;\r\n __wxAppid?: string;\r\n __wxWxapkgUseProxy?: boolean;\r\n };\r\n if (win.__wxCdnResolver && typeof win.__wxCdnResolver === 'object') {\r\n globalResolver = win.__wxCdnResolver;\r\n }\r\n if (typeof win.__wxAppid === 'string') globalAppid = win.__wxAppid;\r\n if (typeof win.__wxWxapkgUseProxy === 'boolean') {\r\n globalUseProxy = win.__wxWxapkgUseProxy;\r\n }\r\n}\r\n\r\nexport function getGlobalResolver(): CdnResolverConfig | null {\r\n return globalResolver;\r\n}\r\n\r\nexport function getGlobalAppid(): string | undefined {\r\n return globalAppid;\r\n}\r\n\r\nexport function getGlobalUseProxy(): boolean {\r\n return globalUseProxy;\r\n}\r\n", "/**\r\n * CommonJS Module System & Subpackage Loading for WeChat Mini Game\r\n *\r\n * WeChat Mini Game wxapkg packages use a CommonJS-like module system:\r\n *\r\n * define(\"path/to/module.js\", function(require, module, exports) { ... })\r\n * require(\"path/to/module.js\")\r\n *\r\n * This module provides:\r\n * - define() \u2014 registers module factories (called by game.js / subpackage code)\r\n * - require() \u2014 resolves and executes modules, returns exports\r\n * - wx.loadSubpackage() \u2014 loads subpackage entry scripts dynamically\r\n *\r\n * The module registry is shared with the plugin system (plugin-compat.ts),\r\n * which uses the same define() for \"__plugin__/...\" prefixed modules.\r\n *\r\n * In both 'directory' and 'wxapkg' modes, files are served by the static server.\r\n * The static server handles wxapkg decoding and file extraction transparently.\r\n * The unified GET /api/wxapkg/:appid?version=xxx endpoint provides CDN URLs\r\n * for downloading wxapkg packages when needed.\r\n */\r\n\r\nimport { nativeConsole, NativeXMLHttpRequest } from './native-globals';\r\nimport { resolveGameUrl, loadGameManifest } from './url-utils';\r\nimport { has as vfsHas } from './virtual-fs';\r\nimport {\r\n loadWxapkg,\r\n getGlobalResolver as getWxapkgResolver,\r\n getGlobalAppid as getWxapkgAppid,\r\n getGlobalUseProxy as getWxapkgUseProxy,\r\n} from './wxapkg-loader';\r\n\r\n// \u2500\u2500\u2500 Module System Initialization \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Initialize the module system.\r\n * Called from globals-compat.ts during initialization.\r\n * Reads the game mode from window.__wxGameMode for logging purposes.\r\n */\r\nexport function initModuleSystem(): void {\r\n const win = window as unknown as Record<string, unknown>;\r\n const mode = (win.__wxGameMode as string) || 'directory';\r\n\r\n nativeConsole.log(`[wx-compat][module] Module system initialized: mode=${mode}`);\r\n}\r\n\r\n// \u2500\u2500\u2500 Module Registry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Module factory function signature (matches WeChat's define callback) */\r\ntype ModuleFactory = (\r\n require: (id: string) => unknown,\r\n module: { exports: unknown },\r\n exports: unknown,\r\n) => void;\r\n\r\n/** Registered module factories (set by define()) */\r\nconst moduleFactories = new Map<string, ModuleFactory>();\r\n\r\n/** Cached module exports (lazy-evaluated on first require) */\r\nconst moduleCache = new Map<string, { exports: unknown }>();\r\n\r\n// \u2500\u2500\u2500 Package Scope Stack \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n//\r\n// Every wxapkg (main package, subpackage, plugin package) runs its top-level\r\n// code within an implicit **package root**. When code inside `subpackages/foo/`\r\n// calls `define(\"game.js\", f)` or `require(\"game.js\")`, the intent is\r\n// \"define/require the `game.js` file WITHIN this package\", not the main\r\n// package's `game.js`. WeChat's native runtime keeps each wxapkg in its own\r\n// module namespace; we flatten everything into a single Map, so we must\r\n// re-introduce that scoping at define/require time.\r\n//\r\n// Usage: `pushPackageScope(\"subpackages/foo\")` before executing a subpackage\r\n// entry script, `popPackageScope()` after. While the scope is active:\r\n// - define(\"x.js\", f) \u2192 registered as \"subpackages/foo/x.js\"\r\n// - require(\"x.js\") \u2192 resolves \"subpackages/foo/x.js\" first, falls back\r\n// to \"x.js\" so a subpackage can still reach main\r\n// package modules when it really means to.\r\n//\r\n// Main package code runs with an empty stack, so behavior is unchanged there.\r\nconst packageScopeStack: string[] = [];\r\n\r\nfunction currentPackageScope(): string {\r\n return packageScopeStack.length > 0\r\n ? packageScopeStack[packageScopeStack.length - 1]\r\n : '';\r\n}\r\n\r\nexport function pushPackageScope(root: string): void {\r\n // Normalize: strip leading/trailing slashes, collapse empty \u2192 ''\r\n const normalized = (root || '').replace(/^\\/+|\\/+$/g, '');\r\n packageScopeStack.push(normalized);\r\n __trace('SCOPE-PUSH', { root: normalized, depth: packageScopeStack.length });\r\n}\r\n\r\nexport function popPackageScope(): void {\r\n const popped = packageScopeStack.pop();\r\n __trace('SCOPE-POP', { root: popped ?? '', depth: packageScopeStack.length });\r\n}\r\n\r\n/**\r\n * Apply the current package scope to a module id.\r\n *\r\n * Rules (in order):\r\n * 1. No scope active \u2192 id unchanged.\r\n * 2. id starts with \"__plugin__/\" \u2192 id unchanged (plugins have their own\r\n * namespace; scope must not stack on top).\r\n * 3. id already starts with \"<scope>/\" \u2192 id unchanged (idempotent; also\r\n * handles pre-namespaced producers\r\n * like the \"multi-dir\" unpack variant\r\n * that already emits full paths).\r\n * 4. id contains \"/\" and is therefore plausibly a project-root-relative path\r\n * \u2192 id unchanged, to avoid double-scoping files that the packer already\r\n * addresses with an explicit path (e.g. \"src/utils.js\").\r\n * 5. Otherwise (bare filename like \"game.js\")\r\n * \u2192 rewritten to \"<scope>/<id>\".\r\n *\r\n * The \"contains slash\" heuristic in (4) is intentionally conservative on the\r\n * *define* side: a packer that emits `define(\"subpackages/foo/src/x.js\", ...)`\r\n * from the root game.js must not get double-scoped to\r\n * `subpackages/foo/subpackages/foo/src/x.js`. The symmetric concern \u2014 that\r\n * `require(\"src/x.js\")` issued *from inside* a subpackage must still find\r\n * that package-local `src/x.js` \u2014 is handled on the require side (see\r\n * `internalRequire` Step 3.6's package-root-prefix walk), not here.\r\n */\r\nfunction applyPackageScope(id: string): string {\r\n const scope = currentPackageScope();\r\n if (!scope) return id;\r\n if (id.startsWith('__plugin__/')) return id;\r\n if (id.startsWith(scope + '/')) return id;\r\n if (id.includes('/')) return id;\r\n return scope + '/' + id;\r\n}\r\n\r\n// \u2500\u2500\u2500 Trace logging \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// Lightweight tracing for diagnosing module-loading differences between\r\n// multi-file-unpacked vs single-game.js-bundled wxapkg variants.\r\n// Disable at runtime via: window.__wxModuleTrace = false\r\nlet __traceSeq = 0;\r\nlet __traceDepth = 0;\r\nfunction __traceEnabled(): boolean {\r\n const v = (window as unknown as Record<string, unknown>).__wxModuleTrace;\r\n return v !== false; // default ON\r\n}\r\nfunction __trace(tag: string, info: Record<string, unknown>): void {\r\n if (!__traceEnabled()) return;\r\n // Temporarily silenced \u2014 keep code for future re-enable.\r\n // const indent = ' '.repeat(__traceDepth);\r\n // const parts: string[] = [];\r\n // for (const k of Object.keys(info)) {\r\n // const v = info[k];\r\n // parts.push(`${k}=${typeof v === 'string' ? v : JSON.stringify(v)}`);\r\n // }\r\n // nativeConsole.log(`[wx-compat][mod-trace] #${++__traceSeq} ${indent}${tag} ${parts.join(' ')}`);\r\n void tag; void info;\r\n}\r\n\r\n// \u2500\u2500\u2500 define() \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Register a module factory.\r\n *\r\n * Called by wxapkg game.js code like:\r\n * define(\"game.js\", function(require, module, exports) { ... })\r\n * define(\"src/utils.js\", function(require, module, exports) { ... })\r\n * define(\"__plugin__/wx0446ba2621dda60a/base.js\", function(require, module, exports) { ... })\r\n *\r\n * @param moduleId The module identifier (e.g. \"src/utils.js\")\r\n * @param factory The module factory function\r\n */\r\nexport function define(\r\n moduleId: string,\r\n factory: ModuleFactory,\r\n): void {\r\n const scopedId = applyPackageScope(moduleId);\r\n const isOverwrite = moduleFactories.has(scopedId);\r\n moduleFactories.set(scopedId, factory);\r\n __trace('DEFINE', {\r\n id: scopedId,\r\n raw: moduleId,\r\n scope: currentPackageScope(),\r\n overwrite: isOverwrite,\r\n total: moduleFactories.size,\r\n });\r\n}\r\n// \u2500\u2500\u2500 Path Resolution Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Resolve a relative path against a base directory.\r\n * e.g. resolvePath(\"src/lib\", \"./utils.js\") \u2192 \"src/lib/utils.js\"\r\n * resolvePath(\"src/lib\", \"../core.js\") \u2192 \"src/core.js\"\r\n */\r\nfunction resolvePath(base: string, relative: string): string {\r\n const parts = base ? base.split('/') : [];\r\n const relParts = relative.split('/');\r\n for (const part of relParts) {\r\n if (part === '..') {\r\n parts.pop();\r\n } else if (part !== '.') {\r\n parts.push(part);\r\n }\r\n }\r\n return parts.join('/');\r\n}\r\n\r\n/**\r\n * Normalize a module ID: ensure .js extension if not present.\r\n * Skip appending for known extensions (.json, .mjs, .cjs) or if the\r\n * exact ID already exists in the registry.\r\n */\r\nfunction normalizeModuleId(id: string): string {\r\n if (id.match(/\\.(?:js|json|mjs|cjs)$/)) {\r\n return id;\r\n }\r\n // If exact ID exists in registry (e.g. provider-only entries), use as-is\r\n if (moduleFactories.has(id) || moduleCache.has(id)) {\r\n return id;\r\n }\r\n return id + '.js';\r\n}\r\n\r\n// \u2500\u2500\u2500 require() \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Internal require implementation with context directory for relative resolution.\r\n *\r\n * @param moduleId The module path to require\r\n * @param contextDir The directory of the requiring module (for relative paths)\r\n * @returns The module's exports\r\n */\r\nfunction internalRequire(moduleId: string, contextDir: string): unknown {\r\n const __entrySeq = ++__traceSeq;\r\n // Temporarily silenced \u2014 keep code for future re-enable.\r\n // if (__traceEnabled()) {\r\n // const indent = ' '.repeat(__traceDepth);\r\n // nativeConsole.log(\r\n // `[wx-compat][mod-trace] #${__entrySeq} ${indent}REQ\\u2192 id=${JSON.stringify(moduleId)} ctx=${JSON.stringify(contextDir)} depth=${__traceDepth}`,\r\n // );\r\n // }\r\n void __entrySeq;\r\n __traceDepth++;\r\n\r\n // Step 1: Resolve relative paths\r\n let resolvedId = moduleId;\r\n if (moduleId.startsWith('./') || moduleId.startsWith('../')) {\r\n resolvedId = resolvePath(contextDir, moduleId);\r\n }\r\n\r\n // Step 1.5: Strip any leading slashes. SystemJS's internal URL normalization\r\n // (and some game-side import-map handlers) can hand us IDs like\r\n // \"//src/chunks/bundle.xxx.js\" or \"/src/foo.js\". These are logically the\r\n // same module as \"src/foo.js\" \u2014 registry/cache keys should be unified, and\r\n // when we later build a URL via `'/' + resolvedId` we must not end up with\r\n // `http://host//src/...`, because some static-server middlewares 404 on\r\n // doubled-slash paths even though URL-wise it's valid.\r\n resolvedId = resolvedId.replace(/^\\/+/, '');\r\n\r\n // Step 2: Normalize (add .js extension if needed)\r\n resolvedId = normalizeModuleId(resolvedId);\r\n\r\n // Step 3: For non-relative, non-prefixed paths within a __plugin__ context,\r\n // try prepending the plugin namespace (same logic as plugin-compat.ts)\r\n if (!resolvedId.startsWith('__plugin__/') &&\r\n (contextDir === '__plugin__' || contextDir.startsWith('__plugin__/'))) {\r\n // Strategy 1: prepend \"__plugin__/\"\r\n const withPrefix = '__plugin__/' + resolvedId;\r\n if (moduleFactories.has(withPrefix) || moduleCache.has(withPrefix)) {\r\n resolvedId = withPrefix;\r\n } else {\r\n // Strategy 2: prepend full namespace \"__plugin__/<provider>/\"\r\n const parts = contextDir.split('/');\r\n if (parts.length >= 2) {\r\n const namespacePrefix = parts[0] + '/' + parts[1];\r\n const namespacedId = namespacePrefix + '/' + resolvedId;\r\n if (moduleFactories.has(namespacedId) || moduleCache.has(namespacedId)) {\r\n resolvedId = namespacedId;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Step 3.6: Package-local resolution (both bare filenames and\r\n // package-root-relative multi-segment paths).\r\n //\r\n // In WeChat's native runtime, each wxapkg (main / subpackage / plugin)\r\n // owns a flat module namespace rooted at its package path. Two shapes of\r\n // non-relative `require(...)` calls issued from *inside* a package must\r\n // resolve to package-local ids:\r\n //\r\n // 1) Bare filename, e.g. inside `subpackages/foo/` a call to\r\n // `require(\"bar.js\")` means `subpackages/foo/bar.js`, not a\r\n // top-level `bar.js`.\r\n //\r\n // 2) Package-root-relative path, e.g. inside `subpackages/engine/` a\r\n // call to `require(\"src/polyfills.bundle.js\")` means the engine\r\n // subpackage's own `subpackages/engine/src/polyfills.bundle.js`.\r\n // This is the exact shape Cocos Creator's subpackage entry emits\r\n // when it bootstraps SystemJS:\r\n // define(\"subpackages/engine/src/polyfills.bundle.js\", ...)\r\n // require(\"src/polyfills.bundle.js\") // from engine/game.js\r\n //\r\n // We flatten every wxapkg into a single registry and encode the package\r\n // root into each module's id at `define()` time (via `applyPackageScope`).\r\n // The symmetric lookup on the require side: walk `contextDir`'s own path\r\n // and every ancestor prefix (deepest \u2192 shallowest), trying each one as a\r\n // potential \"package root\" and checking if `<prefix>/<resolvedId>` is\r\n // registered. First hit wins. If none match we fall through to the bare\r\n // id so that a subpackage can still reach true main-package modules when\r\n // it really means to (preserving prior behavior).\r\n //\r\n // Guards:\r\n // \u2022 contextDir must be non-empty (top-level main-package has\r\n // contextDir === '' so this is a no-op there).\r\n // \u2022 Skip when resolvedId is already plugin-scoped \u2014 plugin namespaces\r\n // are independent of host package roots.\r\n // \u2022 Skip when resolvedId already starts with `contextDir + '/'` \u2014 it\r\n // was pre-namespaced and prefixing again would double-stack.\r\n if (\r\n contextDir &&\r\n !resolvedId.startsWith('__plugin__/') &&\r\n !resolvedId.startsWith(contextDir + '/')\r\n ) {\r\n // Candidate package-root prefixes, deepest first. For contextDir\r\n // \"subpackages/engine/sub\" we try\r\n // \"subpackages/engine/sub\", \"subpackages/engine\", \"subpackages\"\r\n // so that both entry-file requires (ctx = package root) and nested\r\n // requires from deeper directories within the same package work.\r\n const ctxParts = contextDir.split('/');\r\n for (let i = ctxParts.length; i >= 1; i--) {\r\n const prefix = ctxParts.slice(0, i).join('/');\r\n const packageLocalId = prefix + '/' + resolvedId;\r\n if (moduleFactories.has(packageLocalId) || moduleCache.has(packageLocalId)) {\r\n resolvedId = packageLocalId;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // Step 4: Check cache\r\n if (moduleCache.has(resolvedId)) {\r\n __traceDepth--;\r\n __trace('REQ-HIT', { resolved: resolvedId, src: 'cache' });\r\n return moduleCache.get(resolvedId)!.exports;\r\n }\r\n\r\n // Step 5: Find factory \u2014 if not in registry, try loading from network\r\n let factory = moduleFactories.get(resolvedId);\r\n const hadFactory = !!factory;\r\n if (!factory) {\r\n // Try loading the file from the static server via synchronous XHR.\r\n // This emulates WeChat's require() which loads files from the wxapkg filesystem.\r\n // In our srcdoc iframe environment, files are served by the local static server.\r\n factory = tryLoadModuleFromNetwork(resolvedId, contextDir);\r\n }\r\n if (!factory) {\r\n __traceDepth--;\r\n __trace('REQ-HIT', { resolved: resolvedId, src: 'miss' });\r\n nativeConsole.warn(\r\n `[wx-compat][module] Cannot find module: \"${moduleId}\" (resolved: \"${resolvedId}\", context: \"${contextDir}\")`,\r\n );\r\n // Return empty object instead of throwing \u2014 some game code uses\r\n // try/catch around require or expects graceful degradation\r\n return {};\r\n }\r\n __trace('REQ-HIT', { resolved: resolvedId, src: hadFactory ? 'factory' : 'network' });\r\n\r\n // Step 6: Create module object and cache it (before execution for circular deps)\r\n const mod: { exports: unknown } = { exports: {} };\r\n moduleCache.set(resolvedId, mod);\r\n\r\n // Step 7: Determine context directory for nested requires\r\n const newContextDir = resolvedId.includes('/')\r\n ? resolvedId.substring(0, resolvedId.lastIndexOf('/'))\r\n : '';\r\n\r\n // Step 8: Create a scoped require function for this module\r\n const scopedRequire = (id: string): unknown => {\r\n return internalRequire(id, newContextDir);\r\n };\r\n\r\n // Step 9: Execute factory\r\n const __t0 = Date.now();\r\n try {\r\n factory(scopedRequire, mod, mod.exports);\r\n } catch (e) {\r\n // Remove from cache on error so it can be retried\r\n moduleCache.delete(resolvedId);\r\n __traceDepth--;\r\n __trace('REQ\\u2190', { resolved: resolvedId, error: String(e).slice(0, 200) });\r\n nativeConsole.error(`[wx-compat][module] Error executing module \"${resolvedId}\":`, e);\r\n throw e;\r\n }\r\n\r\n __traceDepth--;\r\n const exp = mod.exports;\r\n const expKind = exp === null\r\n ? 'null'\r\n : typeof exp === 'object'\r\n ? `object(keys=${Object.keys(exp as object).length})`\r\n : typeof exp;\r\n __trace('REQ\\u2190', { resolved: resolvedId, ms: Date.now() - __t0, exports: expKind });\r\n\r\n return mod.exports;\r\n}\r\n\r\n/**\r\n * Global require function \u2014 the entry point for game code.\r\n *\r\n * This is installed as a global function so that wxapkg game.js code can call:\r\n * require(\"src/utils.js\")\r\n * require(\"./relative/path.js\")\r\n *\r\n * @param moduleId The module path to require\r\n * @returns The module's exports\r\n */\r\nexport function require(moduleId: string): unknown {\r\n // Top-level require. If a package scope is active (e.g. we're running a\r\n // subpackage entry script), route the lookup through `applyPackageScope`\r\n // so `require(\"game.js\")` inside `subpackages/foo/game.js` resolves to\r\n // the subpackage's own file rather than the main package's.\r\n //\r\n // `applyPackageScope` is idempotent for already-scoped / plugin / deep-path\r\n // ids, so calling it unconditionally is safe even for top-level main-package\r\n // requires (the stack is empty there and it becomes a no-op).\r\n const scopedId = applyPackageScope(moduleId);\r\n return internalRequire(scopedId, '');\r\n}\r\n\r\n// \u2500\u2500\u2500 Exports for plugin-compat.ts \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Get the shared module factories map.\r\n * Used by plugin-compat.ts to check/access registered modules.\r\n */\r\nexport function getModuleFactories(): Map<string, ModuleFactory> {\r\n return moduleFactories;\r\n}\r\n\r\n/**\r\n * Get the shared module cache map.\r\n * Used by plugin-compat.ts to check/access cached modules.\r\n */\r\nexport function getModuleCache(): Map<string, { exports: unknown }> {\r\n return moduleCache;\r\n}\r\n\r\n/**\r\n * Require a module with a specific context directory.\r\n * Used by plugin-compat.ts for scoped requires within plugin modules.\r\n */\r\nexport function requireWithContext(moduleId: string, contextDir: string): unknown {\r\n return internalRequire(moduleId, contextDir);\r\n}\r\n\r\n// \u2500\u2500\u2500 wx.loadSubpackage \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ninterface SubpackageLoadTask {\r\n onProgressUpdate(callback: (res: { progress: number; totalBytesWritten: number; totalBytesExpectedToWrite: number }) => void): void;\r\n}\r\n\r\n/**\r\n * Load a subpackage.\r\n *\r\n * In 'directory' mode: All files are already available via the static server.\r\n * We simply fetch the subpackage's game.js entry and execute it.\r\n *\r\n * In 'wxapkg' mode: The subpackage wxapkg needs to be downloaded from CDN,\r\n * decoded, and its files merged into the package directory.\r\n * The CDN URL is obtained via GET /api/wxapkg/:appid?version=xxx.\r\n * The server handles the download + decode + merge.\r\n */\r\nfunction loadSubpackage(options: {\r\n name: string;\r\n success?: (res: { errMsg: string }) => void;\r\n fail?: (err: { errMsg: string }) => void;\r\n complete?: (res: { errMsg: string }) => void;\r\n}): SubpackageLoadTask {\r\n const progressCallbacks: Array<(res: { progress: number; totalBytesWritten: number; totalBytesExpectedToWrite: number }) => void> = [];\r\n\r\n // Resolve the subpackage root from the game manifest's subPackages config.\r\n // In real WeChat, subpackages have a \"root\" field that specifies the actual\r\n // directory path (e.g. \"/subpackages/resources/\"), while \"name\" is just a label.\r\n // We need to map name \u2192 root to construct the correct URL.\r\n //\r\n // In wxapkg mode the manifest lives in /app-config.json; in legacy source\r\n // mode it lives in /game.json. loadGameManifest() transparently tries both.\r\n let subpackageRoot = options.name; // fallback: use name as path\r\n const manifest = loadGameManifest();\r\n if (manifest) {\r\n const subPackages = manifest.subPackages || manifest.subpackages || [];\r\n const pkg = subPackages.find(\r\n (p: { name: string; root: string }) => p.name === options.name,\r\n );\r\n if (pkg && pkg.root) {\r\n // Normalize: remove leading/trailing slashes\r\n subpackageRoot = pkg.root.replace(/^\\/+|\\/+$/g, '');\r\n }\r\n }\r\n\r\n // \u2500\u2500\u2500 Phase A: ensure the subpackage files are available \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n //\r\n // Three scenarios, tried in order:\r\n //\r\n // (1) VFS already has /<root>/game.js \u2014 files pre-staged via preloadFiles()\r\n // or already downloaded+unpacked on a previous call. Nothing to do.\r\n //\r\n // (2) Client-side wxapkg download \u2014 the host exposed a CDN resolver (RN /\r\n // wxapkg mode). We call wxapkg-loader to fetch the binary and unpack\r\n // it into /<root>/... in the VFS. Progress events reported from the\r\n // streamed download bubble up via wx.loadSubpackage({ onProgressUpdate }).\r\n //\r\n // (3) Legacy: files already served by a static HTTP server. Same behaviour\r\n // as before this refactor: we just assume loadAndExec can hit them.\r\n // Synthesise a 100% progress event so callers don't stall.\r\n const alreadyInVfs = vfsHas(`/${subpackageRoot}/game.js`);\r\n const resolver = getWxapkgResolver();\r\n const needsClientDownload = !alreadyInVfs && resolver != null;\r\n\r\n const progressFn = (progress: number, written: number, expected: number) => {\r\n progressCallbacks.forEach(cb => {\r\n try {\r\n cb({\r\n progress,\r\n totalBytesWritten: written,\r\n totalBytesExpectedToWrite: expected,\r\n });\r\n } catch { /* swallow user callback errors */ }\r\n });\r\n };\r\n\r\n const phaseA: Promise<void> = (async () => {\r\n if (alreadyInVfs) {\r\n // Fake one 100% tick for consumers that listen on onProgressUpdate.\r\n setTimeout(() => progressFn(100, 0, 0), 0);\r\n return;\r\n }\r\n if (needsClientDownload) {\r\n const result = await loadWxapkg({\r\n resolver,\r\n appid: getWxapkgAppid(),\r\n path: subpackageRoot,\r\n mountRoot: subpackageRoot,\r\n useProxy: getWxapkgUseProxy(),\r\n onProgress: progressFn,\r\n label: `subpkg:${options.name}`,\r\n });\r\n if (!result) {\r\n throw new Error(`failed to download/unpack subpackage \"${options.name}\"`);\r\n }\r\n return;\r\n }\r\n // Legacy HTTP mode.\r\n setTimeout(() => progressFn(100, 1024, 1024), 0);\r\n })();\r\n\r\n // \u2500\u2500\u2500 Phase B: fetch-and-exec subpackage/<root>/game.js \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n //\r\n // `__wxLoadAndExec` has a VFS fast path of its own: when the unpacked\r\n // files are present in the VFS, resolveGameUrl returns a `wxvfs:` url\r\n // and the sandbox executes from memory without touching the network.\r\n // When the static-server fallback is active, it behaves exactly as\r\n // before.\r\n //\r\n // IMPORTANT: do NOT call resolveGameUrl() *before* phaseA. When wxapkg\r\n // client-side unpack is in play, the subpackage files land in the VFS\r\n // only after phaseA resolves. If we resolved the URL eagerly here, the\r\n // VFS would still be empty \u2192 resolveGameUrl() would return the remote\r\n // asset-base URL, and loadAndExec's own VFS fast path would be bypassed\r\n // (because its early-return treats any absolute http(s) URL as \"already\r\n // resolved, no VFS check\"). The result: a spurious HTTP fetch to the\r\n // preview origin's catch-all, returning the SPA index.html and crashing\r\n // the sandbox with `Unexpected token '<'`.\r\n //\r\n // Passing the relative path lets loadAndExec do the resolution at the\r\n // correct moment \u2014 after phaseA has populated the VFS.\r\n const subpackageEntryUrl = `/${subpackageRoot}/game.js`;\r\n const loadAndExec = (window as unknown as Record<string, unknown>).__wxLoadAndExec as\r\n ((\r\n url: string,\r\n sourceURL?: string,\r\n execHooks?: { beforeExec?: () => void; afterExec?: () => void },\r\n ) => Promise<void>) | undefined;\r\n\r\n if (!loadAndExec) {\r\n const errMsg = `loadSubpackage:fail __wxLoadAndExec not available`;\r\n nativeConsole.error(`[wx-compat] ${errMsg}`);\r\n const errRes = { errMsg };\r\n options.fail?.(errRes);\r\n options.complete?.(errRes);\r\n return { onProgressUpdate(cb) { progressCallbacks.push(cb); } };\r\n }\r\n\r\n phaseA\r\n .then(() =>\r\n loadAndExec(subpackageEntryUrl, `${options.name}/game.js`, {\r\n beforeExec: () => pushPackageScope(subpackageRoot),\r\n afterExec: () => popPackageScope(),\r\n })\r\n )\r\n .then(() => {\r\n nativeConsole.log(`[wx-compat] loadSubpackage: \"${options.name}\" loaded successfully.`);\r\n const okRes = { errMsg: 'loadSubpackage:ok' };\r\n options.success?.(okRes);\r\n options.complete?.(okRes);\r\n })\r\n .catch(err => {\r\n const errMsg = `loadSubpackage:fail \"${options.name}\": ${err}`;\r\n nativeConsole.error(`[wx-compat] ${errMsg}`);\r\n const errRes = { errMsg };\r\n options.fail?.(errRes);\r\n options.complete?.(errRes);\r\n });\r\n\r\n return {\r\n onProgressUpdate(callback) {\r\n progressCallbacks.push(callback);\r\n },\r\n };\r\n}\r\n\r\nexport { loadSubpackage };\r\n\r\n// \u2500\u2500\u2500 Module URL Resolution \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Resolve a module ID to a URL path on the static server.\r\n *\r\n * For regular game files (e.g. \"src/utils.js\" \u2192 \"/src/utils.js\").\r\n * __plugin__/ paths are NOT resolved here \u2014 plugin/engine modules are loaded\r\n * via wxapkg unpack in plugin-compat.ts and registered via define().\r\n */\r\nfunction resolveModuleUrl(resolvedId: string): string {\r\n // Defensively strip any leading slashes before building the URL path.\r\n // `internalRequire` already normalizes this, but this helper is also\r\n // called from `tryLoadModuleFromNetwork` with `resolvedId + '.js'` /\r\n // `'/index.js'` suffixes, and callers outside the hot path may hand us\r\n // already-slashed strings. We always want exactly one leading slash in\r\n // the URL path so the static server sees a well-formed path.\r\n const clean = resolvedId.replace(/^\\/+/, '');\r\n return resolveGameUrl('/' + clean);\r\n}\r\n\r\n// \u2500\u2500\u2500 Network Module Loading \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Set of module IDs that we've already attempted to load from network (to avoid infinite loops) */\r\nconst networkLoadAttempted = new Set<string>();\r\n\r\n/**\r\n * Map of \"local plugins\": provider \u2192 { localPath, main }.\r\n *\r\n * When game.json (directory mode) or app-config.json (wxapkg mode) has\r\n * `gamePlugins[alias].path`, the plugin code lives locally:\r\n * - directory mode: as static files under `${assetBaseUrl}/${localPath}/`\r\n * - wxapkg mode: bundled inside the main wxapkg and mounted at\r\n * `/${localPath}/...` in the VFS (i.e. a \"self-contained\" plugin \u2014\r\n * there is NO separate wxapkg to fetch from CDN).\r\n *\r\n * In both cases `__plugin__/<provider>/<rest>` is rewritten to\r\n * `${localPath}/${rest}` and fetched through the normal module pipeline\r\n * (which transparently picks VFS bytes or HTTP based on `resolveGameUrl`).\r\n *\r\n * `main` comes from the plugin's `plugin.json` and tells us which file\r\n * serves as the plugin's \"main entry\" \u2014 required to satisfy\r\n * `require(\"__plugin__/<provider>\")` (empty rest).\r\n *\r\n * Populated by plugin-compat.ts during preloadPlugins().\r\n */\r\ninterface LocalPluginEntry {\r\n localPath: string;\r\n main?: string;\r\n}\r\nconst localPluginMap = new Map<string, LocalPluginEntry>();\r\n\r\n/**\r\n * Register a local plugin mapping: provider \u2192 localPath (+ optional main).\r\n * Called by plugin-compat.ts when a plugin in game.json has `path` and\r\n * local files are confirmed to exist.\r\n */\r\nexport function setLocalPlugin(provider: string, localPath: string, main?: string): void {\r\n // Normalize: strip leading/trailing slashes\r\n const normalizedPath = localPath.replace(/^\\/+|\\/+$/g, '');\r\n const normalizedMain = typeof main === 'string' && main ? main.replace(/^\\/+/, '') : undefined;\r\n localPluginMap.set(provider, { localPath: normalizedPath, main: normalizedMain });\r\n nativeConsole.log(\r\n `[wx-compat][module] Registered local plugin: provider=${provider} \u2192 path=\"${normalizedPath}\"` +\r\n (normalizedMain ? ` main=\"${normalizedMain}\"` : ''),\r\n );\r\n}\r\n\r\n/**\r\n * Check whether a provider has been registered as a local plugin.\r\n */\r\nexport function isLocalPluginProvider(provider: string): boolean {\r\n return localPluginMap.has(provider);\r\n}\r\n\r\n/**\r\n * Get the local path for a plugin provider (or undefined if not local).\r\n */\r\nexport function getLocalPluginPath(provider: string): string | undefined {\r\n return localPluginMap.get(provider)?.localPath;\r\n}\r\n\r\n/**\r\n * Try to load a module from the static server via synchronous XHR.\r\n *\r\n * This emulates WeChat's native require() behavior:\r\n * - WeChat's require(\"./web-adapter\") loads web-adapter.js from the wxapkg filesystem\r\n * - Our require(\"./web-adapter\") loads web-adapter.js from the static server via XHR\r\n *\r\n * The loaded file is executed inside the sandbox (via __wxSandboxExec).\r\n * After execution, we check if the module was registered via define() and return its factory.\r\n *\r\n * For files that are NOT wrapped in define() (e.g. web-adapter.js, first-screen.js),\r\n * we wrap them in a synthetic CommonJS module so they can be required normally.\r\n *\r\n * CommonJS-compatible resolution order:\r\n * 1. Exact path (resolvedId)\r\n * 2. resolvedId + \".js\"\r\n * 3. resolvedId + \"/index.js\" (directory with index)\r\n *\r\n * For __plugin__/ paths, the provider prefix is mapped to the actual file directory\r\n * on the static server (e.g. __plugin__/wx.../xxx.js \u2192 /cocos-js/xxx.js).\r\n *\r\n * @param resolvedId The resolved module ID\r\n * @param _contextDir The context directory (unused, kept for signature compatibility)\r\n * @returns The module factory if loading succeeded, or undefined if failed\r\n */\r\nfunction tryLoadModuleFromNetwork(\r\n resolvedId: string,\r\n _contextDir: string,\r\n): ModuleFactory | undefined {\r\n // Prevent infinite loops: if we already tried loading this module, don't try again\r\n if (networkLoadAttempted.has(resolvedId)) {\r\n return undefined;\r\n }\r\n networkLoadAttempted.add(resolvedId);\r\n\r\n // For __plugin__/<provider>/<rest>:\r\n // - If the provider is registered as a LOCAL plugin (game.json plugins[alias].path),\r\n // rewrite to `${localPath}/${rest}` and fetch from the static server.\r\n // This matches games whose import-map maps `../cocos-js/xxx.js` to\r\n // `plugin:cocos/xxx.js` even though the code physically lives in a\r\n // local directory (e.g. `cocos/`) rather than a remote wxapkg.\r\n // - Otherwise fall through: the module is expected to have been registered\r\n // by the preloaded wxapkg plugin.js via define(). If it isn't, skip\r\n // network loading to avoid 404 spam.\r\n if (resolvedId.startsWith('__plugin__/')) {\r\n // Strip the \"__plugin__/\" prefix \u2192 \"<provider>/<rest>\" or just \"<provider>\"\r\n const afterPrefix = resolvedId.substring('__plugin__/'.length);\r\n const firstSlash = afterPrefix.indexOf('/');\r\n const rawProvider = firstSlash >= 0 ? afterPrefix.substring(0, firstSlash) : afterPrefix;\r\n const rest = firstSlash >= 0 ? afterPrefix.substring(firstSlash + 1) : '';\r\n\r\n // The module loader may tack on \".js\" when the original require target\r\n // didn't carry an extension (e.g. `require(\"__plugin__/<provider>\")` gets\r\n // retried as `__plugin__/<provider>.js`). When there is no sub-path the\r\n // \".js\" ends up glued onto the provider itself \u2014 strip it before\r\n // consulting localPluginMap so the lookup still succeeds.\r\n const provider = !rest && rawProvider.endsWith('.js')\r\n ? rawProvider.substring(0, rawProvider.length - 3)\r\n : rawProvider;\r\n\r\n const entry = localPluginMap.get(provider);\r\n if (entry) {\r\n // Resolve the rewrite target:\r\n // - sub-path require \u2192 \"${localPath}/${rest}\"\r\n // - main-entry require (no rest) \u2192 \"${localPath}/${main}\", with \"plugin.js\"\r\n // as a last-resort fallback when plugin.json didn't declare a main.\r\n const effectiveRest = rest || entry.main || 'plugin.js';\r\n const rewrittenId = `${entry.localPath}/${effectiveRest}`;\r\n const factory = tryLoadModuleFromNetwork(rewrittenId, _contextDir);\r\n if (factory) {\r\n // Cache under the ORIGINAL id that the game requested, so subsequent\r\n // lookups via either name hit the factory directly.\r\n moduleFactories.set(resolvedId, factory);\r\n }\r\n return factory;\r\n }\r\n\r\n // Not a local plugin \u2192 fall back to \"skip\" (expected to be preregistered\r\n // by a remote wxapkg plugin.js via define()).\r\n nativeConsole.warn(\r\n `[wx-compat][module] Skipping network load for plugin path \"${resolvedId}\" ` +\r\n `(no local plugin path registered for provider \"${provider}\"; expected to be preregistered by plugin.js via define())`,\r\n );\r\n return undefined;\r\n }\r\n\r\n // Skip binary/data files \u2014 they are handled by other mechanisms\r\n if (resolvedId.endsWith('.wasm') || resolvedId.endsWith('.bin')) {\r\n return undefined;\r\n }\r\n\r\n // Handle .json files: load and parse as JSON module\r\n if (resolvedId.endsWith('.json')) {\r\n return tryLoadJsonModule(resolvedId);\r\n }\r\n\r\n // Build candidate URLs following CommonJS resolution order:\r\n // 1. Exact path\r\n // 2. path + \".js\" (if no extension)\r\n // 3. path + \"/index.js\" (directory with index)\r\n const primaryUrl = resolveModuleUrl(resolvedId);\r\n const candidateUrls: Array<{ url: string; label: string }> = [\r\n { url: primaryUrl, label: resolvedId },\r\n ];\r\n\r\n // If the ID doesn't end with a known extension, try .js and /index.js\r\n if (!resolvedId.match(/\\.(?:js|mjs|cjs)$/)) {\r\n candidateUrls.push(\r\n { url: resolveModuleUrl(resolvedId + '.js'), label: resolvedId + '.js' },\r\n { url: resolveModuleUrl(resolvedId + '/index.js'), label: resolvedId + '/index.js' },\r\n );\r\n } else {\r\n // Even with .js extension, try /index.js as fallback (directory named like a file)\r\n candidateUrls.push(\r\n { url: resolveModuleUrl(resolvedId.replace(/\\.js$/, '/index.js')), label: resolvedId.replace(/\\.js$/, '/index.js') },\r\n );\r\n }\r\n\r\n const sandboxExec = (window as unknown as Record<string, unknown>).__wxSandboxExec as\r\n ((\r\n code: string,\r\n sourceURL?: string,\r\n moduleContext?: {\r\n module: { exports: unknown };\r\n exports: unknown;\r\n require: (id: string) => unknown;\r\n },\r\n ) => void) | undefined;\r\n\r\n if (!sandboxExec) {\r\n nativeConsole.warn('[wx-compat][module] sandboxExec not available for network module loading');\r\n return undefined;\r\n }\r\n\r\n // Try each candidate URL\r\n for (const candidate of candidateUrls) {\r\n try {\r\n const xhr = new NativeXMLHttpRequest();\r\n xhr.open('GET', candidate.url, false); // synchronous\r\n xhr.send();\r\n\r\n if (xhr.status !== 200) {\r\n continue; // Try next candidate\r\n }\r\n\r\n const code = xhr.responseText;\r\n\r\n // \u2500\u2500 File-existence check: don't trust HTTP 200 alone \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n //\r\n // On a real WeChat device, require() queries a closed wxapkg file\r\n // table: the file either exists (and is JS) or it doesn't, period.\r\n // In preview we delegate that question to whatever served the bytes:\r\n //\r\n // \u2022 VFS (wxapkg mode) \u2014 `has()` is authoritative; resolveGameUrl\r\n // returns a `wxvfs:` url that the XHR shim 404s correctly on miss.\r\n //\r\n // \u2022 static server (directory mode) \u2014 many dev servers implement\r\n // SPA-style fallback: unknown paths return HTTP 200 + index.html.\r\n // Loading `/crypto.js` on such a server doesn't mean \"crypto.js\r\n // exists\"; it means \"the server didn't know and handed back the\r\n // app shell\". That's the preview equivalent of \"file not in\r\n // wxapkg table\" \u2014 semantically it must behave like a 404.\r\n //\r\n // Identifying an HTML fallback response is a hard, cheap signal: a\r\n // valid JS module never starts with '<'. wxapkg-packed JS is always\r\n // already-compiled (no JSX), and the leading whitespace / BOM /\r\n // `\"use strict\"` / `/* */ comment / `;` / identifier char cases\r\n // all have first non-whitespace characters that are NOT '<'. So a\r\n // response whose first non-whitespace byte is '<' is unambiguously\r\n // HTML (or XML / SVG, which are equally not-a-JS-module).\r\n //\r\n // When we detect this shape we skip the candidate silently \u2014 the\r\n // outer loop will try the next candidate (e.g. `<id>/index.js`),\r\n // and if none of them are real JS the function returns `undefined`\r\n // and internalRequire's miss path (returning `{}` + one warn line)\r\n // takes over. This is the same graceful-degradation semantics that\r\n // require('crypto') relies on in libraries like seedrandom.\r\n const firstNonWs = code.search(/\\S/);\r\n if (firstNonWs >= 0 && code.charCodeAt(firstNonWs) === 0x3c /* '<' */) {\r\n continue;\r\n }\r\n\r\n nativeConsole.log(\r\n `[wx-compat][module] Loading module from network: ${resolvedId} \u2192 ${candidate.url}`,\r\n );\r\n\r\n // Record the number of modules before execution\r\n const sizeBeforeExec = moduleFactories.size;\r\n\r\n // \u2500\u2500 Build a CommonJS module context for this file \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Each required file gets its own `module`, `exports`, and contextual\r\n // `require` so code like `module.exports = X` / `exports.foo = X` /\r\n // `require('./sibling')` works exactly as on Node.js and WeChat's\r\n // real device. sandboxExec injects these as function parameters and\r\n // the sandbox Proxy's `has` trap excludes them so `with(sandbox)`\r\n // doesn't intercept them.\r\n const contextDir = resolvedId.includes('/')\r\n ? resolvedId.substring(0, resolvedId.lastIndexOf('/'))\r\n : '';\r\n const mod: { exports: unknown } = { exports: {} };\r\n const ctxRequire = (id: string): unknown => {\r\n // Delegate to internalRequire with the current file's directory\r\n // as the context so relative paths resolve against THIS file.\r\n return internalRequire(id, contextDir);\r\n };\r\n\r\n // Execute the code in the sandbox.\r\n // The file may:\r\n // a) Call define(resolvedId, factory) \u2014 registering itself in moduleFactories\r\n // b) Be a plain CommonJS script that writes to module.exports / exports\r\n // (e.g. web-adapter.js, first-screen.js, Babel-compiled files)\r\n // c) Call System.register() for SystemJS modules\r\n sandboxExec(code, candidate.label, {\r\n module: mod,\r\n exports: mod.exports,\r\n require: ctxRequire,\r\n });\r\n\r\n // Check if the module was registered via define() during execution\r\n if (moduleFactories.has(resolvedId)) {\r\n return moduleFactories.get(resolvedId);\r\n }\r\n\r\n // If new modules were registered but not with the exact resolvedId,\r\n // the file might have registered under a different name.\r\n if (moduleFactories.size > sizeBeforeExec) {\r\n if (moduleFactories.has(resolvedId)) {\r\n return moduleFactories.get(resolvedId);\r\n }\r\n }\r\n\r\n // The file didn't call define() \u2014 it's either a plain CommonJS script\r\n // or a System.register file. For CommonJS scripts, `mod.exports` now\r\n // holds whatever the file assigned (e.g. `module.exports = { ... }`\r\n // or `exports.foo = ...`). For System.register files, SystemJS's\r\n // U() wrapper will call getRegister() to pick up the registration \u2014\r\n // the mod.exports stays as the initial `{}` but that's fine because\r\n // SystemJS tracks its own module graph.\r\n nativeConsole.log(\r\n `[wx-compat][module] Module \"${resolvedId}\" loaded as plain/SystemJS script from ${candidate.url} ` +\r\n `(exports keys=${typeof mod.exports === 'object' && mod.exports !== null ? Object.keys(mod.exports as object).length : 'n/a'})`,\r\n );\r\n const capturedExports = mod.exports;\r\n const plainFactory: ModuleFactory = (_req, outMod, _exp) => {\r\n // The file's side-effects (including module.exports assignment) have\r\n // already run during sandboxExec above. We just propagate the captured\r\n // exports to the outer internalRequire() caller, which will cache it.\r\n outMod.exports = capturedExports;\r\n };\r\n moduleFactories.set(resolvedId, plainFactory);\r\n return plainFactory;\r\n\r\n } catch (e) {\r\n nativeConsole.error(\r\n `[wx-compat][module] Error loading module from network: ${candidate.url}`,\r\n e,\r\n );\r\n }\r\n }\r\n\r\n // All candidates failed\r\n nativeConsole.warn(\r\n `[wx-compat][module] Failed to load module from network: ${resolvedId} (all candidates exhausted)`,\r\n );\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Load a .json file as a CommonJS module.\r\n */\r\nfunction tryLoadJsonModule(resolvedId: string): ModuleFactory | undefined {\r\n const url = resolveModuleUrl(resolvedId);\r\n try {\r\n const xhr = new NativeXMLHttpRequest();\r\n xhr.open('GET', url, false);\r\n xhr.send();\r\n if (xhr.status === 200) {\r\n const jsonData = JSON.parse(xhr.responseText);\r\n const factory: ModuleFactory = (_req, mod, _exp) => {\r\n mod.exports = jsonData;\r\n };\r\n moduleFactories.set(resolvedId, factory);\r\n return factory;\r\n }\r\n } catch (e) {\r\n nativeConsole.error(`[wx-compat][module] Error loading JSON module: ${url}`, e);\r\n }\r\n return undefined;\r\n}\r\n", "/**\r\n * WeixinJSBridge compatibility shell.\r\n *\r\n * In the real WeChat runtime, all wx.* API calls are routed through\r\n * WeixinJSBridge.invoke() \u2192 native layer. Some low-level SDKs and game\r\n * engines call WeixinJSBridge directly instead of going through wx.*.\r\n *\r\n * This module provides a lightweight shell that:\r\n * 1. Prevents \"WeixinJSBridge is not defined\" errors\r\n * 2. Routes invoke() calls to the corresponding wx.* API when available\r\n * 3. Stores event listeners (on/subscribe) for potential future use\r\n *\r\n * Reference: extensions/src/inject/jsbridge/\r\n */\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype AnyCallback = (...args: any[]) => void;\r\n\r\n/** Registered event listeners via WeixinJSBridge.on() */\r\nconst eventListeners = new Map<string, Set<AnyCallback>>();\r\n\r\n/** Registered subscriptions via WeixinJSBridge.subscribe() */\r\nconst subscriptions = new Map<string, Set<AnyCallback>>();\r\n\r\n/**\r\n * Install WeixinJSBridge on the window object.\r\n * Must be called during global shim installation (before game code runs).\r\n */\r\nexport function installJSBridge(): void {\r\n const win = window as unknown as Record<string, unknown>;\r\n\r\n // Don't overwrite if already defined (e.g. by actual WeChat runtime)\r\n if (win.WeixinJSBridge) return;\r\n\r\n win.WeixinJSBridge = {\r\n /**\r\n * Invoke a native API. In preview mode, we try to route to the\r\n * corresponding wx.* method. If the method doesn't exist, we call\r\n * back with a \"not supported\" error.\r\n */\r\n invoke(api: string, args: Record<string, unknown>, callback?: AnyCallback): void {\r\n const wx = (window as unknown as Record<string, unknown>).wx as\r\n | Record<string, unknown>\r\n | undefined;\r\n\r\n if (wx && typeof wx[api] === 'function') {\r\n // Route to the existing wx API implementation\r\n const wxFn = wx[api] as (opts: Record<string, unknown>) => void;\r\n wxFn({\r\n ...args,\r\n success: (res: unknown) => callback?.({ errMsg: `${api}:ok`, ...((res as object) || {}) }),\r\n fail: (err: unknown) => callback?.({ errMsg: `${api}:fail`, ...((err as object) || {}) }),\r\n });\r\n } else {\r\n // API not implemented \u2014 return error via callback\r\n callback?.({ errMsg: `${api}:fail not supported in preview` });\r\n }\r\n },\r\n\r\n /**\r\n * Register a handler for a system event.\r\n * In preview mode we store it but most events won't fire.\r\n */\r\n on(event: string, callback: AnyCallback): void {\r\n if (!eventListeners.has(event)) {\r\n eventListeners.set(event, new Set());\r\n }\r\n eventListeners.get(event)!.add(callback);\r\n },\r\n\r\n /**\r\n * Publish an event to the native layer.\r\n * No-op in preview mode (no native layer to receive it).\r\n */\r\n publish(event: string, _data?: unknown): void {\r\n // No-op \u2014 preview environment has no native receiver\r\n void event;\r\n },\r\n\r\n /**\r\n * Subscribe to messages from the native layer.\r\n * Stored for potential future use but won't fire in preview.\r\n */\r\n subscribe(event: string, callback: AnyCallback): void {\r\n if (!subscriptions.has(event)) {\r\n subscriptions.set(event, new Set());\r\n }\r\n subscriptions.get(event)!.add(callback);\r\n },\r\n };\r\n}\r\n", "/**\r\n * Plugin System Compatibility Layer for WeChat Mini Game\r\n *\r\n * WeChat Mini Games support a plugin system where:\r\n * 1. game.json defines plugin aliases with version and provider:\r\n * { \"plugins\": { \"cocos\": { \"version\": \"3.8.8\", \"provider\": \"wx0446ba2621dda60a\" } } }\r\n *\r\n * 2. Plugin files (plugin.js) register modules via define():\r\n * define(\"__plugin__/<provider>/<path>\", function(require, module, exports) { ... })\r\n *\r\n * 3. Game code calls requirePlugin(\"<alias>/<path>\") which:\r\n * - Looks up the alias in game.json plugins to get the provider\r\n * - Maps to \"__plugin__/<provider>/<path>\"\r\n * - Executes the registered define factory and returns module.exports\r\n *\r\n * \u2500\u2500 Loading strategy (Plan A: preload all plugins before game.js runs) \u2500\u2500\r\n *\r\n * Rationale: browsers forbid setting responseType='arraybuffer' on synchronous\r\n * XHR from a document context. Since the game's require/requirePlugin API is\r\n * synchronous (it must return the module value immediately), we cannot download\r\n * wxapkg binaries lazily inside requirePlugin. Instead we preload all plugins\r\n * declared in game.json before game.js starts executing:\r\n *\r\n * [async preload phase \u2014 before game.js executes]\r\n * for each plugin in game.json.plugins (in parallel):\r\n * 1. GET /api/wxapkg/<provider>?version=<version> \u2192 { cdnUrl }\r\n * 2. GET /cdn-proxy?url=<cdnUrl> \u2192 wxapkg binary\r\n * 3. unpack(wxapkg) \u2192 find plugin.js\r\n * 4. sandboxExec(plugin.js) \u2192 registers all __plugin__/<provider>/...\r\n * modules via define()\r\n *\r\n * [synchronous runtime phase \u2014 game.js running]\r\n * requirePlugin(\"cocos/base.js\")\r\n * \u2192 alias=\"cocos\" \u2192 provider=wx0446ba2621dda60a\r\n * \u2192 look up \"__plugin__/wx0446ba2621dda60a/base.js\" in moduleFactories\r\n * \u2192 execute its factory and return module.exports\r\n * (no network IO \u2014 all modules are already registered)\r\n *\r\n * This module uses the shared module registry from module-compat.ts so that\r\n * both game modules and plugin modules share the same define/require system.\r\n */\r\n\r\nimport { nativeConsole } from './native-globals';\r\nimport { loadGameManifest } from './url-utils';\r\nimport { getText as vfsGetText, has as vfsHas } from './virtual-fs';\r\nimport {\r\n loadWxapkg,\r\n getGlobalResolver as getWxapkgResolver,\r\n getGlobalAppid as getWxapkgAppid,\r\n getGlobalUseProxy as getWxapkgUseProxy,\r\n} from './wxapkg-loader';\r\nimport {\r\n define,\r\n require as moduleRequire,\r\n getModuleFactories,\r\n requireWithContext,\r\n setLocalPlugin,\r\n isLocalPluginProvider,\r\n} from './module-compat';\r\n\r\n// \u2500\u2500\u2500 Plugin Config \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ninterface PluginInfo {\r\n version: string;\r\n provider: string;\r\n /**\r\n * Optional local path (relative to the game root). When set, the plugin's\r\n * code is bundled inside the game directory (e.g. \"cocos\"), instead of being\r\n * delivered as a remote wxapkg. We try the local path first and only fall\r\n * back to remote wxapkg if the local probe fails.\r\n */\r\n path?: string;\r\n}\r\n\r\n/** Cached plugins config (loaded once on first access) */\r\nlet pluginsConfig: Record<string, PluginInfo> | null = null;\r\nlet pluginsConfigLoaded = false;\r\n\r\n/**\r\n * Load plugins configuration (cached after first call).\r\n *\r\n * Rationale (mirrors minigame_web_host's parsePluginsFromAppConfig +\r\n * mergePluginConfigs):\r\n * - app-config.json (wxapkg-decoded form) carries plugins under\r\n * `gamePlugins`. The shape matches game.json's `plugins` 1:1 so we\r\n * accept either spelling transparently.\r\n * - Newer host pipelines also embed plugin metadata under `plugins`\r\n * keyed by alias (legacy form) \u2014 same fallback path.\r\n * - When BOTH spellings are present (rare but happens when wxapkg-loader\r\n * synthesises one and the host injects the other), we merge them with\r\n * `gamePlugins` taking precedence per-key. This preserves any host-\r\n * supplied overrides (e.g. a pinned version) while still picking up\r\n * entries the host didn't know about.\r\n * - Each merged record is sanitised: only `version`, `provider` and\r\n * optional `path` survive \u2014 extra fields the manifest may carry\r\n * (signature, sha, etc.) are dropped so they cannot accidentally\r\n * reach plugin lookup.\r\n */\r\nfunction loadPluginsConfig(): Record<string, PluginInfo> {\r\n if (pluginsConfigLoaded) {\r\n return pluginsConfig || {};\r\n }\r\n pluginsConfigLoaded = true;\r\n\r\n const manifest = loadGameManifest();\r\n if (manifest) {\r\n pluginsConfig = parsePluginsFromManifest(manifest);\r\n if (pluginsConfig && Object.keys(pluginsConfig).length > 0) {\r\n nativeConsole.log(\r\n '[wx-compat][plugin] Loaded plugins config:',\r\n Object.keys(pluginsConfig).join(', '),\r\n );\r\n }\r\n }\r\n\r\n return pluginsConfig || {};\r\n}\r\n\r\n/**\r\n * Pure helper \u2014 extract & merge the plugin table from a manifest.\r\n * Exported for tests; production callers go through loadPluginsConfig().\r\n *\r\n * @param manifest Either an app-config.json (wxapkg form) or a game.json\r\n * (raw source form) as parsed JSON.\r\n * @returns A normalised alias \u2192 PluginInfo map. Returns an empty\r\n * object when the manifest declares no plugins.\r\n */\r\nexport function parsePluginsFromManifest(\r\n manifest: Record<string, unknown>,\r\n): Record<string, PluginInfo> {\r\n const tables: Array<Record<string, unknown> | null | undefined> = [\r\n // Order matters: later entries override earlier on key collisions.\r\n manifest.plugins as Record<string, unknown> | undefined,\r\n manifest.gamePlugins as Record<string, unknown> | undefined,\r\n ];\r\n\r\n const merged: Record<string, PluginInfo> = {};\r\n for (const table of tables) {\r\n if (!table || typeof table !== 'object') continue;\r\n for (const [alias, raw] of Object.entries(table)) {\r\n const info = sanitizePluginInfo(raw);\r\n if (info) merged[alias] = info;\r\n }\r\n }\r\n return merged;\r\n}\r\n\r\n/**\r\n * Validate a single plugin entry from a manifest. Returns null when the\r\n * entry is malformed (missing version or provider), so the caller can\r\n * skip it without aborting the rest of the table.\r\n */\r\nfunction sanitizePluginInfo(raw: unknown): PluginInfo | null {\r\n if (!raw || typeof raw !== 'object') return null;\r\n const r = raw as Record<string, unknown>;\r\n const version = typeof r.version === 'string' ? r.version : '';\r\n const provider = typeof r.provider === 'string' ? r.provider : '';\r\n if (!version || !provider) return null;\r\n const path = typeof r.path === 'string' ? r.path : undefined;\r\n return path ? { version, provider, path } : { version, provider };\r\n}\r\n\r\n/**\r\n * Resolve a plugin path to the full module ID in the define registry.\r\n *\r\n * @param pluginPath Path like \"cocos/base.js\" or just \"cocos\"\r\n * The first segment is the plugin alias from game.json.\r\n * @returns The full module ID like \"__plugin__/wx0446ba2621dda60a/base.js\"\r\n * or \"__plugin__/wx0446ba2621dda60a\" for the main entry\r\n */\r\nfunction resolvePluginPath(pluginPath: string): string {\r\n const config = loadPluginsConfig();\r\n\r\n const slashIndex = pluginPath.indexOf('/');\r\n let alias: string;\r\n let rest: string;\r\n if (slashIndex >= 0) {\r\n alias = pluginPath.substring(0, slashIndex);\r\n rest = pluginPath.substring(slashIndex + 1);\r\n } else {\r\n alias = pluginPath;\r\n rest = '';\r\n }\r\n\r\n const pluginInfo = config[alias];\r\n if (!pluginInfo) {\r\n nativeConsole.warn(\r\n `[wx-compat][plugin] Plugin alias \"${alias}\" not found in game.json plugins config. ` +\r\n `Available aliases: ${Object.keys(config).join(', ') || '(none)'}`,\r\n );\r\n // Fallback: treat alias itself as provider (best effort)\r\n return rest ? `__plugin__/${alias}/${rest}` : `__plugin__/${alias}`;\r\n }\r\n\r\n const { provider } = pluginInfo;\r\n return rest ? `__plugin__/${provider}/${rest}` : `__plugin__/${provider}`;\r\n}\r\n\r\n// \u2500\u2500\u2500 Plugin wxapkg Preload (async) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Set of plugin aliases whose wxapkg has already been loaded and executed */\r\nconst loadedPluginScripts = new Set<string>();\r\n\r\n/** Set of plugin aliases that were confirmed to be served from a LOCAL path\r\n * (so no wxapkg download was needed). These are also registered in\r\n * module-compat's localPluginMap via setLocalPlugin(). */\r\nconst localPluginAliases = new Set<string>();\r\n\r\n/**\r\n * Asynchronously download, unpack and execute the plugin.js of a single\r\n * plugin wxapkg. Safe to call multiple times \u2014 it is a no-op after the\r\n * first successful load.\r\n *\r\n * Steps:\r\n * 1. GET /api/wxapkg/<provider>?version=<version> \u2192 { cdnUrl }\r\n * 2. fetch(/cdn-proxy?url=<cdnUrl>).arrayBuffer() \u2192 wxapkg binary\r\n * 3. unpack(wxapkg) \u2192 find plugin.js\r\n * 4. sandboxExec(plugin.js) \u2192 registers modules via define()\r\n */\r\nasync function loadPluginWxapkgAsync(\r\n alias: string,\r\n version: string,\r\n provider: string,\r\n): Promise<void> {\r\n if (loadedPluginScripts.has(alias)) return;\r\n\r\n const moduleFactories = getModuleFactories();\r\n const sandboxExec = (window as unknown as Record<string, unknown>).__wxSandboxExec as\r\n ((code: string, sourceURL?: string) => void) | undefined;\r\n\r\n if (!sandboxExec) {\r\n nativeConsole.error('[wx-compat][plugin] sandboxExec not available for plugin loading');\r\n return;\r\n }\r\n\r\n const mountRoot = `__plugin__/${provider}`;\r\n const pluginJsVfsPath = `/${mountRoot}/plugin.js`;\r\n\r\n // \u2500\u2500 Fast path: plugin.js already mounted in VFS (e.g. via preloadFiles) \u2500\u2500\r\n if (vfsHas(pluginJsVfsPath)) {\r\n nativeConsole.log(`[wx-compat][plugin] Using VFS-mounted plugin.js for ${alias}`);\r\n const code = vfsGetText(pluginJsVfsPath);\r\n if (code) {\r\n const sizeBefore = moduleFactories.size;\r\n try {\r\n sandboxExec(code, `plugin://${alias}/${version}/plugin.js`);\r\n loadedPluginScripts.add(alias);\r\n nativeConsole.log(\r\n `[wx-compat][plugin] Plugin script loaded from VFS: ${alias} v${version} ` +\r\n `(${moduleFactories.size - sizeBefore} new modules registered)`,\r\n );\r\n } catch (e) {\r\n nativeConsole.error(`[wx-compat][plugin] Error executing VFS plugin.js for ${alias}:`, e);\r\n }\r\n }\r\n return;\r\n }\r\n\r\n // \u2500\u2500 Normal path: resolve CDN + download + unpack via wxapkg-loader \u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Plugins use the provider id as the resolver `path` segment. For legacy\r\n // deployments (no resolver.baseAPI configured on window) wxapkg-loader\r\n // falls back to `/api/wxapkg/<provider>?version=<version>` automatically.\r\n nativeConsole.log(\r\n `[wx-compat][plugin] Fetching wxapkg for ${alias} v${version} (provider: ${provider})...`,\r\n );\r\n\r\n const result = await loadWxapkg({\r\n resolver: getWxapkgResolver(),\r\n appid: getWxapkgAppid(),\r\n path: provider,\r\n version,\r\n mountRoot,\r\n useProxy: getWxapkgUseProxy(),\r\n label: `plugin:${alias}`,\r\n });\r\n\r\n if (!result) {\r\n nativeConsole.error(\r\n `[wx-compat][plugin] Failed to load wxapkg for \"${alias}\" v${version} (provider: ${provider}).`,\r\n );\r\n return;\r\n }\r\n\r\n const code = vfsGetText(pluginJsVfsPath);\r\n if (!code) {\r\n nativeConsole.error(\r\n `[wx-compat][plugin] plugin.js not found after unpack for ${alias}. ` +\r\n `Mounted paths: ${result.mountedPaths.join(', ')}`,\r\n );\r\n return;\r\n }\r\n\r\n const sizeBefore = moduleFactories.size;\r\n try {\r\n const sourceURL = `plugin://${alias}/${version}/plugin.js`;\r\n sandboxExec(code, sourceURL);\r\n loadedPluginScripts.add(alias);\r\n nativeConsole.log(\r\n `[wx-compat][plugin] Plugin script loaded: ${alias} v${version} ` +\r\n `(${moduleFactories.size} modules registered, ${moduleFactories.size - sizeBefore} new)`,\r\n );\r\n } catch (e) {\r\n nativeConsole.error(`[wx-compat][plugin] Error executing plugin.js for ${alias}:`, e);\r\n }\r\n}/**\r\n * Preload ALL plugins declared in game.json before game.js executes.\r\n *\r\n * This is the entry point of Plan A. It is exposed as window.__wxPreloadPlugins\r\n * so that the game-host iframe bootstrap can `await` it before calling\r\n * sandboxExec(gameCode).\r\n *\r\n * All plugins are downloaded in parallel for faster startup.\r\n */\r\nexport async function preloadPlugins(): Promise<void> {\r\n const config = loadPluginsConfig();\r\n const aliases = Object.keys(config);\r\n\r\n if (aliases.length === 0) {\r\n nativeConsole.log('[wx-compat][plugin] No plugins declared in game.json, skipping preload.');\r\n return;\r\n }\r\n\r\n nativeConsole.log(\r\n `[wx-compat][plugin] Preloading ${aliases.length} plugin(s): ${aliases.join(', ')}`,\r\n );\r\n\r\n // Policy: every plugin declared in gamePlugins / plugins is ALWAYS fetched\r\n // from the remote wxapkg CDN. We intentionally do NOT probe whether the\r\n // main package happened to carry a (possibly placeholder) copy of the\r\n // plugin directory \u2014 wxapkg decodes often mount only `plugin.json` +\r\n // `signature.json` while the actual code lives in a separate plugin\r\n // wxapkg on the CDN, and getting that wrong is fatal. Downloading an\r\n // extra copy is cheap; missing the real one breaks the game.\r\n //\r\n // If the plugin entry also carries a `path` hint (where the plugin\r\n // claims to sit inside the main package), we still register that path\r\n // with module-compat as a SECONDARY lookup source. `loadPluginWxapkgAsync`\r\n // will mount the authoritative copy under `__plugin__/<provider>/...`,\r\n // which stays the primary resolution \u2014 the local path is only consulted\r\n // when the remote mount doesn't cover a particular module id, which\r\n // should never happen but costs nothing to keep as a safety net.\r\n for (const alias of aliases) {\r\n const info = config[alias];\r\n const { provider, path: localPath } = info;\r\n if (localPath) {\r\n setLocalPlugin(provider, localPath, undefined);\r\n localPluginAliases.add(alias);\r\n nativeConsole.log(\r\n `[wx-compat][plugin] Registered local path hint for \"${alias}\" \u2192 \"${localPath}\" ` +\r\n `(secondary lookup; remote wxapkg is still authoritative).`,\r\n );\r\n }\r\n }\r\n\r\n // Download every declared plugin's wxapkg in parallel. One failure must\r\n // not block others \u2014 errors are caught and logged inside the helper.\r\n await Promise.all(\r\n aliases.map((alias) => {\r\n const { version, provider } = config[alias];\r\n return loadPluginWxapkgAsync(alias, version, provider);\r\n }),\r\n );\r\n\r\n nativeConsole.log(\r\n `[wx-compat][plugin] Preload complete. Loaded aliases: ` +\r\n `${Array.from(loadedPluginScripts).join(', ') || '(none)'}`,\r\n );\r\n}\r\n\r\n// \u2500\u2500\u2500 requirePlugin() \u2014 purely synchronous module lookup \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Options for requirePlugin (used by Unity and other engines) */\r\ninterface RequirePluginOptions {\r\n /** When true, the plugin can require modules from the host game */\r\n enableRequireHostModule?: boolean;\r\n /** Custom environment variables injected into the plugin's isolated context */\r\n customEnv?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * requirePlugin \u2014 the global function that game code calls to load plugin modules.\r\n *\r\n * This is a PURELY SYNCHRONOUS module lookup. All plugin wxapkgs must have\r\n * been preloaded via preloadPlugins() BEFORE game.js starts running, so\r\n * every __plugin__/<provider>/... module is already registered in\r\n * moduleFactories by the time game.js calls requirePlugin.\r\n *\r\n * Usage in game.js:\r\n * requirePlugin(\"cocos/base.js\") \u2192 __plugin__/wx0446ba2621dda60a/base.js\r\n * requirePlugin(\"cocos\") \u2192 __plugin__/wx0446ba2621dda60a (main entry)\r\n * requirePlugin(\"UnityPlugin\", { customEnv: { wx, canvas, ... } })\r\n *\r\n * @param pluginPath Plugin path in the format \"<alias>/<module-path>\"\r\n * @param options Optional configuration (customEnv, enableRequireHostModule, etc.)\r\n * @returns The module exports\r\n */\r\nexport function requirePlugin(pluginPath: string, options?: RequirePluginOptions): unknown {\r\n const config = loadPluginsConfig();\r\n\r\n // Extract alias to look up plugin info for pluginEnv setup\r\n const slashIndex = pluginPath.indexOf('/');\r\n const alias = slashIndex >= 0 ? pluginPath.substring(0, slashIndex) : pluginPath;\r\n const pluginInfo = config[alias];\r\n\r\n if (pluginInfo) {\r\n // Set up pluginEnv global for plugins that need it (e.g. Unity).\r\n // Only needs to be done once per requirePlugin call chain.\r\n if (options?.customEnv) {\r\n setupPluginEnv(options.customEnv, pluginInfo.provider);\r\n }\r\n\r\n // Warn (but don't fail) if this plugin hasn't been preloaded yet \u2014\r\n // this indicates a bug in the preload orchestration.\r\n // Local plugins bypass this check (they don't need preload; module-compat\r\n // will fetch the files lazily via HTTP when require is called).\r\n if (!loadedPluginScripts.has(alias) && !isLocalPluginProvider(pluginInfo.provider)) {\r\n nativeConsole.warn(\r\n `[wx-compat][plugin] requirePlugin(\"${pluginPath}\") called before plugin \"${alias}\" ` +\r\n `was preloaded. The require will likely fail. ` +\r\n `Make sure preloadPlugins() completes before game.js executes.`,\r\n );\r\n }\r\n }\r\n\r\n const fullModuleId = resolvePluginPath(pluginPath);\r\n const contextDir = fullModuleId.includes('/')\r\n ? fullModuleId.substring(0, fullModuleId.lastIndexOf('/'))\r\n : '';\r\n\r\n // Synchronous module lookup \u2014 expects the factory to already be registered.\r\n return requireWithContext(fullModuleId, contextDir);\r\n}\r\n\r\n/**\r\n * Private-data store used by the `coverview` stub's `getPrivateThis` /\r\n * `removePrivateThis` APIs. We map each host object (`this`) to a private\r\n * bag, matching WeChat's documented semantics where each CoverView Component\r\n * instance can stash \"private\" fields via `getPrivateThis(this)`.\r\n */\r\nconst coverviewPrivateStore: WeakMap<object, Record<string, unknown>> = new WeakMap();\r\n\r\n/**\r\n * Stub for `pluginEnv.coverview.webviewLayout` \u2014 the \"WebView layer manager\"\r\n * that cover-view backed UIs (Unity loading page, crash dialog, feedback\r\n * panels) use to add / remove / update HTML overlays on top of the canvas.\r\n *\r\n * On real WeChat it's an object (not a function) whose methods all return\r\n * Promises. The Unity plugin's `showAbort()` (triggered by `GameGlobal.onCrash`)\r\n * calls `webviewLayout.add(...)` expecting a Promise; if `add` is missing,\r\n * the resulting `TypeError: P.add is not a function` masks whatever crash\r\n * originally called `onCrash`.\r\n *\r\n * In the browser preview we have no WebView layer, so every method is a\r\n * no-op that resolves immediately. This keeps the shape compatible with\r\n * real-device code without pretending to actually render anything.\r\n *\r\n * We also emit a one-time warn when `add` is called, because in practice\r\n * it means the game has already crashed and the Unity plugin is trying to\r\n * display its abort UI \u2014 callers should look *above* this warning in the\r\n * console for the real crash.\r\n */\r\nfunction createWebviewLayoutStub(): Record<string, unknown> {\r\n let addWarnedOnce = false;\r\n const resolveUndef = (): Promise<undefined> => Promise.resolve(undefined);\r\n return {\r\n add(..._args: unknown[]): Promise<undefined> {\r\n if (!addWarnedOnce) {\r\n addWarnedOnce = true;\r\n nativeConsole.warn(\r\n '[wx-compat][plugin] coverview.webviewLayout.add() was called. ' +\r\n 'This usually means the game triggered onCrash/showAbort. ' +\r\n 'Look ABOVE this line for the real crash cause \u2014 the browser preview ' +\r\n 'has no WebView layer so the abort UI cannot actually be rendered.',\r\n );\r\n }\r\n return resolveUndef();\r\n },\r\n remove: (..._args: unknown[]): Promise<undefined> => resolveUndef(),\r\n show: (..._args: unknown[]): Promise<undefined> => resolveUndef(),\r\n hide: (..._args: unknown[]): Promise<undefined> => resolveUndef(),\r\n clear: (..._args: unknown[]): Promise<undefined> => resolveUndef(),\r\n update: (..._args: unknown[]): Promise<undefined> => resolveUndef(),\r\n resize: (..._args: unknown[]): Promise<undefined> => resolveUndef(),\r\n relaunch: (..._args: unknown[]): Promise<undefined> => resolveUndef(),\r\n destroy: (..._args: unknown[]): Promise<undefined> => resolveUndef(),\r\n query: (..._args: unknown[]): Promise<null> => Promise.resolve(null),\r\n };\r\n}\r\n\r\n/**\r\n * Minimal stub for the `coverview` API surface that isolated-context plugins\r\n * (notably the Unity plugin `wxe5a48f1ed5f544b7`) require from `pluginEnv`.\r\n *\r\n * On real WeChat, `pluginEnv.coverview` exposes a handful of internal helpers\r\n * (`Component`, `getPrivateThis`, `removePrivateThis`, `create`, `init`,\r\n * `webviewLayout`, `xmlParser`) used by cover-view backed UIs such as the\r\n * Unity loading page. In the browser preview we neither render a cover-view\r\n * nor parse its XML, so each entry is stubbed just well enough that plugin\r\n * initialization (constructor of `class extends Component`) completes without\r\n * throwing.\r\n *\r\n * Note on shapes: `Component` is a class, `getPrivateThis / removePrivateThis\r\n * / create / init / xmlParser` are methods (callable), and `webviewLayout`\r\n * is an OBJECT (a manager with `add/remove/show/hide/...` methods). Mixing\r\n * these up on real-device semantics is what causes `TypeError: P.add is not\r\n * a function` during crash handling, so we mirror the exact shapes here.\r\n */\r\nfunction createCoverviewStub(): Record<string, unknown> {\r\n return {\r\n // Base class for plugin UI components. Unity's index.js does\r\n // `class X extends f.Component { constructor() { super(); ... } }`.\r\n Component: class {},\r\n\r\n // Returns a writable private bag bound to `self`. Unity stores fields\r\n // like `globalPrivate.xom` / `globalPrivate.style` on it.\r\n getPrivateThis(self: object): Record<string, unknown> {\r\n let priv = coverviewPrivateStore.get(self);\r\n if (priv === undefined) {\r\n priv = {};\r\n coverviewPrivateStore.set(self, priv);\r\n }\r\n return priv;\r\n },\r\n\r\n // Drop the private bag when the component is destroyed.\r\n removePrivateThis(self: object): void {\r\n coverviewPrivateStore.delete(self);\r\n },\r\n\r\n // No-op lifecycle hooks: we do not actually mount a cover-view in the\r\n // browser preview, so create/init simply succeed silently.\r\n create: (..._args: unknown[]): undefined => undefined,\r\n init: (..._args: unknown[]): undefined => undefined,\r\n\r\n // `webviewLayout` is a MANAGER OBJECT, not a function. Exposes\r\n // Promise-returning no-op methods that mirror the real-device shape.\r\n webviewLayout: createWebviewLayoutStub(),\r\n\r\n // Minimal XML parser stub. Unity's `loadXML()` destructures `{ root }`\r\n // from the return value; returning `null` here lets the plugin skip\r\n // cover-view rendering without crashing.\r\n xmlParser: (_xml: string): { root: null } => ({ root: null }),\r\n };\r\n}\r\n\r\n/**\r\n * Set up the global `pluginEnv` object that WeChat provides in plugin\r\n * isolated contexts. Unity plugins check `typeof pluginEnv !== 'undefined'`\r\n * to detect they are running as a plugin and read customEnv from it.\r\n *\r\n * Handling multiple requirePlugin() calls with different customEnv:\r\n *\r\n * On a real device each plugin runs in its own isolated V8 context and sees\r\n * its own `pluginEnv.customEnv`. We do NOT have that isolation \u2014 every plugin\r\n * shares the same browser realm, so we expose one global `pluginEnv` and\r\n * overlay customEnv contributions from every `requirePlugin(alias, {customEnv})`\r\n * call.\r\n *\r\n * Unity games (e.g. wxaofflinedata2) demonstrate why merging matters:\r\n *\r\n * 1) require(\"./MiniGameCommon\")\r\n * \u2192 requirePlugin(\"MiniGameCommon\", { customEnv: { wx } })\r\n * \u2192 pluginEnv.customEnv = { wx }\r\n *\r\n * 2) (0, a.default)().then(() => requirePlugin(\"UnityPlugin\", {\r\n * customEnv: { wx, unityNamespace, document, canvas, events, WXWASMSDK }\r\n * }))\r\n * \u2192 without merging: pluginEnv.customEnv is still { wx },\r\n * so the Unity plugin reads `J.unityNamespace` as undefined and\r\n * crashes with \"Cannot read properties of undefined (reading\r\n * 'isCacheableFile')\".\r\n *\r\n * The fix: create `pluginEnv` on the first call with the default stubs, and\r\n * on every subsequent call merge the new customEnv on top of the existing\r\n * one (last writer wins per key). This gives the Unity plugin the keys it\r\n * needs while leaving MiniGameCommon's earlier contributions intact.\r\n */\r\nfunction setupPluginEnv(customEnv: Record<string, unknown>, provider: string): void {\r\n const win = window as unknown as Record<string, unknown>;\r\n\r\n const existing = win.pluginEnv as { customEnv?: Record<string, unknown> } | null | undefined;\r\n if (existing != null) {\r\n // pluginEnv object already exists \u2014 merge new customEnv fields into it so\r\n // that every plugin's customEnv contribution is visible to later plugins.\r\n const mergedCustomEnv: Record<string, unknown> = {\r\n ...(existing.customEnv || {}),\r\n ...customEnv,\r\n };\r\n existing.customEnv = mergedCustomEnv;\r\n\r\n nativeConsole.log(\r\n `[wx-compat][plugin] pluginEnv.customEnv merged for provider ${provider}; ` +\r\n `new keys from this call: ${Object.keys(customEnv).join(', ') || '(none)'}; ` +\r\n `merged keys: ${Object.keys(mergedCustomEnv).join(', ')}`,\r\n );\r\n return;\r\n }\r\n\r\n win.pluginEnv = {\r\n customEnv: { ...customEnv },\r\n instanceId: '',\r\n setFileSpaceStatistics: (..._args: unknown[]) => { /* stub */ },\r\n getPrivateFileSystemManager: undefined,\r\n coverview: createCoverviewStub(),\r\n getWxCommonFont: undefined,\r\n reportKeyValue: (..._args: unknown[]) => { /* stub */ },\r\n gameTransfer: (..._args: unknown[]) => { /* stub */ },\r\n navigateToMiniProgramDirectly: undefined,\r\n createScreenCanvas: undefined,\r\n PIXI: undefined,\r\n TWEEN: undefined,\r\n };\r\n\r\n nativeConsole.log(\r\n `[wx-compat][plugin] pluginEnv set up for provider ${provider} with customEnv keys:`,\r\n Object.keys(customEnv).join(', '),\r\n );\r\n}\r\n\r\n// \u2500\u2500\u2500 Install \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Install the plugin system globals (define + requirePlugin + require).\r\n * Called from globals-compat.ts during initialization.\r\n *\r\n * Installs:\r\n * - define() \u2014 CommonJS module registration\r\n * - require() \u2014 CommonJS module loading\r\n * - requirePlugin() \u2014 Plugin-specific synchronous lookup\r\n * - __wxPreloadPlugins() \u2014 async preload hook for the iframe bootstrap\r\n */\r\nexport function installPluginSystem(): void {\r\n const win = window as unknown as Record<string, unknown>;\r\n\r\n win.require = moduleRequire;\r\n win.define = define;\r\n win.requirePlugin = requirePlugin;\r\n // Expose preloadPlugins for the game-host iframe bootstrap to await\r\n // before executing game.js. This is Plan A: preload everything upfront\r\n // so that requirePlugin can be a purely synchronous lookup at runtime.\r\n win.__wxPreloadPlugins = preloadPlugins;\r\n\r\n nativeConsole.log(\r\n '[wx-compat][plugin] Module system installed (define, require, requirePlugin, __wxPreloadPlugins)',\r\n );\r\n}\r\n", "/**\r\n * Global Functions Compatibility Layer for WeChat Mini Game\r\n *\r\n * Uses captured native constructors from native-globals.ts to avoid\r\n * circular calls with game adapters.\r\n */\r\n\r\nimport { preheatBrotliWasm } from './brotli-decoder';\r\nimport { getOrCreateMainCanvas } from './canvas';\r\nimport { createImage } from './image';\r\nimport { installJSBridge } from './jsbridge';\r\nimport { installPluginSystem } from './plugin-compat';\r\nimport { initModuleSystem } from './module-compat';\r\nimport { NativeXMLHttpRequest, nativeConsole, nativeFetch, wxResourceFetch } from './native-globals';\r\nimport { cdnProxyUrl } from './network';\r\nimport { resolveGameUrl } from './url-utils';\r\nimport {\r\n drainPreloadPoolFromWindow,\r\n fromVfsUrl,\r\n getDecodedArrayBuffer as vfsGetDecoded,\r\n getDecodedArrayBufferSync as vfsGetDecodedSync,\r\n getEntry as vfsGetEntry,\r\n has as vfsHas,\r\n installRuntimeHooks as installVfsRuntimeHooks,\r\n isVfsUrl,\r\n} from './virtual-fs';\r\nimport { configureFromWindow as configureWxapkgLoader } from './wxapkg-loader';\r\n\r\n// \u2500\u2500\u2500 Configuration Object \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ninterface WxConfig {\r\n platform: string;\r\n env: string;\r\n appLaunchInfo: Record<string, unknown>;\r\n ext: Record<string, unknown>;\r\n envVersion: string;\r\n [key: string]: unknown;\r\n}\r\n\r\nfunction createWxConfig(): WxConfig {\r\n return {\r\n platform: 'devtools',\r\n env: 'develop',\r\n appLaunchInfo: {\r\n scene: 1001,\r\n path: '',\r\n query: {},\r\n },\r\n ext: {},\r\n envVersion: 'develop',\r\n };\r\n}\r\n\r\n// \u2500\u2500\u2500 Global Installation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Install all global function shims required by WeChat Mini Game code.\r\n * Called from wx-compat.ts during initialization.\r\n */\r\nexport function installGlobalShims(): void {\r\n const win = window as unknown as Record<string, unknown>;\r\n\r\n // \u2500\u2500 Timers (already in browsers, but re-export for safety) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Some bundlers or environments might strip these; ensure they exist\r\n if (!win.setTimeout) { win.setTimeout = setTimeout; }\r\n if (!win.clearTimeout) { win.clearTimeout = clearTimeout; }\r\n if (!win.setInterval) { win.setInterval = setInterval; }\r\n if (!win.clearInterval) { win.clearInterval = clearInterval; }\r\n\r\n // \u2500\u2500 Base64 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n if (!win.btoa) { win.btoa = btoa; }\r\n if (!win.atob) { win.atob = atob; }\r\n\r\n // \u2500\u2500 TextEncoder / TextDecoder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n if (!win.TextEncoder) { win.TextEncoder = TextEncoder; }\r\n if (!win.TextDecoder) { win.TextDecoder = TextDecoder; }\r\n\r\n // \u2500\u2500 WeChat internal config objects \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Some game frameworks (e.g., Cocos, Laya) check for these\r\n if (!win.__wxConfig) {\r\n win.__wxConfig = createWxConfig();\r\n }\r\n\r\n // Error handler used by WeChat runtime\r\n if (!win.__errorHandler) {\r\n win.__errorHandler = (err: unknown) => {\r\n console.error('[wx-compat] __errorHandler:', err);\r\n };\r\n }\r\n\r\n // App code registry (used by WeChat framework internals)\r\n if (!win.__wxAppCode__) {\r\n win.__wxAppCode__ = {};\r\n }\r\n\r\n // Current route (used by some frameworks)\r\n if (!win.__wxRoute) {\r\n win.__wxRoute = '';\r\n }\r\n\r\n // \u2500\u2500 Global `canvas` variable \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // WeChat Mini Games have a global `canvas` variable pointing to the main canvas.\r\n // Cocos game.js uses `if (canvas) { ... canvas.width ... }` to check it.\r\n // We use getOrCreateMainCanvas() to get the main on-screen canvas singleton.\r\n // Note: wx.createCanvas() always creates NEW off-screen canvases.\r\n if (!win.canvas) {\r\n win.canvas = getOrCreateMainCanvas();\r\n }\r\n\r\n // \u2500\u2500 GameGlobal extras \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // WeChat Mini Games have a `GameGlobal` object that acts like `window`.\r\n // Already set in wx-compat.ts, but ensure additional properties exist.\r\n if (win.GameGlobal) {\r\n const gg = win.GameGlobal as Record<string, unknown>;\r\n // Cocos and other engines sometimes check for these on GameGlobal\r\n if (!gg.setTimeout) { gg.setTimeout = win.setTimeout; }\r\n if (!gg.clearTimeout) { gg.clearTimeout = win.clearTimeout; }\r\n if (!gg.setInterval) { gg.setInterval = win.setInterval; }\r\n if (!gg.clearInterval) { gg.clearInterval = win.clearInterval; }\r\n if (!gg.requestAnimationFrame) { gg.requestAnimationFrame = win.requestAnimationFrame; }\r\n if (!gg.cancelAnimationFrame) { gg.cancelAnimationFrame = win.cancelAnimationFrame; }\r\n // Ensure GameGlobal has canvas reference\r\n if (!gg.canvas) { gg.canvas = win.canvas; }\r\n // Ensure GameGlobal has document reference (web-adapter checks for this)\r\n if (!gg.document) { gg.document = document; }\r\n // NOTE: We intentionally do NOT set GameGlobal.screencanvas here.\r\n // Web-adapter checks: GameGlobal.screencanvas = GameGlobal.screencanvas || new Canvas()\r\n // If we pre-set it, web-adapter skips new Canvas() and won't wrap the canvas\r\n // with its required properties (getBoundingClientRect, style, etc.).\r\n // Instead, web-adapter's Canvas constructor calls wx.createCanvas(), which\r\n // returns our main canvas on the first call \u2014 so everything stays consistent.\r\n }\r\n\r\n // \u2500\u2500 getApp mock \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // WeChat Mini Programs (not games) use getApp(), some adapters check typeof getApp\r\n // to distinguish mini-program vs mini-game context. In mini-game mode,\r\n // getApp should not be defined. But if it is referenced, provide a safe stub.\r\n // DO NOT define it \u2014 web-adapter checks `typeof getApp` to distinguish contexts.\r\n\r\n // NOTE: We intentionally do NOT overwrite document.createElement here.\r\n // Cocos web-adapter replaces it with a version that returns custom wrapper\r\n // objects (e.g. canvas wrappers with defineProperty-based clientWidth).\r\n // Overwriting createElement back to the native version would break those\r\n // wrappers (causing \"Cannot redefine property: clientWidth\" errors).\r\n // All wx-compat modules use nativeCreateElement (from native-globals.ts)\r\n // for their internal DOM needs, so they are safe regardless.\r\n\r\n // \u2500\u2500 WeixinJSBridge \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Some SDKs and game engines call WeixinJSBridge directly.\r\n // Install a lightweight shell to prevent \"not defined\" errors.\r\n installJSBridge();\r\n\r\n // \u2500\u2500 console.group / groupEnd \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n if (!console.group) {\r\n console.group = console.log;\r\n }\r\n if (!console.groupEnd) {\r\n console.groupEnd = () => {};\r\n }\r\n\r\n // \u2500\u2500 fsUtils \u2014 File system utility used by Cocos engine plugins \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Cocos plugin.js expects a global `fsUtils` object with methods like\r\n // readJsonSync(path) and readArrayBuffer(path, callback).\r\n // In the browser preview we implement these via synchronous/async XHR.\r\n if (!win.fsUtils) {\r\n win.fsUtils = createFsUtils();\r\n }\r\n\r\n // \u2500\u2500 WXWebAssembly \u2014 WeChat WebAssembly shim \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // WeChat Mini Games provide WXWebAssembly globally. The Cocos web-adapter\r\n // does: `i.CCWebAssembly = i.WebAssembly = i.WXWebAssembly`\r\n // If WXWebAssembly is missing, WebAssembly becomes undefined and WASM\r\n // loading fails. We shim it by wrapping the browser's native WebAssembly.\r\n if (!win.WXWebAssembly) {\r\n win.WXWebAssembly = createWXWebAssembly();\r\n }\r\n\r\n // \u2500\u2500 Image factory \u2014 wx.createImage() shim \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // In the real WeChat Mini Game environment, web-adapter replaces window.Image\r\n // with a factory function: `function() { return wx.createImage() }`.\r\n // Our sandbox shadows `globalThis` \u2192 GameGlobal Proxy, whose get trap falls\r\n // back to the real window for unknown properties. So setting window.Image here\r\n // makes `globalThis.Image` (and `G.Image` in plugin code) resolve correctly\r\n // via the Proxy fallback chain: overrides \u2192 sandboxTarget \u2192 real window.\r\n win.Image = createImage;\r\n\r\n // \u2500\u2500 VFS bootstrap \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Ingest the preload pool that iframe-manager stashed on window BEFORE\r\n // wx-compat loaded, copy the resolver config into module-scope state,\r\n // and expose runtime hooks so the host page can push more files later.\r\n //\r\n // Must run before XHR/fetch patching so that the very first sync XHR\r\n // (e.g. the one module-compat uses to load game.js) can already hit\r\n // memory if the host preloaded it.\r\n drainPreloadPoolFromWindow();\r\n configureWxapkgLoader();\r\n installVfsRuntimeHooks();\r\n\r\n // \u2500\u2500 Brotli decoder warm-up \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Kick off wasm instantiation NOW so that by the time the game loads a\r\n // subpackage / plugin and starts issuing *synchronous* reads against\r\n // `.br` assets (readCompressedFileSync / sync XHR on wxvfs:), the wasm\r\n // module is ready and `decompressBrotliSync` can succeed. Fire-and-\r\n // forget: if init fails, async decode paths still have the native\r\n // `DecompressionStream('br')` fallback.\r\n preheatBrotliWasm();\r\n\r\n // \u2500\u2500 XHR base URL rewriting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // In srcdoc iframes, relative URLs (e.g. \"/game.json\", \"background.png\")\r\n // resolve to vscode-webview:// which returns 403. Patch the native\r\n // XMLHttpRequest.prototype.open to rewrite relative paths to the game\r\n // server's absolute URL. This affects ALL XHR instances (including\r\n // NativeXMLHttpRequest used by internal modules and ProxiedXMLHttpRequest).\r\n // The same patch intercepts the `wxvfs:` pseudo-scheme so synchronous\r\n // XHR can read from the in-memory VFS transparently.\r\n patchXHRBaseUrl();\r\n\r\n // \u2500\u2500 fetch base URL rewriting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Same problem as XHR, but for fetch(). Engines (e.g. Cocos meshopt,\r\n // streaming WASM loaders, Unity streaming assets) and user code may call\r\n // fetch() directly with relative URLs. Without this patch, those requests\r\n // resolve against the srcdoc iframe's null origin and return 403.\r\n patchFetchBaseUrl();\r\n\r\n // \u2500\u2500 Proxied XMLHttpRequest \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // In WeChat, XMLHttpRequest (via wx.request) has no CORS restrictions.\r\n // In browser preview, cross-origin requests to CDN servers get blocked.\r\n // We install a proxied XMLHttpRequest that automatically rewrites\r\n // cross-origin URLs to go through the server-side /cdn-proxy endpoint.\r\n // This ensures Unity plugins (which receive XMLHttpRequest via customEnv)\r\n // can load CDN assets without CORS errors.\r\n win.XMLHttpRequest = createProxiedXMLHttpRequest();\r\n\r\n // \u2500\u2500 Module System Initialization \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Initialize the module system with the current game mode (directory/wxapkg).\r\n // Must be called before installPluginSystem() so that the mode is known\r\n // when plugins are loaded.\r\n initModuleSystem();\r\n\r\n // \u2500\u2500 Plugin System (define + requirePlugin) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // WeChat Mini Games support a plugin system where game.json defines plugin\r\n // aliases and plugin.js files register modules via define(). Game code\r\n // loads plugins via requirePlugin(\"<alias>/<path>\").\r\n // Plugin scripts are loaded lazily on first requirePlugin() call.\r\n installPluginSystem();\r\n\r\n console.log('[wx-compat] Global shims installed (timers, config, canvas, GameGlobal, plugins, fsUtils, etc.).');\r\n}\r\n\r\n// \u2500\u2500\u2500 fsUtils \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Create a browser-compatible fsUtils object.\r\n *\r\n * In the real WeChat Mini Game environment, fsUtils is a global utility\r\n * provided by the runtime for file system operations. Cocos engine plugins\r\n * use it to read settings files and WASM binaries.\r\n *\r\n * Methods implemented:\r\n * - readJsonSync(path): Synchronously reads and parses a JSON file\r\n * - readArrayBuffer(path, callback): Asynchronously reads a file as ArrayBuffer\r\n */\r\nfunction createFsUtils(): Record<string, unknown> {\r\n return {\r\n /**\r\n * Synchronously read and parse a JSON file.\r\n * Returns the parsed object on success, or an Error on failure.\r\n */\r\n readJsonSync(path: string): unknown {\r\n try {\r\n const xhr = new NativeXMLHttpRequest();\r\n xhr.open('GET', path, false); // synchronous\r\n xhr.send();\r\n if (xhr.status === 200) {\r\n return JSON.parse(xhr.responseText);\r\n }\r\n return new Error(`readJsonSync failed: HTTP ${xhr.status} for ${path}`);\r\n } catch (e) {\r\n nativeConsole.error('[wx-compat][fsUtils] readJsonSync error:', path, e);\r\n return e instanceof Error ? e : new Error(String(e));\r\n }\r\n },\r\n\r\n /**\r\n * Asynchronously read a file as ArrayBuffer.\r\n * Calls callback(err, data) when complete.\r\n */\r\n readArrayBuffer(path: string, callback: (err: Error | null, data?: ArrayBuffer) => void): void {\r\n try {\r\n const xhr = new NativeXMLHttpRequest();\r\n xhr.open('GET', path, true); // asynchronous\r\n xhr.responseType = 'arraybuffer';\r\n xhr.onload = () => {\r\n if (xhr.status === 200) {\r\n callback(null, xhr.response as ArrayBuffer);\r\n } else {\r\n callback(new Error(`readArrayBuffer failed: HTTP ${xhr.status} for ${path}`));\r\n }\r\n };\r\n xhr.onerror = () => {\r\n callback(new Error(`readArrayBuffer network error for ${path}`));\r\n };\r\n xhr.send();\r\n } catch (e) {\r\n nativeConsole.error('[wx-compat][fsUtils] readArrayBuffer error:', path, e);\r\n callback(e instanceof Error ? e : new Error(String(e)));\r\n }\r\n },\r\n };\r\n}\r\n\r\n// \u2500\u2500\u2500 WXWebAssembly \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Unified \"give me the raw wasm bytes\" loader used by every WXWebAssembly\r\n * entry point. The WeChat contract for `WXWebAssembly.instantiate(path, imports)`\r\n * is that `path` is a **code package relative path** \u2014 the runtime's job is\r\n * to turn that into bytes; the caller never handles URLs. We honour that\r\n * contract rather than leaking URL-ness back into the engine.\r\n *\r\n * Lookup order (first hit wins; every step is logged so the failure mode is\r\n * obvious in the RN WebView log stream):\r\n *\r\n * 1. VFS exact \u2014 `.wasm` / `.wasm.br` that the preload pool or\r\n * wxapkg-loader already registered. Bytes are\r\n * read from memory; `.br` is transparently brotli-\r\n * decoded via getDecodedArrayBuffer().\r\n * 2. VFS `.br` fallback \u2014 many wxapkg builds ship `foo.wasm.br` while the\r\n * engine asks for `foo.wasm`. Add `.br` and retry.\r\n * 3. Remote exact \u2014 only when a baseUrl is configured (VSCode webview\r\n * dev server, or a CDN in hybrid deployments).\r\n * 4. Remote `.br` \u2014 same fallback trick, remote side.\r\n *\r\n * Every branch returns *decoded* bytes ready for `WebAssembly.instantiate`.\r\n * Callers never see compressed data, never see `wxvfs:`, never see a\r\n * `Response` \u2014 just an ArrayBuffer.\r\n *\r\n * @param path Package-relative path the engine handed us. May be bare\r\n * (`cocos-js/spine.wasm`), absolute (`/wasmcode/foo.wasm.br`), or already\r\n * `wxvfs:/...` (we accept this for robustness but strip the scheme).\r\n * @throws When every branch fails (last error is chained).\r\n */\r\nasync function readWasmBytes(path: string): Promise<ArrayBuffer> {\r\n const tag = '[wx-compat][WXWebAssembly][readWasmBytes]';\r\n\r\n // Normalise path: strip `wxvfs:` pseudo-scheme if the caller already went\r\n // through resolveGameUrl (shouldn't happen via public API, but we've seen\r\n // engines pass arbitrary strings). Keep it as a plain relative-ish path.\r\n let logical = path;\r\n if (logical.startsWith('wxvfs:')) {\r\n logical = fromVfsUrl(logical);\r\n }\r\n // WeChat paths are always package-relative; canonicalise by dropping a\r\n // leading \"/\" for remote fallbacks, and by *adding* one for VFS lookups.\r\n const withSlash = logical.startsWith('/') ? logical : '/' + logical;\r\n const noSlash = logical.startsWith('/') ? logical.substring(1) : logical;\r\n\r\n nativeConsole.log(`${tag} request path=${path} normalized=${withSlash}`);\r\n\r\n // \u2500\u2500 1. VFS exact hit \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n if (vfsHas(withSlash)) {\r\n const rawEntry = vfsGetEntry(withSlash);\r\n const rawBytes = rawEntry ? rawEntry.data.byteLength : -1;\r\n const buf = await vfsGetDecoded(withSlash);\r\n if (buf) {\r\n // When raw vs decoded size differ, a brotli decode happened under the\r\n // hood. Surface that explicitly \u2014 this is the single most useful clue\r\n // for \"byteLength != defaultSize\" style mismatches in Unity/Cocos.\r\n const note = rawBytes === buf.byteLength ? '' : ` (raw=${rawBytes} \u2192 decoded=${buf.byteLength} \u2014 brotli decompressed)`;\r\n nativeConsole.log(`${tag} source=vfs path=${withSlash} bytes=${buf.byteLength}${note}`);\r\n return buf;\r\n }\r\n // Entry exists but decode failed \u2014 fall through, but surface the reason.\r\n nativeConsole.warn(`${tag} vfs entry present but decode failed: ${withSlash} (raw=${rawBytes} bytes)`);\r\n }\r\n\r\n // \u2500\u2500 2. VFS `.br` fallback (engine asked for foo.wasm, archive ships .br) \u2500\r\n const brPath = withSlash.toLowerCase().endsWith('.br') ? null : withSlash + '.br';\r\n if (brPath && vfsHas(brPath)) {\r\n const rawBrEntry = vfsGetEntry(brPath);\r\n const rawBrBytes = rawBrEntry ? rawBrEntry.data.byteLength : -1;\r\n const buf = await vfsGetDecoded(brPath);\r\n if (buf) {\r\n nativeConsole.log(\r\n `${tag} source=vfs-br path=${brPath} raw=${rawBrBytes} \u2192 decoded=${buf.byteLength} bytes (requested ${withSlash})`,\r\n );\r\n return buf;\r\n }\r\n nativeConsole.warn(`${tag} vfs .br entry present but decode failed: ${brPath} (raw=${rawBrBytes} bytes)`);\r\n }\r\n\r\n // \u2500\u2500 3. Remote exact \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // resolveGameUrl returns an http(s) URL if baseUrl is configured; otherwise\r\n // it may return a wxvfs: url (offline mode) which we already exhausted\r\n // above, or the original string (no baseUrl + no offline flag), which we\r\n // can still try to fetch \u2014 the network layer will surface a real error.\r\n const remoteExact = resolveGameUrl(noSlash);\r\n const remoteBr = brPath ? resolveGameUrl(noSlash + '.br') : null;\r\n\r\n // Helper: fetch a remote URL, decompress if `.br`, return bytes.\r\n //\r\n // NB: dev servers under our control (static-server, web-server/game-files,\r\n // web-server/cdn-proxy) all set `Content-Encoding: br` on `.br` payloads so\r\n // the browser transparently decompresses them at the HTTP layer \u2014 by the\r\n // time `resp.arrayBuffer()` resolves we already hold the canonical\r\n // uncompressed bytes. Running our own `decompressBrotli` on top of that is\r\n // a double-decode and blows up with \"Decompression failed\" / similar \u2014\r\n // which then gets swallowed by the `catch` below, making every remote\r\n // fetch look like a silent 404 and producing the misleading\r\n // \"exhausted VFS (with .br fallback) and remote paths\" error.\r\n //\r\n // The only reliable signal we have is the WebAssembly magic (`\\0asm` /\r\n // 00 61 73 6d). If we see it, we're done. Otherwise the payload is still\r\n // a raw brotli stream (e.g. the server forgot the header, or a CDN\r\n // stripped it) and we run our own decoder as a fallback.\r\n const looksLikeWasm = (view: Uint8Array): boolean =>\r\n view.byteLength >= 4 &&\r\n view[0] === 0x00 && view[1] === 0x61 && view[2] === 0x73 && view[3] === 0x6d;\r\n\r\n const tryRemote = async (url: string, label: string): Promise<ArrayBuffer | null> => {\r\n if (!url || isVfsUrl(url)) return null; // Already tried VFS.\r\n const fetchUrl = cdnProxyUrl(url);\r\n try {\r\n nativeConsole.log(`${tag} ${label} fetching ${fetchUrl}`);\r\n const resp = await wxResourceFetch(fetchUrl);\r\n if (!resp.ok) {\r\n nativeConsole.warn(`${tag} ${label} HTTP ${resp.status} for ${fetchUrl}`);\r\n return null;\r\n }\r\n const buf = await resp.arrayBuffer();\r\n const view = new Uint8Array(buf);\r\n\r\n // Happy path: the server (or an intermediate proxy that honoured\r\n // `Content-Encoding: br`) handed us an already-decompressed wasm.\r\n if (looksLikeWasm(view)) {\r\n nativeConsole.log(\r\n `${tag} source=${label} url=${fetchUrl} bytes=${buf.byteLength} (server pre-decoded)`,\r\n );\r\n return buf;\r\n }\r\n\r\n // Bytes aren't wasm yet. If we asked for a `.br` URL, assume the\r\n // server didn't strip Content-Encoding and run the decoder ourselves.\r\n if (url.toLowerCase().endsWith('.br')) {\r\n const { decompressBrotli } = await import('./brotli-decoder');\r\n try {\r\n const decoded = await decompressBrotli(view);\r\n const out = new Uint8Array(decoded.byteLength);\r\n out.set(decoded);\r\n nativeConsole.log(\r\n `${tag} source=${label} url=${fetchUrl} bytes=${out.byteLength} (client-decoded from ${buf.byteLength})`,\r\n );\r\n return out.buffer;\r\n } catch (decodeErr) {\r\n nativeConsole.warn(\r\n `${tag} ${label} brotli decode failed for ${fetchUrl} (first bytes: ${Array.from(view.slice(0, 4)).map((b) => b.toString(16).padStart(2, '0')).join(' ')}):`,\r\n decodeErr,\r\n );\r\n return null;\r\n }\r\n }\r\n\r\n // Neither wasm nor `.br`: trust it and let WebAssembly.instantiate\r\n // surface a proper CompileError if the shape is wrong.\r\n nativeConsole.log(`${tag} source=${label} url=${fetchUrl} bytes=${buf.byteLength}`);\r\n return buf;\r\n } catch (e) {\r\n nativeConsole.warn(`${tag} ${label} failed for ${fetchUrl}:`, e);\r\n return null;\r\n }\r\n };\r\n\r\n const exactBuf = await tryRemote(remoteExact, 'remote');\r\n if (exactBuf) return exactBuf;\r\n\r\n if (remoteBr) {\r\n const brBuf = await tryRemote(remoteBr, 'remote-br');\r\n if (brBuf) return brBuf;\r\n }\r\n\r\n throw new Error(\r\n `WXWebAssembly: failed to read ${path} \u2014 exhausted VFS (with .br fallback) and remote paths. ` +\r\n `See preceding [readWasmBytes] logs for per-branch status.`,\r\n );\r\n}\r\n\r\n/**\r\n * Create a WXWebAssembly shim that wraps the browser's native WebAssembly.\r\n *\r\n * Design principle (per WeChat's own spec):\r\n * `WXWebAssembly.instantiate(path, imports)` \u2014 `path` is a **code-package\r\n * relative path**, NOT a URL. Our job is to map \"path \u2192 bytes \u2192 Instance\".\r\n *\r\n * The web-adapter aliases: `i.CCWebAssembly = i.WebAssembly = i.WXWebAssembly`\r\n * so every engine wasm call (Cocos Spine, meshopt, Unity streaming, \u2026) flows\r\n * through here. Historically we delegated `compileStreaming` /\r\n * `instantiateStreaming` to native, which let engines hand a raw `wxvfs:`\r\n * string to the browser \u2014 the RN WebView then wrapped the unknown scheme\r\n * with its own `/cdn-proxy?url=wxvfs:...` layer and failed with\r\n * \"Network request failed\". Taking control of both streaming entry points\r\n * fixes that class of bugs: we always produce bytes through `readWasmBytes`\r\n * and never let a `wxvfs:` URL escape to a native fetch.\r\n */\r\nfunction createWXWebAssembly(): Record<string, unknown> {\r\n const WA = WebAssembly;\r\n\r\n // \u2500\u2500 instantiate(pathOrSource, imports) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // \u2022 string \u2192 readWasmBytes(path) \u2192 WebAssembly.instantiate(bytes)\r\n // \u2022 BufferSource \u2192 native (already bytes in memory)\r\n // \u2022 WebAssembly.Module \u2192 native (already compiled)\r\n const instantiate = (\r\n pathOrSource: string | BufferSource | WebAssembly.Module,\r\n imports?: WebAssembly.Imports,\r\n ): Promise<WebAssembly.WebAssemblyInstantiatedSource | WebAssembly.Instance> => {\r\n if (typeof pathOrSource === 'string') {\r\n const path = pathOrSource;\r\n nativeConsole.log(`[wx-compat][WXWebAssembly] instantiate(path) path=${path}`);\r\n return readWasmBytes(path)\r\n .then((buffer) => {\r\n nativeConsole.log(\r\n `[wx-compat][WXWebAssembly] instantiating ${path} (${buffer.byteLength} bytes)`,\r\n );\r\n return WA.instantiate(buffer, imports);\r\n })\r\n .then((result) => {\r\n nativeConsole.log(`[wx-compat][WXWebAssembly] instantiate OK for ${path}`);\r\n return result;\r\n })\r\n .catch((err) => {\r\n nativeConsole.error(`[wx-compat][WXWebAssembly] instantiate FAILED for ${path}:`, err);\r\n throw err;\r\n });\r\n }\r\n // Standard WebAssembly.instantiate behavior\r\n return WA.instantiate(pathOrSource as BufferSource, imports);\r\n };\r\n\r\n // \u2500\u2500 compile(pathOrSource) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // WeChat docs don't actually promise `compile(path)` \u2014 stock browsers\r\n // only accept BufferSource. But some engines (e.g. Unity) call compile\r\n // with a path anyway because it mirrors instantiate. Handle both.\r\n const compile = (\r\n pathOrSource: string | BufferSource,\r\n ): Promise<WebAssembly.Module> => {\r\n if (typeof pathOrSource === 'string') {\r\n const path = pathOrSource;\r\n nativeConsole.log(`[wx-compat][WXWebAssembly] compile(path) path=${path}`);\r\n return readWasmBytes(path)\r\n .then((buffer) => WA.compile(buffer))\r\n .catch((err) => {\r\n nativeConsole.error(`[wx-compat][WXWebAssembly] compile FAILED for ${path}:`, err);\r\n throw err;\r\n });\r\n }\r\n return WA.compile(pathOrSource as BufferSource);\r\n };\r\n\r\n // \u2500\u2500 instantiateStreaming / compileStreaming \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // CRITICAL: do NOT `.bind(WA)`. Native streaming accepts `Response` or\r\n // `Promise<Response>` and internally calls `fetch()`-like reads on it,\r\n // which in RN means our `wxvfs:` bytes can't flow through (the native\r\n // layer intercepts and wraps every URL in `/cdn-proxy?url=...`).\r\n //\r\n // We accept exactly the same argument shapes the browser does, but\r\n // always convert to bytes first via `arrayBuffer()`. As a convenience we\r\n // also accept a plain string (since some engines forget which API they're\r\n // calling) \u2014 route it to the path-based loader.\r\n const toBytes = async (\r\n src: Response | Promise<Response> | string,\r\n ): Promise<ArrayBuffer> => {\r\n if (typeof src === 'string') {\r\n return readWasmBytes(src);\r\n }\r\n const resp = await Promise.resolve(src);\r\n if (!resp.ok) {\r\n throw new Error(`WXWebAssembly streaming: fetch not ok: HTTP ${resp.status}`);\r\n }\r\n return resp.arrayBuffer();\r\n };\r\n\r\n const instantiateStreaming = (\r\n source: Response | Promise<Response> | string,\r\n imports?: WebAssembly.Imports,\r\n ): Promise<WebAssembly.WebAssemblyInstantiatedSource> => {\r\n nativeConsole.log(\r\n `[wx-compat][WXWebAssembly] instantiateStreaming source=${typeof source === 'string' ? source : '[Response]'}`,\r\n );\r\n return toBytes(source)\r\n .then((buffer) => WA.instantiate(buffer, imports) as Promise<WebAssembly.WebAssemblyInstantiatedSource>)\r\n .catch((err) => {\r\n nativeConsole.error('[wx-compat][WXWebAssembly] instantiateStreaming FAILED:', err);\r\n throw err;\r\n });\r\n };\r\n\r\n const compileStreaming = (\r\n source: Response | Promise<Response> | string,\r\n ): Promise<WebAssembly.Module> => {\r\n nativeConsole.log(\r\n `[wx-compat][WXWebAssembly] compileStreaming source=${typeof source === 'string' ? source : '[Response]'}`,\r\n );\r\n return toBytes(source)\r\n .then((buffer) => WA.compile(buffer))\r\n .catch((err) => {\r\n nativeConsole.error('[wx-compat][WXWebAssembly] compileStreaming FAILED:', err);\r\n throw err;\r\n });\r\n };\r\n\r\n const wxWasm: Record<string, unknown> = {\r\n // Core types \u2014 pass through from native WebAssembly\r\n Module: WA.Module,\r\n Instance: WA.Instance,\r\n Memory: WA.Memory,\r\n Table: WA.Table,\r\n Global: WA.Global,\r\n\r\n // Error types\r\n CompileError: WA.CompileError,\r\n LinkError: WA.LinkError,\r\n RuntimeError: WA.RuntimeError,\r\n\r\n // validate \u2014 byte-only, pass through\r\n validate: WA.validate.bind(WA),\r\n\r\n // Path-aware entry points (all take control; never delegate to native\r\n // streaming with a possibly-wxvfs URL in hand).\r\n instantiate,\r\n instantiateStreaming,\r\n compile,\r\n compileStreaming,\r\n };\r\n\r\n return wxWasm;\r\n}\r\n\r\n// \u2500\u2500\u2500 XHR Base URL Rewriting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Patch NativeXMLHttpRequest.prototype.open to rewrite relative URLs\r\n * to the game server base URL. This is a one-time monkey-patch that\r\n * affects ALL XHR instances created from NativeXMLHttpRequest (and its\r\n * subclasses like ProxiedXMLHttpRequest via super.open()).\r\n *\r\n * In addition, any resolved URL with the `wxvfs:` scheme is intercepted\r\n * here: open/send are stubbed out to read synchronously from the virtual\r\n * file system, so legacy synchronous-XHR code paths (require(), game.json\r\n * loading, etc.) keep working even when the preview is serving files\r\n * entirely from memory.\r\n */\r\nfunction patchXHRBaseUrl(): void {\r\n const proto = NativeXMLHttpRequest.prototype;\r\n const originalOpen = proto.open;\r\n const originalSend = proto.send;\r\n const originalSetRequestHeader = proto.setRequestHeader;\r\n const originalAbort = proto.abort;\r\n const originalOverrideMimeType = proto.overrideMimeType;\r\n\r\n // We keep a per-instance record describing whether the current open()\r\n // targeted the VFS. All other XHR entry points read this flag and branch\r\n // to a memory-serving fast path instead of hitting the real network.\r\n type VfsState = {\r\n active: boolean;\r\n path: string;\r\n method: string;\r\n async: boolean;\r\n responseType: string;\r\n /**\r\n * Last value passed to xhr.overrideMimeType(). Legacy binary-via-sync-XHR\r\n * code (e.g. `fetchPackageFileSync` in file-system.ts) calls\r\n * xhr.overrideMimeType('text/plain; charset=x-user-defined')\r\n * so that `responseText` returns each byte 1:1 as code-points 0\u2013255.\r\n * If we honour the standard TextDecoder(UTF-8) path instead, any\r\n * non-UTF-8 byte sequence (common in .data / .bin / .br payloads) is\r\n * silently replaced with U+FFFD and the caller's charCodeAt()&0xff loop\r\n * recovers fewer bytes than the original, corrupting binary assets.\r\n */\r\n mimeTypeOverride: string;\r\n };\r\n const stateKey = '__wxVfsState__';\r\n\r\n proto.open = function patchedOpen(\r\n this: XMLHttpRequest,\r\n method: string,\r\n url: string | URL,\r\n ...rest: unknown[]\r\n ): void {\r\n const resolved = resolveGameUrl(String(url));\r\n\r\n if (isVfsUrl(resolved)) {\r\n // Record VFS intent but still call the original open() with a harmless\r\n // about:blank URL so that readyState bookkeeping stays consistent\r\n // with the native state machine until we fire fake events in send().\r\n const async = rest.length === 0 ? true : rest[0] !== false;\r\n const state: VfsState = {\r\n active: true,\r\n path: fromVfsUrl(resolved),\r\n method,\r\n async,\r\n responseType: (this as { responseType?: string }).responseType || '',\r\n mimeTypeOverride: '',\r\n };\r\n (this as unknown as Record<string, unknown>)[stateKey] = state;\r\n // Intentionally NOT calling originalOpen \u2014 we simulate the whole thing.\r\n // Manually flip readyState to OPENED via dispatchEvent? Not required:\r\n // most callers just rely on status/response after send() completes.\r\n return;\r\n }\r\n // Clear any leftover state from a prior vfs open() on the same instance.\r\n (this as unknown as Record<string, unknown>)[stateKey] = {\r\n active: false,\r\n path: '',\r\n method: '',\r\n async: true,\r\n responseType: '',\r\n mimeTypeOverride: '',\r\n } as VfsState;\r\n // @ts-expect-error \u2014 spread args match the overloaded open() signatures\r\n return originalOpen.call(this, method, resolved, ...rest);\r\n } as typeof proto.open;\r\n\r\n proto.setRequestHeader = function patchedSetRequestHeader(\r\n this: XMLHttpRequest, header: string, value: string,\r\n ): void {\r\n const s = (this as unknown as Record<string, unknown>)[stateKey] as VfsState | undefined;\r\n if (s && s.active) return; // No-op for VFS targets.\r\n return originalSetRequestHeader.call(this, header, value);\r\n } as typeof proto.setRequestHeader;\r\n\r\n proto.abort = function patchedAbort(this: XMLHttpRequest): void {\r\n const s = (this as unknown as Record<string, unknown>)[stateKey] as VfsState | undefined;\r\n if (s && s.active) {\r\n s.active = false;\r\n return;\r\n }\r\n return originalAbort.call(this);\r\n } as typeof proto.abort;\r\n\r\n proto.overrideMimeType = function patchedOverrideMimeType(\r\n this: XMLHttpRequest, mime: string,\r\n ): void {\r\n const s = (this as unknown as Record<string, unknown>)[stateKey] as VfsState | undefined;\r\n if (s && s.active) {\r\n // Record for the deliver() branch to honour. Native XHR would throw if\r\n // called after send(); we intentionally don't replicate that \u2014 our\r\n // callers always invoke overrideMimeType() between open() and send().\r\n s.mimeTypeOverride = String(mime || '');\r\n return;\r\n }\r\n return originalOverrideMimeType.call(this, mime);\r\n } as typeof proto.overrideMimeType;\r\n\r\n proto.send = function patchedSend(\r\n this: XMLHttpRequest, _body?: Document | BodyInit | null,\r\n ): void {\r\n const s = (this as unknown as Record<string, unknown>)[stateKey] as VfsState | undefined;\r\n if (!s || !s.active) {\r\n // @ts-expect-error \u2014 body type union is wider than the original signature\r\n return originalSend.call(this, _body);\r\n }\r\n // Refresh responseType in case the caller set it after open().\r\n s.responseType = (this as { responseType?: string }).responseType || '';\r\n // Prefer the decoded accessor \u2014 it transparently handles `.br` entries\r\n // (brotli-wasm sync decode, warmed at install time). Fall back to the\r\n // raw entry only when the decoded path can't produce bytes (e.g. wasm\r\n // not ready yet for a never-before-seen `.br`), so non-brotli or\r\n // already-decoded assets work exactly like before.\r\n const decodedBuf = vfsGetDecodedSync(s.path);\r\n const rawEntry = vfsGetEntry(s.path);\r\n const entry = decodedBuf\r\n ? { data: new Uint8Array(decodedBuf), isText: rawEntry ? rawEntry.isText : false }\r\n : rawEntry;\r\n\r\n // \u2500\u2500 DIAG: datapackage / mismatch-data-size forensics \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Unity plugins validate `fileSize` against an engine-baked\r\n // `defaultSize`. If we transparently brotli-decode a `.data.br`\r\n // (or `.data.unityweb.br`) here, the caller sees a shorter buffer\r\n // than the meta expects and fails with \"mismatch data size\".\r\n // These logs let us confirm that decompression path from logs alone.\r\n const rawBytes = rawEntry ? rawEntry.data.byteLength : -1;\r\n const servedBytes = entry ? entry.data.byteLength : -1;\r\n const wasDecompressed = rawEntry && decodedBuf && rawBytes !== servedBytes;\r\n const isSensitive =\r\n /\\.(data|unityweb|wasm|bundle)(\\.br)?$/i.test(s.path) ||\r\n /datapackage/i.test(s.path);\r\n if (isSensitive || wasDecompressed) {\r\n nativeConsole.log(\r\n `[wx-compat][XHR][vfs] path=${s.path} responseType=${s.responseType || '(default)'} ` +\r\n `raw=${rawBytes} served=${servedBytes}` +\r\n (wasDecompressed ? ' [AUTO-BROTLI-DECODED]' : '') +\r\n (entry ? '' : ' [MISS \u2192 404]'),\r\n );\r\n }\r\n const xhr = this as unknown as {\r\n readyState: number;\r\n status: number;\r\n statusText: string;\r\n responseText: string;\r\n response: unknown;\r\n onreadystatechange: (() => void) | null;\r\n onload: (() => void) | null;\r\n onerror: ((e: Event) => void) | null;\r\n onloadend: (() => void) | null;\r\n dispatchEvent?: (e: Event) => boolean;\r\n };\r\n\r\n // \u2500\u2500 Populate the instance to look like a completed request \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n //\r\n // `status`, `statusText`, `readyState`, `response`, `responseText` are all\r\n // readonly getters on XMLHttpRequest.prototype per the DOM spec. Direct\r\n // assignment (`xhr.status = 200`) silently no-ops in sloppy mode and\r\n // throws `TypeError: Cannot set property ... which has only a getter` in\r\n // strict mode (which esbuild/TS module output always is). To emulate a\r\n // completed request we shadow those prototype properties with own data\r\n // properties on the instance via Object.defineProperty.\r\n const setProp = (key: string, value: unknown): void => {\r\n try {\r\n Object.defineProperty(xhr, key, {\r\n configurable: true,\r\n enumerable: true,\r\n writable: true,\r\n value,\r\n });\r\n } catch {\r\n /* ignore \u2014 some engines forbid redefining; downstream code will just see the default getter */\r\n }\r\n };\r\n\r\n const deliver = (): void => {\r\n let finalStatus = 0;\r\n if (entry) {\r\n finalStatus = 200;\r\n setProp('status', 200);\r\n setProp('statusText', 'OK');\r\n const type = s.responseType;\r\n if (type === 'arraybuffer') {\r\n // Copy so callers can freely transfer the buffer.\r\n const out = new Uint8Array(entry.data.byteLength);\r\n out.set(entry.data);\r\n setProp('response', out.buffer);\r\n // responseText is unreliable for arraybuffer \u2014 leave empty.\r\n setProp('responseText', '');\r\n } else if (type === 'json') {\r\n let parsed: unknown = null;\r\n try { parsed = JSON.parse(new TextDecoder().decode(entry.data)); } catch { /* leave null */ }\r\n setProp('response', parsed);\r\n try { setProp('responseText', new TextDecoder().decode(entry.data)); } catch { /* noop */ }\r\n } else if (type === 'blob') {\r\n // Construct a Blob from the bytes.\r\n const buf = entry.data.slice().buffer;\r\n setProp('response', new Blob([buf]));\r\n setProp('responseText', '');\r\n } else {\r\n // '', 'text', 'document' \u2014 treat as text.\r\n //\r\n // Legacy binary-via-sync-XHR callers (fetchPackageFileSync) set\r\n // xhr.overrideMimeType('text/plain; charset=x-user-defined')\r\n // so that responseText exposes each source byte as a code point\r\n // in 0\u2013255. Honour that here: if we UTF-8-decode a `.data` /\r\n // `.wasm` / `.bin` payload (which is common under wxvfs:), any\r\n // non-UTF-8 byte runs collapse to U+FFFD and the caller's\r\n // `charCodeAt(i) & 0xff` reconstruction loses bytes \u2014 producing\r\n // the classic Unity \"mismatch data size\" failure.\r\n const mimeLower = (s.mimeTypeOverride || '').toLowerCase();\r\n const forceBinarySafe = mimeLower.includes('x-user-defined');\r\n let text: string;\r\n if (forceBinarySafe) {\r\n // Build the string in chunks to avoid blowing the JS engine's\r\n // argument-count limit on huge files (~100k+ bytes).\r\n const bytes = entry.data;\r\n const CHUNK = 0x8000; // 32k chars per call\r\n const parts: string[] = [];\r\n for (let i = 0; i < bytes.length; i += CHUNK) {\r\n parts.push(\r\n String.fromCharCode.apply(\r\n null,\r\n bytes.subarray(i, Math.min(i + CHUNK, bytes.length)) as unknown as number[],\r\n ),\r\n );\r\n }\r\n text = parts.join('');\r\n } else {\r\n text = new TextDecoder().decode(entry.data);\r\n }\r\n setProp('responseText', text);\r\n setProp('response', text);\r\n }\r\n } else {\r\n finalStatus = 404;\r\n setProp('status', 404);\r\n setProp('statusText', 'Not Found');\r\n setProp('responseText', '');\r\n setProp('response', '');\r\n }\r\n setProp('readyState', 4);\r\n // Fire lifecycle callbacks. We don't know if callers prefer onload vs\r\n // onreadystatechange, so fire both (matches native XHR behaviour).\r\n try { xhr.onreadystatechange?.(); } catch { /* swallow */ }\r\n if (finalStatus === 200) {\r\n try { xhr.onload?.(); } catch { /* swallow */ }\r\n } else {\r\n try { xhr.onerror?.(new Event('error')); } catch { /* swallow */ }\r\n }\r\n try { xhr.onloadend?.(); } catch { /* swallow */ }\r\n };\r\n\r\n if (s.async) {\r\n // Defer to next microtask so callers have time to attach onload.\r\n Promise.resolve().then(deliver);\r\n } else {\r\n deliver();\r\n }\r\n } as typeof proto.send;\r\n}\r\n\r\n// \u2500\u2500\u2500 Fetch Base URL Rewriting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Patch window.fetch to rewrite relative URLs to the game server base URL.\r\n *\r\n * In srcdoc iframes the document origin is null, so fetch(\"foo/bar.wasm\")\r\n * resolves to vscode-webview://.../foo/bar.wasm and returns 403. We rewrite\r\n * the URL with resolveGameUrl() before delegating to the captured native fetch.\r\n *\r\n * Notes:\r\n * - Absolute URLs (http://, https://, blob:, data:, wxfile://) are left\r\n * unchanged by resolveGameUrl.\r\n * - We intentionally do NOT run cdnProxyUrl here: engines that want CORS\r\n * bypass should use wx.request (which already goes through cdnProxyUrl)\r\n * or WXWebAssembly.instantiate (which also does). Blanket-proxying all\r\n * fetch() would double-wrap URLs that are already same-origin.\r\n * - Request objects (fetch(new Request(url))) are left untouched \u2014 they\r\n * already carry an absolute URL computed at Request construction time.\r\n */\r\nfunction patchFetchBaseUrl(): void {\r\n const win = window as unknown as Record<string, unknown>;\r\n const originalFetch = win.fetch as typeof fetch | undefined;\r\n if (typeof originalFetch !== 'function') return;\r\n\r\n // Serve `wxvfs:<path>` urls directly from the VFS as a synthetic Response.\r\n // Returning a real Response here means every downstream consumer (`res.text()`,\r\n // `res.arrayBuffer()`, `res.body.getReader()`) keeps working unchanged.\r\n // Note: `.br` entries are lazily decompressed via getDecodedArrayBuffer so\r\n // the caller gets the canonical uncompressed payload.\r\n const vfsFetch = async (url: string): Promise<Response> => {\r\n const path = fromVfsUrl(url);\r\n if (!vfsHas(path)) {\r\n nativeConsole.log(`[wx-compat][fetch][vfs] MISS \u2192 404 path=${path}`);\r\n return new Response(null, { status: 404, statusText: 'Not Found' });\r\n }\r\n const rawEntry = vfsGetEntry(path);\r\n const rawBytes = rawEntry ? rawEntry.data.byteLength : -1;\r\n const buffer = await vfsGetDecoded(path);\r\n if (!buffer) {\r\n nativeConsole.warn(`[wx-compat][fetch][vfs] decode failed path=${path} raw=${rawBytes}`);\r\n return new Response(null, { status: 502, statusText: 'VFS decode failed' });\r\n }\r\n const wasDecompressed = rawBytes !== buffer.byteLength;\r\n const isSensitive =\r\n /\\.(data|unityweb|wasm|bundle)(\\.br)?$/i.test(path) ||\r\n /datapackage/i.test(path);\r\n if (isSensitive || wasDecompressed) {\r\n nativeConsole.log(\r\n `[wx-compat][fetch][vfs] path=${path} raw=${rawBytes} served=${buffer.byteLength}` +\r\n (wasDecompressed ? ' [AUTO-BROTLI-DECODED]' : ''),\r\n );\r\n }\r\n const headers: HeadersInit = {\r\n 'Content-Length': String(buffer.byteLength),\r\n };\r\n return new Response(buffer, { status: 200, statusText: 'OK', headers });\r\n };\r\n\r\n const patched: typeof fetch = function patchedFetch(\r\n input: RequestInfo | URL,\r\n init?: RequestInit,\r\n ): Promise<Response> {\r\n if (typeof input === 'string') {\r\n const resolved = resolveGameUrl(input);\r\n if (isVfsUrl(resolved)) return vfsFetch(resolved);\r\n return originalFetch(resolved, init);\r\n }\r\n if (input instanceof URL) {\r\n const resolved = resolveGameUrl(input.toString());\r\n if (isVfsUrl(resolved)) return vfsFetch(resolved);\r\n return originalFetch(resolved, init);\r\n }\r\n // Request object \u2014 already has a fully-qualified URL; don't touch it.\r\n return originalFetch(input, init);\r\n };\r\n\r\n win.fetch = patched;\r\n}\r\n\r\n// \u2500\u2500\u2500 Proxied XMLHttpRequest \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Create a proxied XMLHttpRequest constructor that automatically rewrites\r\n * cross-origin URLs to go through the server-side /cdn-proxy endpoint.\r\n *\r\n * In WeChat, XMLHttpRequest (via wx.request) has no CORS restrictions.\r\n * Unity and other engines pass XMLHttpRequest via customEnv to their plugins,\r\n * which then use it to load assets from CDN servers. In browser preview,\r\n * these cross-origin requests get blocked by CORS. This wrapper transparently\r\n * proxies such requests through the server.\r\n */\r\nfunction createProxiedXMLHttpRequest(): typeof XMLHttpRequest {\r\n const OrigXHR = NativeXMLHttpRequest;\r\n\r\n class ProxiedXMLHttpRequest extends OrigXHR {\r\n open(\r\n method: string,\r\n url: string | URL,\r\n async?: boolean,\r\n username?: string | null,\r\n password?: string | null,\r\n ): void {\r\n const rewrittenUrl = cdnProxyUrl(String(url));\r\n if (rewrittenUrl !== String(url)) {\r\n nativeConsole.log(\r\n `[wx-compat][ProxiedXHR] Proxying cross-origin request: ${url} \u2192 ${rewrittenUrl}`,\r\n );\r\n }\r\n if (async === undefined) {\r\n super.open(method, rewrittenUrl);\r\n } else {\r\n super.open(\r\n method,\r\n rewrittenUrl,\r\n async,\r\n username ?? undefined,\r\n password ?? undefined,\r\n );\r\n }\r\n }\r\n }\r\n\r\n return ProxiedXMLHttpRequest as unknown as typeof XMLHttpRequest;\r\n}\r\n", "/**\r\n * Permission Manager \u2014 declarative API permission control.\r\n *\r\n * Inspired by `minigame_web_host/wmpf-meta/permission/map.ts` and the\r\n * native scope.* permission model. In native WeChat, every privacy-\r\n * sensitive API (camera, location, userInfo, ...) is gated by a\r\n * `scope.<name>` permission that must be granted via `wx.authorize` /\r\n * `wx.openSetting` before the API can succeed.\r\n *\r\n * In preview/browser mode we cannot ask the real user via WeChat's UI,\r\n * but games still execute the same flow: they call `wx.getSetting` \u2192\r\n * read `authSetting['scope.userLocation']` \u2192 call `wx.authorize` if\r\n * missing \u2192 finally invoke the gated API. If our shim always returns\r\n * \"granted\" we mask programming errors that would surface on real\r\n * devices; if we always return \"denied\" games crash hard. The middle\r\n * ground is to expose a configurable, default-grant policy:\r\n *\r\n * - The host can override the policy at iframe creation time by\r\n * setting `window.__wxPermissionPolicy = { 'scope.userLocation':\r\n * 'denied', 'scope.camera': 'prompt' }` BEFORE wx-compat is loaded.\r\n * - Games hitting an `unset` permission via gated APIs are treated\r\n * as \"granted\" (preview-friendly default), but the lookup is\r\n * centralised so we can flip behaviour later without touching every\r\n * API module.\r\n * - Dev tools UI (future) can mutate the live policy at runtime via\r\n * `setApiPermission(scope, value)`.\r\n *\r\n * The API \u2192 scope map below is hand-derived from the native SDK source\r\n * tree (`wx-sdk/sdk/src/.../jsapi/.../permission.ts`) and the wmpf-meta\r\n * permission/map.ts table. We intentionally only list APIs that have a\r\n * privacy-relevant gate; pure capability stubs (showToast, request, ...)\r\n * stay outside the model.\r\n */\r\n\r\nimport { nativeConsole } from './native-globals';\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype AnyCallback = (...args: any[]) => void;\r\n\r\ninterface CallbackOpts {\r\n success?: AnyCallback;\r\n fail?: AnyCallback;\r\n complete?: AnyCallback;\r\n [key: string]: unknown;\r\n}\r\n\r\n// \u2500\u2500\u2500 Scope catalogue \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Every native permission scope we care about. Keys mirror the strings\r\n * games pass to `wx.authorize({ scope: ... })` and the keys in the\r\n * `authSetting` map returned by `wx.getSetting`.\r\n */\r\nexport const SCOPES = {\r\n USER_INFO: 'scope.userInfo',\r\n USER_LOCATION: 'scope.userLocation',\r\n USER_LOCATION_BACKGROUND: 'scope.userLocationBackground',\r\n ADDRESS: 'scope.address',\r\n INVOICE_TITLE: 'scope.invoiceTitle',\r\n INVOICE: 'scope.invoice',\r\n WERUN: 'scope.werun',\r\n RECORD: 'scope.record',\r\n WRITE_PHOTOS_ALBUM: 'scope.writePhotosAlbum',\r\n CAMERA: 'scope.camera',\r\n BLUETOOTH: 'scope.bluetooth',\r\n ADD_PHONE_CONTACT: 'scope.addPhoneContact',\r\n ADD_PHONE_CALENDAR: 'scope.addPhoneCalendar',\r\n} as const;\r\nexport type Scope = typeof SCOPES[keyof typeof SCOPES];\r\n\r\n/**\r\n * Permission state values, matching native semantics.\r\n * - `granted` : API call proceeds.\r\n * - `denied` : API call fails fast with `:fail auth deny`.\r\n * - `prompt` : preview-only \u2014 emits a console hint and falls through\r\n * to `granted`. Useful for surfacing missing host wiring\r\n * without blocking the game.\r\n */\r\nexport type PermissionState = 'granted' | 'denied' | 'prompt';\r\n\r\n/**\r\n * Map of API name \u2192 required scope. Lookup is by the public wx.* method\r\n * name (no leading \"wx.\") to keep call-sites short. Multiple APIs can\r\n * share a single scope (e.g. `getLocation`/`startLocationUpdate`).\r\n *\r\n * Source: hand-curated from native wx-sdk + wmpf-meta. Not exhaustive\r\n * \u2014 only the APIs whose preview shims we want gated. Add more as needed.\r\n */\r\nexport const API_SCOPE_MAP: Readonly<Record<string, Scope>> = Object.freeze({\r\n // Location\r\n getLocation: SCOPES.USER_LOCATION,\r\n startLocationUpdate: SCOPES.USER_LOCATION,\r\n startLocationUpdateBackground: SCOPES.USER_LOCATION_BACKGROUND,\r\n chooseLocation: SCOPES.USER_LOCATION,\r\n choosePoi: SCOPES.USER_LOCATION,\r\n\r\n // User info\r\n getUserInfo: SCOPES.USER_INFO,\r\n getUserProfile: SCOPES.USER_INFO,\r\n\r\n // Camera / Album\r\n chooseImage: SCOPES.WRITE_PHOTOS_ALBUM,\r\n chooseMedia: SCOPES.WRITE_PHOTOS_ALBUM,\r\n chooseVideo: SCOPES.WRITE_PHOTOS_ALBUM,\r\n saveImageToPhotosAlbum: SCOPES.WRITE_PHOTOS_ALBUM,\r\n saveVideoToPhotosAlbum: SCOPES.WRITE_PHOTOS_ALBUM,\r\n createCamera: SCOPES.CAMERA,\r\n scanCode: SCOPES.CAMERA,\r\n\r\n // Audio recording\r\n getRecorderManager: SCOPES.RECORD,\r\n\r\n // Bluetooth\r\n openBluetoothAdapter: SCOPES.BLUETOOTH,\r\n\r\n // Address / Invoice (commerce)\r\n chooseAddress: SCOPES.ADDRESS,\r\n chooseInvoice: SCOPES.INVOICE,\r\n chooseInvoiceTitle: SCOPES.INVOICE_TITLE,\r\n\r\n // Phone book / Calendar\r\n addPhoneContact: SCOPES.ADD_PHONE_CONTACT,\r\n addPhoneCalendar: SCOPES.ADD_PHONE_CALENDAR,\r\n\r\n // Werun (step counter)\r\n getWeRunData: SCOPES.WERUN,\r\n});\r\n\r\n// \u2500\u2500\u2500 Live policy store \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Default policy for every known scope. In preview we lean toward\r\n * `granted` so games \"just work\"; the host can lock things down by\r\n * supplying overrides via `window.__wxPermissionPolicy` before wx-compat\r\n * loads, or by calling `setApiPermission` at runtime.\r\n */\r\nconst DEFAULT_POLICY: Readonly<Record<Scope, PermissionState>> = Object.freeze({\r\n [SCOPES.USER_INFO]: 'granted',\r\n [SCOPES.USER_LOCATION]: 'granted',\r\n [SCOPES.USER_LOCATION_BACKGROUND]: 'denied',\r\n [SCOPES.ADDRESS]: 'granted',\r\n [SCOPES.INVOICE_TITLE]: 'granted',\r\n [SCOPES.INVOICE]: 'granted',\r\n [SCOPES.WERUN]: 'denied',\r\n [SCOPES.RECORD]: 'prompt',\r\n [SCOPES.WRITE_PHOTOS_ALBUM]: 'granted',\r\n [SCOPES.CAMERA]: 'prompt',\r\n [SCOPES.BLUETOOTH]: 'denied',\r\n [SCOPES.ADD_PHONE_CONTACT]: 'denied',\r\n [SCOPES.ADD_PHONE_CALENDAR]: 'denied',\r\n});\r\n\r\nconst livePolicy: Record<string, PermissionState> = { ...DEFAULT_POLICY };\r\n\r\n/**\r\n * Pull host overrides from `window.__wxPermissionPolicy`. Called once\r\n * during installation so the host can ship a tighter (or looser) policy\r\n * than the defaults above without modifying wx-compat source.\r\n */\r\nfunction loadHostOverrides(): void {\r\n const override = (window as unknown as Record<string, unknown>).__wxPermissionPolicy as\r\n | Record<string, PermissionState>\r\n | undefined;\r\n if (!override || typeof override !== 'object') return;\r\n for (const [scope, state] of Object.entries(override)) {\r\n if (state === 'granted' || state === 'denied' || state === 'prompt') {\r\n livePolicy[scope] = state;\r\n }\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Look up the current permission state for a scope. Unknown scopes\r\n * default to `granted` (preview-friendly fallback).\r\n */\r\nexport function getPermissionState(scope: string): PermissionState {\r\n return livePolicy[scope] ?? 'granted';\r\n}\r\n\r\n/**\r\n * Set the permission state for a scope. Used by the dev-tools UI and\r\n * by `wx.authorize` / `wx.openSetting` shims to persist user choices\r\n * during the lifetime of the iframe.\r\n */\r\nexport function setApiPermission(scope: string, state: PermissionState): void {\r\n livePolicy[scope] = state;\r\n}\r\n\r\n/**\r\n * Snapshot the current authSetting map, mirroring the shape returned by\r\n * `wx.getSetting`. `prompt` collapses to `false` (i.e. \"not yet granted\")\r\n * to match native semantics \u2014 games then call `wx.authorize` to upgrade\r\n * it, at which point our `authorize` shim flips it to `granted`.\r\n */\r\nexport function getAuthSetting(): Record<string, boolean> {\r\n const out: Record<string, boolean> = {};\r\n for (const scope of Object.values(SCOPES)) {\r\n const state = livePolicy[scope];\r\n out[scope] = state === 'granted';\r\n }\r\n return out;\r\n}\r\n\r\n/**\r\n * Resolve the scope (if any) gating the given API name. Returns null\r\n * for ungated APIs (the vast majority).\r\n */\r\nexport function getRequiredScope(apiName: string): Scope | null {\r\n return API_SCOPE_MAP[apiName] ?? null;\r\n}\r\n\r\n/**\r\n * Gatekeeper helper used by API shims. Returns `true` when the call\r\n * may proceed; otherwise invokes `opts.fail/complete` with the standard\r\n * \"auth deny\" error and returns `false` so the caller can early-return.\r\n *\r\n * Usage in an API module:\r\n *\r\n * export function getLocation(opts: CallbackOpts) {\r\n * if (!checkPermission('getLocation', opts)) return;\r\n * // ... real implementation\r\n * }\r\n */\r\nexport function checkPermission(apiName: string, opts?: CallbackOpts): boolean {\r\n const scope = getRequiredScope(apiName);\r\n if (!scope) return true;\r\n const state = getPermissionState(scope);\r\n if (state === 'granted') return true;\r\n if (state === 'prompt') {\r\n nativeConsole.info(\r\n `[wx-compat][permission] \"${apiName}\" requires \"${scope}\" \u2014 preview policy is \"prompt\", allowing through. ` +\r\n `Call setApiPermission(\"${scope}\", \"granted\" | \"denied\") to lock the answer.`,\r\n );\r\n return true;\r\n }\r\n // denied\r\n opts?.fail?.({ errMsg: `${apiName}:fail auth deny` });\r\n opts?.complete?.();\r\n return false;\r\n}\r\n\r\n/**\r\n * Install the global `__wxPermission` debug surface so the host page or\r\n * a browser-devtools eval can inspect / mutate the policy from the\r\n * outside. This is *not* a documented API for game authors \u2014 its main\r\n * consumer is the future preview UI that surfaces permission prompts.\r\n */\r\nexport function installPermissionDebugApi(): void {\r\n loadHostOverrides();\r\n (window as unknown as Record<string, unknown>).__wxPermission = {\r\n get: getPermissionState,\r\n set: setApiPermission,\r\n snapshot: () => ({ ...livePolicy }),\r\n scopes: { ...SCOPES },\r\n };\r\n}\r\n", "/**\r\n * Clean Globals \u2014 Sandbox the browser environment to match WeChat Mini Game runtime.\r\n *\r\n * WeChat Mini Games run in a stripped-down environment where most browser DOM/BOM\r\n * APIs are removed. Only a small whitelist of properties survives on `window` and\r\n * `document`. This module replicates that behaviour so our preview catches the\r\n * same errors that would appear on a real device.\r\n *\r\n * Inspired by WeChat DevTools' `cleanglobal.ts` + `cleanconfig.ts`.\r\n *\r\n * IMPORTANT: This must run AFTER native-globals.ts captures browser APIs and\r\n * AFTER globals-compat.ts installs wx/GameGlobal/canvas, but BEFORE game.js loads.\r\n */\r\n\r\nimport { nativeBody, nativeConsole, nativeCreateElement, nativeLocation, nativeDevicePixelRatio } from './native-globals';\r\nimport { createCanvas, getMainCanvas } from './canvas';\r\nimport { createImage } from './image';\r\n\r\n// \u2500\u2500\u2500 JS Built-in Globals (never delete) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst JS_BUILTINS: Record<string, boolean> = {};\r\n[\r\n // Core language\r\n 'Object', 'Function', 'Array', 'Number', 'parseFloat', 'parseInt',\r\n 'Boolean', 'String', 'Symbol', 'Date', 'Promise', 'RegExp',\r\n // Errors\r\n 'Error', 'EvalError', 'RangeError', 'ReferenceError', 'SyntaxError',\r\n 'TypeError', 'URIError', 'AggregateError',\r\n // JSON / Math / Intl\r\n 'JSON', 'Math', 'Intl',\r\n // Typed arrays & buffers\r\n 'ArrayBuffer', 'SharedArrayBuffer', 'Uint8Array', 'Int8Array',\r\n 'Uint16Array', 'Int16Array', 'Uint32Array', 'Int32Array',\r\n 'Float32Array', 'Float64Array', 'Uint8ClampedArray', 'DataView',\r\n // Collections\r\n 'Map', 'Set', 'WeakMap', 'WeakSet',\r\n // Meta-programming\r\n 'Proxy', 'Reflect',\r\n // Special values\r\n 'Infinity', 'NaN', 'undefined',\r\n // Encoding/decoding\r\n 'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent',\r\n 'escape', 'unescape',\r\n // Eval & type checks\r\n 'eval', 'isFinite', 'isNaN',\r\n // WebAssembly\r\n 'WebAssembly',\r\n // Console\r\n 'console',\r\n // Structured clone\r\n 'structuredClone',\r\n // queueMicrotask\r\n 'queueMicrotask',\r\n // Iterator/Generator\r\n 'Iterator', 'GeneratorFunction', 'AsyncGeneratorFunction',\r\n].forEach(k => { JS_BUILTINS[k] = true; });\r\n\r\n// \u2500\u2500\u2500 Window Property Whitelist \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// Matches WeChat DevTools cleanconfig.ts windowRemain + our own additions.\r\n\r\nconst WINDOW_REMAIN: Record<string, boolean> = {};\r\n[\r\n // --- From WeChat DevTools cleanconfig.ts ---\r\n 'parent', '__global', 'atob', 'onload',\r\n 'setTimeout', 'setInterval', 'clearTimeout', 'clearInterval',\r\n 'requestAnimationFrame', 'cancelAnimationFrame',\r\n 'WebGLRenderingContext', 'WebGL2RenderingContext',\r\n 'innerWidth', 'innerHeight',\r\n 'require',\r\n 'navigator', 'self', 'performance',\r\n 'webkitURL', 'scrollTo',\r\n 'FontFace',\r\n 'WeakRef', 'FinalizationRegistry',\r\n 'Path2D',\r\n 'TextDecoder', 'TextEncoder',\r\n 'AudioContext',\r\n 'globalThis',\r\n 'BigInt', 'BigInt64Array', 'BigUint64Array', 'Atomics',\r\n 'URL', 'PromiseRejectionEvent',\r\n 'WeixinJSContext',\r\n // WebRTC\r\n 'RTCPeerConnection', 'RTCSessionDescription', 'RTCIceCandidate',\r\n 'MediaStream', 'MediaStreamTrack', 'WebRTC',\r\n\r\n // --- Our additions for wx-compat ---\r\n 'wx', 'GameGlobal', 'canvas',\r\n '__wxConfig', '__errorHandler', '__wxAppCode__', '__wxRoute',\r\n 'WeixinJSBridge',\r\n // Plugin system globals (define + requirePlugin)\r\n 'define', 'requirePlugin',\r\n // File system utility used by Cocos engine plugins\r\n 'fsUtils',\r\n // window.window and window.top are non-configurable in browsers, so they\r\n // survive regardless, but list them to be explicit.\r\n 'window', 'top',\r\n // Event constructors needed by touch emulation & game adapters\r\n 'TouchEvent', 'Touch', 'MouseEvent', 'KeyboardEvent', 'Event', 'CustomEvent',\r\n 'PointerEvent', 'WheelEvent', 'ErrorEvent',\r\n // ImageData / ImageBitmap (used by canvas operations)\r\n 'ImageData', 'ImageBitmap', 'createImageBitmap',\r\n // Blob / File for canvas export\r\n 'Blob', 'File', 'FileReader',\r\n // Crypto\r\n 'crypto', 'Crypto', 'CryptoKey', 'SubtleCrypto',\r\n // MessageEvent for postMessage communication\r\n 'MessageEvent', 'MessageChannel', 'MessagePort',\r\n 'postMessage', 'addEventListener', 'removeEventListener',\r\n // Worker support\r\n 'Worker',\r\n // DOMException\r\n 'DOMException',\r\n // AbortController (used by fetch)\r\n 'AbortController', 'AbortSignal',\r\n // TextMetrics (canvas)\r\n 'TextMetrics',\r\n // Headers, Request, Response (fetch related - game adapters may need)\r\n 'Headers', 'Request', 'Response',\r\n].forEach(k => { WINDOW_REMAIN[k] = true; });\r\n\r\n// \u2500\u2500\u2500 Document Properties That Must Come From Adapter \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// In real WeChat Mini Game runtime, `document` doesn't exist natively.\r\n// The weapp-adapter creates a plain object as `document` and sets properties\r\n// like `documentElement`, `body`, `head` on it. Different adapters may provide\r\n// different shapes (e.g. some include `appendChild`, some don't).\r\n//\r\n// To match real device behavior, these properties should ONLY come from what\r\n// the adapter writes (via document.xxx = value), NOT from the native browser's\r\n// document. If the adapter doesn't set them, they should be `undefined`.\r\n\r\nconst DOCUMENT_ADAPTER_OWNED: Record<string, boolean> = {};\r\n[\r\n 'documentElement',\r\n 'body',\r\n 'head',\r\n].forEach(k => { DOCUMENT_ADAPTER_OWNED[k] = true; });\r\n\r\n// \u2500\u2500\u2500 Document Property Whitelist \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// Matches WeChat DevTools cleanconfig.ts documentRemain.\r\n\r\nconst DOCUMENT_REMAIN: Record<string, boolean> = {};\r\n[\r\n // From WeChat DevTools cleanconfig.ts\r\n 'body', 'head', 'fonts',\r\n 'documentElement',\r\n 'createElement', 'createDocumentFragment', 'createTextNode',\r\n 'addEventListener', 'removeEventListener',\r\n 'readyState',\r\n 'activeElement', 'childNodes',\r\n 'pointerLockElement', 'exitPointerLock',\r\n 'dispatchEvent',\r\n 'querySelectorAll', 'styleSheets',\r\n // Our addition: needed by mouse-touch emulation & game adapters\r\n 'getElementById',\r\n 'createElementNS',\r\n 'hidden', 'visibilityState',\r\n].forEach(k => { DOCUMENT_REMAIN[k] = true; });\r\n\r\n// \u2500\u2500\u2500 Window Own Properties to Remove (Blacklist) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// Instead of removing everything NOT in a whitelist (which deleted 1000+ props\r\n// and broke game engine internals), we only remove specific known DOM/BOM APIs\r\n// that don't exist in the WeChat Mini Game runtime.\r\n//\r\n// This list is intentionally conservative \u2014 it targets high-visibility browser\r\n// APIs that game code should NOT rely on in a mini-game context. Properties not\r\n// on this list are left alone, ensuring game engines (Cocos, Phaser, etc.) can\r\n// safely use internal browser APIs for their adapter layers.\r\n\r\nconst WINDOW_OWN_PROPS_REMOVE = [\r\n // \u2500\u2500 DOM Element Constructors (no DOM in WeChat Mini Game) \u2500\u2500\r\n 'HTMLElement', 'HTMLCanvasElement', 'HTMLImageElement', 'HTMLVideoElement',\r\n 'HTMLAudioElement', 'HTMLDivElement', 'HTMLSpanElement', 'HTMLUnknownElement',\r\n 'HTMLDocument', 'HTMLBodyElement', 'HTMLHeadElement', 'HTMLStyleElement',\r\n 'HTMLScriptElement', 'HTMLLinkElement', 'HTMLInputElement', 'HTMLButtonElement',\r\n 'HTMLFormElement', 'HTMLMediaElement', 'HTMLSourceElement',\r\n 'HTMLSelectElement', 'HTMLOptionElement', 'HTMLTextAreaElement',\r\n 'HTMLTableElement', 'HTMLTableRowElement', 'HTMLTableCellElement',\r\n 'HTMLParagraphElement', 'HTMLPreElement', 'HTMLBRElement', 'HTMLHRElement',\r\n 'HTMLAnchorElement', 'HTMLLabelElement', 'HTMLFieldSetElement',\r\n 'HTMLLegendElement', 'HTMLUListElement', 'HTMLOListElement', 'HTMLLIElement',\r\n 'HTMLDListElement', 'HTMLMetaElement', 'HTMLTitleElement', 'HTMLBaseElement',\r\n 'HTMLTemplateElement', 'HTMLSlotElement', 'HTMLDialogElement',\r\n 'HTMLDetailsElement', 'HTMLSummaryElement', 'HTMLMenuElement',\r\n 'HTMLOutputElement', 'HTMLProgressElement', 'HTMLMeterElement',\r\n 'HTMLDataElement', 'HTMLTimeElement', 'HTMLPictureElement',\r\n 'HTMLEmbedElement', 'HTMLObjectElement', 'HTMLAreaElement', 'HTMLMapElement',\r\n 'HTMLModElement', 'HTMLQuoteElement',\r\n\r\n // \u2500\u2500 Core DOM types (document/node tree \u2014 not available in WeChat) \u2500\u2500\r\n // NOTE: DOMParser is intentionally KEPT (not listed here). Cocos 3.x's\r\n // plist asset parser (`_parseXML`) throws \"Dom parser is not supported\r\n // in this platform!\" when DOMParser is missing. On real WeChat, Cocos\r\n // uses a native C++ plist parser; we don't have that bridge, so we\r\n // expose the browser's DOMParser \u2014 which only provides XML parsing\r\n // (not a live DOM tree), matching the semantic the engine actually\r\n // needs here. Node/Element/Document constructors below remain deleted.\r\n 'Node', 'Element', 'Document', 'DocumentFragment', 'DocumentType',\r\n 'NamedNodeMap', 'DOMTokenList', 'DOMImplementation',\r\n 'Attr', 'CharacterData', 'Comment', 'CDATASection',\r\n\r\n // \u2500\u2500 SVG (not available in WeChat Mini Game) \u2500\u2500\r\n 'SVGElement', 'SVGSVGElement',\r\n\r\n // \u2500\u2500 Storage & IndexedDB (WeChat uses wx.setStorage, not localStorage) \u2500\u2500\r\n // localStorage/sessionStorage are safe to delete: the wx storage shim\r\n // (storage.ts) uses nativeLocalStorage captured in native-globals.ts\r\n // before cleanup runs.\r\n 'localStorage', 'sessionStorage',\r\n 'IDBFactory', 'IDBDatabase', 'IDBTransaction', 'IDBObjectStore',\r\n 'IDBIndex', 'IDBCursor', 'IDBCursorWithValue', 'IDBKeyRange',\r\n 'IDBRequest', 'IDBOpenDBRequest', 'IDBVersionChangeEvent',\r\n\r\n // \u2500\u2500 Navigation/History (no browser navigation in mini games) \u2500\u2500\r\n 'history', 'History', 'PopStateEvent', 'HashChangeEvent',\r\n\r\n // \u2500\u2500 Dialog APIs (use wx.showModal instead) \u2500\u2500\r\n 'alert', 'confirm', 'prompt',\r\n\r\n // \u2500\u2500 Window management (not available in mini games) \u2500\u2500\r\n 'open', 'close', 'print', 'stop',\r\n 'moveBy', 'moveTo', 'resizeBy', 'resizeTo',\r\n\r\n // \u2500\u2500 Service Workers & Cache (not in mini game runtime) \u2500\u2500\r\n 'ServiceWorker', 'ServiceWorkerContainer', 'ServiceWorkerRegistration',\r\n 'Cache', 'CacheStorage',\r\n\r\n // \u2500\u2500 Notifications (not available) \u2500\u2500\r\n 'Notification',\r\n\r\n // \u2500\u2500 Payment APIs (use wx.requestPayment) \u2500\u2500\r\n 'PaymentRequest', 'PaymentResponse', 'PaymentMethodChangeEvent',\r\n 'PaymentRequestUpdateEvent',\r\n\r\n // \u2500\u2500 Speech APIs \u2500\u2500\r\n 'SpeechSynthesis', 'SpeechSynthesisUtterance', 'SpeechSynthesisEvent',\r\n 'SpeechRecognition', 'SpeechRecognitionEvent',\r\n\r\n // \u2500\u2500 Deprecated/Legacy \u2500\u2500\r\n 'ApplicationCache',\r\n];\r\n\r\n// \u2500\u2500\u2500 Non-enumerable Window Properties to Remove \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// These constructors are non-enumerable but should be removed to match WeChat.\r\n// Game adapters (weapp-adapter.js) will re-shim the ones they need.\r\n\r\nconst WINDOW_NON_ENUM_REMOVE = [\r\n 'XMLHttpRequest', 'WebSocket', 'Audio',\r\n // DOMParser intentionally kept \u2014 see note in WINDOW_PROP_REMOVE above.\r\n 'HTMLElement', 'HTMLCanvasElement', 'HTMLImageElement',\r\n 'HTMLVideoElement', 'HTMLAudioElement', 'HTMLDivElement', 'HTMLSpanElement',\r\n 'HTMLUnknownElement', 'HTMLDocument', 'HTMLBodyElement', 'HTMLHeadElement',\r\n 'HTMLStyleElement', 'HTMLScriptElement', 'HTMLLinkElement',\r\n 'HTMLInputElement', 'HTMLButtonElement', 'HTMLFormElement',\r\n 'Node', 'Element', 'Document', 'DocumentFragment',\r\n 'NodeList', 'NamedNodeMap', 'DOMTokenList', 'DOMRect', 'DOMRectReadOnly',\r\n 'SVGElement', 'SVGSVGElement',\r\n 'fetch',\r\n 'localStorage', 'sessionStorage',\r\n 'indexedDB', 'IDBFactory', 'IDBDatabase', 'IDBTransaction',\r\n 'location', 'history',\r\n 'screen', 'devicePixelRatio',\r\n 'getComputedStyle', 'getSelection',\r\n 'alert', 'confirm', 'prompt',\r\n 'open', 'close', 'print',\r\n 'MutationObserver', 'IntersectionObserver', 'ResizeObserver',\r\n 'requestIdleCallback', 'cancelIdleCallback',\r\n];\r\n\r\n// \u2500\u2500\u2500 Document Prototype Properties to Force-Override \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// These are getter properties defined on Document.prototype (or HTMLDocument.prototype).\r\n// They can't be overridden by Object.defineProperty on the document instance\r\n// because the browser ignores own data properties that conflict with prototype\r\n// accessors. Instead, we must modify the prototype getter directly.\r\n//\r\n// In real WeChat Mini Game runtime, `document` doesn't exist at all.\r\n// In WeChat DevTools (nw.js), their cleanup can override these because nw.js\r\n// has different internal constraints. In standard Chromium WebView (our env),\r\n// we need prototype-level overrides.\r\n\r\nconst DOCUMENT_PROTOTYPE_FORCE_UNDEFINED = [\r\n // NOTE: 'documentElement' is no longer force-undefined here.\r\n // Instead, it is whitelisted in DOCUMENT_REMAIN and the document Proxy\r\n // returns a fake mock element (matching weapp-adapter behavior) so that\r\n // game frameworks like Phaser can call documentElement.appendChild (noop)\r\n // without errors, just like on real WeChat devices.\r\n\r\n // Other prototype getters that WeChat doesn't expose\r\n 'implementation',\r\n 'URL',\r\n 'documentURI',\r\n 'compatMode',\r\n 'characterSet',\r\n 'charset',\r\n 'inputEncoding',\r\n 'contentType',\r\n 'doctype',\r\n 'xmlEncoding',\r\n 'xmlVersion',\r\n 'xmlStandalone',\r\n 'domain',\r\n 'referrer',\r\n 'cookie',\r\n 'lastModified',\r\n 'title',\r\n 'dir',\r\n 'designMode',\r\n 'defaultView',\r\n 'onreadystatechange',\r\n 'embeds',\r\n 'plugins',\r\n 'scripts',\r\n 'all',\r\n 'currentScript',\r\n 'fullscreenEnabled',\r\n 'fullscreenElement',\r\n 'pictureInPictureEnabled',\r\n 'pictureInPictureElement',\r\n 'scrollingElement',\r\n 'timeline',\r\n 'featurePolicy',\r\n 'adoptedStyleSheets',\r\n 'images',\r\n 'links',\r\n 'forms',\r\n 'anchors',\r\n 'applets',\r\n 'rootElement',\r\n // DOM methods that don't exist in WeChat Mini Game runtime\r\n // (weapp-adapter's document object doesn't define them)\r\n 'elementFromPoint',\r\n 'elementsFromPoint',\r\n 'getSelection',\r\n 'createRange',\r\n 'createNodeIterator',\r\n 'createTreeWalker',\r\n 'importNode',\r\n 'adoptNode',\r\n 'createAttribute',\r\n 'createAttributeNS',\r\n 'createEvent',\r\n 'createComment',\r\n 'createCDATASection',\r\n 'createProcessingInstruction',\r\n 'caretRangeFromPoint',\r\n 'caretPositionFromPoint',\r\n 'exitFullscreen',\r\n 'exitPictureInPicture',\r\n 'getAnimations',\r\n 'getElementsByClassName',\r\n 'hasFocus',\r\n 'prepend',\r\n 'append',\r\n 'replaceChildren',\r\n 'write',\r\n 'writeln',\r\n 'open',\r\n 'close',\r\n // Event handlers on document\r\n 'onfullscreenchange',\r\n 'onfullscreenerror',\r\n 'onpointerlockchange',\r\n 'onpointerlockerror',\r\n 'onvisibilitychange',\r\n 'onbeforecopy',\r\n 'onbeforecut',\r\n 'onbeforepaste',\r\n 'onfreeze',\r\n 'onresume',\r\n 'onsearch',\r\n 'onsecuritypolicyviolation',\r\n 'onselectionchange',\r\n 'onwebkitfullscreenchange',\r\n 'onwebkitfullscreenerror',\r\n 'onprerenderingchange',\r\n];\r\n\r\n// \u2500\u2500\u2500 Window Prototype Properties to Force-Override \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// Same issue: some Window properties are prototype getters that survive\r\n// Object.getOwnPropertyNames-based deletion.\r\n\r\nconst WINDOW_PROTOTYPE_FORCE_UNDEFINED = [\r\n // NOTE: 'document' is NOT here \u2014 we replace it with a Proxy instead\r\n 'location',\r\n 'history',\r\n 'screen',\r\n 'screenX',\r\n 'screenY',\r\n 'screenLeft',\r\n 'screenTop',\r\n 'outerWidth',\r\n 'outerHeight',\r\n 'devicePixelRatio',\r\n 'clientInformation',\r\n 'styleMedia',\r\n 'defaultStatus',\r\n 'defaultstatus',\r\n 'isSecureContext',\r\n 'crossOriginIsolated',\r\n 'localStorage',\r\n 'sessionStorage',\r\n 'indexedDB',\r\n 'caches',\r\n 'cookieStore',\r\n 'launchQueue',\r\n 'documentPictureinPicture',\r\n 'getScreenDetails',\r\n 'getComputedStyle',\r\n 'getSelection',\r\n 'matchMedia',\r\n 'moveTo',\r\n 'moveBy',\r\n 'resizeTo',\r\n 'resizeBy',\r\n 'scroll',\r\n 'scrollBy',\r\n 'open',\r\n 'close',\r\n 'stop',\r\n 'focus',\r\n 'blur',\r\n 'print',\r\n 'alert',\r\n 'confirm',\r\n 'prompt',\r\n 'find',\r\n 'fetch',\r\n 'createImageBitmap',\r\n 'requestIdleCallback',\r\n 'cancelIdleCallback',\r\n];\r\n\r\n// \u2500\u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n// \u2500\u2500\u2500 Sandbox Configuration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Fine-grained control over which sandbox steps to apply.\r\n *\r\n * Each step can be independently enabled/disabled to help diagnose which\r\n * cleanup operations break specific preview features (e.g. resolution\r\n * switching, orientation toggling).\r\n */\r\nexport interface SandboxConfig {\r\n /** Remove non-whitelisted own properties from window (safe) */\r\n cleanWindowOwnProps: boolean;\r\n /** Remove specific non-enumerable constructors/APIs from window (safe, uses trimmed list) */\r\n cleanWindowNonEnumAPIs: boolean;\r\n /** Remove non-whitelisted properties from document (safe) */\r\n cleanDocumentProps: boolean;\r\n /** Override document prototype getters to return undefined (risky \u2014 may break DOM) */\r\n overrideDocumentPrototype: boolean;\r\n /** Override window prototype getters to return undefined (DANGEROUS \u2014 breaks location, screen, etc.) */\r\n overrideWindowPrototype: boolean;\r\n /** Replace window.document with a sandboxed Proxy (risky \u2014 may break adapter DOM access) */\r\n installDocumentProxy: boolean;\r\n}\r\n\r\n/** Default config: all sandbox operations enabled (native APIs are aliased, safe to fully sandbox) */\r\nexport const SANDBOX_SAFE_DEFAULTS: SandboxConfig = {\r\n cleanWindowOwnProps: true,\r\n cleanWindowNonEnumAPIs: true,\r\n cleanDocumentProps: true,\r\n overrideDocumentPrototype: true,\r\n overrideWindowPrototype: true,\r\n installDocumentProxy: true,\r\n};\r\n\r\n\r\n\r\n/**\r\n * Strip window and document down to whitelisted properties, matching\r\n * the WeChat Mini Game runtime sandbox.\r\n *\r\n * Call this AFTER installGlobalShims() and BEFORE game.js executes.\r\n *\r\n * @param enabledOrConfig Pass false to skip all cleanup, true to use safe defaults,\r\n * or a SandboxConfig object for fine-grained control.\r\n */\r\nexport function cleanGlobals(enabledOrConfig: boolean | SandboxConfig = true): void {\r\n // Resolve config\r\n let config: SandboxConfig;\r\n if (typeof enabledOrConfig === 'boolean') {\r\n if (!enabledOrConfig) {\r\n nativeConsole.log('[wx-compat][sandbox] Sandbox disabled \u2014 full browser environment retained');\r\n return;\r\n }\r\n config = { ...SANDBOX_SAFE_DEFAULTS };\r\n } else {\r\n config = enabledOrConfig;\r\n }\r\n\r\n nativeConsole.log('[wx-compat][sandbox] Sandbox config:', JSON.stringify(config));\r\n\r\n let windowCleaned = 0;\r\n let documentCleaned = 0;\r\n let protoCleaned = 0;\r\n\r\n // \u2500\u2500 Step A: Clean window own properties \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n if (config.cleanWindowOwnProps) {\r\n // BLACKLIST mode: only delete known DOM/BOM APIs that don't exist in WeChat\r\n // Mini Game runtime. This is much safer than whitelist mode (deleting everything\r\n // not explicitly kept) because it avoids accidentally removing properties that\r\n // game engines/adapters set on window during their initialization.\r\n //\r\n // The previous whitelist approach deleted 1000+ properties and broke game engine\r\n // internals (e.g. CanvasRenderingContext2D, HTMLCanvasElement, HTMLElement, etc.)\r\n // that adapters like Cocos web-adapter rely on for canvas resize handling.\r\n const deletedProps: string[] = [];\r\n\r\n for (const k of WINDOW_OWN_PROPS_REMOVE) {\r\n if (WINDOW_REMAIN[k] || JS_BUILTINS[k]) continue;\r\n\r\n const descriptor = Object.getOwnPropertyDescriptor(window, k);\r\n if (descriptor && descriptor.configurable === true) {\r\n try {\r\n delete (window as unknown as Record<string, unknown>)[k];\r\n deletedProps.push(k);\r\n windowCleaned++;\r\n } catch {\r\n // Some properties throw on delete despite configurable: true\r\n }\r\n }\r\n }\r\n nativeConsole.log('[wx-compat][sandbox][StepA] Deleted props (' + deletedProps.length + '):', deletedProps.join(', '));\r\n }\r\n\r\n // \u2500\u2500 Step B: Remove specific non-enumerable constructors/APIs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n if (config.cleanWindowNonEnumAPIs) {\r\n for (const k of WINDOW_NON_ENUM_REMOVE) {\r\n if (WINDOW_REMAIN[k] || JS_BUILTINS[k]) continue;\r\n const descriptor = Object.getOwnPropertyDescriptor(window, k);\r\n if (descriptor && descriptor.configurable === true) {\r\n try {\r\n delete (window as unknown as Record<string, unknown>)[k];\r\n windowCleaned++;\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n }\r\n }\r\n\r\n // \u2500\u2500 Step C: Clean document own + enumerable properties \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n if (config.cleanDocumentProps) {\r\n for (const k in document) {\r\n if (DOCUMENT_REMAIN[k]) continue;\r\n\r\n // Try own property first\r\n const ownDescriptor = Object.getOwnPropertyDescriptor(document, k);\r\n if (ownDescriptor) {\r\n if (ownDescriptor.configurable === true) {\r\n try {\r\n delete (document as unknown as Record<string, unknown>)[k];\r\n Object.defineProperty(document, k, {\r\n configurable: true,\r\n value: undefined,\r\n });\r\n documentCleaned++;\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n } else {\r\n // Property is from the prototype chain \u2014 try to shadow it on the instance\r\n try {\r\n Object.defineProperty(document, k, {\r\n configurable: true,\r\n writable: true,\r\n value: undefined,\r\n });\r\n documentCleaned++;\r\n } catch {\r\n // Prototype getter can't be shadowed on instance \u2014 will handle below\r\n }\r\n }\r\n }\r\n }\r\n\r\n // \u2500\u2500 Step D: Force-override document prototype getters \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // These are getters on Document.prototype / HTMLDocument.prototype that can't\r\n // be shadowed by creating own properties. We must modify the prototype itself.\r\n\r\n if (config.overrideDocumentPrototype) {\r\n const docProto = Object.getPrototypeOf(document);\r\n for (const k of DOCUMENT_PROTOTYPE_FORCE_UNDEFINED) {\r\n if (DOCUMENT_REMAIN[k]) continue;\r\n\r\n // Check if our instance-level override already worked\r\n try {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const val = (document as any)[k];\r\n if (val === undefined) continue; // Already cleaned\r\n } catch {\r\n continue; // Accessing it throws \u2014 effectively removed\r\n }\r\n\r\n // Try to override on the instance first (cheapest)\r\n try {\r\n Object.defineProperty(document, k, {\r\n configurable: true,\r\n writable: true,\r\n value: undefined,\r\n });\r\n protoCleaned++;\r\n continue;\r\n } catch {\r\n // Can't shadow on instance \u2014 fall through to prototype\r\n }\r\n\r\n // Override the getter on the prototype chain\r\n // Walk up prototypes to find where the getter lives\r\n let proto = docProto;\r\n while (proto) {\r\n const protoDesc = Object.getOwnPropertyDescriptor(proto, k);\r\n if (protoDesc) {\r\n if (protoDesc.configurable) {\r\n try {\r\n Object.defineProperty(proto, k, {\r\n configurable: true,\r\n get() { return undefined; },\r\n set() { /* no-op \u2014 matches WeChat behaviour where assignment silently fails or throws */ },\r\n });\r\n protoCleaned++;\r\n } catch {\r\n // Last resort: ignore\r\n }\r\n }\r\n break;\r\n }\r\n proto = Object.getPrototypeOf(proto);\r\n }\r\n }\r\n } // end overrideDocumentPrototype\r\n\r\n // \u2500\u2500 Step E: Force-override window prototype getters \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Same approach for window properties that are prototype getters.\r\n // NOTE: This overrides `location`, `screen`, `devicePixelRatio`,\r\n // `matchMedia`, `fetch` etc. at the prototype level. This is safe because\r\n // all internal code uses aliased natives (native-globals.ts) captured before\r\n // cleanup runs.\r\n\r\n if (config.overrideWindowPrototype) {\r\n const winProto = Object.getPrototypeOf(window);\r\n for (const k of WINDOW_PROTOTYPE_FORCE_UNDEFINED) {\r\n if (WINDOW_REMAIN[k] || JS_BUILTINS[k]) continue;\r\n\r\n // Check if already cleaned\r\n try {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const val = (window as any)[k];\r\n if (val === undefined) continue;\r\n } catch {\r\n continue;\r\n }\r\n\r\n // Try instance-level override\r\n try {\r\n Object.defineProperty(window, k, {\r\n configurable: true,\r\n writable: true,\r\n value: undefined,\r\n });\r\n protoCleaned++;\r\n continue;\r\n } catch {\r\n // Fall through to prototype\r\n }\r\n\r\n // Walk prototype chain\r\n let proto = winProto;\r\n while (proto) {\r\n const protoDesc = Object.getOwnPropertyDescriptor(proto, k);\r\n if (protoDesc) {\r\n if (protoDesc.configurable) {\r\n try {\r\n Object.defineProperty(proto, k, {\r\n configurable: true,\r\n get() { return undefined; },\r\n set() {},\r\n });\r\n protoCleaned++;\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n break;\r\n }\r\n proto = Object.getPrototypeOf(proto);\r\n }\r\n }\r\n } // end overrideWindowPrototype\r\n\r\n // \u2500\u2500 Step F: Replace window.document with a sandboxed proxy \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // After cleaning document properties, wrap it in a Proxy so that any\r\n // remaining prototype getters we couldn't override still return undefined.\r\n // The Proxy only intercepts property access on the document object itself;\r\n // the original native document is preserved in window.__global.document.\r\n\r\n if (config.installDocumentProxy) {\r\n try {\r\n // \u2500\u2500 WeChat-compatible document method shims \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // In real WeChat Mini Game runtime, document is a plain object created by\r\n // weapp-adapter with custom implementations of getElementById, createElement,\r\n // etc. We create bound shims here that match that behavior.\r\n\r\n // getElementById: only finds the main canvas by its id, returns null for everything else.\r\n // This matches weapp-adapter/document.js: getElementById(id) { if (id === window.canvas.id) return window.canvas; return null; }\r\n const shimGetElementById = (id: string): unknown => {\r\n const mainCanvas = getMainCanvas();\r\n const winCanvas = (window as unknown as Record<string, unknown>).canvas as HTMLCanvasElement | undefined;\r\n // Match by main canvas id or window.canvas.id (same as weapp-adapter behavior)\r\n if (mainCanvas && id === mainCanvas.id) {\r\n return winCanvas || mainCanvas;\r\n }\r\n if (winCanvas && (winCanvas as unknown as Record<string, unknown>).id === id) {\r\n return winCanvas;\r\n }\r\n return null;\r\n };\r\n\r\n // createElement: matches weapp-adapter/document.js behavior.\r\n // 'canvas' \u2192 wx.createCanvas() (returns off-screen canvas since main canvas is already created)\r\n // 'img' \u2192 wx.createImage()\r\n // 'audio' \u2192 new Audio() (handled by native)\r\n // others \u2192 minimal mock HTMLElement\r\n const shimCreateElement = (tagName: string): unknown => {\r\n tagName = tagName.toLowerCase();\r\n if (tagName === 'canvas') {\r\n // In real WeChat, document.createElement('canvas') calls new Canvas()\r\n // which internally calls wx.createCanvas(). Since the first wx.createCanvas()\r\n // call was already consumed by GameGlobal.screencanvas initialization,\r\n // subsequent calls return new off-screen canvases.\r\n return createCanvas();\r\n } else if (tagName === 'img') {\r\n return createImage();\r\n } else if (tagName === 'audio') {\r\n return nativeCreateElement('audio');\r\n }\r\n // For other tags, return a minimal mock element (matching weapp-adapter's HTMLElement)\r\n return {\r\n tagName: tagName.toUpperCase(),\r\n type: tagName,\r\n style: {},\r\n children: [],\r\n childNodes: [],\r\n parentNode: null,\r\n parentElement: null,\r\n className: '',\r\n classList: { add: () => {}, remove: () => {}, contains: () => false, toggle: () => {} },\r\n innerHTML: '',\r\n appendChild: () => {},\r\n removeChild: () => {},\r\n insertBefore: () => {},\r\n addEventListener: () => {},\r\n removeEventListener: () => {},\r\n setAttribute: () => {},\r\n getAttribute: () => null,\r\n focus: () => {},\r\n blur: () => {},\r\n };\r\n };\r\n\r\n // createElementNS: delegates to createElement (same as weapp-adapter)\r\n const shimCreateElementNS = (_nameSpace: string, tagName: string): unknown => {\r\n return shimCreateElement(tagName);\r\n };\r\n\r\n // querySelector: matches weapp-adapter/document.js behavior\r\n const shimQuerySelector = (query: string): unknown => {\r\n const winCanvas = (window as unknown as Record<string, unknown>).canvas as HTMLCanvasElement | undefined;\r\n if (query === 'head') {\r\n return documentOverrides.get('head') ?? null;\r\n } else if (query === 'body') {\r\n return documentOverrides.get('body') ?? null;\r\n } else if (query === 'canvas') {\r\n return winCanvas ?? null;\r\n } else if (winCanvas && query === `#${(winCanvas as unknown as Record<string, unknown>).id}`) {\r\n return winCanvas;\r\n }\r\n return null;\r\n };\r\n\r\n // querySelectorAll: matches weapp-adapter/document.js behavior\r\n const shimQuerySelectorAll = (query: string): unknown[] => {\r\n const winCanvas = (window as unknown as Record<string, unknown>).canvas as HTMLCanvasElement | undefined;\r\n if (query === 'head') {\r\n const head = documentOverrides.get('head');\r\n return head ? [head] : [];\r\n } else if (query === 'body') {\r\n const body = documentOverrides.get('body');\r\n return body ? [body] : [];\r\n } else if (query === 'canvas') {\r\n return winCanvas ? [winCanvas] : [];\r\n }\r\n return [];\r\n };\r\n\r\n // getElementsByTagName: matches weapp-adapter/document.js behavior\r\n const shimGetElementsByTagName = (tagName: string): unknown[] => {\r\n tagName = tagName.toLowerCase();\r\n const winCanvas = (window as unknown as Record<string, unknown>).canvas as HTMLCanvasElement | undefined;\r\n if (tagName === 'head') {\r\n const head = documentOverrides.get('head');\r\n return head ? [head] : [];\r\n } else if (tagName === 'body') {\r\n const body = documentOverrides.get('body');\r\n return body ? [body] : [];\r\n } else if (tagName === 'canvas') {\r\n return winCanvas ? [winCanvas] : [];\r\n }\r\n return [];\r\n };\r\n\r\n // getElementsByTagNameNS: delegates to getElementsByTagName (same as weapp-adapter)\r\n const shimGetElementsByTagNameNS = (_nameSpace: string, tagName: string): unknown[] => {\r\n return shimGetElementsByTagName(tagName);\r\n };\r\n\r\n // Map of document methods that should use our shims instead of native browser methods\r\n const documentMethodShims: Record<string, unknown> = {\r\n getElementById: shimGetElementById,\r\n createElement: shimCreateElement,\r\n createElementNS: shimCreateElementNS,\r\n querySelector: shimQuerySelector,\r\n querySelectorAll: shimQuerySelectorAll,\r\n getElementsByTagName: shimGetElementsByTagName,\r\n getElementsByTagNameNS: shimGetElementsByTagNameNS,\r\n };\r\n\r\n const sandboxedDocument = new Proxy(document, {\r\n get(target, prop, receiver) {\r\n // For adapter-owned properties (documentElement, body, head),\r\n // return from override store only. If the adapter hasn't set them,\r\n // return undefined (matching WeChat runtime where these don't exist\r\n // until the adapter creates them).\r\n if (typeof prop === 'string' && DOCUMENT_ADAPTER_OWNED[prop]) {\r\n if (documentOverrides.has(prop)) {\r\n return documentOverrides.get(prop);\r\n }\r\n // Not set by adapter \u2014 return undefined\r\n return undefined;\r\n }\r\n // Return shimmed document methods that match weapp-adapter behavior\r\n if (typeof prop === 'string' && documentMethodShims[prop]) {\r\n return documentMethodShims[prop];\r\n }\r\n // Allow whitelisted properties\r\n if (typeof prop === 'string' && DOCUMENT_REMAIN[prop]) {\r\n return Reflect.get(target, prop, receiver);\r\n }\r\n // Allow symbols (iterator, toStringTag, etc.)\r\n if (typeof prop === 'symbol') {\r\n return Reflect.get(target, prop, receiver);\r\n }\r\n // Block everything else\r\n return undefined;\r\n },\r\n set(target, prop, value) {\r\n // For adapter-owned properties, store in the override map so that\r\n // subsequent reads return exactly what the adapter wrote.\r\n // This replicates real WeChat behavior where the adapter creates\r\n // document as a plain object and freely assigns properties.\r\n if (typeof prop === 'string' && DOCUMENT_ADAPTER_OWNED[prop]) {\r\n documentOverrides.set(prop, value);\r\n return true;\r\n }\r\n // Allow setting whitelisted properties (game adapters may need this)\r\n if (typeof prop === 'string' && DOCUMENT_REMAIN[prop]) {\r\n return Reflect.set(target, prop, value);\r\n }\r\n // For non-whitelisted: allow setting on the target but it won't be readable\r\n // This matches WeChat DevTools behavior where assignment succeeds but reads return undefined\r\n try {\r\n return Reflect.set(target, prop, value);\r\n } catch {\r\n return true;\r\n }\r\n },\r\n has(target, prop) {\r\n // 'in' operator \u2014 only whitelisted properties should be found\r\n if (typeof prop === 'string' && DOCUMENT_ADAPTER_OWNED[prop]) {\r\n // Adapter-owned: report present only if the adapter has set it\r\n return documentOverrides.has(prop);\r\n }\r\n if (typeof prop === 'string' && DOCUMENT_REMAIN[prop]) {\r\n return prop in target;\r\n }\r\n if (typeof prop === 'symbol') {\r\n return prop in target;\r\n }\r\n return false;\r\n },\r\n });\r\n\r\n // Override store: holds values that game adapters write to document\r\n // (e.g. document.documentElement = {...}, document.body = {...}).\r\n // This ensures adapter writes are faithfully returned on subsequent reads,\r\n // matching real WeChat behavior where document is a plain adapter-created object.\r\n const documentOverrides = new Map<string, unknown>();\r\n\r\n // \u2500\u2500 Pre-populate adapter-owned properties with WeChat-compatible mocks \u2500\u2500\u2500\u2500\r\n // In the real WeChat Mini Game runtime, document.body is a minimal object\r\n // created by weapp-adapter (e.g. { appendChild(){}, style:{} }) that does NOT\r\n // have getBoundingClientRect. Game frameworks like Phaser's ScaleManager call\r\n // this.parent.getBoundingClientRect() when parent falls back to document.body,\r\n // which fails on real devices. By pre-setting these mocks, our preview catches\r\n // the same error instead of silently using the browser's native HTMLBodyElement.\r\n //\r\n // Game adapters (e.g. Cocos web-adapter, Phaser adapter) can still overwrite\r\n // these via `document.body = ...` which goes through the Proxy set() handler\r\n // and updates documentOverrides.\r\n const noop = () => {};\r\n // Create a mock element matching the WeChat Mini Game runtime behavior.\r\n // - getBoundingClientRect is intentionally omitted on ALL mock elements\r\n // because real WeChat document.body does NOT have this method.\r\n // - appendChild/removeChild/insertBefore are included on body & head\r\n // (weapp-adapter's Body & HTMLElement classes define them as noop),\r\n // but OMITTED on documentElement to match iOS WeChat behavior where\r\n // document.documentElement.appendChild is not a function.\r\n // (Android has it via weapp-adapter, but iOS does not \u2014 we match the\r\n // strictest platform so developers catch iOS issues during preview.)\r\n const createMinimalMockElement = (tagName: string, opts?: { omitDomMutations?: boolean }): Record<string, unknown> => {\r\n const el: Record<string, unknown> = {\r\n tagName: tagName.toUpperCase(),\r\n style: {},\r\n children: [],\r\n childNodes: [],\r\n addEventListener: noop,\r\n removeEventListener: noop,\r\n setAttribute: noop,\r\n getAttribute: () => null,\r\n innerHTML: '',\r\n className: '',\r\n classList: { add: noop, remove: noop, contains: () => false, toggle: noop },\r\n parentNode: null,\r\n parentElement: null,\r\n };\r\n // Only add DOM mutation methods when NOT omitted (body/head have them, documentElement on iOS does not)\r\n if (!opts?.omitDomMutations) {\r\n el.appendChild = noop;\r\n el.removeChild = noop;\r\n el.insertBefore = noop;\r\n }\r\n return el;\r\n };\r\n const mockBody = createMinimalMockElement('body');\r\n // Expose pointer-lock & fullscreen methods on mock body so that Unity/Emscripten\r\n // capability checks (e.g. _emscripten_set_pointerlockchange_callback_on_thread)\r\n // detect support and register the necessary event callbacks.\r\n // These delegate to the real native body element preserved in native-globals.\r\n if (nativeBody.requestPointerLock) {\r\n mockBody.requestPointerLock = nativeBody.requestPointerLock.bind(nativeBody);\r\n }\r\n if (nativeBody.requestFullscreen) {\r\n mockBody.requestFullscreen = nativeBody.requestFullscreen.bind(nativeBody);\r\n }\r\n if ((nativeBody as unknown as Record<string, unknown>).webkitRequestFullscreen) {\r\n mockBody.webkitRequestFullscreen = ((nativeBody as unknown as Record<string, unknown>).webkitRequestFullscreen as Function).bind(nativeBody);\r\n }\r\n documentOverrides.set('body', mockBody);\r\n documentOverrides.set('head', createMinimalMockElement('head'));\r\n // documentElement: omit appendChild/removeChild/insertBefore to match iOS WeChat\r\n // where document.documentElement.appendChild is not a function\r\n documentOverrides.set('documentElement', createMinimalMockElement('html', { omitDomMutations: true }));\r\n nativeConsole.log('[wx-compat][sandbox] Pre-populated document.body/head/documentElement with WeChat-compatible mocks (no getBoundingClientRect, documentElement has no appendChild)');\r\n nativeConsole.log('[wx-compat][pointerlock] mockBody.requestPointerLock =', typeof mockBody.requestPointerLock);\r\n\r\n // Replace window.document with the proxied version\r\n // Note: window.document is usually non-configurable in browsers,\r\n // so we try multiple approaches\r\n let proxyInstalled = false;\r\n try {\r\n Object.defineProperty(window, 'document', {\r\n configurable: true,\r\n get() { return sandboxedDocument; },\r\n });\r\n proxyInstalled = true;\r\n nativeConsole.log('[wx-compat][sandbox] document replaced with sandboxed proxy');\r\n } catch {\r\n // If we can't replace window.document, the prototype overrides above\r\n // are our fallback \u2014 they handle the most critical cases like documentElement\r\n nativeConsole.log('[wx-compat][sandbox] Could not replace window.document (non-configurable), using prototype overrides');\r\n }\r\n\r\n // \u2500\u2500 Fallback: patch document.body directly when proxy replacement failed \u2500\u2500\r\n // When Object.defineProperty fails (window.document is non-configurable),\r\n // game code still accesses the native document.body which has\r\n // getBoundingClientRect \u2014 hiding real-device errors. Patch it in-place.\r\n if (!proxyInstalled) {\r\n try {\r\n const mockBody = createMinimalMockElement('body');\r\n Object.defineProperty(document, 'body', {\r\n configurable: true,\r\n get() { return mockBody; },\r\n set(val) {\r\n // Allow adapters to replace it\r\n Object.defineProperty(document, 'body', {\r\n configurable: true,\r\n writable: true,\r\n value: val,\r\n });\r\n },\r\n });\r\n nativeConsole.log('[wx-compat][sandbox] Patched document.body with WeChat-compatible mock (fallback)');\r\n } catch {\r\n nativeConsole.warn('[wx-compat][sandbox] Could not patch document.body \u2014 preview may not catch getBoundingClientRect errors');\r\n }\r\n }\r\n } catch (e) {\r\n nativeConsole.warn('[wx-compat][sandbox] Failed to create document proxy:', e);\r\n }\r\n } // end installDocumentProxy\r\n\r\n // \u2500\u2500 Step G: Restore devicePixelRatio with simulated value \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Steps B & E removed window.devicePixelRatio (it doesn't exist in WeChat\r\n // Mini Game runtime natively). However, many game engines (Cocos, Phaser,\r\n // Three.js, etc.) read `window.devicePixelRatio` directly to determine the\r\n // rendering resolution. In the real WeChat runtime, the adapter or runtime\r\n // provides this value. We restore it here with the simulated DPR from the\r\n // URL params / __wxDevicePixelRatio so that game code gets the correct device pixel ratio.\r\n {\r\n const _wxDpr = typeof (window as unknown as Record<string, unknown>).__wxDevicePixelRatio === 'number'\r\n ? ((window as unknown as Record<string, unknown>).__wxDevicePixelRatio as number)\r\n : 0;\r\n const _params = new URLSearchParams(nativeLocation.search);\r\n const _pdpr = _wxDpr || parseFloat(_params.get('dpr') || '0');\r\n const simulatedDPR = (_pdpr > 0 && _pdpr <= 5) ? _pdpr : (nativeDevicePixelRatio || 2);\r\n try {\r\n Object.defineProperty(window, 'devicePixelRatio', {\r\n configurable: true,\r\n writable: true,\r\n value: simulatedDPR,\r\n });\r\n nativeConsole.log(`[wx-compat][sandbox] Restored window.devicePixelRatio = ${simulatedDPR}`);\r\n } catch {\r\n // If instance-level override fails, try prototype-level\r\n try {\r\n const winProto = Object.getPrototypeOf(window);\r\n let proto = winProto;\r\n while (proto) {\r\n const desc = Object.getOwnPropertyDescriptor(proto, 'devicePixelRatio');\r\n if (desc && desc.configurable) {\r\n Object.defineProperty(proto, 'devicePixelRatio', {\r\n configurable: true,\r\n get() { return simulatedDPR; },\r\n set() {},\r\n });\r\n nativeConsole.log(`[wx-compat][sandbox] Restored window.devicePixelRatio = ${simulatedDPR} (prototype)`);\r\n break;\r\n }\r\n proto = Object.getPrototypeOf(proto);\r\n }\r\n } catch {\r\n nativeConsole.warn('[wx-compat][sandbox] Could not restore window.devicePixelRatio');\r\n }\r\n }\r\n }\r\n\r\n nativeConsole.log(\r\n `[wx-compat][sandbox] Environment cleaned: ${windowCleaned} window props, ` +\r\n `${documentCleaned} document props, ${protoCleaned} prototype overrides`\r\n );\r\n}\r\n", "/**\r\n * API Monitor \u2014 tracks all wx.xxx and global API invocations with call counts.\r\n *\r\n * When enabled (via `window.__wxApiMonitorEnabled`), this module:\r\n * 1. Wraps the wx Proxy so that every property access that leads to a\r\n * function call is counted.\r\n * 2. Tracks global function calls (setTimeout, setInterval, requestAnimationFrame, etc.)\r\n * that are exposed to game code through the GameGlobal sandbox.\r\n * 3. Periodically (or on-demand) posts an aggregate report to the parent frame\r\n * via postMessage, which the host then relays to the caller's `onApiMonitorReport` callback.\r\n *\r\n * Report payload shape:\r\n * {\r\n * type: '__wx_api_monitor_report__',\r\n * appId: string,\r\n * timestamp: number,\r\n * apis: Array<{ name: string, callCount: number }>\r\n * }\r\n */\r\n\r\n// \u2500\u2500 Call Counter Storage \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst wxApiCalls = new Map<string, number>();\r\nconst globalApiCalls = new Map<string, number>();\r\n\r\n/** Record a wx.xxx API call */\r\nexport function recordWxApiCall(apiName: string): void {\r\n wxApiCalls.set(apiName, (wxApiCalls.get(apiName) || 0) + 1);\r\n}\r\n\r\n/** Record a global API call (e.g. setTimeout, requestAnimationFrame) */\r\nexport function recordGlobalApiCall(apiName: string): void {\r\n globalApiCalls.set(apiName, (globalApiCalls.get(apiName) || 0) + 1);\r\n}\r\n\r\n// \u2500\u2500 Monitoring State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nlet monitorEnabled = false;\r\nlet reportIntervalId: ReturnType<typeof setInterval> | null = null;\r\n\r\n/** Default report interval: 10 seconds */\r\nconst DEFAULT_REPORT_INTERVAL_MS = 10_000;\r\n\r\n/**\r\n * Check if API monitoring is enabled.\r\n */\r\nexport function isMonitorEnabled(): boolean {\r\n return monitorEnabled;\r\n}\r\n\r\n/**\r\n * Initialize the API monitor based on window config.\r\n * Called during wx-compat startup AFTER device config is injected.\r\n */\r\nexport function initApiMonitor(): void {\r\n const win = window as unknown as Record<string, unknown>;\r\n monitorEnabled = !!(win.__wxApiMonitorEnabled);\r\n\r\n if (!monitorEnabled) return;\r\n\r\n const intervalMs =\r\n (typeof win.__wxApiMonitorInterval === 'number' && win.__wxApiMonitorInterval > 0)\r\n ? win.__wxApiMonitorInterval as number\r\n : DEFAULT_REPORT_INTERVAL_MS;\r\n\r\n console.log(\r\n `[wx-compat][api-monitor] Enabled. Report interval: ${intervalMs}ms`\r\n );\r\n\r\n // Start periodic reporting\r\n reportIntervalId = setInterval(() => {\r\n flushReport();\r\n }, intervalMs);\r\n\r\n // Also report before the page unloads\r\n window.addEventListener('beforeunload', () => {\r\n flushReport();\r\n });\r\n}\r\n\r\n/**\r\n * Flush the current accumulated data and post it to the parent frame.\r\n * After flushing, counters are reset.\r\n */\r\nexport function flushReport(): void {\r\n if (!monitorEnabled) return;\r\n\r\n const win = window as unknown as Record<string, unknown>;\r\n const appId = (win.__wxAppid as string) || (win.__wxMonitorAppId as string) || 'unknown';\r\n\r\n // Build the merged report\r\n const apis: Array<{ name: string; callCount: number }> = [];\r\n\r\n for (const [name, count] of wxApiCalls.entries()) {\r\n if (count > 0) {\r\n apis.push({ name: `wx.${name}`, callCount: count });\r\n }\r\n }\r\n for (const [name, count] of globalApiCalls.entries()) {\r\n if (count > 0) {\r\n apis.push({ name, callCount: count });\r\n }\r\n }\r\n\r\n // Skip empty reports\r\n if (apis.length === 0) return;\r\n\r\n // Sort by callCount desc for readability\r\n apis.sort((a, b) => b.callCount - a.callCount);\r\n\r\n const report = {\r\n type: '__wx_api_monitor_report__',\r\n appId,\r\n timestamp: Date.now(),\r\n apis,\r\n };\r\n\r\n // Post to parent frame\r\n try {\r\n window.parent.postMessage(report, '*');\r\n } catch (e) {\r\n console.warn('[wx-compat][api-monitor] Failed to post report:', e);\r\n }\r\n\r\n // Reset counters after reporting\r\n wxApiCalls.clear();\r\n globalApiCalls.clear();\r\n}\r\n\r\n/**\r\n * Stop the API monitor (cleanup).\r\n */\r\nexport function stopApiMonitor(): void {\r\n if (reportIntervalId !== null) {\r\n clearInterval(reportIntervalId);\r\n reportIntervalId = null;\r\n }\r\n monitorEnabled = false;\r\n}\r\n\r\n// \u2500\u2500 Proxy Wrappers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Wrap a wx API object with call-counting instrumentation.\r\n * Returns a Proxy that intercepts function calls and records them.\r\n *\r\n * @param wxProxy - The original wx Proxy object\r\n * @returns A new Proxy that adds monitoring on top\r\n */\r\nexport function wrapWxWithMonitor<T extends object>(wxProxy: T): T {\r\n if (!monitorEnabled) return wxProxy;\r\n\r\n return new Proxy(wxProxy, {\r\n get(target, prop, receiver) {\r\n const value = Reflect.get(target, prop, receiver);\r\n if (typeof prop === 'symbol') return value;\r\n\r\n const key = String(prop);\r\n\r\n // If it's a function, wrap it to count calls\r\n if (typeof value === 'function') {\r\n return function monitoredWxApi(this: unknown, ...args: unknown[]) {\r\n recordWxApiCall(key);\r\n return (value as Function).apply(this, args);\r\n };\r\n }\r\n\r\n return value;\r\n },\r\n });\r\n}\r\n\r\n/**\r\n * List of WeChat-specific global functions/constructors that should be\r\n * monitored when accessed via the GameGlobal sandbox proxy.\r\n *\r\n * Standard browser APIs (setTimeout, fetch, XMLHttpRequest, WebSocket, etc.)\r\n * are NOT monitored \u2014 only globals that are unique to the WeChat Mini Game\r\n * runtime environment and are callable (typeof === 'function').\r\n *\r\n * Note: wx.xxx APIs are monitored separately via wrapWxWithMonitor().\r\n */\r\nexport const MONITORED_GLOBALS = new Set([\r\n // WeChat's Image factory (window.Image is replaced with wx.createImage shim)\r\n 'Image',\r\n]);\r\n\r\n/**\r\n * Wrap a global function value with call-counting instrumentation.\r\n * Used by the GameGlobal proxy's get trap.\r\n *\r\n * Supports both regular function calls (e.g. `setTimeout(fn, 100)`) and\r\n * constructor calls (e.g. `new XMLHttpRequest()`). We use a Proxy with\r\n * both `apply` and `construct` traps to handle both cases transparently.\r\n *\r\n * @param name - The global function name (e.g. 'setTimeout')\r\n * @param value - The actual function\r\n * @returns Wrapped function that records calls\r\n */\r\nexport function wrapGlobalWithMonitor(name: string, value: Function): Function {\r\n if (!monitorEnabled) return value;\r\n if (!MONITORED_GLOBALS.has(name)) return value;\r\n\r\n return new Proxy(value, {\r\n apply(_target, thisArg, argArray) {\r\n recordGlobalApiCall(name);\r\n return Reflect.apply(value, thisArg, argArray);\r\n },\r\n construct(_target, argArray, newTarget) {\r\n recordGlobalApiCall(name);\r\n return Reflect.construct(value, argArray, newTarget);\r\n },\r\n });\r\n}\r\n", "/**\r\n * Share API stubs (P0 \u2014 prevents runtime errors).\r\n *\r\n * In the real WeChat runtime, share APIs trigger native share sheets.\r\n * In preview mode, these are no-ops that call success/complete callbacks.\r\n *\r\n * Reference: official devtools marks share APIs as `ibForbiddenApi`\r\n * (disabled in preview), so returning success without action is correct.\r\n */\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype AnyCallback = (...args: any[]) => void;\r\n\r\ninterface CallbackOpts {\r\n success?: AnyCallback;\r\n fail?: AnyCallback;\r\n complete?: AnyCallback;\r\n [key: string]: unknown;\r\n}\r\n\r\n// \u2500\u2500\u2500 Share message listeners \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst shareAppMessageListeners = new Set<AnyCallback>();\r\n\r\n/**\r\n * wx.onShareAppMessage \u2014 register a handler to provide share content.\r\n * Stored but never triggered in preview mode.\r\n */\r\nexport function onShareAppMessage(callback: AnyCallback): void {\r\n shareAppMessageListeners.add(callback);\r\n}\r\n\r\n/**\r\n * wx.offShareAppMessage \u2014 remove a previously registered handler.\r\n */\r\nexport function offShareAppMessage(callback: AnyCallback): void {\r\n shareAppMessageListeners.delete(callback);\r\n}\r\n\r\n// \u2500\u2500\u2500 Share actions (no-op) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * wx.shareAppMessage \u2014 trigger sharing. No-op in preview.\r\n */\r\nexport function shareAppMessage(opts?: CallbackOpts): void {\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.showShareMenu \u2014 show the share button in title bar. No-op in preview.\r\n */\r\nexport function showShareMenu(opts?: CallbackOpts): void {\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.hideShareMenu \u2014 hide the share button. No-op in preview.\r\n */\r\nexport function hideShareMenu(opts?: CallbackOpts): void {\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.updateShareMenu \u2014 update share menu settings. No-op in preview.\r\n */\r\nexport function updateShareMenu(opts?: CallbackOpts): void {\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.showShareImageMenu \u2014 show image share menu. No-op in preview.\r\n */\r\nexport function showShareImageMenu(opts?: CallbackOpts): void {\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.shareFileMessage \u2014 share a file message. No-op in preview.\r\n */\r\nexport function shareFileMessage(opts?: CallbackOpts): void {\r\n opts?.success?.();\r\n opts?.complete?.();\r\n}\r\n\r\n// \u2500\u2500\u2500 Share timeline \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst shareTimelineListeners = new Set<AnyCallback>();\r\n\r\n/**\r\n * wx.onShareTimeline \u2014 register handler for timeline share content.\r\n */\r\nexport function onShareTimeline(callback: AnyCallback): void {\r\n shareTimelineListeners.add(callback);\r\n}\r\n\r\n/**\r\n * wx.offShareTimeline \u2014 remove timeline share handler.\r\n */\r\nexport function offShareTimeline(callback: AnyCallback): void {\r\n shareTimelineListeners.delete(callback);\r\n}\r\n\r\n// \u2500\u2500\u2500 Add to favorites \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// wx.onAddToFavorites fires when the user taps \"Add to Favorites\" in the\r\n// menu. The handler provides favorites-sheet metadata (title, imageUrl,\r\n// query). In preview we register the handler but never invoke it \u2014 the\r\n// exact same treatment as onShareAppMessage.\r\n\r\nconst addToFavoritesListeners = new Set<AnyCallback>();\r\n\r\n/**\r\n * wx.onAddToFavorites \u2014 register handler for the \"Add to Favorites\" menu.\r\n * Stored but never triggered in preview mode.\r\n */\r\nexport function onAddToFavorites(callback: AnyCallback): void {\r\n addToFavoritesListeners.add(callback);\r\n}\r\n\r\n/**\r\n * wx.offAddToFavorites \u2014 remove a previously registered handler.\r\n */\r\nexport function offAddToFavorites(callback: AnyCallback): void {\r\n addToFavoritesListeners.delete(callback);\r\n}\r\n\r\n// \u2500\u2500\u2500 Share message to friend (open-data-domain) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n//\r\n// Basic library 2.9.4+. `wx.shareMessageToFriend` is used from the open data\r\n// context to share a card to a specific friend. `wx.onShareMessageToFriend`\r\n// listens for success/failure of that operation in the main domain.\r\n//\r\n// In preview mode there is no open-data channel and no friend to share\r\n// with, so:\r\n// - shareMessageToFriend is a no-op (returns nothing, matching the real\r\n// signature \u2014 the result comes via the main-domain listener, not a\r\n// direct callback).\r\n// - onShareMessageToFriend stores the listener but never triggers it.\r\n//\r\n// Reference:\r\n// https://developers.weixin.qq.com/minigame/dev/api/share/wx.onShareMessageToFriend.html\r\n// https://developers.weixin.qq.com/minigame/dev/api/open-api/share/wx.shareMessageToFriend.html\r\n\r\nconst shareMessageToFriendListeners = new Set<AnyCallback>();\r\n\r\n/**\r\n * wx.onShareMessageToFriend \u2014 register a listener for the result of\r\n * `wx.shareMessageToFriend`. Listener receives `{ success, errMsg }`.\r\n * Stored but never invoked in preview.\r\n */\r\nexport function onShareMessageToFriend(callback: AnyCallback): void {\r\n if (typeof callback !== 'function') return;\r\n shareMessageToFriendListeners.add(callback);\r\n}\r\n\r\n/**\r\n * wx.offShareMessageToFriend \u2014 remove a previously registered listener.\r\n */\r\nexport function offShareMessageToFriend(callback: AnyCallback): void {\r\n shareMessageToFriendListeners.delete(callback);\r\n}\r\n\r\n/**\r\n * wx.shareMessageToFriend \u2014 share a card to a specific friend from the\r\n * open-data context. In preview we cannot really share, but many games\r\n * gate progression on the success callback firing. To keep the game\r\n * playable we asynchronously notify all registered listeners with a\r\n * success result.\r\n */\r\nexport function shareMessageToFriend(_opts?: {\r\n openId: string;\r\n title?: string;\r\n imageUrl?: string;\r\n imageUrlId?: string;\r\n query?: string;\r\n}): void {\r\n // Dispatch asynchronously to match the real platform semantics (the\r\n // main-domain listener fires in a later tick, not synchronously).\r\n setTimeout(() => {\r\n const res = { success: true, errMsg: 'shareMessageToFriend:ok' };\r\n shareMessageToFriendListeners.forEach((cb) => {\r\n try {\r\n cb(res);\r\n } catch (e) {\r\n console.warn('[wx-compat] onShareMessageToFriend listener threw:', e);\r\n }\r\n });\r\n }, 0);\r\n}\r\n", "/**\r\n * Login / Authorization / User Info mock implementations (P0).\r\n *\r\n * In preview mode, we return mock data similar to the official DevTools'\r\n * \"tourist mode\" (see extensions/src/appservice/utils/tourist.ts).\r\n * This ensures games that call wx.login() / wx.getUserInfo() during\r\n * startup don't crash.\r\n */\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype AnyCallback = (...args: any[]) => void;\r\n\r\nimport { getAuthSetting, setApiPermission, getPermissionState } from './permission';\r\n\r\ninterface CallbackOpts {\r\n success?: AnyCallback;\r\n fail?: AnyCallback;\r\n complete?: AnyCallback;\r\n [key: string]: unknown;\r\n}\r\n\r\n// \u2500\u2500\u2500 Mock user data \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst MOCK_USER_INFO = {\r\n nickName: '\u9884\u89C8\u7528\u6237',\r\n avatarUrl: '',\r\n gender: 0,\r\n country: 'CN',\r\n province: '',\r\n city: '',\r\n language: 'zh_CN',\r\n};\r\n\r\n// \u2500\u2500\u2500 Login \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * wx.login \u2014 get a temporary login code.\r\n * Returns a mock code in preview mode.\r\n */\r\nexport function login(opts?: CallbackOpts): void {\r\n opts?.success?.({\r\n code: 'preview_mock_code_' + Date.now().toString(36),\r\n errMsg: 'login:ok',\r\n });\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.checkSession \u2014 check if the session is still valid.\r\n * Always succeeds in preview mode.\r\n */\r\nexport function checkSession(opts?: CallbackOpts): void {\r\n opts?.success?.({ errMsg: 'checkSession:ok' });\r\n opts?.complete?.();\r\n}\r\n\r\n// \u2500\u2500\u2500 Authorization \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * wx.authorize \u2014 request user authorization for a scope.\r\n *\r\n * Honours the live permission policy (see permission.ts). If the scope\r\n * is currently `denied` we faithfully reject the request so games can\r\n * exercise their fallback paths; for any other state (`granted` /\r\n * `prompt`) we flip it to `granted` and reply success \u2014 mirroring the\r\n * native UX where the user just tapped \"Allow\".\r\n */\r\nexport function authorize(opts?: CallbackOpts & { scope?: string }): void {\r\n const scope = typeof opts?.scope === 'string' ? opts.scope : '';\r\n if (scope) {\r\n const state = getPermissionState(scope);\r\n if (state === 'denied') {\r\n opts?.fail?.({ errMsg: 'authorize:fail auth deny' });\r\n opts?.complete?.();\r\n return;\r\n }\r\n setApiPermission(scope, 'granted');\r\n }\r\n opts?.success?.({ errMsg: 'authorize:ok' });\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.getSetting \u2014 return the live authSetting derived from the\r\n * permission module so games that gate behaviour on existing\r\n * authorizations behave consistently across calls.\r\n */\r\nexport function getSetting(opts?: CallbackOpts): void {\r\n opts?.success?.({\r\n authSetting: getAuthSetting(),\r\n errMsg: 'getSetting:ok',\r\n });\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.openSetting \u2014 same payload as getSetting. The native UI lets\r\n * users toggle scopes; in preview the host can drive the same effect\r\n * by mutating window.__wxPermission.set(scope, state).\r\n */\r\nexport function openSetting(opts?: CallbackOpts): void {\r\n opts?.success?.({\r\n authSetting: getAuthSetting(),\r\n errMsg: 'openSetting:ok',\r\n });\r\n opts?.complete?.();\r\n}\r\n\r\n// \u2500\u2500\u2500 User Info \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * wx.getUserInfo \u2014 get user info (deprecated but still widely used).\r\n */\r\nexport function getUserInfo(opts?: CallbackOpts): void {\r\n opts?.success?.({\r\n userInfo: { ...MOCK_USER_INFO },\r\n rawData: JSON.stringify(MOCK_USER_INFO),\r\n signature: '',\r\n encryptedData: '',\r\n iv: '',\r\n errMsg: 'getUserInfo:ok',\r\n });\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.getUserProfile \u2014 get user profile (replacement for getUserInfo).\r\n */\r\nexport function getUserProfile(opts?: CallbackOpts): void {\r\n opts?.success?.({\r\n userInfo: { ...MOCK_USER_INFO },\r\n rawData: JSON.stringify(MOCK_USER_INFO),\r\n signature: '',\r\n encryptedData: '',\r\n iv: '',\r\n errMsg: 'getUserProfile:ok',\r\n });\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.createUserInfoButton \u2014 create a button to get user info.\r\n * Returns a mock button object in preview mode.\r\n */\r\nexport function createUserInfoButton(_opts?: Record<string, unknown>): Record<string, unknown> {\r\n const tapCallbacks = new Set<AnyCallback>();\r\n\r\n return {\r\n type: 'text',\r\n text: '',\r\n style: {},\r\n show(): void { /* no-op in preview */ },\r\n hide(): void { /* no-op in preview */ },\r\n destroy(): void { tapCallbacks.clear(); },\r\n onTap(callback: AnyCallback): void { tapCallbacks.add(callback); },\r\n offTap(callback: AnyCallback): void { tapCallbacks.delete(callback); },\r\n };\r\n}\r\n", "/**\r\n * Open Data Context (\u5F00\u653E\u6570\u636E\u57DF) \u2014 preview-grade implementation.\r\n *\r\n * The Open Data Context is a sandboxed execution scope used to access\r\n * social relationship data (friend rankings, group leaderboards,\r\n * cloud-storage KV pairs). On native, it runs in a separate JS realm\r\n * with its OWN canvas (the \"shared canvas\"); main-game code can render\r\n * the leaderboard onto that canvas without ever seeing the underlying\r\n * private data.\r\n *\r\n * Reference shape on native:\r\n * const ctx = wx.getOpenDataContext();\r\n * ctx.canvas \u2192 SharedCanvas (drawn into by sub-context code)\r\n * ctx.postMessage() \u2192 main \u2192 sub\r\n *\r\n * Inside the sub-context (its own scope `wx.getSharedCanvas()` returns\r\n * the same SharedCanvas, and `wx.onMessage(cb)` receives main-thread\r\n * messages):\r\n * const sc = wx.getSharedCanvas();\r\n * wx.onMessage(handleMsg);\r\n *\r\n * Browser preview implementation\r\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n * The minigame_web_host project ships a `subcontext-engine` that runs\r\n * the open-data bundle in a hidden iframe. That's powerful but heavy\r\n * for a preview tool. We instead provide a same-realm shim:\r\n *\r\n * 1. `wx.getOpenDataContext()` returns an object whose `.canvas` is\r\n * a real off-screen canvas sized to the device viewport.\r\n * 2. The host (or game) can register an open-data bundle via\r\n * `__wxOpenDataContext.runBundle(code)` (exposed through window).\r\n * We execute the bundle in a Function-scope sandbox where:\r\n * - `wx` is a tiny fa\u00E7ade exposing only the open-data subset:\r\n * getSharedCanvas / onMessage / offMessage / getUserInfo /\r\n * getFriendCloudStorage / getUserCloudStorage / etc.\r\n * - `canvas` is the same SharedCanvas exposed on `ctx.canvas`.\r\n * - `postMessage(msg)` (free function) sends sub \u2192 main.\r\n * 3. `ctx.postMessage(msg)` and the sub-context's `wx.onMessage(cb)`\r\n * are wired through a Map of subscribers, so games that walk the\r\n * full main\u2194sub message protocol exercise their real code path.\r\n *\r\n * This is enough for preview/playable scenarios where the leaderboard\r\n * needs to render *something* (typically empty data) and games must\r\n * not crash on `wx.getOpenDataContext().postMessage(...)`.\r\n */\r\n\r\nimport { nativeCreateElement } from './native-globals';\r\nimport { DEVICE } from './constants';\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype AnyCallback = (...args: any[]) => void;\r\n\r\ninterface CallbackOpts {\r\n success?: AnyCallback;\r\n fail?: AnyCallback;\r\n complete?: AnyCallback;\r\n [key: string]: unknown;\r\n}\r\n\r\n// \u2500\u2500\u2500 Shared message bus \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Listeners registered inside the SUB-context via wx.onMessage. */\r\nconst subContextMessageListeners = new Set<(msg: unknown) => void>();\r\n/** Listeners registered on MAIN side via ctx.onMessage (rarely used but\r\n * documented in newer SDKs). */\r\nconst mainContextMessageListeners = new Set<(msg: unknown) => void>();\r\n\r\n// \u2500\u2500\u2500 Open Data Context object \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ninterface OpenDataContext {\r\n canvas: HTMLCanvasElement;\r\n postMessage(message: Record<string, unknown>): void;\r\n /**\r\n * Newer SDKs expose `onMessage` on the main-side context too so that\r\n * sub\u2192main traffic can be observed without polling. Documented since\r\n * 2.20+. We expose it always; native ignores it on older targets.\r\n */\r\n onMessage?(callback: (message: unknown) => void): void;\r\n}\r\n\r\nlet sharedContext: OpenDataContext | null = null;\r\nlet sharedCanvas: HTMLCanvasElement | null = null;\r\n\r\nfunction getSharedCanvas(): HTMLCanvasElement {\r\n if (sharedCanvas) return sharedCanvas;\r\n sharedCanvas = nativeCreateElement('canvas') as HTMLCanvasElement;\r\n sharedCanvas.width = DEVICE.width;\r\n sharedCanvas.height = DEVICE.height;\r\n return sharedCanvas;\r\n}\r\n\r\n/**\r\n * wx.getOpenDataContext \u2014 returns the singleton Open Data Context.\r\n */\r\nexport function getOpenDataContext(): OpenDataContext {\r\n if (sharedContext) return sharedContext;\r\n\r\n const canvas = getSharedCanvas();\r\n\r\n sharedContext = {\r\n canvas,\r\n postMessage(message: Record<string, unknown>): void {\r\n // main \u2192 sub: dispatch to every listener registered inside the\r\n // sub-context via the wx.onMessage shim. Errors in listeners are\r\n // swallowed individually so one bad subscriber doesn't break the rest.\r\n subContextMessageListeners.forEach((cb) => {\r\n try { cb(message); } catch (e) {\r\n console.error('[wx-compat][open-data] sub-context onMessage threw:', e);\r\n }\r\n });\r\n },\r\n onMessage(callback: (message: unknown) => void): void {\r\n if (typeof callback === 'function') mainContextMessageListeners.add(callback);\r\n },\r\n };\r\n\r\n return sharedContext;\r\n}\r\n\r\n// \u2500\u2500\u2500 Sub-context bundle runner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Execute an Open Data bundle inside our same-realm sandbox. The bundle\r\n * gets a tiny `wx` fa\u00E7ade with just the open-data API surface plus a\r\n * direct `canvas` and free-function `postMessage` for sub\u2192main traffic.\r\n *\r\n * Designed for preview/playable scenarios \u2014 production native uses a\r\n * separate JS context which we cannot replicate from inside a single\r\n * iframe without spawning yet another nested iframe. Games that rely on\r\n * strict realm isolation should be tested on a real device, not here.\r\n */\r\nfunction runOpenDataBundle(code: string, sourceURL = 'open-data-context.js'): void {\r\n const canvas = getSharedCanvas();\r\n\r\n // Sub-context wx fa\u00E7ade. Only exposes APIs that are documented as\r\n // available inside the open data scope \u2014 anything else games try to\r\n // call is silently a no-op (matches native behaviour: those APIs throw\r\n // a \"permission denied\" there too).\r\n const subWx = {\r\n getSharedCanvas: () => canvas,\r\n onMessage(cb: (m: unknown) => void): void {\r\n if (typeof cb === 'function') subContextMessageListeners.add(cb);\r\n },\r\n offMessage(cb: (m: unknown) => void): void {\r\n subContextMessageListeners.delete(cb);\r\n },\r\n getUserInfo(opts?: CallbackOpts): void {\r\n opts?.success?.({ data: [], errMsg: 'getUserInfo:ok' });\r\n opts?.complete?.();\r\n },\r\n getFriendCloudStorage(opts?: CallbackOpts): void {\r\n opts?.success?.({ data: [], errMsg: 'getFriendCloudStorage:ok' });\r\n opts?.complete?.();\r\n },\r\n getGroupCloudStorage(opts?: CallbackOpts): void {\r\n opts?.success?.({ data: [], errMsg: 'getGroupCloudStorage:ok' });\r\n opts?.complete?.();\r\n },\r\n getUserCloudStorage(opts?: CallbackOpts): void {\r\n opts?.success?.({ KVDataList: [], errMsg: 'getUserCloudStorage:ok' });\r\n opts?.complete?.();\r\n },\r\n setUserCloudStorage(opts?: CallbackOpts): void {\r\n opts?.success?.({ errMsg: 'setUserCloudStorage:ok' });\r\n opts?.complete?.();\r\n },\r\n removeUserCloudStorage(opts?: CallbackOpts): void {\r\n opts?.success?.({ errMsg: 'removeUserCloudStorage:ok' });\r\n opts?.complete?.();\r\n },\r\n getPotentialFriendList(opts?: CallbackOpts): void {\r\n opts?.success?.({ list: [], errMsg: 'getPotentialFriendList:ok' });\r\n opts?.complete?.();\r\n },\r\n };\r\n\r\n // sub \u2192 main: messages flow back through this free function as well as\r\n // `worker.postMessage`-style calls. We forward to every listener the\r\n // main side registered via ctx.onMessage().\r\n function postMessageToMain(message: unknown): void {\r\n mainContextMessageListeners.forEach((cb) => {\r\n try { cb(message); } catch (e) {\r\n console.error('[wx-compat][open-data] main onMessage threw:', e);\r\n }\r\n });\r\n }\r\n\r\n try {\r\n // Function-scope sandbox: the bundle sees `wx`, `canvas`, and the\r\n // free postMessage function as locals. There's no realm isolation \u2014\r\n // the bundle COULD reach for window.* and break out \u2014 but matching\r\n // native exactly would require another iframe. This is good enough\r\n // for preview where the bundle is the host's own code.\r\n const factory = new Function(\r\n 'wx', 'canvas', 'postMessage', 'sharedCanvas',\r\n `${code}\\n//# sourceURL=${sourceURL}`,\r\n );\r\n factory(subWx, canvas, postMessageToMain, canvas);\r\n } catch (e) {\r\n console.error('[wx-compat][open-data] bundle execution failed:', e);\r\n throw e;\r\n }\r\n}\r\n\r\n/**\r\n * Reset all open-data state. Used by the host between game reloads so\r\n * leftover listeners don't leak into the next session.\r\n */\r\nfunction resetOpenDataContext(): void {\r\n subContextMessageListeners.clear();\r\n mainContextMessageListeners.clear();\r\n sharedContext = null;\r\n // Keep the shared canvas alive \u2014 recreating it would invalidate any\r\n // textures the game already uploaded as `ctx.canvas`.\r\n}\r\n\r\n// Expose the sub-context runner on a debug global so the host (or a\r\n// test fixture) can inject an open-data bundle without recompiling.\r\n// Intentionally NOT part of the public wx surface.\r\n(window as unknown as Record<string, unknown>).__wxOpenDataContext = {\r\n runBundle: runOpenDataBundle,\r\n reset: resetOpenDataContext,\r\n getSharedCanvas,\r\n};\r\n\r\n// \u2500\u2500\u2500 Cloud Storage APIs (mock empty data) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * wx.getFriendCloudStorage \u2014 get friends' key-value data.\r\n * Returns empty list in preview mode (no social graph).\r\n */\r\nexport function getFriendCloudStorage(opts?: CallbackOpts & { keyList?: string[] }): void {\r\n opts?.success?.({ data: [], errMsg: 'getFriendCloudStorage:ok' });\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.getGroupCloudStorage \u2014 get group members' key-value data.\r\n * Returns empty list in preview mode.\r\n */\r\nexport function getGroupCloudStorage(opts?: CallbackOpts & {\r\n shareTicket?: string;\r\n keyList?: string[];\r\n}): void {\r\n opts?.success?.({ data: [], errMsg: 'getGroupCloudStorage:ok' });\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.getUserCloudStorage \u2014 get current user's key-value data.\r\n * Returns empty list in preview mode.\r\n */\r\nexport function getUserCloudStorage(opts?: CallbackOpts & { keyList?: string[] }): void {\r\n opts?.success?.({ KVDataList: [], errMsg: 'getUserCloudStorage:ok' });\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.setUserCloudStorage \u2014 set current user's key-value data.\r\n * No-op in preview mode.\r\n */\r\nexport function setUserCloudStorage(opts?: CallbackOpts & {\r\n KVDataList?: Array<{ key: string; value: string }>;\r\n}): void {\r\n opts?.success?.({ errMsg: 'setUserCloudStorage:ok' });\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.removeUserCloudStorage \u2014 remove current user's key-value data.\r\n * No-op in preview mode.\r\n */\r\nexport function removeUserCloudStorage(opts?: CallbackOpts & { keyList?: string[] }): void {\r\n opts?.success?.({ errMsg: 'removeUserCloudStorage:ok' });\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.getUserInteractiveStorage \u2014 get user's interactive storage data.\r\n * Returns empty list in preview mode.\r\n */\r\nexport function getUserInteractiveStorage(opts?: CallbackOpts & { keyList?: string[] }): void {\r\n opts?.success?.({ KVDataList: [], errMsg: 'getUserInteractiveStorage:ok' });\r\n opts?.complete?.();\r\n}\r\n", "/**\r\n * Ad API mock implementations (P1).\r\n *\r\n * In preview mode, ads never actually load or display. These mocks ensure\r\n * game code that creates and shows ads doesn't crash. The mock behavior:\r\n * - load() resolves after a brief delay (simulates ad load)\r\n * - show() resolves immediately, then fires onClose({ isEnded: true })\r\n * - All event methods (onLoad, onError, onClose, etc.) use Set<Callback>\r\n *\r\n * Reference: WeChat Mini Game Ad APIs\r\n * https://developers.weixin.qq.com/minigame/dev/api/ad/wx.createRewardedVideoAd.html\r\n */\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype AnyCallback = (...args: any[]) => void;\r\n\r\n// \u2500\u2500\u2500 Base Ad Class \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nclass MockAd {\r\n protected _loadCbs = new Set<AnyCallback>();\r\n protected _errorCbs = new Set<AnyCallback>();\r\n protected _closeCbs = new Set<AnyCallback>();\r\n protected _destroyed = false;\r\n\r\n load(): Promise<void> {\r\n if (this._destroyed) return Promise.reject(new Error('ad already destroyed'));\r\n return new Promise((resolve) => {\r\n setTimeout(() => {\r\n this._loadCbs.forEach((cb) => cb());\r\n resolve();\r\n }, 100);\r\n });\r\n }\r\n\r\n show(): Promise<void> {\r\n if (this._destroyed) return Promise.reject(new Error('ad already destroyed'));\r\n return new Promise((resolve) => {\r\n resolve();\r\n // Fire onClose after a microtask (simulates user watching/closing the ad)\r\n setTimeout(() => {\r\n this._closeCbs.forEach((cb) => cb({ isEnded: true }));\r\n }, 50);\r\n });\r\n }\r\n\r\n destroy(): void {\r\n this._destroyed = true;\r\n this._loadCbs.clear();\r\n this._errorCbs.clear();\r\n this._closeCbs.clear();\r\n }\r\n\r\n onLoad(callback: AnyCallback): void { this._loadCbs.add(callback); }\r\n offLoad(callback: AnyCallback): void { this._loadCbs.delete(callback); }\r\n onError(callback: AnyCallback): void { this._errorCbs.add(callback); }\r\n offError(callback: AnyCallback): void { this._errorCbs.delete(callback); }\r\n onClose(callback: AnyCallback): void { this._closeCbs.add(callback); }\r\n offClose(callback: AnyCallback): void { this._closeCbs.delete(callback); }\r\n}\r\n\r\n// \u2500\u2500\u2500 Rewarded Video Ad \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * wx.createRewardedVideoAd \u2014 creates a rewarded video ad instance.\r\n * In preview mode, show() always simulates a completed video (isEnded: true).\r\n */\r\nexport function createRewardedVideoAd(_opts: {\r\n adUnitId: string;\r\n multiton?: boolean;\r\n}): MockAd {\r\n return new MockAd();\r\n}\r\n\r\n// \u2500\u2500\u2500 Interstitial Ad \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * wx.createInterstitialAd \u2014 creates an interstitial ad instance.\r\n * In preview mode, show() resolves immediately with onClose callback.\r\n */\r\nexport function createInterstitialAd(_opts: {\r\n adUnitId: string;\r\n}): MockAd {\r\n return new MockAd();\r\n}\r\n\r\n// \u2500\u2500\u2500 Banner Ad \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nclass MockBannerAd extends MockAd {\r\n private _resizeCbs = new Set<AnyCallback>();\r\n private _visible = false;\r\n\r\n style = {\r\n left: 0,\r\n top: 0,\r\n width: 300,\r\n height: 80,\r\n realWidth: 300,\r\n realHeight: 80,\r\n };\r\n\r\n constructor(opts?: { style?: Record<string, number> }) {\r\n super();\r\n if (opts?.style) {\r\n Object.assign(this.style, opts.style);\r\n }\r\n }\r\n\r\n show(): Promise<void> {\r\n if (this._destroyed) return Promise.reject(new Error('ad already destroyed'));\r\n this._visible = true;\r\n return Promise.resolve();\r\n }\r\n\r\n hide(): Promise<void> {\r\n this._visible = false;\r\n return Promise.resolve();\r\n }\r\n\r\n destroy(): void {\r\n super.destroy();\r\n this._visible = false;\r\n this._resizeCbs.clear();\r\n }\r\n\r\n onResize(callback: AnyCallback): void { this._resizeCbs.add(callback); }\r\n offResize(callback: AnyCallback): void { this._resizeCbs.delete(callback); }\r\n}\r\n\r\n/**\r\n * wx.createBannerAd \u2014 creates a banner ad instance.\r\n * In preview mode, the banner is never actually visible.\r\n */\r\nexport function createBannerAd(opts: {\r\n adUnitId: string;\r\n adIntervals?: number;\r\n style?: Record<string, number>;\r\n}): MockBannerAd {\r\n return new MockBannerAd(opts);\r\n}\r\n\r\n// \u2500\u2500\u2500 Custom Ad (\u539F\u751F\u6A21\u677F\u5E7F\u544A) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Mock for `CustomAd` (\u539F\u751F\u6A21\u677F\u5E7F\u544A\u7EC4\u4EF6).\r\n *\r\n * Per the WeChat docs, a CustomAd instance must expose the full event surface\r\n * (`onLoad/offLoad`, `onError/offError`, `onClose/offClose`, `onHide/offHide`,\r\n * `onResize/offResize`) plus `show()`, `hide()`, `isShow()`, `destroy()` and\r\n * a mutable `style` object. Games such as `wx7d28c8407ce3e4f4` call\r\n * `customAd.onHide(listener)` right after creation; if any of these methods\r\n * are missing the game crashes with\r\n * `TypeError: o.onHide is not a function`.\r\n *\r\n * In preview mode the ad is never actually visible; every method is a no-op\r\n * that keeps listener bookkeeping so callers can later remove them.\r\n *\r\n * Reference: https://developers.weixin.qq.com/minigame/dev/api/ad/wx.createCustomAd.html\r\n */\r\nclass MockCustomAd extends MockAd {\r\n private _hideCbs = new Set<AnyCallback>();\r\n private _resizeCbs = new Set<AnyCallback>();\r\n private _visible = false;\r\n\r\n style: { left: number; top: number; fixed?: boolean; width?: number } = {\r\n left: 0,\r\n top: 0,\r\n fixed: false,\r\n };\r\n\r\n constructor(opts?: { style?: Record<string, number | boolean> }) {\r\n super();\r\n if (opts?.style) {\r\n Object.assign(this.style, opts.style);\r\n }\r\n }\r\n\r\n show(): Promise<void> {\r\n if (this._destroyed) return Promise.reject(new Error('ad already destroyed'));\r\n this._visible = true;\r\n // CustomAd does not auto-fire onClose on show (unlike rewarded video),\r\n // so we intentionally do nothing besides resolving here.\r\n return Promise.resolve();\r\n }\r\n\r\n hide(): Promise<void> {\r\n if (this._visible) {\r\n this._visible = false;\r\n // Fire onHide listeners on an async boundary to mimic real behavior.\r\n setTimeout(() => {\r\n this._hideCbs.forEach((cb) => cb());\r\n }, 0);\r\n }\r\n return Promise.resolve();\r\n }\r\n\r\n isShow(): boolean {\r\n return this._visible;\r\n }\r\n\r\n destroy(): void {\r\n super.destroy();\r\n this._visible = false;\r\n this._hideCbs.clear();\r\n this._resizeCbs.clear();\r\n }\r\n\r\n onHide(callback: AnyCallback): void { this._hideCbs.add(callback); }\r\n offHide(callback: AnyCallback): void { this._hideCbs.delete(callback); }\r\n onResize(callback: AnyCallback): void { this._resizeCbs.add(callback); }\r\n offResize(callback: AnyCallback): void { this._resizeCbs.delete(callback); }\r\n}\r\n\r\n/**\r\n * wx.createCustomAd \u2014 creates a custom (native template) ad instance.\r\n * In preview mode, the ad is never actually visible.\r\n * Reference: https://developers.weixin.qq.com/minigame/dev/api/ad/wx.createCustomAd.html\r\n */\r\nexport function createCustomAd(opts: {\r\n adUnitId: string;\r\n adIntervals?: number;\r\n style?: Record<string, number | boolean>;\r\n}): MockCustomAd {\r\n return new MockCustomAd(opts);\r\n}\r\n", "/**\r\n * Media selection and info APIs (P2).\r\n *\r\n * chooseImage uses a real <input type=\"file\"> for actual file selection.\r\n * getImageInfo loads the image to get real dimensions.\r\n * Other APIs are mock/no-op stubs.\r\n */\r\n\r\nimport { NativeImage, nativeCreateElement, nativeBody } from './native-globals';\r\nimport { resolveImageSrc } from './image';\r\nimport { checkPermission } from './permission';\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype AnyCallback = (...args: any[]) => void;\r\n\r\ninterface CallbackOpts {\r\n success?: AnyCallback;\r\n fail?: AnyCallback;\r\n complete?: AnyCallback;\r\n [key: string]: unknown;\r\n}\r\n\r\n// \u2500\u2500\u2500 File picker helper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction pickFiles(accept: string, multiple: boolean): Promise<File[]> {\r\n return new Promise((resolve) => {\r\n const input = nativeCreateElement('input') as HTMLInputElement;\r\n input.type = 'file';\r\n input.accept = accept;\r\n input.multiple = multiple;\r\n input.style.display = 'none';\r\n nativeBody.appendChild(input);\r\n input.addEventListener('change', () => {\r\n const files = Array.from(input.files || []);\r\n nativeBody.removeChild(input);\r\n resolve(files);\r\n });\r\n // If user cancels, no change event fires \u2014 resolve empty after timeout\r\n input.addEventListener('cancel', () => {\r\n nativeBody.removeChild(input);\r\n resolve([]);\r\n });\r\n input.click();\r\n });\r\n}\r\n\r\n// \u2500\u2500\u2500 Choose Image \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * wx.chooseImage \u2014 open file picker for images.\r\n * Uses real <input type=\"file\"> in browser.\r\n */\r\nexport function chooseImage(opts?: CallbackOpts & {\r\n count?: number;\r\n sizeType?: string[];\r\n sourceType?: string[];\r\n}): void {\r\n if (!checkPermission('chooseImage', opts)) return;\r\n const count = (opts?.count as number) ?? 9;\r\n pickFiles('image/*', count > 1)\r\n .then((files) => {\r\n if (files.length === 0) {\r\n opts?.fail?.({ errMsg: 'chooseImage:fail cancel' });\r\n opts?.complete?.();\r\n return;\r\n }\r\n const tempFilePaths = files.map((f) => URL.createObjectURL(f));\r\n const tempFiles = files.map((f, i) => ({\r\n path: tempFilePaths[i],\r\n size: f.size,\r\n }));\r\n opts?.success?.({ tempFilePaths, tempFiles, errMsg: 'chooseImage:ok' });\r\n opts?.complete?.();\r\n })\r\n .catch((e) => {\r\n opts?.fail?.({ errMsg: `chooseImage:fail ${e}` });\r\n opts?.complete?.();\r\n });\r\n}\r\n\r\n/**\r\n * wx.chooseMedia \u2014 open file picker for images/videos.\r\n */\r\nexport function chooseMedia(opts?: CallbackOpts & {\r\n count?: number;\r\n mediaType?: string[];\r\n sourceType?: string[];\r\n}): void {\r\n if (!checkPermission('chooseMedia', opts)) return;\r\n const count = (opts?.count as number) ?? 9;\r\n pickFiles('image/*,video/*', count > 1)\r\n .then((files) => {\r\n if (files.length === 0) {\r\n opts?.fail?.({ errMsg: 'chooseMedia:fail cancel' });\r\n opts?.complete?.();\r\n return;\r\n }\r\n const tempFiles = files.map((f) => ({\r\n tempFilePath: URL.createObjectURL(f),\r\n size: f.size,\r\n fileType: f.type.startsWith('video') ? 'video' : 'image',\r\n }));\r\n opts?.success?.({ tempFiles, type: 'mix', errMsg: 'chooseMedia:ok' });\r\n opts?.complete?.();\r\n })\r\n .catch((e) => {\r\n opts?.fail?.({ errMsg: `chooseMedia:fail ${e}` });\r\n opts?.complete?.();\r\n });\r\n}\r\n\r\n/**\r\n * wx.chooseVideo \u2014 open file picker for video.\r\n */\r\nexport function chooseVideo(opts?: CallbackOpts): void {\r\n if (!checkPermission('chooseVideo', opts)) return;\r\n pickFiles('video/*', false)\r\n .then((files) => {\r\n if (files.length === 0) {\r\n opts?.fail?.({ errMsg: 'chooseVideo:fail cancel' });\r\n opts?.complete?.();\r\n return;\r\n }\r\n const f = files[0];\r\n opts?.success?.({\r\n tempFilePath: URL.createObjectURL(f),\r\n size: f.size,\r\n duration: 0,\r\n width: 0,\r\n height: 0,\r\n errMsg: 'chooseVideo:ok',\r\n });\r\n opts?.complete?.();\r\n })\r\n .catch((e) => {\r\n opts?.fail?.({ errMsg: `chooseVideo:fail ${e}` });\r\n opts?.complete?.();\r\n });\r\n}\r\n\r\n/**\r\n * wx.chooseMessageFile \u2014 open file picker for any file.\r\n */\r\nexport function chooseMessageFile(opts?: CallbackOpts & { count?: number }): void {\r\n const count = (opts?.count as number) ?? 1;\r\n pickFiles('*/*', count > 1)\r\n .then((files) => {\r\n if (files.length === 0) {\r\n opts?.fail?.({ errMsg: 'chooseMessageFile:fail cancel' });\r\n opts?.complete?.();\r\n return;\r\n }\r\n const tempFiles = files.map((f) => ({\r\n path: URL.createObjectURL(f),\r\n name: f.name,\r\n size: f.size,\r\n type: 'file',\r\n }));\r\n opts?.success?.({ tempFiles, errMsg: 'chooseMessageFile:ok' });\r\n opts?.complete?.();\r\n })\r\n .catch((e) => {\r\n opts?.fail?.({ errMsg: `chooseMessageFile:fail ${e}` });\r\n opts?.complete?.();\r\n });\r\n}\r\n\r\n// \u2500\u2500\u2500 Image Info \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * wx.getImageInfo \u2014 load image and return its dimensions.\r\n * Actually loads the image to get real width/height.\r\n */\r\nexport function getImageInfo(opts: CallbackOpts & { src: string }): void {\r\n const img = new NativeImage();\r\n img.crossOrigin = 'anonymous';\r\n img.onload = () => {\r\n opts.success?.({\r\n width: img.naturalWidth,\r\n height: img.naturalHeight,\r\n path: opts.src,\r\n orientation: 'up',\r\n type: opts.src.endsWith('.png') ? 'png' : opts.src.endsWith('.gif') ? 'gif' : 'jpeg',\r\n errMsg: 'getImageInfo:ok',\r\n });\r\n opts.complete?.();\r\n };\r\n img.onerror = () => {\r\n opts.fail?.({ errMsg: `getImageInfo:fail load image error` });\r\n opts.complete?.();\r\n };\r\n // Resolve wxfile:// paths to blob URLs so the browser can load them\r\n img.src = resolveImageSrc(opts.src);\r\n}\r\n\r\n/**\r\n * wx.getVideoInfo \u2014 get video information. Mock in preview.\r\n */\r\nexport function getVideoInfo(opts: CallbackOpts & { src: string }): void {\r\n opts.success?.({\r\n duration: 0,\r\n size: 0,\r\n width: 0,\r\n height: 0,\r\n type: '',\r\n orientation: 'up',\r\n fps: 30,\r\n bitrate: 0,\r\n errMsg: 'getVideoInfo:ok',\r\n });\r\n opts.complete?.();\r\n}\r\n\r\n// \u2500\u2500\u2500 Preview / Save (no-op) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * wx.previewImage \u2014 preview images in fullscreen. No-op in preview.\r\n */\r\nexport function previewImage(opts?: CallbackOpts): void {\r\n opts?.success?.({ errMsg: 'previewImage:ok' });\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.previewMedia \u2014 preview media in fullscreen. No-op in preview.\r\n */\r\nexport function previewMedia(opts?: CallbackOpts): void {\r\n opts?.success?.({ errMsg: 'previewMedia:ok' });\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.saveImageToPhotosAlbum \u2014 save image to album. No-op in preview.\r\n */\r\nexport function saveImageToPhotosAlbum(opts?: CallbackOpts): void {\r\n opts?.success?.({ errMsg: 'saveImageToPhotosAlbum:ok' });\r\n opts?.complete?.();\r\n}\r\n\r\n/**\r\n * wx.saveVideoToPhotosAlbum \u2014 save video to album. No-op in preview.\r\n */\r\nexport function saveVideoToPhotosAlbum(opts?: CallbackOpts): void {\r\n opts?.success?.({ errMsg: 'saveVideoToPhotosAlbum:ok' });\r\n opts?.complete?.();\r\n}\r\n", "/**\r\n * Router / Navigation API stubs (P2).\r\n *\r\n * Mini games are single-page, so navigation APIs are mostly no-ops.\r\n * exitMiniProgram closes the preview window if possible.\r\n */\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype AnyCallback = (...args: any[]) => void;\r\n\r\ninterface CallbackOpts {\r\n success?: AnyCallback;\r\n fail?: AnyCallback;\r\n complete?: AnyCallback;\r\n [key: string]: unknown;\r\n}\r\n\r\n/** wx.navigateTo \u2014 no-op in mini game context */\r\nexport function navigateTo(opts?: CallbackOpts): void {\r\n console.warn('[wx-compat] navigateTo is not supported in mini game preview');\r\n opts?.success?.({ errMsg: 'navigateTo:ok' });\r\n opts?.complete?.();\r\n}\r\n\r\n/** wx.navigateBack \u2014 no-op */\r\nexport function navigateBack(opts?: CallbackOpts): void {\r\n opts?.success?.({ errMsg: 'navigateBack:ok' });\r\n opts?.complete?.();\r\n}\r\n\r\n/** wx.redirectTo \u2014 no-op */\r\nexport function redirectTo(opts?: CallbackOpts): void {\r\n opts?.success?.({ errMsg: 'redirectTo:ok' });\r\n opts?.complete?.();\r\n}\r\n\r\n/** wx.reLaunch \u2014 no-op */\r\nexport function reLaunch(opts?: CallbackOpts): void {\r\n opts?.success?.({ errMsg: 'reLaunch:ok' });\r\n opts?.complete?.();\r\n}\r\n\r\n/** wx.switchTab \u2014 no-op */\r\nexport function switchTab(opts?: CallbackOpts): void {\r\n opts?.success?.({ errMsg: 'switchTab:ok' });\r\n opts?.complete?.();\r\n}\r\n\r\n/** wx.navigateToMiniProgram \u2014 no-op in preview */\r\nexport function navigateToMiniProgram(opts?: CallbackOpts): void {\r\n console.warn('[wx-compat] navigateToMiniProgram is not supported in preview');\r\n opts?.fail?.({ errMsg: 'navigateToMiniProgram:fail not supported in preview' });\r\n opts?.complete?.();\r\n}\r\n\r\n/** wx.navigateBackMiniProgram \u2014 no-op */\r\nexport function navigateBackMiniProgram(opts?: CallbackOpts): void {\r\n opts?.fail?.({ errMsg: 'navigateBackMiniProgram:fail not supported in preview' });\r\n opts?.complete?.();\r\n}\r\n\r\n/** wx.exitMiniProgram \u2014 attempts to close the preview window */\r\nexport function exitMiniProgram(opts?: CallbackOpts): void {\r\n opts?.success?.({ errMsg: 'exitMiniProgram:ok' });\r\n opts?.complete?.();\r\n try {\r\n window.close();\r\n } catch {\r\n // Can't close in iframe context \u2014 ignore\r\n }\r\n}\r\n\r\n/**\r\n * wx.restartMiniProgram \u2014 restart the current mini program.\r\n * In preview, we simulate \"restart\" by reloading the page.\r\n * The optional `path` parameter is ignored since mini games are single-page.\r\n */\r\nexport function restartMiniProgram(opts?: CallbackOpts & { path?: string }): void {\r\n // Fire success callback first so the game has a chance to cleanup\r\n opts?.success?.({ errMsg: 'restartMiniProgram:ok' });\r\n opts?.complete?.();\r\n if (opts?.path) {\r\n console.warn(\r\n `[wx-compat] restartMiniProgram: path=\"${opts.path}\" is ignored in preview; reloading page.`\r\n );\r\n }\r\n // Defer reload to next tick to let success callback finish synchronously\r\n try {\r\n setTimeout(() => {\r\n try {\r\n window.location.reload();\r\n } catch {\r\n // ignore \u2014 e.g. cross-origin restrictions\r\n }\r\n }, 0);\r\n } catch {\r\n // ignore\r\n }\r\n}\r\n", "/**\r\n * Payment API stubs (P2).\r\n *\r\n * In preview mode, payment always fails with \"not supported\" message.\r\n * Real payments require the WeChat backend infrastructure.\r\n */\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype AnyCallback = (...args: any[]) => void;\r\n\r\ninterface CallbackOpts {\r\n success?: AnyCallback;\r\n fail?: AnyCallback;\r\n complete?: AnyCallback;\r\n [key: string]: unknown;\r\n}\r\n\r\n/** wx.requestMidasPayment \u2014 always fails in preview */\r\nexport function requestMidasPayment(opts?: CallbackOpts): void {\r\n opts?.fail?.({ errMsg: 'requestMidasPayment:fail \u9884\u89C8\u73AF\u5883\u4E0D\u652F\u6301\u652F\u4ED8' });\r\n opts?.complete?.();\r\n}\r\n\r\n/** wx.requestMidasFriendPayment \u2014 always fails in preview */\r\nexport function requestMidasFriendPayment(opts?: CallbackOpts): void {\r\n opts?.fail?.({ errMsg: 'requestMidasFriendPayment:fail \u9884\u89C8\u73AF\u5883\u4E0D\u652F\u6301\u652F\u4ED8' });\r\n opts?.complete?.();\r\n}\r\n", "/**\r\n * Playable Ad APIs (mock).\r\n *\r\n * These APIs are ONLY available in the playable ad (\u8BD5\u73A9\u5E7F\u544A) scenario on the\r\n * WeChat base library, not in standard Mini Game runtime. In the preview\r\n * environment we cannot show the real \"playable end\" UI provided by the base\r\n * library, so we just record the call and emit a log for debugging.\r\n *\r\n * Reference:\r\n * wx.notifyMiniProgramPlayableStatus({ isEnd: boolean })\r\n * \u2014 \u901A\u77E5\u57FA\u7840\u5E93\u5C55\u793A\u8BD5\u73A9\u7ED3\u675F\u754C\u9762\uFF0C\u4EC5\u9002\u7528\u4E8E\u8BD5\u73A9\u5E7F\u544A\u573A\u666F\u3002\r\n * wx.reportGameEvent({ eventId, costTime?, result?, success?, fail?, complete? })\r\n * \u2014 \u4E0A\u62A5\u8BD5\u73A9\u81EA\u5B9A\u4E49\u6570\u636E\uFF0C\u4EC5\u9002\u7528\u4E8E\u8BD5\u73A9\u5E7F\u544A\u573A\u666F\u3002\r\n */\r\n\r\ninterface NotifyMiniProgramPlayableStatusOptions {\r\n /** Whether the playable session has ended. Required. */\r\n isEnd: boolean;\r\n}\r\n\r\n/** Latest playable status reported by the game, kept for debugging/inspection. */\r\nlet lastPlayableStatus: NotifyMiniProgramPlayableStatusOptions | null = null;\r\n\r\n/**\r\n * wx.notifyMiniProgramPlayableStatus \u2014 playable-ad-only API.\r\n *\r\n * In preview this is a no-op: it validates the argument shape, stores the\r\n * latest status, and logs it. Returning void matches the official signature.\r\n */\r\nexport function notifyMiniProgramPlayableStatus(\r\n options: NotifyMiniProgramPlayableStatusOptions,\r\n): void {\r\n if (!options || typeof options.isEnd !== 'boolean') {\r\n console.warn(\r\n '[wx-compat] notifyMiniProgramPlayableStatus: `isEnd` (boolean) is required',\r\n );\r\n return;\r\n }\r\n\r\n lastPlayableStatus = { isEnd: options.isEnd };\r\n\r\n // eslint-disable-next-line no-console\r\n console.log(\r\n `[wx-compat] notifyMiniProgramPlayableStatus: isEnd=${options.isEnd} ` +\r\n '(mocked in preview \u2014 playable-ad-only API)',\r\n );\r\n}\r\n\r\n/** Test/debug helper \u2014 returns the last reported playable status, if any. */\r\nexport function __getLastPlayableStatus():\r\n | NotifyMiniProgramPlayableStatusOptions\r\n | null {\r\n return lastPlayableStatus;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// wx.reportGameEvent \u2014 playable-ad-only custom event reporting API.\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Event result code: 1 = success, 2 = failure. */\r\ntype ReportGameEventResult = 1 | 2;\r\n\r\ninterface ReportGameEventOptions {\r\n /** Custom event id. Required. Keep total event ids within 50. */\r\n eventId: number;\r\n /** Event cost time in ms. Optional, default 0. */\r\n costTime?: number;\r\n /** Event result: 1-success, 2-failure. Optional, default 1. */\r\n result?: ReportGameEventResult;\r\n /** Success callback. */\r\n success?: (res: { errMsg: string }) => void;\r\n /** Failure callback. */\r\n fail?: (err: { errMsg: string }) => void;\r\n /** Complete callback, invoked on both success and failure. */\r\n complete?: (res: { errMsg: string }) => void;\r\n}\r\n\r\n/** Record of the latest reported game event, kept for debugging/inspection. */\r\ninterface RecordedGameEvent {\r\n eventId: number;\r\n costTime: number;\r\n result: ReportGameEventResult;\r\n timestamp: number;\r\n}\r\n\r\nlet lastGameEvent: RecordedGameEvent | null = null;\r\n\r\n/**\r\n * wx.reportGameEvent \u2014 playable-ad-only API for reporting custom events.\r\n *\r\n * In preview this is a no-op: it validates the argument shape (matching the\r\n * official error codes), records the last event, logs it, and invokes the\r\n * success/complete callbacks synchronously on the next microtask so game code\r\n * that chains on `success`/`complete` keeps working.\r\n */\r\nexport function reportGameEvent(options: ReportGameEventOptions): void {\r\n const opts = options || ({} as ReportGameEventOptions);\r\n\r\n // Validate eventId \u2014 official error: \"eventId is not a number\".\r\n if (typeof opts.eventId !== 'number' || !Number.isFinite(opts.eventId)) {\r\n const errMsg = 'reportGameEvent:fail eventId is not a number';\r\n console.warn(`[wx-compat] ${errMsg}`);\r\n try {\r\n opts.fail?.({ errMsg });\r\n opts.complete?.({ errMsg });\r\n } catch (e) {\r\n console.warn('[wx-compat] reportGameEvent callback threw:', e);\r\n }\r\n return;\r\n }\r\n\r\n // Validate result \u2014 official error: \"result is not valid\".\r\n const result: ReportGameEventResult =\r\n opts.result === undefined ? 1 : (opts.result as ReportGameEventResult);\r\n if (result !== 1 && result !== 2) {\r\n const errMsg = 'reportGameEvent:fail result is not valid';\r\n console.warn(`[wx-compat] ${errMsg}`);\r\n try {\r\n opts.fail?.({ errMsg });\r\n opts.complete?.({ errMsg });\r\n } catch (e) {\r\n console.warn('[wx-compat] reportGameEvent callback threw:', e);\r\n }\r\n return;\r\n }\r\n\r\n const costTime =\r\n typeof opts.costTime === 'number' && Number.isFinite(opts.costTime)\r\n ? opts.costTime\r\n : 0;\r\n\r\n lastGameEvent = {\r\n eventId: opts.eventId,\r\n costTime,\r\n result,\r\n timestamp: Date.now(),\r\n };\r\n\r\n // eslint-disable-next-line no-console\r\n console.log(\r\n `[wx-compat] reportGameEvent: eventId=${opts.eventId} ` +\r\n `costTime=${costTime}ms result=${result} ` +\r\n '(mocked in preview \u2014 playable-ad-only API)',\r\n );\r\n\r\n const successRes = { errMsg: 'reportGameEvent:ok' };\r\n try {\r\n opts.success?.(successRes);\r\n opts.complete?.(successRes);\r\n } catch (e) {\r\n console.warn('[wx-compat] reportGameEvent callback threw:', e);\r\n }\r\n}\r\n\r\n/** Test/debug helper \u2014 returns the last reported game event, if any. */\r\nexport function __getLastGameEvent(): RecordedGameEvent | null {\r\n return lastGameEvent;\r\n}\r\n", "/**\r\n * Game Recorder / Video / Camera mock APIs (P2).\r\n *\r\n * Returns mock objects that don't actually record or capture.\r\n * Prevents runtime errors in games that use these features.\r\n */\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype AnyCallback = (...args: any[]) => void;\r\n\r\n// \u2500\u2500\u2500 Game Recorder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction createMockGameRecorder() {\r\n const listeners = new Map<string, Set<AnyCallback>>();\r\n\r\n return {\r\n start(_opts?: Record<string, unknown>): void {\r\n console.warn('[wx-compat] GameRecorder.start() is not supported in preview');\r\n },\r\n stop(): void { /* no-op */ },\r\n pause(): void { /* no-op */ },\r\n resume(): void { /* no-op */ },\r\n abort(): void { /* no-op */ },\r\n on(event: string, callback: AnyCallback): void {\r\n if (!listeners.has(event)) listeners.set(event, new Set());\r\n listeners.get(event)!.add(callback);\r\n },\r\n off(event: string, callback: AnyCallback): void {\r\n listeners.get(event)?.delete(callback);\r\n },\r\n isFrameSupported(): boolean { return false; },\r\n isAtempoSupported(): boolean { return false; },\r\n isSoundSupported(): boolean { return false; },\r\n };\r\n}\r\n\r\nlet _recorder: ReturnType<typeof createMockGameRecorder> | null = null;\r\n\r\n/** wx.getGameRecorder \u2014 returns singleton mock game recorder */\r\nexport function getGameRecorder() {\r\n if (!_recorder) _recorder = createMockGameRecorder();\r\n return _recorder;\r\n}\r\n\r\n/** wx.createGameRecorderShareButton \u2014 returns mock share button */\r\nexport function createGameRecorderShareButton(_opts?: Record<string, unknown>) {\r\n const tapCbs = new Set<AnyCallback>();\r\n return {\r\n show(): void { /* no-op */ },\r\n hide(): void { /* no-op */ },\r\n destroy(): void { tapCbs.clear(); },\r\n onTap(callback: AnyCallback): void { tapCbs.add(callback); },\r\n offTap(callback: AnyCallback): void { tapCbs.delete(callback); },\r\n };\r\n}\r\n\r\n// \u2500\u2500\u2500 Video Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** wx.createVideo \u2014 returns mock video object */\r\nexport function createVideo(_opts?: Record<string, unknown>) {\r\n const listeners = new Map<string, Set<AnyCallback>>();\r\n return {\r\n src: '',\r\n loop: false,\r\n muted: false,\r\n autoplay: false,\r\n width: 300,\r\n height: 150,\r\n x: 0,\r\n y: 0,\r\n play(): void { /* no-op */ },\r\n pause(): void { /* no-op */ },\r\n stop(): void { /* no-op */ },\r\n seek(_position: number): void { /* no-op */ },\r\n requestFullScreen(): void { /* no-op */ },\r\n exitFullScreen(): void { /* no-op */ },\r\n destroy(): void { listeners.clear(); },\r\n onPlay(cb: AnyCallback): void { if (!listeners.has('play')) listeners.set('play', new Set()); listeners.get('play')!.add(cb); },\r\n offPlay(cb: AnyCallback): void { listeners.get('play')?.delete(cb); },\r\n onPause(cb: AnyCallback): void { if (!listeners.has('pause')) listeners.set('pause', new Set()); listeners.get('pause')!.add(cb); },\r\n offPause(cb: AnyCallback): void { listeners.get('pause')?.delete(cb); },\r\n onEnded(cb: AnyCallback): void { if (!listeners.has('ended')) listeners.set('ended', new Set()); listeners.get('ended')!.add(cb); },\r\n offEnded(cb: AnyCallback): void { listeners.get('ended')?.delete(cb); },\r\n onError(cb: AnyCallback): void { if (!listeners.has('error')) listeners.set('error', new Set()); listeners.get('error')!.add(cb); },\r\n offError(cb: AnyCallback): void { listeners.get('error')?.delete(cb); },\r\n onTimeUpdate(cb: AnyCallback): void { if (!listeners.has('timeupdate')) listeners.set('timeupdate', new Set()); listeners.get('timeupdate')!.add(cb); },\r\n offTimeUpdate(cb: AnyCallback): void { listeners.get('timeupdate')?.delete(cb); },\r\n onWaiting(cb: AnyCallback): void { if (!listeners.has('waiting')) listeners.set('waiting', new Set()); listeners.get('waiting')!.add(cb); },\r\n offWaiting(cb: AnyCallback): void { listeners.get('waiting')?.delete(cb); },\r\n };\r\n}\r\n\r\n// \u2500\u2500\u2500 Camera Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** wx.createCamera \u2014 returns mock camera object */\r\nexport function createCamera(_opts?: Record<string, unknown>) {\r\n return {\r\n startRecord(): void { /* no-op */ },\r\n stopRecord(_opts?: Record<string, unknown>): void { /* no-op */ },\r\n takePhoto(_opts?: Record<string, unknown>): void { /* no-op */ },\r\n destroy(): void { /* no-op */ },\r\n onStop(_cb: AnyCallback): void { /* no-op */ },\r\n onError(_cb: AnyCallback): void { /* no-op */ },\r\n };\r\n}\r\n", "/**\r\n * Catch-all no-op stubs for all remaining WeChat Mini Game APIs (P2).\r\n *\r\n * These prevent \"wx.xxx is not a function\" errors. Organized by category.\r\n * All functions follow the standard callback pattern (success/fail/complete).\r\n *\r\n * Categories:\r\n * - Capability detection (canIUse)\r\n * - Crypto (getRandomValues)\r\n * - Screen / UI chrome\r\n * - Navigation bar / Tab bar\r\n * - Background audio / Recording\r\n * - Location\r\n * - App lifecycle\r\n * - Bluetooth / NFC / Beacon\r\n * - VoIP\r\n * - Misc platform APIs\r\n */\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype AnyCallback = (...args: any[]) => void;\r\n\r\nimport { checkPermission } from './permission';\r\n\r\ninterface CallbackOpts {\r\n success?: AnyCallback;\r\n fail?: AnyCallback;\r\n complete?: AnyCallback;\r\n [key: string]: unknown;\r\n}\r\n\r\n// \u2500\u2500 Helper: create a success-returning stub \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction successStub(name: string) {\r\n return (opts?: CallbackOpts) => {\r\n opts?.success?.({ errMsg: `${name}:ok` });\r\n opts?.complete?.();\r\n };\r\n}\r\n\r\nfunction failStub(name: string, reason = 'not supported in preview') {\r\n return (opts?: CallbackOpts) => {\r\n opts?.fail?.({ errMsg: `${name}:fail ${reason}` });\r\n opts?.complete?.();\r\n };\r\n}\r\n\r\nfunction noop() { /* no-op */ }\r\n\r\n// \u2500\u2500\u2500 Capability Detection \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * wx.canIUse \u2014 check if an API/component/feature is supported.\r\n * In preview, return true for known APIs, false for unknown.\r\n *\r\n * NOTE: we intentionally use the `in` operator rather than\r\n * `typeof wx[name]` because `window.wx` is a Proxy that fabricates\r\n * safe no-op stubs for common event-style API names it does not actually\r\n * implement. Reading through `typeof` would cause `canIUse` to report\r\n * `true` for those stub names (which would in turn make games take\r\n * code paths that depend on the API actually working). `in` bypasses\r\n * the Proxy's `get` trap and reflects only real own/inherited properties\r\n * of the underlying wx object, giving an accurate truth value.\r\n */\r\nexport function canIUse(schema: string): boolean {\r\n const wx = (window as unknown as Record<string, unknown>).wx as\r\n | Record<string, unknown>\r\n | undefined;\r\n if (!wx) return false;\r\n\r\n const apiName = schema.split('.')[0];\r\n return apiName in wx;\r\n}\r\n\r\n// \u2500\u2500\u2500 Crypto \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * wx.getRandomValues \u2014 fill a buffer with cryptographically random values.\r\n */\r\nexport function getRandomValues(opts: CallbackOpts & { length: number }): void {\r\n try {\r\n const length = opts.length;\r\n const randomValues = new Uint8Array(length);\r\n crypto.getRandomValues(randomValues);\r\n opts.success?.({ randomValues: randomValues.buffer, errMsg: 'getRandomValues:ok' });\r\n } catch (e) {\r\n opts.fail?.({ errMsg: `getRandomValues:fail ${e}` });\r\n } finally {\r\n opts.complete?.();\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 Screen \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport const setScreenBrightness = successStub('setScreenBrightness');\r\nexport const getScreenBrightness = (opts?: CallbackOpts) => {\r\n opts?.success?.({ value: 1.0, errMsg: 'getScreenBrightness:ok' });\r\n opts?.complete?.();\r\n};\r\nexport const setStatusBarStyle = successStub('setStatusBarStyle');\r\n\r\n// \u2500\u2500\u2500 Navigation Bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport const showNavigationBarLoading = successStub('showNavigationBarLoading');\r\nexport const hideNavigationBarLoading = successStub('hideNavigationBarLoading');\r\nexport const setNavigationBarTitle = successStub('setNavigationBarTitle');\r\nexport const setNavigationBarColor = successStub('setNavigationBarColor');\r\nexport const hideHomeButton = successStub('hideHomeButton');\r\n\r\n// \u2500\u2500\u2500 Tab Bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport const showTabBar = successStub('showTabBar');\r\nexport const hideTabBar = successStub('hideTabBar');\r\nexport const showTabBarRedDot = successStub('showTabBarRedDot');\r\nexport const hideTabBarRedDot = successStub('hideTabBarRedDot');\r\nexport const setTabBarItem = successStub('setTabBarItem');\r\nexport const setTabBarStyle = successStub('setTabBarStyle');\r\nexport const setTabBarBadge = successStub('setTabBarBadge');\r\nexport const removeTabBarBadge = successStub('removeTabBarBadge');\r\n\r\n// \u2500\u2500\u2500 Background Audio \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nlet _bgAudioManager: Record<string, unknown> | null = null;\r\n\r\n/** wx.getBackgroundAudioManager \u2014 returns mock audio manager */\r\nexport function getBackgroundAudioManager() {\r\n if (_bgAudioManager) return _bgAudioManager;\r\n _bgAudioManager = {\r\n src: '',\r\n title: '',\r\n singer: '',\r\n coverImgUrl: '',\r\n startTime: 0,\r\n duration: 0,\r\n currentTime: 0,\r\n paused: true,\r\n buffered: 0,\r\n play: noop,\r\n pause: noop,\r\n stop: noop,\r\n seek: noop,\r\n onPlay: noop,\r\n onPause: noop,\r\n onStop: noop,\r\n onEnded: noop,\r\n onError: noop,\r\n onTimeUpdate: noop,\r\n onCanplay: noop,\r\n onWaiting: noop,\r\n onSeeking: noop,\r\n onSeeked: noop,\r\n onPrev: noop,\r\n onNext: noop,\r\n };\r\n return _bgAudioManager;\r\n}\r\n\r\n// \u2500\u2500\u2500 Recorder Manager \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nlet _recorderManager: Record<string, unknown> | null = null;\r\n\r\n/** wx.getRecorderManager \u2014 returns mock recorder */\r\nexport function getRecorderManager() {\r\n if (_recorderManager) return _recorderManager;\r\n _recorderManager = {\r\n start: noop,\r\n stop: noop,\r\n pause: noop,\r\n resume: noop,\r\n onStart: noop,\r\n onStop: noop,\r\n onPause: noop,\r\n onResume: noop,\r\n onFrameRecorded: noop,\r\n onError: noop,\r\n onInterruptionBegin: noop,\r\n onInterruptionEnd: noop,\r\n };\r\n return _recorderManager;\r\n}\r\n\r\n// \u2500\u2500\u2500 Update Manager \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n//\r\n// wx.getUpdateManager \u2014 returns a mock UpdateManager.\r\n//\r\n// In preview/browser environments there is no real WeChat update channel,\r\n// so we synthesize a \"no update available\" result on the next tick.\r\n// This matches the shape documented at:\r\n// https://developers.weixin.qq.com/minigame/dev/api/base/update/UpdateManager.html\r\n//\r\n// const mgr = wx.getUpdateManager();\r\n// mgr.onCheckForUpdate(res => { res.hasUpdate === false });\r\n// mgr.onUpdateReady(fn); // never fires in preview\r\n// mgr.onUpdateFailed(fn); // never fires in preview\r\n// mgr.applyUpdate(); // no-op\r\n//\r\n// Listeners registered BEFORE the synthesized dispatch will receive the\r\n// `{ hasUpdate: false }` callback once; listeners registered AFTER will\r\n// be invoked immediately with the cached result so late subscribers still\r\n// see the check-complete state (matches real-device behavior where the\r\n// framework fires the check at launch).\r\n\r\ninterface UpdateManager {\r\n applyUpdate(): void;\r\n onCheckForUpdate(listener: (res: { hasUpdate: boolean }) => void): void;\r\n onUpdateReady(listener: () => void): void;\r\n onUpdateFailed(listener: () => void): void;\r\n}\r\n\r\nlet _updateManager: UpdateManager | null = null;\r\n\r\nexport function getUpdateManager(): UpdateManager {\r\n if (_updateManager) return _updateManager;\r\n\r\n const checkResult = { hasUpdate: false };\r\n const checkListeners = new Set<(res: { hasUpdate: boolean }) => void>();\r\n const readyListeners = new Set<() => void>();\r\n const failedListeners = new Set<() => void>();\r\n let checkDispatched = false;\r\n\r\n // Simulate the \"check for update\" that WeChat fires at launch.\r\n // Use a microtask-ish delay so any listener registered synchronously\r\n // right after getUpdateManager() receives the callback.\r\n setTimeout(() => {\r\n checkDispatched = true;\r\n checkListeners.forEach((cb) => {\r\n try { cb(checkResult); } catch (e) { console.error('[wx-compat] onCheckForUpdate listener threw', e); }\r\n });\r\n }, 0);\r\n\r\n _updateManager = {\r\n applyUpdate() {\r\n // No-op in preview \u2014 there is nothing to apply.\r\n },\r\n onCheckForUpdate(listener) {\r\n if (typeof listener !== 'function') return;\r\n checkListeners.add(listener);\r\n // If the synthesized dispatch already fired, invoke the late\r\n // subscriber immediately with the cached result.\r\n if (checkDispatched) {\r\n try { listener(checkResult); } catch (e) { console.error('[wx-compat] onCheckForUpdate listener threw', e); }\r\n }\r\n },\r\n onUpdateReady(listener) {\r\n if (typeof listener !== 'function') return;\r\n readyListeners.add(listener);\r\n // Never fires in preview \u2014 nothing to download.\r\n },\r\n onUpdateFailed(listener) {\r\n if (typeof listener !== 'function') return;\r\n failedListeners.add(listener);\r\n // Never fires in preview \u2014 no update channel to fail.\r\n },\r\n };\r\n return _updateManager;\r\n}\r\n\r\n// \u2500\u2500\u2500 Location \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst locationCbs = new Set<AnyCallback>();\r\n\r\nexport function getLocation(opts?: CallbackOpts): void {\r\n if (!checkPermission('getLocation', opts)) return;\r\n // Try the real Geolocation API first; fall back to a Beijing mock if\r\n // the browser denies permission or the host disables geolocation.\r\n // Some embedded WebViews reject geolocation outright \u2014 we never block\r\n // the game on this and just hand back the mock coordinate.\r\n const finishWithMock = (): void => {\r\n opts?.success?.({\r\n latitude: 39.9042,\r\n longitude: 116.4074,\r\n speed: 0,\r\n accuracy: 65,\r\n altitude: 0,\r\n verticalAccuracy: 0,\r\n horizontalAccuracy: 65,\r\n errMsg: 'getLocation:ok',\r\n });\r\n opts?.complete?.();\r\n };\r\n // navigator may have been stripped by cleanGlobals on hostile builds\r\n // (it isn't by default, but being defensive costs nothing here).\r\n const geo = typeof navigator !== 'undefined' ? navigator.geolocation : null;\r\n if (!geo || typeof geo.getCurrentPosition !== 'function') {\r\n finishWithMock();\r\n return;\r\n }\r\n let settled = false;\r\n const safetyTimer = setTimeout(() => {\r\n if (settled) return;\r\n settled = true;\r\n finishWithMock();\r\n }, 1500);\r\n try {\r\n geo.getCurrentPosition(\r\n (pos) => {\r\n if (settled) return;\r\n settled = true;\r\n clearTimeout(safetyTimer);\r\n opts?.success?.({\r\n latitude: pos.coords.latitude,\r\n longitude: pos.coords.longitude,\r\n speed: pos.coords.speed || 0,\r\n accuracy: pos.coords.accuracy,\r\n altitude: pos.coords.altitude || 0,\r\n verticalAccuracy: pos.coords.altitudeAccuracy || 0,\r\n horizontalAccuracy: pos.coords.accuracy,\r\n errMsg: 'getLocation:ok',\r\n });\r\n opts?.complete?.();\r\n },\r\n () => {\r\n if (settled) return;\r\n settled = true;\r\n clearTimeout(safetyTimer);\r\n finishWithMock();\r\n },\r\n { timeout: 1200, maximumAge: 30_000 },\r\n );\r\n } catch {\r\n if (!settled) {\r\n settled = true;\r\n clearTimeout(safetyTimer);\r\n finishWithMock();\r\n }\r\n }\r\n}\r\nexport const startLocationUpdate = successStub('startLocationUpdate');\r\nexport const stopLocationUpdate = successStub('stopLocationUpdate');\r\nexport function onLocationChange(callback: AnyCallback): void { locationCbs.add(callback); }\r\nexport function offLocationChange(callback: AnyCallback): void { locationCbs.delete(callback); }\r\nexport const startLocationUpdateBackground = successStub('startLocationUpdateBackground');\r\nexport const stopLocationUpdateBackground = successStub('stopLocationUpdateBackground');\r\nexport const openLocation = successStub('openLocation');\r\nexport const chooseLocation = failStub('chooseLocation');\r\nexport const choosePoi = failStub('choosePoi');\r\n\r\n// \u2500\u2500\u2500 App Lifecycle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst appShowCbs = new Set<AnyCallback>();\r\nconst appHideCbs = new Set<AnyCallback>();\r\n\r\nexport function onAppShow(callback: AnyCallback): void { appShowCbs.add(callback); }\r\nexport function offAppShow(callback: AnyCallback): void { appShowCbs.delete(callback); }\r\nexport function onAppHide(callback: AnyCallback): void { appHideCbs.add(callback); }\r\nexport function offAppHide(callback: AnyCallback): void { appHideCbs.delete(callback); }\r\n\r\n// \u2500\u2500\u2500 Bluetooth \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// All fail with \"not supported\" \u2014 no Bluetooth in browser\r\n\r\nexport const openBluetoothAdapter = failStub('openBluetoothAdapter', 'not available in browser');\r\nexport const closeBluetoothAdapter = failStub('closeBluetoothAdapter', 'not available in browser');\r\nexport const getBluetoothAdapterState = failStub('getBluetoothAdapterState', 'not available in browser');\r\nexport const startBluetoothDevicesDiscovery = failStub('startBluetoothDevicesDiscovery', 'not available in browser');\r\nexport const stopBluetoothDevicesDiscovery = failStub('stopBluetoothDevicesDiscovery', 'not available in browser');\r\nexport const getBluetoothDevices = failStub('getBluetoothDevices', 'not available in browser');\r\nexport const getConnectedBluetoothDevices = failStub('getConnectedBluetoothDevices', 'not available in browser');\r\nexport const createBLEConnection = failStub('createBLEConnection', 'not available in browser');\r\nexport const closeBLEConnection = failStub('closeBLEConnection', 'not available in browser');\r\nexport const getBLEDeviceServices = failStub('getBLEDeviceServices', 'not available in browser');\r\nexport const getBLEDeviceCharacteristics = failStub('getBLEDeviceCharacteristics', 'not available in browser');\r\nexport const readBLECharacteristicValue = failStub('readBLECharacteristicValue', 'not available in browser');\r\nexport const writeBLECharacteristicValue = failStub('writeBLECharacteristicValue', 'not available in browser');\r\nexport const notifyBLECharacteristicValueChange = failStub('notifyBLECharacteristicValueChange', 'not available in browser');\r\nexport const onBluetoothAdapterStateChange = noop;\r\nexport const onBluetoothDeviceFound = noop;\r\nexport const onBLEConnectionStateChange = noop;\r\nexport const onBLECharacteristicValueChange = noop;\r\nexport const offBluetoothAdapterStateChange = noop;\r\nexport const offBluetoothDeviceFound = noop;\r\nexport const offBLEConnectionStateChange = noop;\r\nexport const offBLECharacteristicValueChange = noop;\r\nexport const setBLEMTU = failStub('setBLEMTU', 'not available in browser');\r\nexport const getBLEMTU = failStub('getBLEMTU', 'not available in browser');\r\nexport const getBLEDeviceRSSI = failStub('getBLEDeviceRSSI', 'not available in browser');\r\n\r\n// \u2500\u2500\u2500 NFC \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport const getNFCAdapter = () => null;\r\nexport const startHCE = failStub('startHCE', 'not available in browser');\r\nexport const stopHCE = failStub('stopHCE', 'not available in browser');\r\nexport const sendHCEMessage = failStub('sendHCEMessage', 'not available in browser');\r\nexport const onHCEMessage = noop;\r\nexport const offHCEMessage = noop;\r\n\r\n// \u2500\u2500\u2500 Beacon \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport const startBeaconDiscovery = failStub('startBeaconDiscovery', 'not available in browser');\r\nexport const stopBeaconDiscovery = failStub('stopBeaconDiscovery', 'not available in browser');\r\nexport const getBeacons = failStub('getBeacons', 'not available in browser');\r\nexport const onBeaconUpdate = noop;\r\nexport const onBeaconServiceChange = noop;\r\n\r\n// \u2500\u2500\u2500 WiFi \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport const startWifi = failStub('startWifi', 'not available in browser');\r\nexport const stopWifi = failStub('stopWifi', 'not available in browser');\r\nexport const getWifiList = failStub('getWifiList', 'not available in browser');\r\nexport const getConnectedWifi = failStub('getConnectedWifi', 'not available in browser');\r\nexport const connectWifi = failStub('connectWifi', 'not available in browser');\r\nexport const onWifiConnected = noop;\r\nexport const onGetWifiList = noop;\r\nexport const offWifiConnected = noop;\r\nexport const offGetWifiList = noop;\r\n\r\n// \u2500\u2500\u2500 VoIP \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport const joinVoIPChat = failStub('joinVoIPChat', 'not available in preview');\r\nexport const exitVoIPChat = failStub('exitVoIPChat', 'not available in preview');\r\nexport const updateVoIPChatMuteConfig = failStub('updateVoIPChatMuteConfig', 'not available in preview');\r\nexport const onVoIPChatMembersChanged = noop;\r\nexport const onVoIPChatSpeakersChanged = noop;\r\nexport const onVoIPChatInterrupted = noop;\r\nexport const onVoIPChatStateChanged = noop;\r\nexport const offVoIPChatMembersChanged = noop;\r\nexport const offVoIPChatSpeakersChanged = noop;\r\nexport const offVoIPChatInterrupted = noop;\r\nexport const offVoIPChatStateChanged = noop;\r\nexport const subscribeVoIPVideoMembers = failStub('subscribeVoIPVideoMembers', 'not available in preview');\r\nexport const createMediaRecorder = failStub('createMediaRecorder');\r\n\r\n// \u2500\u2500\u2500 Misc Platform APIs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport function makePhoneCall(opts?: CallbackOpts): void {\r\n console.warn('[wx-compat] makePhoneCall is not supported in preview');\r\n opts?.fail?.({ errMsg: 'makePhoneCall:fail not supported in preview' });\r\n opts?.complete?.();\r\n}\r\n\r\nexport function scanCode(opts?: CallbackOpts): void {\r\n if (!checkPermission('scanCode', opts)) return;\r\n // No real camera available in preview \u2014 prompt the user for a textual\r\n // code via the captured native window.prompt (cleanGlobals removes the\r\n // global function but we still have access to the boxed builtin via\r\n // the host page on dev builds). Falls back to fail-silent in cleaned\r\n // sandboxes so games never hang.\r\n const promptFn = (window as unknown as { prompt?: (m?: string) => string | null }).prompt;\r\n if (typeof promptFn === 'function') {\r\n try {\r\n const text = promptFn('[preview] scanCode \u2014 enter scanned text:') || '';\r\n if (text) {\r\n opts?.success?.({\r\n result: text,\r\n scanType: 'WX_CODE',\r\n charSet: 'utf-8',\r\n path: '',\r\n rawData: text,\r\n errMsg: 'scanCode:ok',\r\n });\r\n opts?.complete?.();\r\n return;\r\n }\r\n } catch { /* fall through to cancel */ }\r\n }\r\n opts?.fail?.({ errMsg: 'scanCode:fail cancel' });\r\n opts?.complete?.();\r\n}\r\n\r\nexport const setEnableDebug = successStub('setEnableDebug');\r\n\r\nexport function getAccountInfoSync() {\r\n return {\r\n miniProgram: { appId: 'preview', envVersion: 'develop', version: '' },\r\n plugin: { appId: '', version: '' },\r\n };\r\n}\r\n\r\n/** wx.createFeedbackButton \u2014 returns mock button */\r\nexport function createFeedbackButton(_opts?: Record<string, unknown>) {\r\n const tapCbs = new Set<AnyCallback>();\r\n return {\r\n show: noop,\r\n hide: noop,\r\n destroy(): void { tapCbs.clear(); },\r\n onTap(cb: AnyCallback): void { tapCbs.add(cb); },\r\n offTap(cb: AnyCallback): void { tapCbs.delete(cb); },\r\n };\r\n}\r\n\r\n/** wx.createGameClubButton \u2014 returns mock button */\r\nexport function createGameClubButton(_opts?: Record<string, unknown>) {\r\n const tapCbs = new Set<AnyCallback>();\r\n return {\r\n show: noop,\r\n hide: noop,\r\n destroy(): void { tapCbs.clear(); },\r\n onTap(cb: AnyCallback): void { tapCbs.add(cb); },\r\n offTap(cb: AnyCallback): void { tapCbs.delete(cb); },\r\n };\r\n}\r\n\r\nexport const requestSubscribeMessage = successStub('requestSubscribeMessage');\r\nexport const requestSubscribeSystemMessage = successStub('requestSubscribeSystemMessage');\r\n\r\n// \u2500\u2500\u2500 Keyboard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport const showKeyboard = successStub('showKeyboard');\r\nexport const hideKeyboard = successStub('hideKeyboard');\r\nexport const updateKeyboard = successStub('updateKeyboard');\r\n\r\nconst keyboardHeightCbs = new Set<AnyCallback>();\r\nconst keyboardInputCbs = new Set<AnyCallback>();\r\nconst keyboardConfirmCbs = new Set<AnyCallback>();\r\nconst keyboardCompleteCbs = new Set<AnyCallback>();\r\n\r\nexport function onKeyboardHeightChange(cb: AnyCallback): void { keyboardHeightCbs.add(cb); }\r\nexport function offKeyboardHeightChange(cb: AnyCallback): void { keyboardHeightCbs.delete(cb); }\r\nexport function onKeyboardInput(cb: AnyCallback): void { keyboardInputCbs.add(cb); }\r\nexport function offKeyboardInput(cb: AnyCallback): void { keyboardInputCbs.delete(cb); }\r\nexport function onKeyboardConfirm(cb: AnyCallback): void { keyboardConfirmCbs.add(cb); }\r\nexport function offKeyboardConfirm(cb: AnyCallback): void { keyboardConfirmCbs.delete(cb); }\r\nexport function onKeyboardComplete(cb: AnyCallback): void { keyboardCompleteCbs.add(cb); }\r\nexport function offKeyboardComplete(cb: AnyCallback): void { keyboardCompleteCbs.delete(cb); }\r\n\r\n// \u2500\u2500\u2500 Interaction \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport const enableAlertBeforeUnload = successStub('enableAlertBeforeUnload');\r\nexport const disableAlertBeforeUnload = successStub('disableAlertBeforeUnload');\r\n\r\n// \u2500\u2500\u2500 Map \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport const createMapContext = () => ({\r\n getCenterLocation: successStub('getCenterLocation'),\r\n moveToLocation: successStub('moveToLocation'),\r\n getRegion: successStub('getRegion'),\r\n getScale: successStub('getScale'),\r\n});\r\n\r\n// \u2500\u2500\u2500 Real-time communication \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport const createLivePusherContext = () => null;\r\nexport const createLivePlayerContext = () => null;\r\n", "/**\r\n * WeChat Mini Game Browser Compatibility Layer \u2014 Entry Point\r\n *\r\n * This script runs in the browser (inside VSCode WebviewPanel iframe).\r\n * It must be loaded BEFORE the game's game.js.\r\n *\r\n * All API implementations are split into separate modules by category:\r\n * - canvas.ts : Canvas creation and management\r\n * - system-info.ts : System info (getSystemInfo, getWindowInfo, etc.)\r\n * - storage.ts : localStorage-backed storage\r\n * - animation-frame.ts: requestAnimationFrame with pause/resume\r\n * - audio.ts : InnerAudioContext via HTML5 Audio\r\n * - network.ts : wx.request, wx.connectSocket, wx.downloadFile, wx.uploadFile\r\n * - device.ts : Vibration + touch events\r\n * - image.ts : Image creation\r\n * - perf.ts : Performance APIs\r\n * - lifecycle.ts : onShow/onHide/onError + onUnhandledRejection + launch options\r\n * - logger.ts : Log interception and forwarding\r\n * - env.ts : wx.env environment variables\r\n * - constants.ts : Shared device dimension constants\r\n * - render-helpers.ts : P1 rendering helpers (Path2D, ImageData, Font)\r\n * - ui.ts : P1 UI components (Toast, Modal, Loading, etc.)\r\n * - input-events.ts : P1 PC input events (Mouse, Wheel, Keyboard)\r\n * - cursor.ts : P2 mouse cursor and pointer lock\r\n * - sensors.ts : P2 accelerometer, gyroscope, compass, orientation, motion\r\n * - device-extras.ts : P2 battery, clipboard, network status, screen, memory, gamepad\r\n * - data-analysis.ts : P2 data reporting and experiments\r\n * - worker-compat.ts : P2 Worker\r\n * - utils.ts : P2 encode/decode, compressImage\r\n * - module-compat.ts : P0 Subpackage loading (wx.loadSubpackage)\r\n * - globals-compat.ts : P0 Global function shims (__wxConfig, timers on GameGlobal, etc.)\r\n * - plugin-compat.ts : P0 Plugin system (define + requirePlugin for engine plugins)\r\n */\r\n\r\n// \u2500\u2500\u2500 Module Imports (esbuild will bundle these into the IIFE) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n// CRITICAL: native-globals MUST be imported first to capture native browser APIs\r\n// before any game adapter (e.g. web-adapter.js) can overwrite them.\r\nimport './native-globals';\r\nimport { nativeBody, nativeFetch } from './native-globals';\r\nimport { resolveGameUrl, loadGameManifest } from './url-utils';\r\n\r\nimport { DEVICE } from './constants';\r\nimport { createCanvas, createOffscreenCanvas } from './canvas';\r\nimport {\r\n getSystemInfo,\r\n getSystemInfoSync,\r\n getSystemInfoAsync,\r\n getWindowInfo,\r\n getDeviceInfo,\r\n getAppBaseInfo,\r\n getSystemSetting,\r\n getDeviceBenchmarkInfo,\r\n} from './system-info';\r\nimport {\r\n setStorage,\r\n getStorage,\r\n removeStorage,\r\n clearStorage,\r\n setStorageSync,\r\n getStorageSync,\r\n removeStorageSync,\r\n clearStorageSync,\r\n getStorageInfo,\r\n getStorageInfoSync,\r\n createBufferURL,\r\n revokeBufferURL,\r\n} from './storage';\r\nimport {\r\n requestAnimationFrame,\r\n cancelAnimationFrame,\r\n pauseAnimationFrames,\r\n resumeAnimationFrames,\r\n} from './animation-frame';\r\nimport { createInnerAudioContext, setInnerAudioOption, createWebAudioContext } from './audio';\r\nimport { request, connectSocket, downloadFile, uploadFile } from './network';\r\nimport {\r\n vibrateShort,\r\n vibrateLong,\r\n onTouchStart,\r\n onTouchMove,\r\n onTouchEnd,\r\n onTouchCancel,\r\n offTouchStart,\r\n offTouchMove,\r\n offTouchEnd,\r\n offTouchCancel,\r\n} from './device';\r\nimport { createImage } from './image';\r\nimport {\r\n getPerformance,\r\n setPreferredFramesPerSecond,\r\n reportPerformance,\r\n triggerGC,\r\n getLogManager,\r\n getRealtimeLogManager,\r\n} from './perf';\r\nimport {\r\n onShow,\r\n offShow,\r\n onHide,\r\n offHide,\r\n onError,\r\n offError,\r\n onUnhandledRejection,\r\n offUnhandledRejection,\r\n onAudioInterruptionBegin,\r\n offAudioInterruptionBegin,\r\n onAudioInterruptionEnd,\r\n offAudioInterruptionEnd,\r\n getLaunchOptionsSync,\r\n getEnterOptionsSync,\r\n} from './lifecycle';\r\nimport { setupLogInterception } from './logger';\r\nimport { env } from './env';\r\nimport {\r\n createPath2D,\r\n createImageData,\r\n loadFont,\r\n getTextLineHeight,\r\n} from './render-helpers';\r\nimport {\r\n showToast,\r\n hideToast,\r\n showModal,\r\n showLoading,\r\n hideLoading,\r\n showActionSheet,\r\n getMenuButtonBoundingClientRect,\r\n onWindowResize,\r\n offWindowResize,\r\n onWindowStateChange,\r\n offWindowStateChange,\r\n} from './ui';\r\nimport {\r\n onMouseDown,\r\n offMouseDown,\r\n onMouseMove,\r\n offMouseMove,\r\n onMouseUp,\r\n offMouseUp,\r\n onWheel,\r\n offWheel,\r\n onKeyDown,\r\n offKeyDown,\r\n onKeyUp,\r\n offKeyUp,\r\n} from './input-events';\r\nimport {\r\n setCursor,\r\n requestPointerLock,\r\n exitPointerLock,\r\n isPointerLocked,\r\n} from './cursor';\r\nimport {\r\n startAccelerometer,\r\n stopAccelerometer,\r\n onAccelerometerChange,\r\n offAccelerometerChange,\r\n startGyroscope,\r\n stopGyroscope,\r\n onGyroscopeChange,\r\n offGyroscopeChange,\r\n startCompass,\r\n stopCompass,\r\n onCompassChange,\r\n offCompassChange,\r\n onDeviceOrientationChange,\r\n offDeviceOrientationChange,\r\n setDeviceOrientation,\r\n startDeviceMotionListening,\r\n stopDeviceMotionListening,\r\n onDeviceMotionChange,\r\n offDeviceMotionChange,\r\n} from './sensors';\r\nimport {\r\n getBatteryInfo,\r\n getBatteryInfoSync,\r\n setClipboardData,\r\n getClipboardData,\r\n getNetworkType,\r\n onNetworkStatusChange,\r\n offNetworkStatusChange,\r\n onNetworkWeakChange,\r\n offNetworkWeakChange,\r\n setKeepScreenOn,\r\n onMemoryWarning,\r\n offMemoryWarning,\r\n getGamepads,\r\n onGamepadConnected,\r\n onGamepadDisconnected,\r\n} from './device-extras';\r\nimport {\r\n reportAnalytics,\r\n reportEvent,\r\n reportMonitor,\r\n reportScene,\r\n getExptInfoSync,\r\n getGameExptInfo,\r\n getGameLogManager,\r\n getMiniReportManager,\r\n} from './data-analysis';\r\nimport { createWorker } from './worker-compat';\r\nimport { encode, decode, compressImage } from './utils';\r\nimport { loadSubpackage } from './module-compat';\r\nimport { installGlobalShims } from './globals-compat';\r\nimport { installPermissionDebugApi } from './permission';\r\nimport {\r\n isVfsUrl,\r\n fromVfsUrl,\r\n getText as vfsGetText,\r\n has as vfsHas,\r\n listPaths as vfsListPaths,\r\n} from './virtual-fs';\r\nimport {\r\n loadWxapkg,\r\n getGlobalResolver as getWxapkgResolver,\r\n getGlobalAppid as getWxapkgAppid,\r\n getGlobalUseProxy as getWxapkgUseProxy,\r\n} from './wxapkg-loader';\r\nimport { cleanGlobals } from './clean-globals';\r\nimport type { SandboxConfig } from './clean-globals';\r\nimport { getFileSystemManager } from './file-system';\r\nimport {\r\n initApiMonitor,\r\n isMonitorEnabled,\r\n wrapWxWithMonitor,\r\n wrapGlobalWithMonitor,\r\n recordGlobalApiCall,\r\n MONITORED_GLOBALS,\r\n} from './api-monitor';\r\nimport { initNetworkMonitor } from './network-monitor';\r\nimport {\r\n shareAppMessage,\r\n onShareAppMessage,\r\n offShareAppMessage,\r\n showShareMenu,\r\n hideShareMenu,\r\n updateShareMenu,\r\n showShareImageMenu,\r\n shareFileMessage,\r\n onShareTimeline,\r\n offShareTimeline,\r\n onAddToFavorites,\r\n offAddToFavorites,\r\n onShareMessageToFriend,\r\n offShareMessageToFriend,\r\n shareMessageToFriend,\r\n} from './share';\r\nimport {\r\n login,\r\n checkSession,\r\n authorize,\r\n getSetting,\r\n openSetting,\r\n getUserInfo,\r\n getUserProfile,\r\n createUserInfoButton,\r\n} from './auth';\r\nimport { canvasToTempFilePath } from './canvas';\r\nimport {\r\n getOpenDataContext,\r\n getFriendCloudStorage,\r\n getGroupCloudStorage,\r\n getUserCloudStorage,\r\n setUserCloudStorage,\r\n removeUserCloudStorage,\r\n getUserInteractiveStorage,\r\n} from './open-data';\r\nimport {\r\n createRewardedVideoAd,\r\n createInterstitialAd,\r\n createBannerAd,\r\n createCustomAd,\r\n} from './ad';\r\nimport { arrayBufferToBase64, base64ToArrayBuffer } from './utils';\r\nimport { canvasGetImageData, canvasPutImageData } from './canvas';\r\nimport {\r\n sendSocketMessage,\r\n closeSocket,\r\n onSocketOpen,\r\n onSocketClose,\r\n onSocketMessage,\r\n onSocketError,\r\n} from './network';\r\nimport {\r\n chooseImage,\r\n chooseMedia,\r\n chooseVideo,\r\n chooseMessageFile,\r\n getImageInfo,\r\n getVideoInfo,\r\n previewImage,\r\n previewMedia,\r\n saveImageToPhotosAlbum,\r\n saveVideoToPhotosAlbum,\r\n} from './media';\r\nimport {\r\n navigateTo,\r\n navigateBack,\r\n redirectTo,\r\n reLaunch,\r\n switchTab,\r\n navigateToMiniProgram,\r\n navigateBackMiniProgram,\r\n exitMiniProgram,\r\n restartMiniProgram,\r\n} from './router';\r\nimport { requestMidasPayment, requestMidasFriendPayment } from './payment';\r\nimport { notifyMiniProgramPlayableStatus, reportGameEvent } from './playable';\r\nimport {\r\n getGameRecorder,\r\n createGameRecorderShareButton,\r\n createVideo,\r\n createCamera,\r\n} from './recorder';\r\nimport {\r\n canIUse,\r\n getRandomValues,\r\n setScreenBrightness,\r\n getScreenBrightness,\r\n setStatusBarStyle,\r\n showNavigationBarLoading,\r\n hideNavigationBarLoading,\r\n setNavigationBarTitle,\r\n setNavigationBarColor,\r\n hideHomeButton,\r\n showTabBar,\r\n hideTabBar,\r\n showTabBarRedDot,\r\n hideTabBarRedDot,\r\n setTabBarItem,\r\n setTabBarStyle,\r\n setTabBarBadge,\r\n removeTabBarBadge,\r\n getBackgroundAudioManager,\r\n getRecorderManager,\r\n getUpdateManager,\r\n getLocation,\r\n startLocationUpdate,\r\n stopLocationUpdate,\r\n onLocationChange,\r\n offLocationChange,\r\n startLocationUpdateBackground,\r\n stopLocationUpdateBackground,\r\n openLocation,\r\n chooseLocation,\r\n choosePoi,\r\n onAppShow,\r\n offAppShow,\r\n onAppHide,\r\n offAppHide,\r\n openBluetoothAdapter,\r\n closeBluetoothAdapter,\r\n getBluetoothAdapterState,\r\n startBluetoothDevicesDiscovery,\r\n stopBluetoothDevicesDiscovery,\r\n getBluetoothDevices,\r\n getConnectedBluetoothDevices,\r\n createBLEConnection,\r\n closeBLEConnection,\r\n getBLEDeviceServices,\r\n getBLEDeviceCharacteristics,\r\n readBLECharacteristicValue,\r\n writeBLECharacteristicValue,\r\n notifyBLECharacteristicValueChange,\r\n onBluetoothAdapterStateChange,\r\n onBluetoothDeviceFound,\r\n onBLEConnectionStateChange,\r\n onBLECharacteristicValueChange,\r\n offBluetoothAdapterStateChange,\r\n offBluetoothDeviceFound,\r\n offBLEConnectionStateChange,\r\n offBLECharacteristicValueChange,\r\n setBLEMTU,\r\n getBLEMTU,\r\n getBLEDeviceRSSI,\r\n getNFCAdapter,\r\n startHCE,\r\n stopHCE,\r\n sendHCEMessage,\r\n onHCEMessage,\r\n offHCEMessage,\r\n startBeaconDiscovery,\r\n stopBeaconDiscovery,\r\n getBeacons,\r\n onBeaconUpdate,\r\n onBeaconServiceChange,\r\n startWifi,\r\n stopWifi,\r\n getWifiList,\r\n getConnectedWifi,\r\n connectWifi,\r\n onWifiConnected,\r\n onGetWifiList,\r\n offWifiConnected,\r\n offGetWifiList,\r\n joinVoIPChat,\r\n exitVoIPChat,\r\n updateVoIPChatMuteConfig,\r\n onVoIPChatMembersChanged,\r\n onVoIPChatSpeakersChanged,\r\n onVoIPChatInterrupted,\r\n onVoIPChatStateChanged,\r\n offVoIPChatMembersChanged,\r\n offVoIPChatSpeakersChanged,\r\n offVoIPChatInterrupted,\r\n offVoIPChatStateChanged,\r\n subscribeVoIPVideoMembers,\r\n createMediaRecorder,\r\n makePhoneCall,\r\n scanCode,\r\n setEnableDebug,\r\n getAccountInfoSync,\r\n createFeedbackButton,\r\n createGameClubButton,\r\n requestSubscribeMessage,\r\n requestSubscribeSystemMessage,\r\n showKeyboard,\r\n hideKeyboard,\r\n updateKeyboard,\r\n onKeyboardHeightChange,\r\n offKeyboardHeightChange,\r\n onKeyboardInput,\r\n offKeyboardInput,\r\n onKeyboardConfirm,\r\n offKeyboardConfirm,\r\n onKeyboardComplete,\r\n offKeyboardComplete,\r\n enableAlertBeforeUnload,\r\n disableAlertBeforeUnload,\r\n createMapContext,\r\n createLivePusherContext,\r\n createLivePlayerContext,\r\n} from './stubs';\r\n\r\n// \u2500\u2500\u2500 Initialize \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n// Setup log interception (patches console.log/warn/error)\r\nsetupLogInterception();\r\nconsole.log('[wx-compat] Log interception installed');\r\n\r\n// Install global function shims (__wxConfig, timers on GameGlobal, etc.)\r\nconsole.log('[wx-compat] Installing global shims...');\r\ninstallGlobalShims();\r\nconsole.log('[wx-compat] Global shims installed');\r\n\r\n// Install permission debug surface (window.__wxPermission). Reads any\r\n// host-supplied policy override from window.__wxPermissionPolicy. Must\r\n// run BEFORE cleanGlobals so the override (which the host sets via the\r\n// device-config script in game-host.ts) is still on window.\r\ninstallPermissionDebugApi();\r\n\r\n// Clean browser globals to match WeChat Mini Game sandbox.\r\n// This removes DOM/BOM APIs that WeChat runtime doesn't provide,\r\n// ensuring games that work in preview also work on real devices.\r\n// Pass ?sandbox=false in the URL to disable all cleanup for debugging.\r\n//\r\n// By default, ALL sandbox steps are enabled. This is safe because all internal\r\n// code uses aliased native APIs (nativeLocalStorage, nativeDocument, etc.)\r\n// captured in native-globals.ts before cleanup runs.\r\nconst sandboxParam = new URLSearchParams(window.location?.search || '').get('sandbox');\r\nlet sandboxConfig: boolean | SandboxConfig;\r\nif (sandboxParam === 'false') {\r\n sandboxConfig = false;\r\n} else {\r\n // Default: full sandbox \u2014 all native APIs are aliased via native-globals.ts,\r\n // so it's safe to clean everything without breaking our mock layer.\r\n sandboxConfig = {\r\n cleanWindowOwnProps: true,\r\n cleanWindowNonEnumAPIs: true,\r\n cleanDocumentProps: true,\r\n overrideDocumentPrototype: true,\r\n overrideWindowPrototype: true,\r\n installDocumentProxy: true,\r\n };\r\n}\r\ncleanGlobals(sandboxConfig);\r\n\r\n// \u2500\u2500\u2500 API Monitor \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// Initialize the API monitor (reads window.__wxApiMonitorEnabled).\r\n// Must run AFTER cleanGlobals but BEFORE the wx object is assembled.\r\ninitApiMonitor();\r\n\r\n// \u2500\u2500\u2500 Network Monitor \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// Initialize the network monitor (reads window.__wxNetworkMonitorEnabled).\r\n// Must run AFTER installGlobalShims so that we wrap the *patched* fetch /\r\n// XHR / WebSocket (cdn-proxy URL rewriting still happens before recording).\r\ninitNetworkMonitor();\r\n\r\n// \u2500\u2500\u2500 Pause / Resume Control \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nwindow.addEventListener('message', (e: MessageEvent) => {\r\n if (!e.data || typeof e.data !== 'object') return;\r\n const { type } = e.data as { type: string };\r\n\r\n if (type === '__wx_pause__') {\r\n pauseAnimationFrames();\r\n console.log('[wx-compat] Game paused');\r\n } else if (type === '__wx_resume__') {\r\n resumeAnimationFrames();\r\n console.log('[wx-compat] Game resumed');\r\n }\r\n});\r\n\r\n// \u2500\u2500\u2500 Assemble wx Object \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst wx = {\r\n // Environment (P0)\r\n env,\r\n\r\n // Canvas\r\n createCanvas,\r\n createOffscreenCanvas,\r\n createImage,\r\n\r\n // Render Helpers (P1)\r\n createPath2D,\r\n createImageData,\r\n loadFont,\r\n getTextLineHeight,\r\n\r\n // System Info\r\n getSystemInfo,\r\n getSystemInfoSync,\r\n getSystemInfoAsync, // P0\r\n getWindowInfo, // P0\r\n getDeviceInfo, // P2\r\n getAppBaseInfo, // P2\r\n getSystemSetting, // P2\r\n getDeviceBenchmarkInfo,// P2\r\n\r\n // Storage\r\n setStorage,\r\n getStorage,\r\n removeStorage,\r\n clearStorage,\r\n setStorageSync,\r\n getStorageSync,\r\n removeStorageSync,\r\n clearStorageSync,\r\n getStorageInfo, // P2\r\n getStorageInfoSync, // P2\r\n createBufferURL, // P2\r\n revokeBufferURL, // P2\r\n\r\n // Animation\r\n requestAnimationFrame,\r\n cancelAnimationFrame,\r\n\r\n // Audio\r\n createInnerAudioContext,\r\n setInnerAudioOption, // P2\r\n createWebAudioContext, // P2\r\n\r\n // Network\r\n request,\r\n connectSocket, // P1\r\n downloadFile, // P1\r\n uploadFile, // P1\r\n\r\n // Vibration\r\n vibrateShort,\r\n vibrateLong,\r\n\r\n // Touch Events (P0)\r\n onTouchStart,\r\n onTouchMove,\r\n onTouchEnd,\r\n onTouchCancel,\r\n offTouchStart,\r\n offTouchMove,\r\n offTouchEnd,\r\n offTouchCancel,\r\n\r\n // Mouse Events (P1)\r\n onMouseDown,\r\n offMouseDown,\r\n onMouseMove,\r\n offMouseMove,\r\n onMouseUp,\r\n offMouseUp,\r\n\r\n // Wheel Events (P1)\r\n onWheel,\r\n offWheel,\r\n\r\n // Keyboard Events (P1)\r\n onKeyDown,\r\n offKeyDown,\r\n onKeyUp,\r\n offKeyUp,\r\n\r\n // Performance\r\n getPerformance,\r\n setPreferredFramesPerSecond,\r\n reportPerformance, // P2\r\n triggerGC, // P2\r\n getLogManager, // P2\r\n getRealtimeLogManager, // P2\r\n\r\n // Lifecycle (P0 + P1 extensions)\r\n onShow,\r\n offShow,\r\n onHide,\r\n offHide,\r\n onError,\r\n offError,\r\n onUnhandledRejection, // P1\r\n offUnhandledRejection, // P1\r\n onAudioInterruptionBegin, // P1 (no-op)\r\n offAudioInterruptionBegin,// P1 (no-op)\r\n onAudioInterruptionEnd, // P1 (no-op)\r\n offAudioInterruptionEnd, // P1 (no-op)\r\n getLaunchOptionsSync, // P1\r\n getEnterOptionsSync, // P1\r\n\r\n // UI (P1)\r\n showToast,\r\n hideToast,\r\n showModal,\r\n showLoading,\r\n hideLoading,\r\n showActionSheet,\r\n getMenuButtonBoundingClientRect,\r\n onWindowResize,\r\n offWindowResize,\r\n onWindowStateChange, // P2\r\n offWindowStateChange, // P2\r\n\r\n // Cursor (P2)\r\n setCursor,\r\n requestPointerLock,\r\n exitPointerLock,\r\n isPointerLocked,\r\n\r\n // Sensors (P2)\r\n startAccelerometer,\r\n stopAccelerometer,\r\n onAccelerometerChange,\r\n offAccelerometerChange,\r\n startGyroscope,\r\n stopGyroscope,\r\n onGyroscopeChange,\r\n offGyroscopeChange,\r\n startCompass,\r\n stopCompass,\r\n onCompassChange,\r\n offCompassChange,\r\n onDeviceOrientationChange,\r\n offDeviceOrientationChange,\r\n setDeviceOrientation,\r\n startDeviceMotionListening,\r\n stopDeviceMotionListening,\r\n onDeviceMotionChange,\r\n offDeviceMotionChange,\r\n\r\n // Device Extras (P2)\r\n getBatteryInfo,\r\n getBatteryInfoSync,\r\n setClipboardData,\r\n getClipboardData,\r\n getNetworkType,\r\n onNetworkStatusChange,\r\n offNetworkStatusChange,\r\n onNetworkWeakChange,\r\n offNetworkWeakChange,\r\n setKeepScreenOn,\r\n onMemoryWarning,\r\n offMemoryWarning,\r\n getGamepads,\r\n onGamepadConnected,\r\n onGamepadDisconnected,\r\n\r\n // Data Analysis (P2)\r\n reportAnalytics,\r\n reportEvent,\r\n reportMonitor,\r\n reportScene,\r\n getExptInfoSync,\r\n getGameExptInfo,\r\n getGameLogManager,\r\n getMiniReportManager,\r\n\r\n // Worker (P2)\r\n createWorker,\r\n\r\n // Subpackage Loading (P1)\r\n loadSubpackage,\r\n\r\n // Utils (P2)\r\n encode,\r\n decode,\r\n compressImage,\r\n\r\n // File System (P0)\r\n getFileSystemManager,\r\n\r\n // Share (P0 \u2014 no-op stubs)\r\n shareAppMessage,\r\n onShareAppMessage,\r\n offShareAppMessage,\r\n showShareMenu,\r\n hideShareMenu,\r\n updateShareMenu,\r\n showShareImageMenu,\r\n shareFileMessage,\r\n onShareTimeline,\r\n offShareTimeline,\r\n onAddToFavorites,\r\n offAddToFavorites,\r\n onShareMessageToFriend,\r\n offShareMessageToFriend,\r\n shareMessageToFriend,\r\n\r\n // Auth / Login (P0 \u2014 mock)\r\n login,\r\n checkSession,\r\n authorize,\r\n getSetting,\r\n openSetting,\r\n getUserInfo,\r\n getUserProfile,\r\n createUserInfoButton,\r\n\r\n // Canvas Export (P1)\r\n canvasToTempFilePath,\r\n\r\n // Open Data Context (P1 \u2014 mock)\r\n getOpenDataContext,\r\n getFriendCloudStorage,\r\n getGroupCloudStorage,\r\n getUserCloudStorage,\r\n setUserCloudStorage,\r\n removeUserCloudStorage,\r\n getUserInteractiveStorage,\r\n\r\n // Ads (P1 \u2014 mock)\r\n createRewardedVideoAd,\r\n createInterstitialAd,\r\n createBannerAd,\r\n createCustomAd,\r\n\r\n // \u2500\u2500\u2500 P2 APIs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n // Base64 encoding\r\n arrayBufferToBase64,\r\n base64ToArrayBuffer,\r\n\r\n // Canvas pixel operations\r\n canvasGetImageData,\r\n canvasPutImageData,\r\n\r\n // Global WebSocket events (legacy)\r\n sendSocketMessage,\r\n closeSocket,\r\n onSocketOpen,\r\n onSocketClose,\r\n onSocketMessage,\r\n onSocketError,\r\n\r\n // Media selection / info\r\n chooseImage,\r\n chooseMedia,\r\n chooseVideo,\r\n chooseMessageFile,\r\n getImageInfo,\r\n getVideoInfo,\r\n previewImage,\r\n previewMedia,\r\n saveImageToPhotosAlbum,\r\n saveVideoToPhotosAlbum,\r\n\r\n // Router / Navigation\r\n navigateTo,\r\n navigateBack,\r\n redirectTo,\r\n reLaunch,\r\n switchTab,\r\n navigateToMiniProgram,\r\n navigateBackMiniProgram,\r\n exitMiniProgram,\r\n restartMiniProgram,\r\n\r\n // Payment\r\n requestMidasPayment,\r\n requestMidasFriendPayment,\r\n\r\n // Playable Ad (\u8BD5\u73A9\u5E7F\u544A\u4E13\u7528)\r\n notifyMiniProgramPlayableStatus,\r\n reportGameEvent,\r\n\r\n // Recorder / Video / Camera\r\n getGameRecorder,\r\n createGameRecorderShareButton,\r\n createVideo,\r\n createCamera,\r\n\r\n // Capability detection\r\n canIUse,\r\n\r\n // Crypto\r\n getRandomValues,\r\n\r\n // Screen\r\n setScreenBrightness,\r\n getScreenBrightness,\r\n setStatusBarStyle,\r\n\r\n // Navigation bar\r\n showNavigationBarLoading,\r\n hideNavigationBarLoading,\r\n setNavigationBarTitle,\r\n setNavigationBarColor,\r\n hideHomeButton,\r\n\r\n // Tab bar\r\n showTabBar,\r\n hideTabBar,\r\n showTabBarRedDot,\r\n hideTabBarRedDot,\r\n setTabBarItem,\r\n setTabBarStyle,\r\n setTabBarBadge,\r\n removeTabBarBadge,\r\n\r\n // Background audio / Recorder\r\n getBackgroundAudioManager,\r\n getRecorderManager,\r\n\r\n // Update manager\r\n getUpdateManager,\r\n\r\n // Location\r\n getLocation,\r\n startLocationUpdate,\r\n stopLocationUpdate,\r\n onLocationChange,\r\n offLocationChange,\r\n startLocationUpdateBackground,\r\n stopLocationUpdateBackground,\r\n openLocation,\r\n chooseLocation,\r\n choosePoi,\r\n\r\n // App lifecycle\r\n onAppShow,\r\n offAppShow,\r\n onAppHide,\r\n offAppHide,\r\n\r\n // Bluetooth\r\n openBluetoothAdapter,\r\n closeBluetoothAdapter,\r\n getBluetoothAdapterState,\r\n startBluetoothDevicesDiscovery,\r\n stopBluetoothDevicesDiscovery,\r\n getBluetoothDevices,\r\n getConnectedBluetoothDevices,\r\n createBLEConnection,\r\n closeBLEConnection,\r\n getBLEDeviceServices,\r\n getBLEDeviceCharacteristics,\r\n readBLECharacteristicValue,\r\n writeBLECharacteristicValue,\r\n notifyBLECharacteristicValueChange,\r\n onBluetoothAdapterStateChange,\r\n onBluetoothDeviceFound,\r\n onBLEConnectionStateChange,\r\n onBLECharacteristicValueChange,\r\n offBluetoothAdapterStateChange,\r\n offBluetoothDeviceFound,\r\n offBLEConnectionStateChange,\r\n offBLECharacteristicValueChange,\r\n setBLEMTU,\r\n getBLEMTU,\r\n getBLEDeviceRSSI,\r\n\r\n // NFC\r\n getNFCAdapter,\r\n startHCE,\r\n stopHCE,\r\n sendHCEMessage,\r\n onHCEMessage,\r\n offHCEMessage,\r\n\r\n // Beacon\r\n startBeaconDiscovery,\r\n stopBeaconDiscovery,\r\n getBeacons,\r\n onBeaconUpdate,\r\n onBeaconServiceChange,\r\n\r\n // WiFi\r\n startWifi,\r\n stopWifi,\r\n getWifiList,\r\n getConnectedWifi,\r\n connectWifi,\r\n onWifiConnected,\r\n onGetWifiList,\r\n offWifiConnected,\r\n offGetWifiList,\r\n\r\n // VoIP\r\n joinVoIPChat,\r\n exitVoIPChat,\r\n updateVoIPChatMuteConfig,\r\n onVoIPChatMembersChanged,\r\n onVoIPChatSpeakersChanged,\r\n onVoIPChatInterrupted,\r\n onVoIPChatStateChanged,\r\n offVoIPChatMembersChanged,\r\n offVoIPChatSpeakersChanged,\r\n offVoIPChatInterrupted,\r\n offVoIPChatStateChanged,\r\n subscribeVoIPVideoMembers,\r\n createMediaRecorder,\r\n\r\n // Misc platform\r\n makePhoneCall,\r\n scanCode,\r\n setEnableDebug,\r\n getAccountInfoSync,\r\n createFeedbackButton,\r\n createGameClubButton,\r\n requestSubscribeMessage,\r\n requestSubscribeSystemMessage,\r\n\r\n // Keyboard\r\n showKeyboard,\r\n hideKeyboard,\r\n updateKeyboard,\r\n onKeyboardHeightChange,\r\n offKeyboardHeightChange,\r\n onKeyboardInput,\r\n offKeyboardInput,\r\n onKeyboardConfirm,\r\n offKeyboardConfirm,\r\n onKeyboardComplete,\r\n offKeyboardComplete,\r\n\r\n // Interaction\r\n enableAlertBeforeUnload,\r\n disableAlertBeforeUnload,\r\n\r\n // Map\r\n createMapContext,\r\n\r\n // Live\r\n createLivePusherContext,\r\n createLivePlayerContext,\r\n};\r\n\r\n// \u2500\u2500\u2500 Global Exports \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n// Before exposing `wx`, wrap it in a Proxy that provides a **safe default**\r\n// for unimplemented event/action style APIs.\r\n//\r\n// Real WeChat ships hundreds of APIs; compat coverage will always trail\r\n// behind. When a game calls something we have not shipped (e.g.\r\n// `wx.onAddToFavorites`, `wx.reportEvent`, `wx.onXxx`), the runtime raises\r\n// `TypeError: x is not a function` and the whole frame dies.\r\n//\r\n// We only provide a fallback for names whose *semantics in preview* are\r\n// clearly no-op: event listeners (`onXxx` / `offXxx`), menu toggles\r\n// (`showXxx` / `hideXxx`), and telemetry (`reportXxx`). For these, silently\r\n// swallowing the call keeps the game running \u2014 which is exactly what the\r\n// native preview sandbox does too (share APIs are marked `ibForbiddenApi`).\r\n//\r\n// We deliberately do NOT fabricate fallbacks for arbitrary names, because\r\n// a getter-style API returning `undefined` would masquerade as success and\r\n// corrupt game logic downstream (e.g. `wx.getLaunchOptionsSync()` returning\r\n// a noop function would later blow up inside the caller).\r\n\r\nfunction isSafeNoopApiName(key: string): boolean {\r\n return (\r\n key.startsWith('on') ||\r\n key.startsWith('off') ||\r\n key.startsWith('show') ||\r\n key.startsWith('hide') ||\r\n key.startsWith('report') ||\r\n key.startsWith('log')\r\n );\r\n}\r\n\r\ninterface NoopCallbackOpts {\r\n success?: (...args: unknown[]) => void;\r\n fail?: (...args: unknown[]) => void;\r\n complete?: (...args: unknown[]) => void;\r\n}\r\n\r\nconst warnedMissing = new Set<string>();\r\n\r\nconst wxProxy = new Proxy(wx, {\r\n get(target, prop, receiver) {\r\n if (typeof prop === 'symbol') {\r\n return Reflect.get(target, prop, receiver);\r\n }\r\n if (prop in target) {\r\n return Reflect.get(target, prop, receiver);\r\n }\r\n const key = String(prop);\r\n if (!isSafeNoopApiName(key)) {\r\n // Not a safe no-op candidate. Return undefined so the game's own\r\n // `typeof wx.x === 'function'` capability check works correctly.\r\n return undefined;\r\n }\r\n // Return a function with the standard callback shape.\r\n const noop = function wxNoopStub(opts?: NoopCallbackOpts) {\r\n if (!warnedMissing.has(key)) {\r\n warnedMissing.add(key);\r\n // eslint-disable-next-line no-console\r\n console.warn(\r\n `[wx-compat] wx.${key} is not implemented \u2014 using safe no-op fallback. ` +\r\n `Register a real implementation if the game depends on it.`,\r\n );\r\n }\r\n opts?.success?.();\r\n opts?.complete?.();\r\n };\r\n return noop;\r\n },\r\n});\r\n\r\n(window as unknown as Record<string, unknown>).wx = wrapWxWithMonitor(wxProxy);\r\n\r\n// \u2500\u2500 GameGlobal as a Proxy over window \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// In real WeChat Mini Game runtime, GameGlobal is a separate global object.\r\n// Game adapters (weapp-adapter) iterate their polyfills and assign them to\r\n// GameGlobal: `for (var p in r) GameGlobal[p] = r[p]`.\r\n//\r\n// Game code is executed inside a Function sandbox (see below) where `window`\r\n// is shadowed by this Proxy. All property reads/writes go through here,\r\n// never touching the real browser Window directly. This eliminates all\r\n// \"Cannot set property X which has only a getter\" errors.\r\n//\r\n// Strategy: Use a plain empty object as Proxy target (no invariant issues).\r\n// All set operations go to our overrides Map. All get operations check\r\n// overrides first, then fall through to the real window.\r\n{\r\n const win = window as unknown as Record<string, unknown>;\r\n const overrides = new Map<string, unknown>();\r\n\r\n // Use a real object as the proxy target so that defineProperty with\r\n // getter/setter descriptors can be stored properly on it.\r\n const sandboxTarget = Object.create(null) as Record<string | symbol, unknown>;\r\n\r\n // \u2500\u2500 UnityLoader.SystemInfo patch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // The Unity plugin (plugin.js) sets `f.UnityLoader = { SystemInfo: {...} }`\r\n // on GameGlobal, but only includes a subset of properties (width, height,\r\n // gpu, browser, browserVersion, language, hasWebGL). The Unity framework\r\n // (webgl.wasm.framework.unityweb.js) reads additional properties like\r\n // hasCursorLock, hasFullscreen, mobile, os, osVersion, hasWasm, hasThreads,\r\n // userAgent, etc. We patch them in automatically when UnityLoader is assigned.\r\n const patchUnityLoaderSystemInfo = (loader: Record<string, unknown>): void => {\r\n const info = loader.SystemInfo as Record<string, unknown> | undefined;\r\n if (!info) return;\r\n\r\n const ua = navigator.userAgent;\r\n // Use nativeBody (preserved before cleanGlobals) for capability detection,\r\n // because the shimmed document.body lacks requestPointerLock / requestFullscreen.\r\n const body = nativeBody as unknown as Record<string, unknown> | null;\r\n const defaults: Record<string, unknown> = {\r\n hasCursorLock: !!(body?.requestPointerLock),\r\n hasFullscreen: !!(body?.requestFullscreen || body?.webkitRequestFullscreen),\r\n hasThreads: typeof SharedArrayBuffer !== 'undefined',\r\n hasWasm: typeof WebAssembly === 'object' && typeof WebAssembly.compile === 'function',\r\n hasWasmThreads: false,\r\n mobile: /Mobile|Android|iP(ad|hone)/.test(ua),\r\n os: 'MacOS',\r\n osVersion: '10.15.7',\r\n userAgent: ua,\r\n };\r\n\r\n for (const [key, val] of Object.entries(defaults)) {\r\n if (!(key in info)) {\r\n info[key] = val;\r\n }\r\n }\r\n };\r\n\r\n const gameGlobalProxy = new Proxy(sandboxTarget as unknown as typeof window, {\r\n set(_target, prop, value) {\r\n if (typeof prop === 'string') {\r\n // Auto-patch UnityLoader.SystemInfo with missing browser capabilities\r\n if (prop === 'UnityLoader' && value && typeof value === 'object') {\r\n patchUnityLoaderSystemInfo(value as Record<string, unknown>);\r\n }\r\n overrides.set(prop, value);\r\n // Also delete from target so overrides Map takes priority\r\n delete sandboxTarget[prop];\r\n\r\n // \u2500\u2500 Auto-trigger window.onload \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // Cocos 3.x engine sets `window.onload = boot` to start the game.\r\n // In a real browser, the 'load' event fires when all resources are ready.\r\n // In our sandboxed environment (about:srcdoc), the document is already\r\n // fully loaded by the time game.js executes, so the 'load' event will\r\n // never fire again. We must trigger the callback manually.\r\n if (prop === 'onload' && typeof value === 'function') {\r\n console.log('[wx-compat] window.onload set \u2014 auto-triggering in next microtask');\r\n Promise.resolve().then(() => {\r\n try {\r\n (value as () => void)();\r\n } catch (e) {\r\n console.error('[wx-compat] Error in window.onload callback:', e);\r\n }\r\n });\r\n }\r\n }\r\n return true;\r\n },\r\n get(_target, prop) {\r\n // Overrides (simple values set via `=`) take priority\r\n if (typeof prop === 'string' && overrides.has(prop)) {\r\n const overrideVal = overrides.get(prop);\r\n // Wrap monitored global functions from overrides too\r\n if (typeof overrideVal === 'function' && isMonitorEnabled() && MONITORED_GLOBALS.has(prop)) {\r\n return wrapGlobalWithMonitor(prop, overrideVal as Function);\r\n }\r\n return overrideVal;\r\n }\r\n // Check properties defined via Object.defineProperty on the target\r\n // (these may have getters that need to be invoked lazily)\r\n if (typeof prop === 'string' && prop in sandboxTarget) {\r\n return sandboxTarget[prop];\r\n }\r\n // Fall through to real window\r\n const value = (window as unknown as Record<string, unknown>)[prop as string];\r\n // Native browser methods (setTimeout, fetch, etc.) throw \"Illegal invocation\"\r\n // if called without the correct `this` (window). We must bind them.\r\n // However, constructors/classes (Object, Array, Map, etc.) must NOT be bound\r\n // because bind() returns a new function that loses static methods\r\n // (e.g. Object.assign, Array.from, Promise.resolve).\r\n //\r\n // Heuristic: In browsers, Web IDL methods (setTimeout, fetch, alert, etc.)\r\n // have `prototype === undefined`, while constructors (Object, Array, Map, etc.)\r\n // have a non-undefined `.prototype`. We use this to distinguish them.\r\n if (typeof value === 'function' && typeof prop === 'string') {\r\n if (value.prototype !== undefined) {\r\n // Constructor / class \u2014 return as-is to preserve static methods\r\n // But if it's a monitored WeChat-specific global, wrap it\r\n if (isMonitorEnabled() && MONITORED_GLOBALS.has(prop)) {\r\n return wrapGlobalWithMonitor(prop, value as Function);\r\n }\r\n return value;\r\n }\r\n // Native method \u2014 bind to window to avoid \"Illegal invocation\"\r\n try {\r\n const bound = value.bind(window);\r\n // Wrap with monitor if it's a tracked global\r\n if (isMonitorEnabled() && MONITORED_GLOBALS.has(prop)) {\r\n return wrapGlobalWithMonitor(prop, bound as Function);\r\n }\r\n return bound;\r\n } catch {\r\n // Some exotic native functions (e.g. Proxy-wrapped or revoked) may\r\n // throw on .bind(). Falling back to the unbound value is safe here\r\n // because the worst case is an \"Illegal invocation\" at call-site,\r\n // which is the same behaviour the caller would see without our proxy.\r\n // We intentionally do NOT log to the preview console to avoid noisy\r\n // warnings for every property access on the global scope proxy.\r\n return value;\r\n }\r\n }\r\n return value;\r\n },\r\n has(_target, prop) {\r\n // `with(proxy)` uses `has` to decide if a bare variable belongs to this scope.\r\n //\r\n // IMPORTANT: We must NOT blindly return `true` for all string properties!\r\n // Doing so causes `var x = ...` assignments inside `with(sandbox)` to be\r\n // intercepted by the proxy's `set` trap, storing the value in `overrides`\r\n // instead of the function-scoped `var x`. When closures (e.g. SystemJS\r\n // register callbacks) later reference `x` outside the `with` block, they\r\n // see the function-scoped `undefined` instead of the assigned value.\r\n //\r\n // Instead, we return `true` only for properties that actually exist in\r\n // our sandbox (overrides, sandboxTarget, or the real window). This way:\r\n // - Global variables (console, setTimeout, __globalAdapter, etc.) are\r\n // intercepted because they exist on window.\r\n // - Game-set globals (e.g. `GameGlobal = {}`) are intercepted because\r\n // they are stored in overrides via explicit `set` on the proxy.\r\n // - Local variables (`var e`, `var r`, etc.) are NOT intercepted because\r\n // they don't exist on window/overrides, so assignments correctly target\r\n // the function-scoped variable binding.\r\n //\r\n // Symbol properties (Symbol.unscopables etc.) must return false so that\r\n // the `with` statement works correctly.\r\n if (typeof prop === 'symbol') {\r\n return false;\r\n }\r\n // Let `module`, `exports`, and `require` fall through to the\r\n // outer function parameters that sandboxExec injects per-module.\r\n // Without this exemption, `with(sandbox)` would intercept these\r\n // CommonJS locals and route them to the global window (where they\r\n // don't exist), breaking `module.exports = ...` / `exports.foo = ...`\r\n // inside loaded module files.\r\n if (prop === 'module' || prop === 'exports' || prop === 'require') {\r\n return false;\r\n }\r\n // Only claim properties that actually exist in our sandbox layers:\r\n // 1. Overrides map (values set via proxy.set or game code assignments)\r\n // 2. sandboxTarget (accessor properties defined via Object.defineProperty)\r\n // 3. Real window (browser globals like console, setTimeout, etc.)\r\n if (overrides.has(prop)) {\r\n return true;\r\n }\r\n if (prop in sandboxTarget) {\r\n return true;\r\n }\r\n if (prop in window) {\r\n return true;\r\n }\r\n return false;\r\n },\r\n getOwnPropertyDescriptor(_target, prop) {\r\n if (typeof prop === 'string' && overrides.has(prop)) {\r\n return {\r\n value: overrides.get(prop),\r\n writable: true,\r\n enumerable: true,\r\n configurable: true,\r\n };\r\n }\r\n // Check target for accessor properties defined via defineProperty\r\n if (typeof prop === 'string' && prop in sandboxTarget) {\r\n const desc = Object.getOwnPropertyDescriptor(sandboxTarget, prop);\r\n if (desc) {\r\n return { ...desc, configurable: true };\r\n }\r\n }\r\n // Fall through to real window. We must ensure the returned descriptor\r\n // is writable + configurable so that the Proxy invariant check does NOT\r\n // block our `set` trap. Without this, if window has a non-writable\r\n // property (e.g. `$` from a library, or a frozen built-in), the engine\r\n // would throw \"Assignment to constant variable\" / \"Cannot assign to\r\n // read only property\" before our `set` trap even runs.\r\n const windowDesc = Object.getOwnPropertyDescriptor(window, prop);\r\n if (windowDesc) {\r\n // For data descriptors, force writable + configurable\r\n if ('value' in windowDesc) {\r\n return {\r\n value: windowDesc.value,\r\n writable: true,\r\n enumerable: windowDesc.enumerable ?? true,\r\n configurable: true,\r\n };\r\n }\r\n // For accessor descriptors, keep get/set but ensure configurable\r\n return { ...windowDesc, configurable: true };\r\n }\r\n return undefined;\r\n },\r\n defineProperty(_target, prop, descriptor) {\r\n if (typeof prop === 'string') {\r\n if ('get' in descriptor || 'set' in descriptor) {\r\n // Accessor descriptor \u2014 define on the real target object so that\r\n // getters/setters are invoked lazily (not eagerly).\r\n // Remove from overrides Map so the get trap reads from target.\r\n overrides.delete(prop);\r\n Object.defineProperty(sandboxTarget, prop, {\r\n ...descriptor,\r\n configurable: true, // must be configurable for proxy invariant\r\n });\r\n } else {\r\n // Data descriptor \u2014 store in overrides Map\r\n overrides.set(prop, descriptor.value);\r\n }\r\n }\r\n return true;\r\n },\r\n deleteProperty(_target, prop) {\r\n if (typeof prop === 'string') {\r\n overrides.delete(prop);\r\n delete sandboxTarget[prop];\r\n }\r\n return true;\r\n },\r\n ownKeys(_target) {\r\n const keys = new Set(Reflect.ownKeys(window));\r\n for (const k of overrides.keys()) {\r\n keys.add(k);\r\n }\r\n return [...keys];\r\n },\r\n });\r\n\r\n win.GameGlobal = gameGlobalProxy;\r\n console.log('[wx-compat] GameGlobal installed as Proxy over window');\r\n}\r\n\r\n// Also export requestAnimationFrame/cancelAnimationFrame as globals\r\n// (WeChat mini games expect these as global functions)\r\n(window as unknown as Record<string, unknown>).requestAnimationFrame = requestAnimationFrame;\r\n(window as unknown as Record<string, unknown>).cancelAnimationFrame = cancelAnimationFrame;\r\n\r\n// \u2500\u2500 Sandbox Execution \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n// Game code must NOT directly access the real browser `window`. Instead, we\r\n// execute it inside a Function scope where `window`, `self`, `globalThis`,\r\n// `document`, etc. are shadowed by our GameGlobal Proxy. This way:\r\n// - `window.navigator = {...}` writes to our overrides Map (via Proxy set)\r\n// - `window.document` returns our sandboxed document Proxy\r\n// - No more \"Cannot set property X which has only a getter\" errors\r\n// - Game code is fully isolated from browser DOM/BOM\r\n{\r\n const win = window as unknown as Record<string, unknown>;\r\n const sandbox = win.GameGlobal;\r\n\r\n /**\r\n * Execute JavaScript code inside a fully sealed sandbox.\r\n *\r\n * Uses `with(proxy)` to intercept ALL bare variable lookups/assignments.\r\n * Combined with parameter shadowing for `window`, `self`, `globalThis`, etc.,\r\n * this ensures game code can NEVER access the real browser Window or DOM\r\n * without going through our Proxy.\r\n *\r\n * How `with(proxy)` works:\r\n * - For every bare variable reference (e.g. `__globalAdapter`, `console`),\r\n * the JS engine calls proxy.has(prop). If true, it uses proxy.get(prop).\r\n * - For every bare assignment (e.g. `__globalAdapter = {}`),\r\n * the JS engine calls proxy.set(prop, value).\r\n * - Our `has` trap returns true for ALL string properties, so nothing\r\n * escapes to the real global scope.\r\n *\r\n * @param code JavaScript source code to execute\r\n * @param sourceURL Optional sourceURL for DevTools debugging (shows in stack traces)\r\n * @param moduleContext Optional CommonJS module context. When provided, the\r\n * script runs with `module`, `exports`, and `require`\r\n * injected as function parameters (matching Node.js /\r\n * WeChat real-device behaviour). Used by\r\n * module-compat.ts when loading files via require().\r\n * When omitted (entry scripts like game.js), the three\r\n * names still work via the global `with(sandbox)` proxy\r\n * for bare `require(...)` calls, while `module` and\r\n * `exports` remain undefined (top-level scripts don't\r\n * typically use them).\r\n */\r\n interface SandboxModuleContext {\r\n module: { exports: unknown };\r\n exports: unknown;\r\n require: (id: string) => unknown;\r\n }\r\n\r\n const sandboxExec = (\r\n code: string,\r\n sourceURL?: string,\r\n moduleContext?: SandboxModuleContext,\r\n ): void => {\r\n // All .js files reaching this sandbox are guaranteed to be CJS / ES5:\r\n // the packager (core/bundler/game-packager.ts) runs miniprogram-ci's\r\n // enhanced babel7 on every source file before serving it, so the\r\n // wrapper can hand `code` straight to `new Function(...)` without any\r\n // runtime ESM\u2192CJS rewriting.\r\n\r\n // Append sourceURL so the code shows up with a readable name in DevTools\r\n const source = sourceURL\r\n ? `${code}\\n//# sourceURL=${sourceURL}`\r\n : code;\r\n try {\r\n // Wrap code in `with(sandbox)` so ALL bare variable access goes through Proxy.\r\n // Also shadow `globalThis` as a parameter \u2014 `with()` cannot intercept\r\n // `globalThis` because it is a JS language keyword, not a variable lookup.\r\n // By passing it as a named parameter we override it inside the function scope,\r\n // making `globalThis === sandbox` (our GameGlobal Proxy) for all executed code.\r\n // This matches WeChat's real device behavior where `globalThis === GameGlobal`.\r\n //\r\n // `module`, `exports`, and `require` are passed as named parameters so that\r\n // each loaded file gets its own CommonJS module trio (matching Node.js /\r\n // WeChat real-device behaviour). The sandbox Proxy's `has` trap explicitly\r\n // excludes these three names so that `with(sandbox)` does NOT intercept\r\n // them \u2014 bare references fall through to the function parameters.\r\n const wrappedSource = `with(sandbox) {\\n${source}\\n}`;\r\n const fn = new Function(\r\n 'sandbox',\r\n 'globalThis',\r\n 'module',\r\n 'exports',\r\n 'require',\r\n wrappedSource,\r\n );\r\n if (moduleContext) {\r\n fn(\r\n sandbox,\r\n sandbox,\r\n moduleContext.module,\r\n moduleContext.exports,\r\n moduleContext.require,\r\n );\r\n } else {\r\n // Entry scripts (e.g. game.js) don't get a per-module CommonJS context,\r\n // but they still use `require(...)` at the top level. Because the\r\n // sandbox Proxy's `has` trap intentionally returns false for `require`\r\n // (so per-module files can shadow it via function parameters), bare\r\n // `require` identifiers in entry scripts fall through to the function\r\n // parameter too. We must therefore pass the GLOBAL require here (the\r\n // one plugin-compat.ts installs as `win.require = moduleRequire`), so\r\n // game.js's `require(\"./first-screen\")` resolves to the real function.\r\n // `module` / `exports` remain undefined \\u2014 entry scripts don't use them.\r\n const globalRequire = (sandbox as unknown as Record<string, unknown>).require;\r\n fn(sandbox, sandbox, undefined, undefined, globalRequire);\r\n }\r\n } catch (e) {\r\n console.error('[wx-compat][sandbox] Error executing code' + (sourceURL ? ` (${sourceURL})` : '') + ':', e);\r\n throw e;\r\n }\r\n };\r\n\r\n // Expose on window so game-host.html and module-compat.ts can call it\r\n win.__wxSandboxExec = sandboxExec;\r\n\r\n /**\r\n * Fetch a script URL and execute it inside the sandbox.\r\n * Uses nativeFetch (captured before cleanup) so it works even after\r\n * cleanGlobals() removes fetch/XMLHttpRequest from window.\r\n *\r\n * Relative URLs are resolved against the game asset base URL\r\n * (`window.__wxAssetBaseUrl`) so that subpackage loading and other\r\n * runtime-triggered script fetches target the local static server instead\r\n * of the host origin (e.g. `vscode-webview://...`, which would 403).\r\n *\r\n * @param url URL to fetch (e.g. '/game.js' or '/subpackages/internal/game.js')\r\n * @param sourceURL Optional sourceURL for DevTools (defaults to url)\r\n * @returns Promise that resolves when execution completes\r\n */\r\n const loadAndExec = (\r\n url: string,\r\n sourceURL?: string,\r\n execHooks?: {\r\n // Invoked SYNCHRONOUSLY right before sandboxExec runs. Use this to\r\n // install transient state (e.g. push a package scope) that must be\r\n // active for the duration of the sandboxed top-level code execution.\r\n // Since sandboxExec is synchronous, the afterExec hook always runs in\r\n // the same microtask, even if sandboxExec throws.\r\n beforeExec?: () => void;\r\n afterExec?: () => void;\r\n },\r\n ): Promise<void> => {\r\n const fetchUrl = resolveGameUrl(url);\r\n\r\n // VFS fast path: if the file has been staged in the in-memory FS (either\r\n // by preloadFiles() or by client-side wxapkg unpacking) serve it directly\r\n // without hitting the network.\r\n if (isVfsUrl(fetchUrl)) {\r\n const path = fromVfsUrl(fetchUrl);\r\n const code = vfsGetText(path);\r\n if (code == null) {\r\n return Promise.reject(new Error('VFS miss: ' + path));\r\n }\r\n console.log('[wx-compat] loadAndExec via VFS:', path, 'len=', code.length);\r\n execHooks?.beforeExec?.();\r\n try {\r\n sandboxExec(code, sourceURL || url);\r\n } finally {\r\n execHooks?.afterExec?.();\r\n }\r\n return Promise.resolve();\r\n }\r\n\r\n // Debug: wrap fetch with timeout to distinguish \"hanging\" vs \"rejected\".\r\n // NOTE: we keep the timer id so we can clearTimeout() as soon as fetch\r\n // settles (success OR failure). Without clearing, the pending setTimeout\r\n // would later reject an already-unreferenced Promise \u2014 harmless in theory,\r\n // but avoids lingering handles that could interact badly with iframe\r\n // destroy / service worker on the next reload.\r\n const fetchP = nativeFetch(fetchUrl);\r\n const FETCH_TIMEOUT_MS = 30_000;\r\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\r\n const timeoutP = new Promise<Response>((_, reject) => {\r\n timeoutId = setTimeout(\r\n () => reject(new Error(`fetch TIMEOUT ${FETCH_TIMEOUT_MS / 1000}s: ` + fetchUrl)),\r\n FETCH_TIMEOUT_MS\r\n );\r\n });\r\n const clearTimer = () => {\r\n if (timeoutId !== undefined) {\r\n clearTimeout(timeoutId);\r\n timeoutId = undefined;\r\n }\r\n };\r\n return Promise.race([fetchP, timeoutP])\r\n .then(res => {\r\n clearTimer();\r\n if (!res.ok) {\r\n throw new Error(`HTTP ${res.status} ${res.statusText}`);\r\n }\r\n return res.text();\r\n }, err => {\r\n clearTimer();\r\n throw err;\r\n })\r\n .then(code => {\r\n // Run beforeExec hook synchronously, right before sandboxExec. Use\r\n // try/finally so afterExec always runs (scope pop must never be\r\n // skipped, even if the sandboxed code throws).\r\n execHooks?.beforeExec?.();\r\n try {\r\n sandboxExec(code, sourceURL || url);\r\n } finally {\r\n execHooks?.afterExec?.();\r\n }\r\n });\r\n };\r\n\r\n win.__wxLoadAndExec = loadAndExec;\r\n\r\n // Expose DEVICE object so game-host loader script can swap dimensions\r\n // at runtime (e.g. when auto orientation detects landscape).\r\n win.__wxCompat = { DEVICE };\r\n\r\n // \u2500\u2500 Main-package wxapkg preloader \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // In wxapkg mode the host page may request that the npm package itself\r\n // download and unpack the main package before game.js executes. We expose\r\n // `__wxPreloadMainWxapkg` for the game-host bootstrap to await; it's a\r\n // no-op when the preview runs in directory mode or when the main package\r\n // has already been preloaded into the VFS.\r\n win.__wxPreloadMainWxapkg = async (): Promise<void> => {\r\n const w = window as unknown as Record<string, unknown>;\r\n const mode = (w.__wxGameMode as string) || 'directory';\r\n if (mode !== 'wxapkg') return;\r\n\r\n // Already staged via preloadFiles()? Then nothing to do \u2014 the files are\r\n // in the VFS and loadAndExec will pick them up.\r\n if (vfsHas('/game.js')) {\r\n console.log('[wx-compat] Main package game.js already in VFS, skipping download.');\r\n return;\r\n }\r\n\r\n const resolver = getWxapkgResolver();\r\n const appid = getWxapkgAppid();\r\n const useProxy = getWxapkgUseProxy();\r\n const preloadedBuf = w.__wxMainWxapkgData as ArrayBuffer | undefined;\r\n\r\n // Nothing to do: no resolver AND no preloaded buffer \u2014 assume the caller\r\n // will serve files over HTTP via assetBaseUrl (legacy behaviour).\r\n if (!resolver && !preloadedBuf) return;\r\n\r\n const result = await loadWxapkg({\r\n resolver,\r\n appid,\r\n path: '',\r\n mountRoot: '',\r\n useProxy,\r\n preloadedWxapkgData: preloadedBuf,\r\n label: 'main',\r\n });\r\n if (!result) {\r\n console.error('[wx-compat] Main wxapkg preload failed.');\r\n } else {\r\n console.log(`[wx-compat] Main wxapkg preload OK: ${result.fileCount} files mounted.`);\r\n }\r\n };\r\n\r\n // \u2500\u2500 Subpackage wxapkg preloader \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n // After the main package has been unpacked its `app-config.json` declares\r\n // all subpackages (name + root). In real WeChat, subpackages are still\r\n // downloaded on-demand via `wx.loadSubpackage`; however for preview we\r\n // download & unpack them all up-front so that game code that calls\r\n // `wx.loadSubpackage` (or that is compiled to reference subpackage files\r\n // directly via `require`) sees every asset immediately in the VFS.\r\n //\r\n // This is a no-op in directory mode (no resolver configured) and when the\r\n // manifest has no subpackages. Individual subpackage failures are logged\r\n // and skipped \u2014 the game may still be playable with only the main bundle.\r\n win.__wxPreloadSubpackages = async (): Promise<void> => {\r\n const w = window as unknown as Record<string, unknown>;\r\n const mode = (w.__wxGameMode as string) || 'directory';\r\n if (mode !== 'wxapkg') return;\r\n\r\n const resolver = getWxapkgResolver();\r\n if (!resolver) {\r\n // No CDN resolver \u2192 no way to fetch subpackage wxapkgs.\r\n return;\r\n }\r\n\r\n const manifest = loadGameManifest();\r\n if (!manifest) return;\r\n const subPackages = (manifest.subPackages || manifest.subpackages || []) as Array<{\r\n name: string;\r\n root: string;\r\n }>;\r\n if (!subPackages.length) {\r\n console.log('[wx-compat] No subpackages declared, skipping subpackage preload.');\r\n return;\r\n }\r\n\r\n const appid = getWxapkgAppid();\r\n const useProxy = getWxapkgUseProxy();\r\n\r\n console.log(\r\n `[wx-compat] Preloading ${subPackages.length} subpackage(s): ` +\r\n subPackages.map(p => p.name).join(', '),\r\n );\r\n\r\n await Promise.all(\r\n subPackages.map(async (pkg) => {\r\n const root = (pkg.root || pkg.name || '').replace(/^\\/+|\\/+$/g, '');\r\n if (!root) return;\r\n // Skip if already staged in the VFS (hot-swap / preloadFiles scenario).\r\n if (vfsHas(`/${root}/game.js`)) {\r\n console.log(`[wx-compat] Subpackage \"${pkg.name}\" already in VFS, skipping download.`);\r\n return;\r\n }\r\n try {\r\n const r = await loadWxapkg({\r\n resolver,\r\n appid,\r\n path: root,\r\n mountRoot: root,\r\n useProxy,\r\n label: `subpkg:${pkg.name}`,\r\n });\r\n if (!r) {\r\n console.error(`[wx-compat] Subpackage preload failed for \"${pkg.name}\" (root=\"${root}\").`);\r\n } else {\r\n console.log(\r\n `[wx-compat] Subpackage preload OK: \"${pkg.name}\" \u2014 ${r.fileCount} files mounted at /${root}/.`,\r\n );\r\n }\r\n } catch (e) {\r\n console.error(`[wx-compat] Subpackage preload error for \"${pkg.name}\":`, e);\r\n }\r\n }),\r\n );\r\n };\r\n}\r\n\r\nconsole.log(\r\n '[wx-compat] WeChat Mini Game compatibility layer initialized. ' +\r\n `Device: ${DEVICE.width}x${DEVICE.height}, pixelRatio: ${DEVICE.pixelRatio}`\r\n);"],
|
|
5
|
+
"mappings": "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AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAMA,MAAM,mCAAmC;AAAA;AAAA,IAEvC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AA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AA,IAGA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA;AAAA,IAGA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA,IAKA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA;AAAA,IAGA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AA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",
|
|
6
|
+
"names": ["ptr", "instance", "decompressBrotli", "copy", "win", "init", "win", "entries", "normalizePath", "db", "encodeString", "entries", "_a", "_b", "size", "data", "_a", "_b", "_c", "_d", "_e", "_win", "_a", "_a", "_a", "win", "init", "onError", "_a", "_a", "_a", "_a", "width", "height", "_a", "mouseListenersSetup", "_a", "ensureMouseListeners", "_a", "_a", "_b", "_c", "_d", "_e", "_f", "_a", "_b", "_a", "errorCallbacks", "win", "_a", "_b", "_c", "_a", "url", "win", "win", "require", "_a", "_b", "win", "wx", "moduleFactories", "code", "sizeBefore", "win", "require", "win", "decompressBrotli", "_a", "init", "_a", "mainCanvas", "_a", "noop", "mockBody", "_wxDpr", "_params", "_pdpr", "monitorEnabled", "reportIntervalId", "DEFAULT_REPORT_INTERVAL_MS", "win", "flushReport", "wxProxy", "_a", "_a", "_a", "_a", "_a", "_a", "_a", "_a", "_opts", "_a", "wx", "noop", "_a", "win", "_b"]
|
|
7
|
+
}
|