@playcraft/devkit 1.0.30 → 1.0.31-beta.1
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/cli/commands/build.js +2 -10
- package/cli/commands/dev.js +1 -1
- package/core/artifacts/emit.js +1 -0
- package/core/artifacts/fflate.js +1 -0
- package/core/artifacts/zip.js +1 -0
- package/core/batch-build.js +4 -4
- package/core/engines/cocos/cli-build.js +4 -0
- package/core/engines/cocos/cli.js +1 -0
- package/core/engines/cocos/constants.js +1 -0
- package/core/engines/cocos/creator-cli.js +1 -0
- package/core/engines/cocos/dev-server.js +3 -0
- package/core/engines/cocos/fs.js +1 -0
- package/core/engines/cocos/injects/3x/init.js +19 -0
- package/core/engines/cocos/injects/3x/main.js +2 -0
- package/core/engines/cocos/injects/libs/pako.js +1 -0
- package/core/engines/cocos/mcp-refresh.js +4 -0
- package/core/engines/cocos/merge.js +6 -0
- package/core/engines/cocos/pack.js +1 -0
- package/core/engines/cocos/strip-social-share.js +7 -0
- package/core/engines/cocos/theme-assets.js +3 -0
- package/core/engines/web/index.js +1 -0
- package/core/engines/web/vite.dev.js +32 -0
- package/core/engines/web/webpack.build.js +80 -0
- package/core/engines/web/webpack.common.js +11 -0
- package/core/engines/web/webpack.dev.js +16 -0
- package/core/index.d.ts +51 -0
- package/core/index.js +1 -1
- package/core/injectors/apply.js +1 -0
- package/core/injectors/check-channel-matrix.js +9 -0
- package/core/injectors/spec.js +107 -0
- package/core/options.js +6 -5
- package/core/utils/mergeOptions.js +1 -1
- package/core/utils/parseArgvOptions.js +2 -2
- package/core/vite.dev.js +1 -32
- package/core/webpack.build.js +1 -81
- package/core/webpack.common.js +1 -11
- package/core/webpack.dev.js +1 -16
- package/package.json +4 -1
package/cli/commands/build.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";process.env.BABEL_ENV="production";process.env.NODE_ENV="production";const fs=require("fs");const path=require("path");const{runBuild}=require("../../core/webpack.build.js");const{runThemeValidation,restoreSchema}=require("../../core/utils/validateThemeData");const{runPreBuildChecks}=require("../../core/validators/pre-build-checker.js");const{FontInjectionWebpackPlugin}=require("../../core/plugins/FontInjectionWebpackPlugin.js");const{SocialMediaInjectorPlugin}=require("../../core/plugins/SocialMediaInjectorPlugin.js");const{getPlaycraftOrientationSuffix}=require("../../core/utils/getPlaycraftOrientationSuffix.js");const{options}=require("../../core/options.js");/**
|
|
1
|
+
"use strict";process.env.BABEL_ENV="production";process.env.NODE_ENV="production";const fs=require("fs");const path=require("path");const{runBuild}=require("../../core/webpack.build.js");const{runThemeValidation,restoreSchema}=require("../../core/utils/validateThemeData");const{runPreBuildChecks}=require("../../core/validators/pre-build-checker.js");const{FontInjectionWebpackPlugin}=require("../../core/plugins/FontInjectionWebpackPlugin.js");const{SocialMediaInjectorPlugin}=require("../../core/plugins/SocialMediaInjectorPlugin.js");const{getPlaycraftOrientationSuffix}=require("../../core/utils/getPlaycraftOrientationSuffix.js");const{options}=require("../../core/options.js");const{isWebEngine}=require("../../core/utils/parseArgvOptions.js");const{prepareCocosTemplate,emitCocosChannel}=require("../../core/engines/cocos/pack.js");/**
|
|
2
2
|
* 从主题入口文件中检测当前主题名称。
|
|
3
3
|
* 支持以下模式:
|
|
4
4
|
* export { default } from './themeName';
|
|
@@ -42,15 +42,7 @@ const orientationChannels=options["playcraftOrientationChannel"]||[];const orien
|
|
|
42
42
|
*/async function buildOneOrientation(orientationValue){const suffix=getPlaycraftOrientationSuffix(orientationValue);if(buildOrientations.length>1){console.log(`\n📱 开始构建方向版本: ${orientationValue}${suffix?` (后缀: ${suffix})`:""}`)}// 注入字体插件(build 模式 base64 内联)
|
|
43
43
|
const fontPlugin=themeName?new FontInjectionWebpackPlugin({projectRoot,themeName,themeConfig}):null;// social_media 渠道:注入 OG / Twitter meta 标签,让 Facebook / LinkedIn
|
|
44
44
|
// 等抓取预览时拿到正确的标题/描述/图片。无 shareMeta 时空跑,不影响构建
|
|
45
|
-
const socialMediaPlugin=themeName&&adNetwork==="social_media"?new SocialMediaInjectorPlugin({projectRoot,themeName,themeConfig}):null;await runBuild(undefined,{playcraftOrientationValue:orientationValue,filename:suffix?`${options.filename}${suffix}`:options.filename},undefined,{plugins:[...(fontPlugin?[fontPlugin]:[]),...(socialMediaPlugin?[socialMediaPlugin]:[])]})}(async()=>{try{
|
|
46
|
-
// 原因:obfuscateLevel=4 等重度混淆/压缩下单次 webpack 编译本身就
|
|
47
|
-
// 会占用数 GB 内存;而该 build.js 进程本身通常已是 batch-build.js
|
|
48
|
-
// 渠道级并发中的一个子进程(多个渠道同时在跑)。若在这里再叠加同
|
|
49
|
-
// 进程内的多方向并发(多个 webpack compiler 共享同一份 V8 堆),
|
|
50
|
-
// 内存需求会成倍叠加,实测会导致 "JavaScript heap out of memory"
|
|
51
|
-
// 崩溃。因此并发只在渠道层(各自独立进程、独立堆)进行,方向版本
|
|
52
|
-
// 层始终串行,以保证稳定性。
|
|
53
|
-
for(const orientationValue of buildOrientations){await buildOneOrientation(orientationValue)}if(schemaPathToRestore)restoreSchema(schemaPathToRestore);// 主动退出进程,避免 TerserPlugin/webpack-obfuscator 等可能残留的
|
|
45
|
+
const socialMediaPlugin=themeName&&adNetwork==="social_media"?new SocialMediaInjectorPlugin({projectRoot,themeName,themeConfig}):null;if(!isWebEngine(options.engine)){await runCocosBuild({playcraftOrientationValue:orientationValue,filename:suffix?`${options.filename}${suffix}`:options.filename,themeName});return}await runBuild(undefined,{playcraftOrientationValue:orientationValue,filename:suffix?`${options.filename}${suffix}`:options.filename},undefined,{plugins:[...(fontPlugin?[fontPlugin]:[]),...(socialMediaPlugin?[socialMediaPlugin]:[])]})}(async()=>{try{if(!isWebEngine(options.engine)){const templateHtml=await prepareCocosTemplate({playcraftOrientationValue:buildOrientations[0]||"both"});for(const orientationValue of buildOrientations){const suffix=getPlaycraftOrientationSuffix(orientationValue);if(buildOrientations.length>1){console.log(`\n📱 开始构建方向版本: ${orientationValue}${suffix?` (后缀: ${suffix})`:""}`)}await emitCocosChannel(templateHtml,{playcraftOrientationValue:orientationValue,filename:suffix?`${options.filename}${suffix}`:options.filename,themeName})}}else{for(const orientationValue of buildOrientations){await buildOneOrientation(orientationValue)}}if(schemaPathToRestore)restoreSchema(schemaPathToRestore);// 主动退出进程,避免 TerserPlugin/webpack-obfuscator 等可能残留的
|
|
54
46
|
// worker 进程句柄(jest-worker 子进程 IPC 通道等)迟迟不释放,
|
|
55
47
|
// 导致本次 build 子进程(乃至上层 batch-build 的 spawn 等待)
|
|
56
48
|
// 迟迟无法结束。此时构建已全部完成,不再有需要等待的异步操作。
|
package/cli/commands/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";process.env.BABEL_ENV="development";process.env.NODE_ENV="development";const{runDev}=require("../../core/webpack.dev.js");runDev()
|
|
1
|
+
"use strict";process.env.BABEL_ENV="development";process.env.NODE_ENV="development";const{options}=require("../../core/options.js");const{isWebEngine}=require("../../core/utils/parseArgvOptions.js");if(!isWebEngine(options.engine)){const{runCocosDev}=require("../../core/engines/cocos/dev-server.js");runCocosDev({projectRoot:process.cwd(),port:process.env.PREVIEW_PORT||options.port||3000,cmd:process.argv[2]||"start"}).catch(err=>{console.error(err);process.exit(1)})}else{const{runDev}=require("../../core/webpack.dev.js");runDev()}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const fs=require("fs");const path=require("path");const{buildTemplateString}=require("../utils/buildTemplateString.js");const{getPlaycraftOrientationSuffix}=require("../utils/getPlaycraftOrientationSuffix.js");const{resolveChannelFold2Zip}=require("../utils/resolveChannelFold2Zip.js");const{applyInjections,extractInlineScripts}=require("../injectors/apply");const{getChannelPackPlan,ADIKTEEV_INDEX,BIGABID_INDEX}=require("../injectors/spec");const{zipDirectory}=require("./zip");const{compressHtml}=require("./fflate");const{mraidPartners}=require("../utils/parseArgvOptions");function getFileName(buildOptions){let filename=buildTemplateString(buildOptions.filename,buildOptions);if(buildOptions.network==="mintegral"){return filename.replace(/\s+/g,"").replace(/[^a-zA-Z0-9]/g,"_").replace("_fullhash_6_",Date.now().toString(36).slice(-6))}return filename}function writeStagingFiles(staging,layout,html){if(layout==="adikteev"){const extracted=extractInlineScripts(html);fs.writeFileSync(path.join(staging,"index.html"),ADIKTEEV_INDEX);fs.writeFileSync(path.join(staging,"creative.js"),extracted.scripts.join("\n"));fs.writeFileSync(path.join(staging,"style.css"),"");return}if(layout==="bigabid"){const extracted=extractInlineScripts(html);fs.writeFileSync(path.join(staging,"index.html"),BIGABID_INDEX);fs.writeFileSync(path.join(staging,"main.js"),extracted.scripts.join("\n"));return}fs.writeFileSync(path.join(staging,"index.html"),html)}async function emitChannel({templateHtml,buildOptions,themePayload,outDir}){if(mraidPartners.includes(buildOptions.network)&&(buildOptions.protocol==="none"||!buildOptions.protocol)){buildOptions={...buildOptions,protocol:"mraid"}}const adNetwork=buildOptions.network;const orientationValue=buildOptions.playcraftOrientationValue||"both";const orientationSuffix=getPlaycraftOrientationSuffix(orientationValue);const outputId=`${adNetwork}${orientationSuffix}`;const plan=getChannelPackPlan(buildOptions,themePayload);const{isChannelFold2Zip,isZipOutputFinal}=resolveChannelFold2Zip({isChannelFold2ZipOption:buildOptions.isChannelFold2Zip,adNetwork,isZipOutput:plan.isZip});let html=applyInjections(templateHtml,plan.spec);if(buildOptions.fflateCompression){html=await compressHtml(html,{googlePlayUrl:buildOptions.googlePlayUrl,appStoreUrl:buildOptions.appStoreUrl})}fs.mkdirSync(outDir,{recursive:true});const fileName=getFileName(buildOptions);if(!isZipOutputFinal){const htmlName=`${fileName}.html`;fs.writeFileSync(path.join(outDir,htmlName),html);console.log(`[cocos] wrote ${htmlName}`);return path.join(outDir,htmlName)}const staging=path.join(outDir,outputId);if(fs.existsSync(staging))fs.rmSync(staging,{recursive:true,force:true});fs.mkdirSync(staging,{recursive:true});writeStagingFiles(staging,plan.layout,html);for(const extra of plan.extraFiles){if(fs.existsSync(extra.from)){fs.copyFileSync(extra.from,path.join(staging,extra.to))}else{console.warn(`[cocos] missing extra file: ${extra.from}`)}}const zipName=isChannelFold2Zip?outputId:fileName;const zipPath=path.join(outDir,`${zipName}.zip`);await zipDirectory(staging,zipPath);fs.rmSync(staging,{recursive:true,force:true});console.log(`[cocos] wrote ${path.basename(zipPath)}`);return zipPath}module.exports={emitChannel,getFileName};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const fs=require("fs");const path=require("path");const fflate=require("fflate");const{minify}=require("terser");const{FflateCompressionPlugin}=require("../plugins/FflateCompressionPlugin.js");async function compressHtml(html,options={}){const plugin=new FflateCompressionPlugin(options);const originalSize=Buffer.byteLength(html,"utf8");const compressedUint8Array=fflate.zlibSync(new TextEncoder().encode(html),{level:9});const base64String=Buffer.from(compressedUint8Array).toString("base64");const fflatePackageRoot=path.join(path.dirname(require.resolve("fflate")),"..");const fflateLibPath=path.join(fflatePackageRoot,"umd","index.js");let fflateLibContent=fs.readFileSync(fflateLibPath,"utf8");const minifiedFflate=await minify(fflateLibContent,{compress:{passes:2,dead_code:true,drop_console:true,drop_debugger:true},mangle:true,format:{comments:false}});fflateLibContent=minifiedFflate.code;const headContent=plugin.extractHeadContent(html);const out=await plugin.generateDecompressHtml(base64String,fflateLibContent,headContent);console.log(`[fflate] ${(originalSize/1024).toFixed(1)}kb → ${(Buffer.byteLength(out,"utf8")/1024).toFixed(1)}kb`);return out}module.exports={compressHtml};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const fs=require("fs");const path=require("path");const yazl=require("yazl");const{MAX_PLAYABLE_PACKAGE_BYTES}=require("../constants.js");function zipDirectory(dirPath,zipPath){return new Promise((resolve,reject)=>{const zipFile=new yazl.ZipFile;const addDir=(dir,prefix)=>{for(const name of fs.readdirSync(dir)){const abs=path.join(dir,name);const entry=prefix?`${prefix}/${name}`:name;if(fs.statSync(abs).isDirectory())addDir(abs,entry);else zipFile.addFile(abs,entry.replace(/\\/g,"/"))}};addDir(dirPath,"");zipFile.end();fs.mkdirSync(path.dirname(zipPath),{recursive:true});const out=fs.createWriteStream(zipPath);zipFile.outputStream.pipe(out);out.on("close",()=>{const size=fs.statSync(zipPath).size;const sizeMb=(size/(1024*1024)).toFixed(2);const maxMb=(MAX_PLAYABLE_PACKAGE_BYTES/(1024*1024)).toFixed(0);console.log(`📦 ZIP size: ${sizeMb}MB (limit: ${maxMb}MB)`);if(size>MAX_PLAYABLE_PACKAGE_BYTES){reject(new Error(`ZIP 产物超过 ${maxMb}MB 上限: ${sizeMb}MB (${path.basename(zipPath)})`));return}resolve(zipPath)});out.on("error",reject)})}module.exports={zipDirectory};
|
package/core/batch-build.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* 2. 每个构建任务使用独立的临时目录(dist-temp-{taskId})
|
|
8
8
|
* 3. 构建完成后自动移动到目标目录并清理临时目录
|
|
9
9
|
* 4. 支持灵活的配置系统
|
|
10
|
-
*/const{execSync,spawn}=require("child_process");const fs=require("fs");const path=require("path");const os=require("os");const{fetchTemporaryCredentials,createCOSClient,uploadDirectoryToCOS,uploadFileToCOS,purgeCDNCache}=require("./cos-uploader");const{runThemeValidation,restoreSchema}=require("./utils/validateThemeData");const{runPreBuildChecks}=require("./validators/pre-build-checker.js");const{getPlaycraftOrientationSuffix}=require("./utils/getPlaycraftOrientationSuffix.js");/**
|
|
10
|
+
*/const{execSync,spawn}=require("child_process");const fs=require("fs");const path=require("path");const os=require("os");const{fetchTemporaryCredentials,createCOSClient,uploadDirectoryToCOS,uploadFileToCOS,purgeCDNCache}=require("./cos-uploader");const{runThemeValidation,restoreSchema}=require("./utils/validateThemeData");const{runPreBuildChecks}=require("./validators/pre-build-checker.js");const{getPlaycraftOrientationSuffix}=require("./utils/getPlaycraftOrientationSuffix.js");const{isWebEngine}=require("./utils/parseArgvOptions.js");const{packCocosBatch}=require("./engines/cocos/pack.js");/**
|
|
11
11
|
* 执行构建命令,实时把 stdout/stderr 落盘到日志文件,而不是像 exec()
|
|
12
12
|
* 那样把全部输出攒在内存里的一个 buffer 中。
|
|
13
13
|
*
|
|
@@ -46,8 +46,8 @@ fs.unlinkSync(tempPreviewPath);log(`✓ preview.json 文件已更新并上传`,"
|
|
|
46
46
|
* - 16 核 CPU → 8 并发(限制最大值)
|
|
47
47
|
*/function getDefaultParallel(){const cpuCount=os.cpus().length;const calculated=Math.max(2,cpuCount-1);// 至少 2 个并发
|
|
48
48
|
const parallel=Math.min(8,calculated);// 最多 8 个并发
|
|
49
|
-
return parallel}const DEFAULT_CONFIG={title:"Phaser Game",appName:"",//
|
|
50
|
-
channels:["adikteev","liftoff","inmobi","applovin","tiktok","snapchat","remerge","ironsource","unity","facebook","moloco","google","mintegral","bigoads"],themes:{enabled:true,sourceDir:"src/theme",entryFile:"src/theme/index.ts",whitelist:null},naming:{language:"EN",format:"\u65E0",supplier:"AIX",follower:"ZQL"},build:{outputDir:"dist-all",tempDirPrefix:"dist-temp",continueOnError:true,cleanTemp:true,parallel:getDefaultParallel()// 根据 CPU 核心数自动设置
|
|
49
|
+
return parallel}const DEFAULT_CONFIG={title:"Phaser Game",appName:"",// empty = original webpack pack (same as omitting engine)
|
|
50
|
+
engine:"",channels:["adikteev","liftoff","inmobi","applovin","tiktok","snapchat","remerge","ironsource","unity","facebook","moloco","google","mintegral","bigoads"],themes:{enabled:true,sourceDir:"src/theme",entryFile:"src/theme/index.ts",whitelist:null},naming:{language:"EN",format:"\u65E0",supplier:"AIX",follower:"ZQL"},build:{outputDir:"dist-all",tempDirPrefix:"dist-temp",continueOnError:true,cleanTemp:true,parallel:getDefaultParallel()// 根据 CPU 核心数自动设置
|
|
51
51
|
}};// ==================== 工具函数 ====================
|
|
52
52
|
let isExiting=false;let backupContent=null;let backupPath=null;let activeSchemaPath=null;// 跟踪当前活动的 schema 路径,用于中断时恢复
|
|
53
53
|
const activeTempDirs=new Set;// 跟踪所有活动的临时目录
|
|
@@ -196,7 +196,7 @@ let channels=args.channels||config.channels;// 始终添加 preview 渠道,用
|
|
|
196
196
|
if(!channels.includes("preview")){channels=[...channels,"preview"];log("\u5DF2\u6DFB\u52A0 preview \u6E20\u9053","info")}// 根据 playcraftOrientationChannel / playcraftOrientation 配置,把需要
|
|
197
197
|
// 多方向版本的渠道拆分为独立的构建任务(渠道_L / 渠道_P / 渠道),
|
|
198
198
|
// 后续统一交给渠道级并发调度,每个方向各自独立进程构建。
|
|
199
|
-
const tasks=buildChannelTasks(channels,config)
|
|
199
|
+
const tasks=buildChannelTasks(channels,config);if(!isWebEngine(config.engine)){log(`引擎: cocos(Creator 编一次,按主题注入 json5 / assets)`,"info");printSummary(config,themes,channels,tasks);const outputDir=path.join(projectRoot,config.build.outputDir);cleanTempDir(outputDir);const allResults=await packCocosBatch({config,themes,tasks,outputDir,projectRoot,isChannelFold2Zip});const failed=allResults.filter(r=>!r.success);const elapsed=((Date.now()-startTime)/1000).toFixed(1);log(`Cocos 批量构建完成: ${allResults.length-failed.length}/${allResults.length} 成功,耗时 ${elapsed}s`,failed.length?"warn":"success");if(failed.length&&!config.build.continueOnError)process.exit(1);return}// ============================================================
|
|
200
200
|
// 📌 编译前检查(埋点验证、主题名称检查等)- 仅在主进程执行一次
|
|
201
201
|
// ============================================================
|
|
202
202
|
const shouldSkipChecks=process.env.SKIP_PRE_BUILD_CHECKS==="1";if(!shouldSkipChecks){log("\u6267\u884C\u7F16\u8BD1\u524D\u68C0\u67E5\uFF08\u57CB\u70B9\u9A8C\u8BC1\u3001\u4E3B\u9898\u540D\u79F0\u68C0\u67E5\u7B49\uFF09...","info");const checkResult=await runPreBuildChecks(projectRoot,{verbose:false,showDetails:true,failFast:false,themes,channels});if(!checkResult.success){log("\u7F16\u8BD1\u524D\u68C0\u67E5\u5931\u8D25\uFF0C\u7EC8\u6B62\u6279\u91CF\u6784\u5EFA\u3002","error");log("\u63D0\u793A\uFF1A\u5982\u9700\u8DF3\u8FC7\u68C0\u67E5\uFF0C\u53EF\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF: SKIP_PRE_BUILD_CHECKS=1","warn");process.exit(1)}log("\u2713 \u7F16\u8BD1\u524D\u68C0\u67E5\u901A\u8FC7","success")}else{log("\u8DF3\u8FC7\u7F16\u8BD1\u524D\u68C0\u67E5\uFF08SKIP_PRE_BUILD_CHECKS=1\uFF09","warn")}// 打印摘要
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"use strict";const fs=require("fs");const path=require("path");const{spawnCocosSync,needsXvfb}=require("./cli.js");const{resolveCreatorOutputDir}=require("./creator-cli.js");const{stripAdsdkCjsImport}=require("./strip-social-share.js");function shouldSkipEngineBuild(buildOptions={}){const cocos=buildOptions.cocos||{};return Boolean(buildOptions.skipEngineBuild||cocos.skipEngineBuild||process.env.PLAYABLE_SKIP_ENGINE_BUILD==="1")}function resolveWebMobileDest(projectRoot,buildOptions={}){const cocos=buildOptions.cocos||{};const fromConfig=resolveCreatorOutputDir(projectRoot,cocos.buildConfig||"build-configs/web-mobile.json");const explicit=cocos.webMobileDir?path.resolve(projectRoot,cocos.webMobileDir):null;if(shouldSkipEngineBuild(buildOptions)){return explicit||fromConfig||path.resolve(projectRoot,"dist/web-mobile")}return fromConfig||explicit||path.resolve(projectRoot,"dist/web-mobile")}function logStrip(result){if(result.skipped&&result.reason==="missing"){console.warn("[cocos] adsdk CJS missing, skip social-share strip");return}if(result.skipped&&result.reason==="already"){console.log("[cocos] social-share import() already stripped");return}if(result.skipped){console.warn("[cocos] social-share import() not found in CJS");return}console.log("[cocos] stripped social-share import() from adsdk CJS")}/**
|
|
2
|
+
* 用官方 cocos CLI 打 web-mobile(不再走 Creator 编辑器)。
|
|
3
|
+
* Linux 上自动套 xvfb-run -a(shader 编译需要虚拟显示)。
|
|
4
|
+
*/function runCocosEngineBuild(projectRoot,buildOptions={}){logStrip(stripAdsdkCjsImport(projectRoot));const dest=resolveWebMobileDest(projectRoot,buildOptions);if(shouldSkipEngineBuild(buildOptions)){if(!fs.existsSync(dest)){throw new Error(`[cocos] skipEngineBuild but missing ${path.relative(projectRoot,dest)}`)}console.log(`[cocos] skip engine build, using ${path.relative(projectRoot,dest)}`);return dest}const cocos=buildOptions.cocos||{};const configRel=cocos.buildConfig||"build-configs/web-mobile.json";const configPath=path.resolve(projectRoot,configRel);if(!fs.existsSync(configPath)){throw new Error(`[cocos] missing build config: ${configRel}`)}const args=["--no-interactive","build","--project",projectRoot,"--platform","web-mobile","--build-config",configPath];if(needsXvfb()){console.log("[cocos] linux, wrapping xvfb-run -a")}console.log(`[cocos] build web-mobile ← ${configRel}`);const result=spawnCocosSync(args,{cwd:projectRoot,stdio:"inherit",env:process.env});if(result.error){throw result.error}if(result.status!==0){throw new Error(`[cocos] build failed, exit ${result.status}`)}console.log(`[cocos] web-mobile ready at ${path.relative(projectRoot,dest)}`);return dest}module.exports={runCocosEngineBuild,resolveWebMobileDest,shouldSkipEngineBuild};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const{spawn,spawnSync}=require("child_process");function resolveCocosBin(){return process.env.COCOS_CLI||"cocos"}function needsXvfb(){return process.platform==="linux"}function cocosCommand(args){const bin=resolveCocosBin();if(needsXvfb()){return{cmd:"xvfb-run",args:["-a",bin,...args]}}return{cmd:bin,args}}function spawnCocos(args,options){const{cmd,args:fullArgs}=cocosCommand(args);return spawn(cmd,fullArgs,options)}function spawnCocosSync(args,options){const{cmd,args:fullArgs}=cocosCommand(args);return spawnSync(cmd,fullArgs,options)}module.exports={resolveCocosBin,needsXvfb,spawnCocos,spawnCocosSync};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const ADAPTER_FETCH="adapterFetch";const TO_STRING_EXTNAME=[".txt",".xml",".vsh",".fsh",".atlas",".tmx",".tsx",".json",".ExportJson",".plist",".fnt",".js",".zip"];const TO_SKIP_EXTNAME=[".ico",".html",".css"];const TRANSPARENT_GIF="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";const FILE_MAX_SIZE=2*1024*1024*0.8;const THEME_ASSET_EXT=/\.(png|webp|jpe?g|gif|svg|mp3|wav|m4a|ogg|mp4)$/i;module.exports={ADAPTER_FETCH,TO_STRING_EXTNAME,TO_SKIP_EXTNAME,TRANSPARENT_GIF,FILE_MAX_SIZE,THEME_ASSET_EXT};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const fs=require("fs");const path=require("path");const{spawnSync}=require("child_process");function readCreatorVersion(root){try{const pkg=require(path.join(root,"package.json"));return pkg.creator&&pkg.creator.version||"3.8.6"}catch{return"3.8.6"}}function resolveCreator(root,creatorBin){if(creatorBin)return creatorBin;if(process.env.COCOS_CREATOR)return process.env.COCOS_CREATOR;const version=readCreatorVersion(root);const darwin=[`/Applications/Cocos/Creator/${version}/CocosCreator.app/Contents/MacOS/CocosCreator`,`/Applications/CocosCreator/Creator/${version}/CocosCreator.app/Contents/MacOS/CocosCreator`];const win32=[`C:\\ProgramData\\cocos\\editors\\Creator\\${version}\\CocosCreator.exe`,`C:\\Cocos\\Creator\\${version}\\CocosCreator.exe`,`C:\\CocosCreator\\Creator\\${version}\\CocosCreator.exe`];const linux=[`/opt/Cocos/Creator/${version}/CocosCreator`,`${process.env.HOME||""}/Cocos/Creator/${version}/CocosCreator`];const candidates=process.platform==="darwin"?darwin:process.platform==="win32"?win32:linux;return candidates.find(p=>p&&fs.existsSync(p))}function creatorEnv(){const env={...process.env};delete env.ELECTRON_RUN_AS_NODE;return env}function resolveCreatorOutputDir(root,buildConfigRel){const configPath=path.resolve(root,buildConfigRel||"build-configs/web-mobile.json");if(!fs.existsSync(configPath))return null;try{const cfg=JSON.parse(fs.readFileSync(configPath,"utf8"));const outputName=cfg.outputName||"web-mobile";const buildPath=cfg.buildPath||"project://build";if(buildPath.startsWith("project://")){const rel=buildPath.slice("project://".length).replace(/^\/+/,"");return path.resolve(root,rel,outputName)}if(path.isAbsolute(buildPath))return path.join(buildPath,outputName);return path.resolve(root,buildPath,outputName)}catch{return null}}function runCreatorBuild(root,buildOptions){const cocos=buildOptions.cocos||{};if(cocos.skipEngineBuild){console.log("[cocos] skipEngineBuild: using existing web-mobile");return}const configPath=path.resolve(root,cocos.buildConfig||"build-configs/web-mobile.json");if(!fs.existsSync(configPath)){throw new Error(`[cocos] missing Creator build config: ${configPath}`)}const bin=resolveCreator(root,cocos.creatorBin);if(!bin){throw new Error("[cocos] Cocos Creator not found. Set COCOS_CREATOR or cocos.creatorBin.")}if(process.platform==="linux"){console.warn("[cocos] Creator fallback on linux; prefer official cocos CLI (xvfb-run -a).")}const buildArg=`configPath=${configPath.replace(/\\/g,"/")};stage=build`;console.log(`[cocos] ${bin}`);console.log(`[cocos] --build ${buildArg}`);const result=spawnSync(bin,["--project",root,"--nologin","--build",buildArg],{cwd:root,stdio:"inherit",env:creatorEnv()});if(result.error)throw result.error;const code=result.status;if(code===36||code===0){console.log("[cocos] web-mobile ready");return}throw new Error(`[cocos] Creator build failed, exit ${code}`)}module.exports={readCreatorVersion,resolveCreator,resolveCreatorOutputDir,creatorEnv,runCreatorBuild};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";const fs=require("fs");const http=require("http");const path=require("path");const{spawnCocos,needsXvfb}=require("./cli.js");const{syncGeneratedTheme}=require("./theme-assets.js");const{refreshAssets}=require("./mcp-refresh.js");const{stripAdsdkCjsImport}=require("./strip-social-share.js");function sleep(ms){return new Promise(resolve=>setTimeout(resolve,ms))}function request(url,{method="GET",timeout=8000}={}){return new Promise((resolve,reject)=>{const req=http.request(url,{method,timeout},res=>{const chunks=[];res.on("data",c=>chunks.push(c));res.on("end",()=>{resolve({status:res.statusCode||0,body:Buffer.concat(chunks).toString("utf8")})})});req.on("timeout",()=>{req.destroy();reject(new Error(`timeout ${url}`))});req.on("error",reject);req.end()})}function resolvePreviewScene(projectRoot,explicit){if(explicit)return explicit;if(process.env.PREVIEW_SCENE)return process.env.PREVIEW_SCENE;try{const cfgPath=path.join(projectRoot,"settings/cocos.config.json");if(fs.existsSync(cfgPath)){const cfg=JSON.parse(fs.readFileSync(cfgPath,"utf8"));const fromConfig=cfg.builder&&cfg.builder.common&&cfg.builder.common.startScene||cfg.builder&&cfg.builder.platforms&&cfg.builder.platforms["web-desktop"]&&cfg.builder.platforms["web-desktop"].startScene||cfg.builder&&cfg.builder.platforms&&cfg.builder.platforms["web-mobile"]&&cfg.builder.platforms["web-mobile"].startScene;if(fromConfig)return fromConfig}}catch(_){}const scenesDir=path.join(projectRoot,"assets/scenes");if(fs.existsSync(scenesDir)){const first=fs.readdirSync(scenesDir).find(name=>name.endsWith(".scene"));if(first)return`db://assets/scenes/${first}`}return""}function killSocialShareForDev(projectRoot){const result=stripAdsdkCjsImport(projectRoot);if(result.skipped&&result.reason==="missing"){console.warn("[dev] adsdk CJS missing, skip social-share strip");return}if(result.skipped&&result.reason==="already"){console.log("[dev] social-share import() already stripped");return}if(result.skipped){console.warn("[dev] social-share import() not found in CJS");return}console.log("[dev] stripped social-share import() from adsdk CJS")}function shouldIgnoreWatch(file){if(!file)return false;const base=path.basename(file);if(base===".DS_Store"||base==="theme.generated.ts")return true;if(base.startsWith(".")&&base!==".json5")return true;const ext=path.extname(file).toLowerCase();return ext===".meta"}/**
|
|
2
|
+
* 常驻官方 cocos CLI 预览:start-mcp-server(同一端口既有 / 也有 /mcp)。
|
|
3
|
+
*/async function runCocosDev(opts={}){const projectRoot=opts.projectRoot||process.cwd();const port=Number(opts.port||process.env.PREVIEW_PORT||3000);const timeoutMs=Number(opts.timeoutMs||process.env.DEV_TIMEOUT_MS||180000);const debounceMs=Number(opts.debounceMs||process.env.DEV_DEBOUNCE_MS||400);const cmd=opts.cmd||process.argv[2]||"start";const scene=resolvePreviewScene(projectRoot,opts.scene);const previewUrl=scene?`http://127.0.0.1:${port}/?scene=${encodeURIComponent(scene)}`:`http://127.0.0.1:${port}/`;const watchDirs=["assets","src/theme"].filter(dir=>fs.existsSync(path.join(projectRoot,dir)));async function isPreviewUp(){try{const res=await request(previewUrl,{timeout:1500});return res.status>0&&res.status<500}catch{return false}}async function waitForPreview(){const start=Date.now();let lastLog=0;while(Date.now()-start<timeoutMs){if(await isPreviewUp())return;if(Date.now()-lastLog>=5000){console.log(`[dev] waiting for ${previewUrl}`);lastLog=Date.now()}await sleep(1000)}throw new Error(`preview not ready after ${timeoutMs}ms: ${previewUrl}`)}function printBanner(reused){console.log(`[dev] ${reused?"reusing cocos CLI":"cocos CLI ready"}`);console.log(`[dev] iframe → ${previewUrl}`);console.log(`[dev] mcp → http://127.0.0.1:${port}/mcp`);console.log(`[dev] watch ${watchDirs.map(d=>`${d}/`).join(" ")}`)}function syncThemeOnce(){try{const result=syncGeneratedTheme(projectRoot);if(!result){console.log("[dev] no theme entry; skip generated module");return false}console.log(`[dev] synced theme ${result.themeName}${result.changed===false?" (unchanged)":""}`);return result.changed!==false}catch(syncErr){console.warn(`[dev] theme sync skipped: ${syncErr.message}`);return false}}async function compile({fatal=true}={}){if(!(await isPreviewUp())){console.error(`[dev] preview is down: ${previewUrl}`);if(fatal){console.error("[dev] Run npm run dev first.");process.exit(1)}return}console.log(`[dev] assets-refresh db://assets`);try{const res=await refreshAssets(port,"db://assets");const err=res.parsed&&(res.parsed.error||res.parsed.result&&res.parsed.result.isError);console.log(`[dev] ${res.status}${err?" error":""}`);if(res.status===404){console.error("[dev] /mcp \u4E0D\u5B58\u5728\u3002\u8BF7\u505C\u6389\u5F53\u524D\u9884\u89C8\uFF0C\u91CD\u65B0 npm run dev\uFF08\u4F1A\u8D77 start-mcp-server\uFF09")}if((res.status>=400||err)&&fatal)process.exit(1)}catch(err){console.error(`[dev] compile failed: ${err.message}`);if(fatal)process.exit(1)}}function watchAndCompile(){let timer=null;let compiling=false;let pending=null;const queue=rel=>{pending=rel;if(timer)clearTimeout(timer);timer=setTimeout(()=>{timer=null;run()},debounceMs)};const run=async()=>{if(compiling)return;const rel=pending;pending=null;compiling=true;if(rel)console.log(`[dev] change ${rel}`);try{if(!rel||rel.startsWith("src/theme")){syncThemeOnce()}await compile({fatal:false})}finally{compiling=false;if(pending)queue(pending)}};for(const dir of watchDirs){const abs=path.join(projectRoot,dir);fs.watch(abs,{recursive:true},(_event,file)=>{if(shouldIgnoreWatch(file))return;const rel=path.join(dir,file||"").replace(/\\/g,"/");queue(rel)})}}function holdUntilExit(child){const stop=()=>{if(child&&child.exitCode==null){child.kill("SIGTERM")}process.exit(0)};process.on("SIGINT",stop);process.on("SIGTERM",stop);if(child){child.on("exit",(code,signal)=>{console.log(`[dev] cocos CLI exited (${signal||code})`);process.exit(code==null?1:code)});return}console.log("[dev] CLI already running; Ctrl+C leaves it open");setInterval(()=>{},60*1000)}async function start(){if(await isPreviewUp()){printBanner(true);const synced=syncThemeOnce();if(synced)await compile({fatal:false});watchAndCompile();holdUntilExit(null);return}if(needsXvfb()){console.log("[dev] linux, wrapping xvfb-run -a")}const args=["--no-interactive","start-mcp-server","--project",projectRoot,"--port",String(port)];if(scene){console.log(`[dev] start scene ${scene}`)}console.log(`[dev] cocos ${args.join(" ")}`);const child=spawnCocos(args,{cwd:projectRoot,env:process.env,stdio:"inherit"});child.on("error",err=>{console.error(err);process.exit(1)});try{await waitForPreview()}catch(err){console.error(`[dev] ${err.message}`);child.kill("SIGTERM");process.exit(1)}printBanner(false);const synced=syncThemeOnce();if(synced)await compile({fatal:false});watchAndCompile();holdUntilExit(child)}killSocialShareForDev(projectRoot);if(cmd==="compile"||cmd==="refresh"){await compile();return}if(cmd==="start"||cmd==="dev"){await start();return}console.error(`[dev] unknown command: ${cmd}`);console.error("[dev] usage: playable-scripts dev [start|compile]");process.exit(1)}module.exports={runCocosDev};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const fs=require("fs");const path=require("path");const{lookup}=require("mime-types");const{ADAPTER_FETCH,TO_STRING_EXTNAME,TO_SKIP_EXTNAME}=require("./constants");function getRealPath(pathStr){return pathStr.indexOf("\\")!==-1?pathStr.replace(/\\/g,"/"):pathStr}function getAllFilesFromDir(dirPath){let files=[];if(!fs.existsSync(dirPath))return files;for(const fileName of fs.readdirSync(dirPath)){const filePath=path.join(dirPath,fileName);const stat=fs.statSync(filePath);if(stat.isDirectory())files=files.concat(getAllFilesFromDir(filePath));else files.push(filePath)}return files}function getBase64FromFile(filePath){const data=fs.readFileSync(filePath).toString("base64");return`data:${lookup(filePath)||"application/octet-stream"};base64,${data}`}function getTargetResData(filePath){const fileExtname=path.extname(filePath);if(!fileExtname)return"";if(TO_STRING_EXTNAME.includes(fileExtname)){return fs.readFileSync(filePath,"utf-8")}return getBase64FromFile(filePath)}function removeXMLHttpRequest(codeStr){return codeStr.replace(/XMLHttpRequest/g,ADAPTER_FETCH)}async function getResourceMapper({dirPath,rmHttp=false,mountCbFn,skipFiles=[]}){const resMapper={};const readPkgPath=getRealPath(`${dirPath}/`);for(const filePath of getAllFilesFromDir(dirPath)){const fileExtname=path.extname(filePath);if(TO_SKIP_EXTNAME.includes(fileExtname))continue;if(skipFiles.includes(filePath))continue;const objKey=getRealPath(filePath).replace(readPkgPath,"");let data=getTargetResData(filePath);if(mountCbFn)data=mountCbFn(objKey,data);if(rmHttp&&fileExtname===".js")data=removeXMLHttpRequest(data);resMapper[objKey]=data}return{resMapper}}module.exports={getRealPath,getAllFilesFromDir,getBase64FromFile,getTargetResData,getResourceMapper,removeXMLHttpRequest};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";window.__adapter_init=function(){// Utilities
|
|
2
|
+
function base64ToBlob(base64,type){let oriResBase64=base64;let base64Arr=oriResBase64.split(",");let mime=type;// mime-type start
|
|
3
|
+
if(base64Arr.length===2){let mimeStr=base64Arr.shift();let regExp=new RegExp(":(.*?);");let array=mimeStr.match(regExp);mime=(array&&array.length>1?array[1]:type)||type}// mime-type end
|
|
4
|
+
// arraybuffer start
|
|
5
|
+
let base64Str=base64Arr.shift();let bytes=window.atob(base64Str);let arrBuf=new ArrayBuffer(bytes.length);// arraybuffer end
|
|
6
|
+
const u8arr=new Uint8Array(arrBuf);for(let i=0;i<bytes.length;i++){u8arr[i]=bytes.charCodeAt(i)}return new Blob([arrBuf],{type:mime})}function base64toArrayBuffer(base64){var bstr=window.atob(base64.substring(base64.indexOf(",")+1));let index=bstr.length;let u8arr=new Uint8Array(index);while(index--){u8arr[index]=bstr.charCodeAt(index)}return u8arr.buffer}class AdapterFetch{constructor(){this.response=null,this.status=200,this.responseType="",this.onload=function(){console.log("onload")}}open(e,t){const n=__adapter_get_resource(t);n?this.response=n:console.log("res",n,t)}send(){switch(this.responseType){case"json":this.response=JSON.parse(this.response);break;case"text":this.response=this.response;break;case"arraybuffer":this.response=base64toArrayBuffer(this.response);break;default:this.response=this.response}this.onload()}}function __adapter_eval(name){if(!window.__adapter_js__[name]){console.warn("window.__adapter_js__ is not found ",name);return}eval(window.__adapter_js__[name]);delete window.__adapter_js__[name]}function __adapter_get_base_url(){const hasDocument=typeof document!=="undefined";let baseUrl;if(hasDocument){let baseEl=document.querySelector("base[href]");if(baseEl)baseUrl=baseEl.href}if(!baseUrl&&typeof location!=="undefined"){baseUrl=location.href.split("#")[0].split("?")[0];var lastSepIndex=baseUrl.lastIndexOf("/");if(lastSepIndex!==-1)baseUrl=baseUrl.slice(0,lastSepIndex+1)}return baseUrl||""}function __adapter_get_res_path(url,target){if(target[url]){return url}for(let key in target){const index=url.indexOf(key);if(index!==-1&&index+key.length===url.length){return key}}return null}function __adapter_get_resource(url){return window.__adapter_resource__[__adapter_get_res_path(url,window.__adapter_resource__)]}function __adapter_get_imports(){const json=JSON.parse(__adapter_get_resource("src/import-map.json"));return json.imports}function __adapter_get_script(url){if(url.indexOf("bullet.wasm")!==-1){for(let k2 in window.__adapter_js__){if(k2.indexOf("bullet.cocos")!==-1){url=k2;break}}}let _key=__adapter_get_res_path(url,window.__adapter_js__);const res=window.__adapter_js__[_key];if(res){delete window.__adapter_js__[_key]}return res}function __adapter_init_http(){window.adapterFetch=AdapterFetch;const _fetch=window.fetch;window.fetch=function(url,options){const resource=__adapter_get_resource(url);if(resource){// 模拟fetch响应结果
|
|
7
|
+
let response={ok:true,status:200,statusText:"OK",headers:{get:function(key){// 根据不同的资源url返回不同的content-type,json、css、wasm
|
|
8
|
+
if(key==="content-type"){if(url.indexOf(".json")!==-1){return"application/json"}else if(url.indexOf(".css")!==-1){return"text/css"}else if(url.indexOf(".wasm")!==-1){return"application/wasm"}}return"application/javascript"}},url:url,clone:function(){return response},text:function(){return Promise.resolve(resource)},json:function(){return Promise.resolve(JSON.parse(resource))},arrayBuffer:function(){return Promise.resolve(base64toArrayBuffer(resource))}};return Promise.resolve(response)}return _fetch(url,options)}}function __adapter_init_js(){const _createScript=System.__proto__.createScript;System.__proto__.createScript=function(url){let baseUrl=url.replace(__adapter_get_base_url(),"");let res=__adapter_get_script(baseUrl);if(!res){console.error(`${url} 找不到资源`);return _createScript.call(this,url)}const blob=new Blob([res],{type:"text/javascript"});return _createScript.call(this,URL.createObjectURL(blob))}}function __adapter_init_cc(){if(window.__adapter_cc_initialized__){return}window.__adapter_cc_initialized__=true;function loadScript(url,options,onComplete){let scriptStr=__adapter_get_resource(url);if(!scriptStr){console.error(url+" isn't load")}eval(scriptStr);onComplete&&onComplete(null)}// Json
|
|
9
|
+
function loadJson(url,options,onComplete){const data=JSON.parse(__adapter_get_resource(url));onComplete(null,data)}function loadBundle(url,options,onComplete){const REGEX=new RegExp("^(?:w+://|.+/).+");let bundleName=cc.path.basename(url);if(!REGEX.test(url)){url="assets/"+bundleName}const version=options.version||cc.assetManager.downloader.bundleVers[bundleName];let count=0;const config=`${url}/config.${version?version+".":""}json`;let out=null,error=null;loadJson(config,options,function(err,response){if(err){error=err}out=response;out&&(out.base=url+"/");count++;if(count===2){onComplete&&onComplete(error,out)}});const js=`${url}/index.${version?version+".":""}js`;loadScript(js,options,function(err){if(err){error=err}count++;if(count===2){onComplete&&onComplete(error,out)}})}function loadFont(url,options,onComplete){const fontFamilyName=url.split("/").pop().split(".")[0];const data=__adapter_get_resource(url);if(data==null){onComplete();return}const fontFace=new FontFace(fontFamilyName,"url("+data+")");document.fonts.add(fontFace);fontFace.load();fontFace.loaded.then(function(){onComplete(null,fontFamilyName)},function(){console.error("url("+url+") load fail");onComplete(null,fontFamilyName)})}// Image
|
|
10
|
+
function loadImage(url,options,onComplete){const data=__adapter_get_resource(url);if(!data){console.error(url+" isn't load")}let img=new Image;const loadCallback=function(){img.removeEventListener("load",loadCallback);img.removeEventListener("error",errorCallback);onComplete&&onComplete(null,img)};const errorCallback=function(){img.removeEventListener("load",loadCallback);img.removeEventListener("error",errorCallback);onComplete&&onComplete(new Error(cc.debug.getError(4930,url)))};img.addEventListener("load",loadCallback);img.addEventListener("error",errorCallback);img.src=data;return img}// Video
|
|
11
|
+
function loadVideo(url,options,onComplete){var video=document.createElement("video");var source=document.createElement("source");video.appendChild(source);let res=__adapter_get_resource(url);if(res){res=base64ToBlob(res);res=URL.createObjectURL(res);source.src=res;onComplete(null,video)}else{onComplete(new Error(url+"(no response)"))}}// Text
|
|
12
|
+
function loadText(url,options,onComplete){options.responseType="text";const data=__adapter_get_resource(url);onComplete(null,data)}// ArrayBuffer
|
|
13
|
+
function loadArrayBuffer(url,options,onComplete){let data=__adapter_get_resource(url);data=base64toArrayBuffer(data);onComplete(null,data)}if(cc.internal.VideoPlayerImplManager){const getImpl=cc.internal.VideoPlayerImplManager.getImpl;cc.internal.VideoPlayerImplManager.getImpl=function(comp){const impl=getImpl.call(this,comp);const createVideoPlayer=impl.createVideoPlayer;impl.createVideoPlayer=function(url){var res=__adapter_get_resource(url);if(res){res=base64ToBlob(res);res=URL.createObjectURL(res);return createVideoPlayer.call(this,res)}return createVideoPlayer.call(this,url)};return impl}}const downloaderList={// Scripts
|
|
14
|
+
".js":loadScript,// Fonts
|
|
15
|
+
".font":loadFont,".eot":loadFont,".ttf":loadFont,".woff":loadFont,".svg":loadFont,".ttc":loadFont,// Images
|
|
16
|
+
".png":loadImage,".jpg":loadImage,".bmp":loadImage,".jpeg":loadImage,".gif":loadImage,".ico":loadImage,".tiff":loadImage,".webp":loadImage,".image":loadImage,// Videos
|
|
17
|
+
".mp4":loadVideo,".avi":loadVideo,".mov":loadVideo,".mpg":loadVideo,".mpeg":loadVideo,".rm":loadVideo,".rmvb":loadVideo,// Text
|
|
18
|
+
".txt":loadText,".xml":loadText,".vsh":loadText,".fsh":loadText,".atlas":loadText,".tmx":loadText,".tsx":loadText,".plist":loadText,".fnt":loadText,// ArrayBuffer
|
|
19
|
+
".pvr":loadArrayBuffer,".pkm":loadArrayBuffer,".astc":loadArrayBuffer,".binary":loadArrayBuffer,".bin":loadArrayBuffer,".dbbin":loadArrayBuffer,".skel":loadArrayBuffer,"bundle":loadBundle,"default":loadText};cc.assetManager.downloader.downloadScript=loadScript;Object.keys(downloaderList).forEach(extname=>{cc.assetManager.downloader.register(extname,downloaderList[extname])})}function __adapter_init_plugins(){if(!window.__adapter_plugins__||window.__adapter_plugins__.length===0){return}window.__adapter_plugins__.forEach(scriptPath=>{const fileName="src/"+scriptPath;__adapter_eval(fileName)})}function __adapter_get_path(key){for(var k in window.__adapter_resource__){if(k.indexOf(key)==0){return k}}throw Error("no find "+key)}__adapter_init_http();__adapter_eval(__adapter_get_path("src/polyfills.bundle"));__adapter_eval(__adapter_get_path("src/system.bundle"));__adapter_init_js();let prepareLoad=Promise.resolve();const importsKeys=Object.keys(__adapter_get_imports());for(let index=importsKeys.length-1;index>=0;index--){const key=importsKeys[index];prepareLoad=prepareLoad.then(()=>System.import(key))}prepareLoad.then(()=>{__adapter_init_cc();__adapter_init_plugins();System.import("./"+__adapter_get_path("index")).catch(err=>{console.error(err)})})};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";;(function(){function base64toArrayBuffer(base64){var bstr=window.atob(base64.substring(base64.indexOf(",")+1));let index=bstr.length;let u8arr=new Uint8Array(index);while(index--){u8arr[index]=bstr.charCodeAt(index)}return u8arr.buffer}function __adapter_unzip(){console.time("load resource");try{const zipData=base64toArrayBuffer(window.__adapter_zip__);const decompressed=pako.inflate(zipData,{to:"string"});window.__adapter_resource__=JSON.parse(decompressed);__adapter_exec_js()}catch(error){console.error(error);throw error}console.timeEnd("load resource")}function __adapter_exec_js(){window.__adapter_js__={};for(const filePath in window.__adapter_resource__){let dirArr=filePath.split(".");if(dirArr[dirArr.length-1]==="js"){window.__adapter_js__[filePath]=window.__adapter_resource__[filePath]}}__adapter_success()}function __adapter_console(){if(window.__adapter_js__["vconsole.min.js"]){eval(window.__adapter_js__["vconsole.min.js"]);delete window.__adapter_js__["vconsole.min.js"];window.VConsole&&(window.vConsole=new VConsole)}}function __adapter_success(){__adapter_console();window.__adapter_init&&window.__adapter_init()}// 如果不存在pako,则直接运行js
|
|
2
|
+
if(!window["pako"]){__adapter_exec_js();return}__adapter_unzip()})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).pako={})}(void 0,function(t){"use strict";function e(t){let e=t.length;for(;--e>=0;)t[e]=0}const a=256,i=286,n=30,s=15,r=new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]),o=new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]),l=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]),h=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),d=new Array(576);e(d);const _=new Array(60);e(_);const f=new Array(512);e(f);const c=new Array(256);e(c);const u=new Array(29);e(u);const w=new Array(n);function m(t,e,a,i,n){this.static_tree=t,this.extra_bits=e,this.extra_base=a,this.elems=i,this.max_length=n,this.has_stree=t&&t.length}let b,g,p;function k(t,e){this.dyn_tree=t,this.max_code=0,this.stat_desc=e}e(w);const v=t=>t<256?f[t]:f[256+(t>>>7)],y=(t,e)=>{t.pending_buf[t.pending++]=255&e,t.pending_buf[t.pending++]=e>>>8&255},x=(t,e,a)=>{t.bi_valid>16-a?(t.bi_buf|=e<<t.bi_valid&65535,y(t,t.bi_buf),t.bi_buf=e>>16-t.bi_valid,t.bi_valid+=a-16):(t.bi_buf|=e<<t.bi_valid&65535,t.bi_valid+=a)},z=(t,e,a)=>{x(t,a[2*e],a[2*e+1])},A=(t,e)=>{let a=0;do{a|=1&t,t>>>=1,a<<=1}while(--e>0);return a>>>1},E=(t,e,a)=>{const i=new Array(16);let n,r,o=0;for(n=1;n<=s;n++)o=o+a[n-1]<<1,i[n]=o;for(r=0;r<=e;r++){let e=t[2*r+1];0!==e&&(t[2*r]=A(i[e]++,e))}},R=t=>{let e;for(e=0;e<i;e++)t.dyn_ltree[2*e]=0;for(e=0;e<n;e++)t.dyn_dtree[2*e]=0;for(e=0;e<19;e++)t.bl_tree[2*e]=0;t.dyn_ltree[512]=1,t.opt_len=t.static_len=0,t.sym_next=t.matches=0},Z=t=>{t.bi_valid>8?y(t,t.bi_buf):t.bi_valid>0&&(t.pending_buf[t.pending++]=t.bi_buf),t.bi_buf=0,t.bi_valid=0},U=(t,e,a,i)=>{const n=2*e,s=2*a;return t[n]<t[s]||t[n]===t[s]&&i[e]<=i[a]},S=(t,e,a)=>{const i=t.heap[a];let n=a<<1;for(;n<=t.heap_len&&(n<t.heap_len&&U(e,t.heap[n+1],t.heap[n],t.depth)&&n++,!U(e,i,t.heap[n],t.depth));)t.heap[a]=t.heap[n],a=n,n<<=1;t.heap[a]=i},D=(t,e,i)=>{let n,s,l,h,d=0;if(0!==t.sym_next)do{n=255&t.pending_buf[t.sym_buf+d++],n+=(255&t.pending_buf[t.sym_buf+d++])<<8,s=t.pending_buf[t.sym_buf+d++],0===n?z(t,s,e):(l=c[s],z(t,l+a+1,e),h=r[l],0!==h&&(s-=u[l],x(t,s,h)),n--,l=v(n),z(t,l,i),h=o[l],0!==h&&(n-=w[l],x(t,n,h)))}while(d<t.sym_next);z(t,256,e)},T=(t,e)=>{const a=e.dyn_tree,i=e.stat_desc.static_tree,n=e.stat_desc.has_stree,r=e.stat_desc.elems;let o,l,h,d=-1;for(t.heap_len=0,t.heap_max=573,o=0;o<r;o++)0!==a[2*o]?(t.heap[++t.heap_len]=d=o,t.depth[o]=0):a[2*o+1]=0;for(;t.heap_len<2;)h=t.heap[++t.heap_len]=d<2?++d:0,a[2*h]=1,t.depth[h]=0,t.opt_len--,n&&(t.static_len-=i[2*h+1]);for(e.max_code=d,o=t.heap_len>>1;o>=1;o--)S(t,a,o);h=r;do{o=t.heap[1],t.heap[1]=t.heap[t.heap_len--],S(t,a,1),l=t.heap[1],t.heap[--t.heap_max]=o,t.heap[--t.heap_max]=l,a[2*h]=a[2*o]+a[2*l],t.depth[h]=(t.depth[o]>=t.depth[l]?t.depth[o]:t.depth[l])+1,a[2*o+1]=a[2*l+1]=h,t.heap[1]=h++,S(t,a,1)}while(t.heap_len>=2);t.heap[--t.heap_max]=t.heap[1],((t,e)=>{const a=e.dyn_tree,i=e.max_code,n=e.stat_desc.static_tree,r=e.stat_desc.has_stree,o=e.stat_desc.extra_bits,l=e.stat_desc.extra_base,h=e.stat_desc.max_length;let d,_,f,c,u,w,m=0;for(c=0;c<=s;c++)t.bl_count[c]=0;for(a[2*t.heap[t.heap_max]+1]=0,d=t.heap_max+1;d<573;d++)_=t.heap[d],c=a[2*a[2*_+1]+1]+1,c>h&&(c=h,m++),a[2*_+1]=c,_>i||(t.bl_count[c]++,u=0,_>=l&&(u=o[_-l]),w=a[2*_],t.opt_len+=w*(c+u),r&&(t.static_len+=w*(n[2*_+1]+u)));if(0!==m){do{for(c=h-1;0===t.bl_count[c];)c--;t.bl_count[c]--,t.bl_count[c+1]+=2,t.bl_count[h]--,m-=2}while(m>0);for(c=h;0!==c;c--)for(_=t.bl_count[c];0!==_;)f=t.heap[--d],f>i||(a[2*f+1]!==c&&(t.opt_len+=(c-a[2*f+1])*a[2*f],a[2*f+1]=c),_--)}})(t,e),E(a,d,t.bl_count)},O=(t,e,a)=>{let i,n,s=-1,r=e[1],o=0,l=7,h=4;for(0===r&&(l=138,h=3),e[2*(a+1)+1]=65535,i=0;i<=a;i++)n=r,r=e[2*(i+1)+1],++o<l&&n===r||(o<h?t.bl_tree[2*n]+=o:0!==n?(n!==s&&t.bl_tree[2*n]++,t.bl_tree[32]++):o<=10?t.bl_tree[34]++:t.bl_tree[36]++,o=0,s=n,0===r?(l=138,h=3):n===r?(l=6,h=3):(l=7,h=4))},I=(t,e,a)=>{let i,n,s=-1,r=e[1],o=0,l=7,h=4;for(0===r&&(l=138,h=3),i=0;i<=a;i++)if(n=r,r=e[2*(i+1)+1],!(++o<l&&n===r)){if(o<h)do{z(t,n,t.bl_tree)}while(0!=--o);else 0!==n?(n!==s&&(z(t,n,t.bl_tree),o--),z(t,16,t.bl_tree),x(t,o-3,2)):o<=10?(z(t,17,t.bl_tree),x(t,o-3,3)):(z(t,18,t.bl_tree),x(t,o-11,7));o=0,s=n,0===r?(l=138,h=3):n===r?(l=6,h=3):(l=7,h=4)}};let F=!1;const L=(t,e,a,i)=>{x(t,0+(i?1:0),3),Z(t),y(t,a),y(t,~a),a&&t.pending_buf.set(t.window.subarray(e,e+a),t.pending),t.pending+=a};var N=(t,e,i,n)=>{let s,r,o=0;t.level>0?(2===t.strm.data_type&&(t.strm.data_type=(t=>{let e,i=4093624447;for(e=0;e<=31;e++,i>>>=1)if(1&i&&0!==t.dyn_ltree[2*e])return 0;if(0!==t.dyn_ltree[18]||0!==t.dyn_ltree[20]||0!==t.dyn_ltree[26])return 1;for(e=32;e<a;e++)if(0!==t.dyn_ltree[2*e])return 1;return 0})(t)),T(t,t.l_desc),T(t,t.d_desc),o=(t=>{let e;for(O(t,t.dyn_ltree,t.l_desc.max_code),O(t,t.dyn_dtree,t.d_desc.max_code),T(t,t.bl_desc),e=18;e>=3&&0===t.bl_tree[2*h[e]+1];e--);return t.opt_len+=3*(e+1)+5+5+4,e})(t),s=t.opt_len+3+7>>>3,r=t.static_len+3+7>>>3,r<=s&&(s=r)):s=r=i+5,i+4<=s&&-1!==e?L(t,e,i,n):4===t.strategy||r===s?(x(t,2+(n?1:0),3),D(t,d,_)):(x(t,4+(n?1:0),3),((t,e,a,i)=>{let n;for(x(t,e-257,5),x(t,a-1,5),x(t,i-4,4),n=0;n<i;n++)x(t,t.bl_tree[2*h[n]+1],3);I(t,t.dyn_ltree,e-1),I(t,t.dyn_dtree,a-1)})(t,t.l_desc.max_code+1,t.d_desc.max_code+1,o+1),D(t,t.dyn_ltree,t.dyn_dtree)),R(t),n&&Z(t)},B={_tr_init:t=>{F||((()=>{let t,e,a,h,k;const v=new Array(16);for(a=0,h=0;h<28;h++)for(u[h]=a,t=0;t<1<<r[h];t++)c[a++]=h;for(c[a-1]=h,k=0,h=0;h<16;h++)for(w[h]=k,t=0;t<1<<o[h];t++)f[k++]=h;for(k>>=7;h<n;h++)for(w[h]=k<<7,t=0;t<1<<o[h]-7;t++)f[256+k++]=h;for(e=0;e<=s;e++)v[e]=0;for(t=0;t<=143;)d[2*t+1]=8,t++,v[8]++;for(;t<=255;)d[2*t+1]=9,t++,v[9]++;for(;t<=279;)d[2*t+1]=7,t++,v[7]++;for(;t<=287;)d[2*t+1]=8,t++,v[8]++;for(E(d,287,v),t=0;t<n;t++)_[2*t+1]=5,_[2*t]=A(t,5);b=new m(d,r,257,i,s),g=new m(_,o,0,n,s),p=new m(new Array(0),l,0,19,7)})(),F=!0),t.l_desc=new k(t.dyn_ltree,b),t.d_desc=new k(t.dyn_dtree,g),t.bl_desc=new k(t.bl_tree,p),t.bi_buf=0,t.bi_valid=0,R(t)},_tr_stored_block:L,_tr_flush_block:N,_tr_tally:(t,e,i)=>(t.pending_buf[t.sym_buf+t.sym_next++]=e,t.pending_buf[t.sym_buf+t.sym_next++]=e>>8,t.pending_buf[t.sym_buf+t.sym_next++]=i,0===e?t.dyn_ltree[2*i]++:(t.matches++,e--,t.dyn_ltree[2*(c[i]+a+1)]++,t.dyn_dtree[2*v(e)]++),t.sym_next===t.sym_end),_tr_align:t=>{x(t,2,3),z(t,256,d),(t=>{16===t.bi_valid?(y(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):t.bi_valid>=8&&(t.pending_buf[t.pending++]=255&t.bi_buf,t.bi_buf>>=8,t.bi_valid-=8)})(t)}};var C=(t,e,a,i)=>{let n=65535&t|0,s=t>>>16&65535|0,r=0;for(;0!==a;){r=a>2e3?2e3:a,a-=r;do{n=n+e[i++]|0,s=s+n|0}while(--r);n%=65521,s%=65521}return n|s<<16|0};const M=new Uint32Array((()=>{let t,e=[];for(var a=0;a<256;a++){t=a;for(var i=0;i<8;i++)t=1&t?3988292384^t>>>1:t>>>1;e[a]=t}return e})());var H=(t,e,a,i)=>{const n=M,s=i+a;t^=-1;for(let a=i;a<s;a++)t=t>>>8^n[255&(t^e[a])];return-1^t},j={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"},K={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8};const{_tr_init:P,_tr_stored_block:Y,_tr_flush_block:G,_tr_tally:X,_tr_align:W}=B,{Z_NO_FLUSH:q,Z_PARTIAL_FLUSH:J,Z_FULL_FLUSH:Q,Z_FINISH:V,Z_BLOCK:$,Z_OK:tt,Z_STREAM_END:et,Z_STREAM_ERROR:at,Z_DATA_ERROR:it,Z_BUF_ERROR:nt,Z_DEFAULT_COMPRESSION:st,Z_FILTERED:rt,Z_HUFFMAN_ONLY:ot,Z_RLE:lt,Z_FIXED:ht,Z_DEFAULT_STRATEGY:dt,Z_UNKNOWN:_t,Z_DEFLATED:ft}=K,ct=258,ut=262,wt=42,mt=113,bt=666,gt=(t,e)=>(t.msg=j[e],e),pt=t=>2*t-(t>4?9:0),kt=t=>{let e=t.length;for(;--e>=0;)t[e]=0},vt=t=>{let e,a,i,n=t.w_size;e=t.hash_size,i=e;do{a=t.head[--i],t.head[i]=a>=n?a-n:0}while(--e);e=n,i=e;do{a=t.prev[--i],t.prev[i]=a>=n?a-n:0}while(--e)};let yt=(t,e,a)=>(e<<t.hash_shift^a)&t.hash_mask;const xt=t=>{const e=t.state;let a=e.pending;a>t.avail_out&&(a=t.avail_out),0!==a&&(t.output.set(e.pending_buf.subarray(e.pending_out,e.pending_out+a),t.next_out),t.next_out+=a,e.pending_out+=a,t.total_out+=a,t.avail_out-=a,e.pending-=a,0===e.pending&&(e.pending_out=0))},zt=(t,e)=>{G(t,t.block_start>=0?t.block_start:-1,t.strstart-t.block_start,e),t.block_start=t.strstart,xt(t.strm)},At=(t,e)=>{t.pending_buf[t.pending++]=e},Et=(t,e)=>{t.pending_buf[t.pending++]=e>>>8&255,t.pending_buf[t.pending++]=255&e},Rt=(t,e,a,i)=>{let n=t.avail_in;return n>i&&(n=i),0===n?0:(t.avail_in-=n,e.set(t.input.subarray(t.next_in,t.next_in+n),a),1===t.state.wrap?t.adler=C(t.adler,e,n,a):2===t.state.wrap&&(t.adler=H(t.adler,e,n,a)),t.next_in+=n,t.total_in+=n,n)},Zt=(t,e)=>{let a,i,n=t.max_chain_length,s=t.strstart,r=t.prev_length,o=t.nice_match;const l=t.strstart>t.w_size-ut?t.strstart-(t.w_size-ut):0,h=t.window,d=t.w_mask,_=t.prev,f=t.strstart+ct;let c=h[s+r-1],u=h[s+r];t.prev_length>=t.good_match&&(n>>=2),o>t.lookahead&&(o=t.lookahead);do{if(a=e,h[a+r]===u&&h[a+r-1]===c&&h[a]===h[s]&&h[++a]===h[s+1]){s+=2,a++;do{}while(h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&s<f);if(i=ct-(f-s),s=f-ct,i>r){if(t.match_start=e,r=i,i>=o)break;c=h[s+r-1],u=h[s+r]}}}while((e=_[e&d])>l&&0!=--n);return r<=t.lookahead?r:t.lookahead},Ut=t=>{const e=t.w_size;let a,i,n;do{if(i=t.window_size-t.lookahead-t.strstart,t.strstart>=e+(e-ut)&&(t.window.set(t.window.subarray(e,e+e-i),0),t.match_start-=e,t.strstart-=e,t.block_start-=e,t.insert>t.strstart&&(t.insert=t.strstart),vt(t),i+=e),0===t.strm.avail_in)break;if(a=Rt(t.strm,t.window,t.strstart+t.lookahead,i),t.lookahead+=a,t.lookahead+t.insert>=3)for(n=t.strstart-t.insert,t.ins_h=t.window[n],t.ins_h=yt(t,t.ins_h,t.window[n+1]);t.insert&&(t.ins_h=yt(t,t.ins_h,t.window[n+3-1]),t.prev[n&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=n,n++,t.insert--,!(t.lookahead+t.insert<3)););}while(t.lookahead<ut&&0!==t.strm.avail_in)},St=(t,e)=>{let a,i,n,s=t.pending_buf_size-5>t.w_size?t.w_size:t.pending_buf_size-5,r=0,o=t.strm.avail_in;do{if(a=65535,n=t.bi_valid+42>>3,t.strm.avail_out<n)break;if(n=t.strm.avail_out-n,i=t.strstart-t.block_start,a>i+t.strm.avail_in&&(a=i+t.strm.avail_in),a>n&&(a=n),a<s&&(0===a&&e!==V||e===q||a!==i+t.strm.avail_in))break;r=e===V&&a===i+t.strm.avail_in?1:0,Y(t,0,0,r),t.pending_buf[t.pending-4]=a,t.pending_buf[t.pending-3]=a>>8,t.pending_buf[t.pending-2]=~a,t.pending_buf[t.pending-1]=~a>>8,xt(t.strm),i&&(i>a&&(i=a),t.strm.output.set(t.window.subarray(t.block_start,t.block_start+i),t.strm.next_out),t.strm.next_out+=i,t.strm.avail_out-=i,t.strm.total_out+=i,t.block_start+=i,a-=i),a&&(Rt(t.strm,t.strm.output,t.strm.next_out,a),t.strm.next_out+=a,t.strm.avail_out-=a,t.strm.total_out+=a)}while(0===r);return o-=t.strm.avail_in,o&&(o>=t.w_size?(t.matches=2,t.window.set(t.strm.input.subarray(t.strm.next_in-t.w_size,t.strm.next_in),0),t.strstart=t.w_size,t.insert=t.strstart):(t.window_size-t.strstart<=o&&(t.strstart-=t.w_size,t.window.set(t.window.subarray(t.w_size,t.w_size+t.strstart),0),t.matches<2&&t.matches++,t.insert>t.strstart&&(t.insert=t.strstart)),t.window.set(t.strm.input.subarray(t.strm.next_in-o,t.strm.next_in),t.strstart),t.strstart+=o,t.insert+=o>t.w_size-t.insert?t.w_size-t.insert:o),t.block_start=t.strstart),t.high_water<t.strstart&&(t.high_water=t.strstart),r?4:e!==q&&e!==V&&0===t.strm.avail_in&&t.strstart===t.block_start?2:(n=t.window_size-t.strstart,t.strm.avail_in>n&&t.block_start>=t.w_size&&(t.block_start-=t.w_size,t.strstart-=t.w_size,t.window.set(t.window.subarray(t.w_size,t.w_size+t.strstart),0),t.matches<2&&t.matches++,n+=t.w_size,t.insert>t.strstart&&(t.insert=t.strstart)),n>t.strm.avail_in&&(n=t.strm.avail_in),n&&(Rt(t.strm,t.window,t.strstart,n),t.strstart+=n,t.insert+=n>t.w_size-t.insert?t.w_size-t.insert:n),t.high_water<t.strstart&&(t.high_water=t.strstart),n=t.bi_valid+42>>3,n=t.pending_buf_size-n>65535?65535:t.pending_buf_size-n,s=n>t.w_size?t.w_size:n,i=t.strstart-t.block_start,(i>=s||(i||e===V)&&e!==q&&0===t.strm.avail_in&&i<=n)&&(a=i>n?n:i,r=e===V&&0===t.strm.avail_in&&a===i?1:0,Y(t,t.block_start,a,r),t.block_start+=a,xt(t.strm)),r?3:1)},Dt=(t,e)=>{let a,i;for(;;){if(t.lookahead<ut){if(Ut(t),t.lookahead<ut&&e===q)return 1;if(0===t.lookahead)break}if(a=0,t.lookahead>=3&&(t.ins_h=yt(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),0!==a&&t.strstart-a<=t.w_size-ut&&(t.match_length=Zt(t,a)),t.match_length>=3){if(i=X(t,t.strstart-t.match_start,t.match_length-3),t.lookahead-=t.match_length,t.match_length<=t.max_lazy_match&&t.lookahead>=3){t.match_length--;do{t.strstart++,t.ins_h=yt(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart}while(0!=--t.match_length);t.strstart++}else t.strstart+=t.match_length,t.match_length=0,t.ins_h=t.window[t.strstart],t.ins_h=yt(t,t.ins_h,t.window[t.strstart+1]);}else i=X(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++;if(i&&(zt(t,!1),0===t.strm.avail_out))return 1}return t.insert=t.strstart<2?t.strstart:2,e===V?(zt(t,!0),0===t.strm.avail_out?3:4):t.sym_next&&(zt(t,!1),0===t.strm.avail_out)?1:2},Tt=(t,e)=>{let a,i,n;for(;;){if(t.lookahead<ut){if(Ut(t),t.lookahead<ut&&e===q)return 1;if(0===t.lookahead)break}if(a=0,t.lookahead>=3&&(t.ins_h=yt(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),t.prev_length=t.match_length,t.prev_match=t.match_start,t.match_length=2,0!==a&&t.prev_length<t.max_lazy_match&&t.strstart-a<=t.w_size-ut&&(t.match_length=Zt(t,a),t.match_length<=5&&(t.strategy===rt||3===t.match_length&&t.strstart-t.match_start>4096)&&(t.match_length=2)),t.prev_length>=3&&t.match_length<=t.prev_length){n=t.strstart+t.lookahead-3,i=X(t,t.strstart-1-t.prev_match,t.prev_length-3),t.lookahead-=t.prev_length-1,t.prev_length-=2;do{++t.strstart<=n&&(t.ins_h=yt(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart)}while(0!=--t.prev_length);if(t.match_available=0,t.match_length=2,t.strstart++,i&&(zt(t,!1),0===t.strm.avail_out))return 1}else if(t.match_available){if(i=X(t,0,t.window[t.strstart-1]),i&&zt(t,!1),t.strstart++,t.lookahead--,0===t.strm.avail_out)return 1}else t.match_available=1,t.strstart++,t.lookahead--}return t.match_available&&(i=X(t,0,t.window[t.strstart-1]),t.match_available=0),t.insert=t.strstart<2?t.strstart:2,e===V?(zt(t,!0),0===t.strm.avail_out?3:4):t.sym_next&&(zt(t,!1),0===t.strm.avail_out)?1:2};function Ot(t,e,a,i,n){this.good_length=t,this.max_lazy=e,this.nice_length=a,this.max_chain=i,this.func=n}const It=[new Ot(0,0,0,0,St),new Ot(4,4,8,4,Dt),new Ot(4,5,16,8,Dt),new Ot(4,6,32,32,Dt),new Ot(4,4,16,16,Tt),new Ot(8,16,32,32,Tt),new Ot(8,16,128,128,Tt),new Ot(8,32,128,256,Tt),new Ot(32,128,258,1024,Tt),new Ot(32,258,258,4096,Tt)];function Ft(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=ft,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new Uint16Array(1146),this.dyn_dtree=new Uint16Array(122),this.bl_tree=new Uint16Array(78),kt(this.dyn_ltree),kt(this.dyn_dtree),kt(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new Uint16Array(16),this.heap=new Uint16Array(573),kt(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new Uint16Array(573),kt(this.depth),this.sym_buf=0,this.lit_bufsize=0,this.sym_next=0,this.sym_end=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}const Lt=t=>{if(!t)return 1;const e=t.state;return!e||e.strm!==t||e.status!==wt&&57!==e.status&&69!==e.status&&73!==e.status&&91!==e.status&&103!==e.status&&e.status!==mt&&e.status!==bt?1:0},Nt=t=>{if(Lt(t))return gt(t,at);t.total_in=t.total_out=0,t.data_type=_t;const e=t.state;return e.pending=0,e.pending_out=0,e.wrap<0&&(e.wrap=-e.wrap),e.status=2===e.wrap?57:e.wrap?wt:mt,t.adler=2===e.wrap?0:1,e.last_flush=-2,P(e),tt},Bt=t=>{const e=Nt(t);var a;return e===tt&&((a=t.state).window_size=2*a.w_size,kt(a.head),a.max_lazy_match=It[a.level].max_lazy,a.good_match=It[a.level].good_length,a.nice_match=It[a.level].nice_length,a.max_chain_length=It[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=2,a.match_available=0,a.ins_h=0),e},Ct=(t,e,a,i,n,s)=>{if(!t)return at;let r=1;if(e===st&&(e=6),i<0?(r=0,i=-i):i>15&&(r=2,i-=16),n<1||n>9||a!==ft||i<8||i>15||e<0||e>9||s<0||s>ht||8===i&&1!==r)return gt(t,at);8===i&&(i=9);const o=new Ft;return t.state=o,o.strm=t,o.status=wt,o.wrap=r,o.gzhead=null,o.w_bits=i,o.w_size=1<<o.w_bits,o.w_mask=o.w_size-1,o.hash_bits=n+7,o.hash_size=1<<o.hash_bits,o.hash_mask=o.hash_size-1,o.hash_shift=~~((o.hash_bits+3-1)/3),o.window=new Uint8Array(2*o.w_size),o.head=new Uint16Array(o.hash_size),o.prev=new Uint16Array(o.w_size),o.lit_bufsize=1<<n+6,o.pending_buf_size=4*o.lit_bufsize,o.pending_buf=new Uint8Array(o.pending_buf_size),o.sym_buf=o.lit_bufsize,o.sym_end=3*(o.lit_bufsize-1),o.level=e,o.strategy=s,o.method=a,Bt(t)};var Mt={deflateInit:(t,e)=>Ct(t,e,ft,15,8,dt),deflateInit2:Ct,deflateReset:Bt,deflateResetKeep:Nt,deflateSetHeader:(t,e)=>Lt(t)||2!==t.state.wrap?at:(t.state.gzhead=e,tt),deflate:(t,e)=>{if(Lt(t)||e>$||e<0)return t?gt(t,at):at;const a=t.state;if(!t.output||0!==t.avail_in&&!t.input||a.status===bt&&e!==V)return gt(t,0===t.avail_out?nt:at);const i=a.last_flush;if(a.last_flush=e,0!==a.pending){if(xt(t),0===t.avail_out)return a.last_flush=-1,tt}else if(0===t.avail_in&&pt(e)<=pt(i)&&e!==V)return gt(t,nt);if(a.status===bt&&0!==t.avail_in)return gt(t,nt);if(a.status===wt&&0===a.wrap&&(a.status=mt),a.status===wt){let e=ft+(a.w_bits-8<<4)<<8,i=-1;if(i=a.strategy>=ot||a.level<2?0:a.level<6?1:6===a.level?2:3,e|=i<<6,0!==a.strstart&&(e|=32),e+=31-e%31,Et(a,e),0!==a.strstart&&(Et(a,t.adler>>>16),Et(a,65535&t.adler)),t.adler=1,a.status=mt,xt(t),0!==a.pending)return a.last_flush=-1,tt}if(57===a.status)if(t.adler=0,At(a,31),At(a,139),At(a,8),a.gzhead)At(a,(a.gzhead.text?1:0)+(a.gzhead.hcrc?2:0)+(a.gzhead.extra?4:0)+(a.gzhead.name?8:0)+(a.gzhead.comment?16:0)),At(a,255&a.gzhead.time),At(a,a.gzhead.time>>8&255),At(a,a.gzhead.time>>16&255),At(a,a.gzhead.time>>24&255),At(a,9===a.level?2:a.strategy>=ot||a.level<2?4:0),At(a,255&a.gzhead.os),a.gzhead.extra&&a.gzhead.extra.length&&(At(a,255&a.gzhead.extra.length),At(a,a.gzhead.extra.length>>8&255)),a.gzhead.hcrc&&(t.adler=H(t.adler,a.pending_buf,a.pending,0)),a.gzindex=0,a.status=69;else if(At(a,0),At(a,0),At(a,0),At(a,0),At(a,0),At(a,9===a.level?2:a.strategy>=ot||a.level<2?4:0),At(a,3),a.status=mt,xt(t),0!==a.pending)return a.last_flush=-1,tt;if(69===a.status){if(a.gzhead.extra){let e=a.pending,i=(65535&a.gzhead.extra.length)-a.gzindex;for(;a.pending+i>a.pending_buf_size;){let n=a.pending_buf_size-a.pending;if(a.pending_buf.set(a.gzhead.extra.subarray(a.gzindex,a.gzindex+n),a.pending),a.pending=a.pending_buf_size,a.gzhead.hcrc&&a.pending>e&&(t.adler=H(t.adler,a.pending_buf,a.pending-e,e)),a.gzindex+=n,xt(t),0!==a.pending)return a.last_flush=-1,tt;e=0,i-=n}let n=new Uint8Array(a.gzhead.extra);a.pending_buf.set(n.subarray(a.gzindex,a.gzindex+i),a.pending),a.pending+=i,a.gzhead.hcrc&&a.pending>e&&(t.adler=H(t.adler,a.pending_buf,a.pending-e,e)),a.gzindex=0}a.status=73}if(73===a.status){if(a.gzhead.name){let e,i=a.pending;do{if(a.pending===a.pending_buf_size){if(a.gzhead.hcrc&&a.pending>i&&(t.adler=H(t.adler,a.pending_buf,a.pending-i,i)),xt(t),0!==a.pending)return a.last_flush=-1,tt;i=0}e=a.gzindex<a.gzhead.name.length?255&a.gzhead.name.charCodeAt(a.gzindex++):0,At(a,e)}while(0!==e);a.gzhead.hcrc&&a.pending>i&&(t.adler=H(t.adler,a.pending_buf,a.pending-i,i)),a.gzindex=0}a.status=91}if(91===a.status){if(a.gzhead.comment){let e,i=a.pending;do{if(a.pending===a.pending_buf_size){if(a.gzhead.hcrc&&a.pending>i&&(t.adler=H(t.adler,a.pending_buf,a.pending-i,i)),xt(t),0!==a.pending)return a.last_flush=-1,tt;i=0}e=a.gzindex<a.gzhead.comment.length?255&a.gzhead.comment.charCodeAt(a.gzindex++):0,At(a,e)}while(0!==e);a.gzhead.hcrc&&a.pending>i&&(t.adler=H(t.adler,a.pending_buf,a.pending-i,i))}a.status=103}if(103===a.status){if(a.gzhead.hcrc){if(a.pending+2>a.pending_buf_size&&(xt(t),0!==a.pending))return a.last_flush=-1,tt;At(a,255&t.adler),At(a,t.adler>>8&255),t.adler=0}if(a.status=mt,xt(t),0!==a.pending)return a.last_flush=-1,tt}if(0!==t.avail_in||0!==a.lookahead||e!==q&&a.status!==bt){let i=0===a.level?St(a,e):a.strategy===ot?((t,e)=>{let a;for(;;){if(0===t.lookahead&&(Ut(t),0===t.lookahead)){if(e===q)return 1;break}if(t.match_length=0,a=X(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++,a&&(zt(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,e===V?(zt(t,!0),0===t.strm.avail_out?3:4):t.sym_next&&(zt(t,!1),0===t.strm.avail_out)?1:2})(a,e):a.strategy===lt?((t,e)=>{let a,i,n,s;const r=t.window;for(;;){if(t.lookahead<=ct){if(Ut(t),t.lookahead<=ct&&e===q)return 1;if(0===t.lookahead)break}if(t.match_length=0,t.lookahead>=3&&t.strstart>0&&(n=t.strstart-1,i=r[n],i===r[++n]&&i===r[++n]&&i===r[++n])){s=t.strstart+ct;do{}while(i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&n<s);t.match_length=ct-(s-n),t.match_length>t.lookahead&&(t.match_length=t.lookahead)}if(t.match_length>=3?(a=X(t,1,t.match_length-3),t.lookahead-=t.match_length,t.strstart+=t.match_length,t.match_length=0):(a=X(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++),a&&(zt(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,e===V?(zt(t,!0),0===t.strm.avail_out?3:4):t.sym_next&&(zt(t,!1),0===t.strm.avail_out)?1:2})(a,e):It[a.level].func(a,e);if(3!==i&&4!==i||(a.status=bt),1===i||3===i)return 0===t.avail_out&&(a.last_flush=-1),tt;if(2===i&&(e===J?W(a):e!==$&&(Y(a,0,0,!1),e===Q&&(kt(a.head),0===a.lookahead&&(a.strstart=0,a.block_start=0,a.insert=0))),xt(t),0===t.avail_out))return a.last_flush=-1,tt}return e!==V?tt:a.wrap<=0?et:(2===a.wrap?(At(a,255&t.adler),At(a,t.adler>>8&255),At(a,t.adler>>16&255),At(a,t.adler>>24&255),At(a,255&t.total_in),At(a,t.total_in>>8&255),At(a,t.total_in>>16&255),At(a,t.total_in>>24&255)):(Et(a,t.adler>>>16),Et(a,65535&t.adler)),xt(t),a.wrap>0&&(a.wrap=-a.wrap),0!==a.pending?tt:et)},deflateEnd:t=>{if(Lt(t))return at;const e=t.state.status;return t.state=null,e===mt?gt(t,it):tt},deflateSetDictionary:(t,e)=>{let a=e.length;if(Lt(t))return at;const i=t.state,n=i.wrap;if(2===n||1===n&&i.status!==wt||i.lookahead)return at;if(1===n&&(t.adler=C(t.adler,e,a,0)),i.wrap=0,a>=i.w_size){0===n&&(kt(i.head),i.strstart=0,i.block_start=0,i.insert=0);let t=new Uint8Array(i.w_size);t.set(e.subarray(a-i.w_size,a),0),e=t,a=i.w_size}const s=t.avail_in,r=t.next_in,o=t.input;for(t.avail_in=a,t.next_in=0,t.input=e,Ut(i);i.lookahead>=3;){let t=i.strstart,e=i.lookahead-2;do{i.ins_h=yt(i,i.ins_h,i.window[t+3-1]),i.prev[t&i.w_mask]=i.head[i.ins_h],i.head[i.ins_h]=t,t++}while(--e);i.strstart=t,i.lookahead=2,Ut(i)}return i.strstart+=i.lookahead,i.block_start=i.strstart,i.insert=i.lookahead,i.lookahead=0,i.match_length=i.prev_length=2,i.match_available=0,t.next_in=r,t.input=o,t.avail_in=s,i.wrap=n,tt},deflateInfo:"pako deflate (from Nodeca project)"};const Ht=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);var jt=function(t){const e=Array.prototype.slice.call(arguments,1);for(;e.length;){const a=e.shift();if(a){if("object"!=typeof a)throw new TypeError(a+"must be non-object");for(const e in a)Ht(a,e)&&(t[e]=a[e])}}return t},Kt=t=>{let e=0;for(let a=0,i=t.length;a<i;a++)e+=t[a].length;const a=new Uint8Array(e);for(let e=0,i=0,n=t.length;e<n;e++){let n=t[e];a.set(n,i),i+=n.length}return a};let Pt=!0;try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(t){Pt=!1}const Yt=new Uint8Array(256);for(let t=0;t<256;t++)Yt[t]=t>=252?6:t>=248?5:t>=240?4:t>=224?3:t>=192?2:1;Yt[254]=Yt[254]=1;var Gt=t=>{if("function"==typeof TextEncoder&&TextEncoder.prototype.encode)return new TextEncoder().encode(t);let e,a,i,n,s,r=t.length,o=0;for(n=0;n<r;n++)a=t.charCodeAt(n),55296==(64512&a)&&n+1<r&&(i=t.charCodeAt(n+1),56320==(64512&i)&&(a=65536+(a-55296<<10)+(i-56320),n++)),o+=a<128?1:a<2048?2:a<65536?3:4;for(e=new Uint8Array(o),s=0,n=0;s<o;n++)a=t.charCodeAt(n),55296==(64512&a)&&n+1<r&&(i=t.charCodeAt(n+1),56320==(64512&i)&&(a=65536+(a-55296<<10)+(i-56320),n++)),a<128?e[s++]=a:a<2048?(e[s++]=192|a>>>6,e[s++]=128|63&a):a<65536?(e[s++]=224|a>>>12,e[s++]=128|a>>>6&63,e[s++]=128|63&a):(e[s++]=240|a>>>18,e[s++]=128|a>>>12&63,e[s++]=128|a>>>6&63,e[s++]=128|63&a);return e},Xt=(t,e)=>{const a=e||t.length;if("function"==typeof TextDecoder&&TextDecoder.prototype.decode)return new TextDecoder().decode(t.subarray(0,e));let i,n;const s=new Array(2*a);for(n=0,i=0;i<a;){let e=t[i++];if(e<128){s[n++]=e;continue}let r=Yt[e];if(r>4)s[n++]=65533,i+=r-1;else{for(e&=2===r?31:3===r?15:7;r>1&&i<a;)e=e<<6|63&t[i++],r--;r>1?s[n++]=65533:e<65536?s[n++]=e:(e-=65536,s[n++]=55296|e>>10&1023,s[n++]=56320|1023&e)}}return((t,e)=>{if(e<65534&&t.subarray&&Pt)return String.fromCharCode.apply(null,t.length===e?t:t.subarray(0,e));let a="";for(let i=0;i<e;i++)a+=String.fromCharCode(t[i]);return a})(s,n)},Wt=(t,e)=>{(e=e||t.length)>t.length&&(e=t.length);let a=e-1;for(;a>=0&&128==(192&t[a]);)a--;return a<0||0===a?e:a+Yt[t[a]]>e?a:e};var qt=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0};const Jt=Object.prototype.toString,{Z_NO_FLUSH:Qt,Z_SYNC_FLUSH:Vt,Z_FULL_FLUSH:$t,Z_FINISH:te,Z_OK:ee,Z_STREAM_END:ae,Z_DEFAULT_COMPRESSION:ie,Z_DEFAULT_STRATEGY:ne,Z_DEFLATED:se}=K;function re(t){this.options=jt({level:ie,method:se,chunkSize:16384,windowBits:15,memLevel:8,strategy:ne},t||{});let e=this.options;e.raw&&e.windowBits>0?e.windowBits=-e.windowBits:e.gzip&&e.windowBits>0&&e.windowBits<16&&(e.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new qt,this.strm.avail_out=0;let a=Mt.deflateInit2(this.strm,e.level,e.method,e.windowBits,e.memLevel,e.strategy);if(a!==ee)throw new Error(j[a]);if(e.header&&Mt.deflateSetHeader(this.strm,e.header),e.dictionary){let t;if(t="string"==typeof e.dictionary?Gt(e.dictionary):"[object ArrayBuffer]"===Jt.call(e.dictionary)?new Uint8Array(e.dictionary):e.dictionary,a=Mt.deflateSetDictionary(this.strm,t),a!==ee)throw new Error(j[a]);this._dict_set=!0}}function oe(t,e){const a=new re(e);if(a.push(t,!0),a.err)throw a.msg||j[a.err];return a.result}re.prototype.push=function(t,e){const a=this.strm,i=this.options.chunkSize;let n,s;if(this.ended)return!1;for(s=e===~~e?e:!0===e?te:Qt,"string"==typeof t?a.input=Gt(t):"[object ArrayBuffer]"===Jt.call(t)?a.input=new Uint8Array(t):a.input=t,a.next_in=0,a.avail_in=a.input.length;;)if(0===a.avail_out&&(a.output=new Uint8Array(i),a.next_out=0,a.avail_out=i),(s===Vt||s===$t)&&a.avail_out<=6)this.onData(a.output.subarray(0,a.next_out)),a.avail_out=0;else{if(n=Mt.deflate(a,s),n===ae)return a.next_out>0&&this.onData(a.output.subarray(0,a.next_out)),n=Mt.deflateEnd(this.strm),this.onEnd(n),this.ended=!0,n===ee;if(0!==a.avail_out){if(s>0&&a.next_out>0)this.onData(a.output.subarray(0,a.next_out)),a.avail_out=0;else if(0===a.avail_in)break}else this.onData(a.output)}return!0},re.prototype.onData=function(t){this.chunks.push(t)},re.prototype.onEnd=function(t){t===ee&&(this.result=Kt(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg};var le={Deflate:re,deflate:oe,deflateRaw:function(t,e){return(e=e||{}).raw=!0,oe(t,e)},gzip:function(t,e){return(e=e||{}).gzip=!0,oe(t,e)},constants:K};const he=16209;var de=function(t,e){let a,i,n,s,r,o,l,h,d,_,f,c,u,w,m,b,g,p,k,v,y,x,z,A;const E=t.state;a=t.next_in,z=t.input,i=a+(t.avail_in-5),n=t.next_out,A=t.output,s=n-(e-t.avail_out),r=n+(t.avail_out-257),o=E.dmax,l=E.wsize,h=E.whave,d=E.wnext,_=E.window,f=E.hold,c=E.bits,u=E.lencode,w=E.distcode,m=(1<<E.lenbits)-1,b=(1<<E.distbits)-1;t:do{c<15&&(f+=z[a++]<<c,c+=8,f+=z[a++]<<c,c+=8),g=u[f&m];e:for(;;){if(p=g>>>24,f>>>=p,c-=p,p=g>>>16&255,0===p)A[n++]=65535&g;else{if(!(16&p)){if(0==(64&p)){g=u[(65535&g)+(f&(1<<p)-1)];continue e}if(32&p){E.mode=16191;break t}t.msg="invalid literal/length code",E.mode=he;break t}k=65535&g,p&=15,p&&(c<p&&(f+=z[a++]<<c,c+=8),k+=f&(1<<p)-1,f>>>=p,c-=p),c<15&&(f+=z[a++]<<c,c+=8,f+=z[a++]<<c,c+=8),g=w[f&b];a:for(;;){if(p=g>>>24,f>>>=p,c-=p,p=g>>>16&255,!(16&p)){if(0==(64&p)){g=w[(65535&g)+(f&(1<<p)-1)];continue a}t.msg="invalid distance code",E.mode=he;break t}if(v=65535&g,p&=15,c<p&&(f+=z[a++]<<c,c+=8,c<p&&(f+=z[a++]<<c,c+=8)),v+=f&(1<<p)-1,v>o){t.msg="invalid distance too far back",E.mode=he;break t}if(f>>>=p,c-=p,p=n-s,v>p){if(p=v-p,p>h&&E.sane){t.msg="invalid distance too far back",E.mode=he;break t}if(y=0,x=_,0===d){if(y+=l-p,p<k){k-=p;do{A[n++]=_[y++]}while(--p);y=n-v,x=A}}else if(d<p){if(y+=l+d-p,p-=d,p<k){k-=p;do{A[n++]=_[y++]}while(--p);if(y=0,d<k){p=d,k-=p;do{A[n++]=_[y++]}while(--p);y=n-v,x=A}}}else if(y+=d-p,p<k){k-=p;do{A[n++]=_[y++]}while(--p);y=n-v,x=A}for(;k>2;)A[n++]=x[y++],A[n++]=x[y++],A[n++]=x[y++],k-=3;k&&(A[n++]=x[y++],k>1&&(A[n++]=x[y++]))}else{y=n-v;do{A[n++]=A[y++],A[n++]=A[y++],A[n++]=A[y++],k-=3}while(k>2);k&&(A[n++]=A[y++],k>1&&(A[n++]=A[y++]))}break}}break}}while(a<i&&n<r);k=c>>3,a-=k,c-=k<<3,f&=(1<<c)-1,t.next_in=a,t.next_out=n,t.avail_in=a<i?i-a+5:5-(a-i),t.avail_out=n<r?r-n+257:257-(n-r),E.hold=f,E.bits=c};const _e=15,fe=new Uint16Array([3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0]),ce=new Uint8Array([16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78]),ue=new Uint16Array([1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0]),we=new Uint8Array([16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64]);var me=(t,e,a,i,n,s,r,o)=>{const l=o.bits;let h,d,_,f,c,u,w=0,m=0,b=0,g=0,p=0,k=0,v=0,y=0,x=0,z=0,A=null;const E=new Uint16Array(16),R=new Uint16Array(16);let Z,U,S,D=null;for(w=0;w<=_e;w++)E[w]=0;for(m=0;m<i;m++)E[e[a+m]]++;for(p=l,g=_e;g>=1&&0===E[g];g--);if(p>g&&(p=g),0===g)return n[s++]=20971520,n[s++]=20971520,o.bits=1,0;for(b=1;b<g&&0===E[b];b++);for(p<b&&(p=b),y=1,w=1;w<=_e;w++)if(y<<=1,y-=E[w],y<0)return-1;if(y>0&&(0===t||1!==g))return-1;for(R[1]=0,w=1;w<_e;w++)R[w+1]=R[w]+E[w];for(m=0;m<i;m++)0!==e[a+m]&&(r[R[e[a+m]]++]=m);if(0===t?(A=D=r,u=20):1===t?(A=fe,D=ce,u=257):(A=ue,D=we,u=0),z=0,m=0,w=b,c=s,k=p,v=0,_=-1,x=1<<p,f=x-1,1===t&&x>852||2===t&&x>592)return 1;for(;;){Z=w-v,r[m]+1<u?(U=0,S=r[m]):r[m]>=u?(U=D[r[m]-u],S=A[r[m]-u]):(U=96,S=0),h=1<<w-v,d=1<<k,b=d;do{d-=h,n[c+(z>>v)+d]=Z<<24|U<<16|S|0}while(0!==d);for(h=1<<w-1;z&h;)h>>=1;if(0!==h?(z&=h-1,z+=h):z=0,m++,0==--E[w]){if(w===g)break;w=e[a+r[m]]}if(w>p&&(z&f)!==_){for(0===v&&(v=p),c+=b,k=w-v,y=1<<k;k+v<g&&(y-=E[k+v],!(y<=0));)k++,y<<=1;if(x+=1<<k,1===t&&x>852||2===t&&x>592)return 1;_=z&f,n[_]=p<<24|k<<16|c-s|0}}return 0!==z&&(n[c+z]=w-v<<24|64<<16|0),o.bits=p,0};const{Z_FINISH:be,Z_BLOCK:ge,Z_TREES:pe,Z_OK:ke,Z_STREAM_END:ve,Z_NEED_DICT:ye,Z_STREAM_ERROR:xe,Z_DATA_ERROR:ze,Z_MEM_ERROR:Ae,Z_BUF_ERROR:Ee,Z_DEFLATED:Re}=K,Ze=16180,Ue=16190,Se=16191,De=16192,Te=16194,Oe=16199,Ie=16200,Fe=16206,Le=16209,Ne=t=>(t>>>24&255)+(t>>>8&65280)+((65280&t)<<8)+((255&t)<<24);function Be(){this.strm=null,this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new Uint16Array(320),this.work=new Uint16Array(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}const Ce=t=>{if(!t)return 1;const e=t.state;return!e||e.strm!==t||e.mode<Ze||e.mode>16211?1:0},Me=t=>{if(Ce(t))return xe;const e=t.state;return t.total_in=t.total_out=e.total=0,t.msg="",e.wrap&&(t.adler=1&e.wrap),e.mode=Ze,e.last=0,e.havedict=0,e.flags=-1,e.dmax=32768,e.head=null,e.hold=0,e.bits=0,e.lencode=e.lendyn=new Int32Array(852),e.distcode=e.distdyn=new Int32Array(592),e.sane=1,e.back=-1,ke},He=t=>{if(Ce(t))return xe;const e=t.state;return e.wsize=0,e.whave=0,e.wnext=0,Me(t)},je=(t,e)=>{let a;if(Ce(t))return xe;const i=t.state;return e<0?(a=0,e=-e):(a=5+(e>>4),e<48&&(e&=15)),e&&(e<8||e>15)?xe:(null!==i.window&&i.wbits!==e&&(i.window=null),i.wrap=a,i.wbits=e,He(t))},Ke=(t,e)=>{if(!t)return xe;const a=new Be;t.state=a,a.strm=t,a.window=null,a.mode=Ze;const i=je(t,e);return i!==ke&&(t.state=null),i};let Pe,Ye,Ge=!0;const Xe=t=>{if(Ge){Pe=new Int32Array(512),Ye=new Int32Array(32);let e=0;for(;e<144;)t.lens[e++]=8;for(;e<256;)t.lens[e++]=9;for(;e<280;)t.lens[e++]=7;for(;e<288;)t.lens[e++]=8;for(me(1,t.lens,0,288,Pe,0,t.work,{bits:9}),e=0;e<32;)t.lens[e++]=5;me(2,t.lens,0,32,Ye,0,t.work,{bits:5}),Ge=!1}t.lencode=Pe,t.lenbits=9,t.distcode=Ye,t.distbits=5},We=(t,e,a,i)=>{let n;const s=t.state;return null===s.window&&(s.wsize=1<<s.wbits,s.wnext=0,s.whave=0,s.window=new Uint8Array(s.wsize)),i>=s.wsize?(s.window.set(e.subarray(a-s.wsize,a),0),s.wnext=0,s.whave=s.wsize):(n=s.wsize-s.wnext,n>i&&(n=i),s.window.set(e.subarray(a-i,a-i+n),s.wnext),(i-=n)?(s.window.set(e.subarray(a-i,a),0),s.wnext=i,s.whave=s.wsize):(s.wnext+=n,s.wnext===s.wsize&&(s.wnext=0),s.whave<s.wsize&&(s.whave+=n))),0};var qe={inflateReset:He,inflateReset2:je,inflateResetKeep:Me,inflateInit:t=>Ke(t,15),inflateInit2:Ke,inflate:(t,e)=>{let a,i,n,s,r,o,l,h,d,_,f,c,u,w,m,b,g,p,k,v,y,x,z=0;const A=new Uint8Array(4);let E,R;const Z=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);if(Ce(t)||!t.output||!t.input&&0!==t.avail_in)return xe;a=t.state,a.mode===Se&&(a.mode=De),r=t.next_out,n=t.output,l=t.avail_out,s=t.next_in,i=t.input,o=t.avail_in,h=a.hold,d=a.bits,_=o,f=l,x=ke;t:for(;;)switch(a.mode){case Ze:if(0===a.wrap){a.mode=De;break}for(;d<16;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}if(2&a.wrap&&35615===h){0===a.wbits&&(a.wbits=15),a.check=0,A[0]=255&h,A[1]=h>>>8&255,a.check=H(a.check,A,2,0),h=0,d=0,a.mode=16181;break}if(a.head&&(a.head.done=!1),!(1&a.wrap)||(((255&h)<<8)+(h>>8))%31){t.msg="incorrect header check",a.mode=Le;break}if((15&h)!==Re){t.msg="unknown compression method",a.mode=Le;break}if(h>>>=4,d-=4,y=8+(15&h),0===a.wbits&&(a.wbits=y),y>15||y>a.wbits){t.msg="invalid window size",a.mode=Le;break}a.dmax=1<<a.wbits,a.flags=0,t.adler=a.check=1,a.mode=512&h?16189:Se,h=0,d=0;break;case 16181:for(;d<16;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}if(a.flags=h,(255&a.flags)!==Re){t.msg="unknown compression method",a.mode=Le;break}if(57344&a.flags){t.msg="unknown header flags set",a.mode=Le;break}a.head&&(a.head.text=h>>8&1),512&a.flags&&4&a.wrap&&(A[0]=255&h,A[1]=h>>>8&255,a.check=H(a.check,A,2,0)),h=0,d=0,a.mode=16182;case 16182:for(;d<32;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}a.head&&(a.head.time=h),512&a.flags&&4&a.wrap&&(A[0]=255&h,A[1]=h>>>8&255,A[2]=h>>>16&255,A[3]=h>>>24&255,a.check=H(a.check,A,4,0)),h=0,d=0,a.mode=16183;case 16183:for(;d<16;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}a.head&&(a.head.xflags=255&h,a.head.os=h>>8),512&a.flags&&4&a.wrap&&(A[0]=255&h,A[1]=h>>>8&255,a.check=H(a.check,A,2,0)),h=0,d=0,a.mode=16184;case 16184:if(1024&a.flags){for(;d<16;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}a.length=h,a.head&&(a.head.extra_len=h),512&a.flags&&4&a.wrap&&(A[0]=255&h,A[1]=h>>>8&255,a.check=H(a.check,A,2,0)),h=0,d=0}else a.head&&(a.head.extra=null);a.mode=16185;case 16185:if(1024&a.flags&&(c=a.length,c>o&&(c=o),c&&(a.head&&(y=a.head.extra_len-a.length,a.head.extra||(a.head.extra=new Uint8Array(a.head.extra_len)),a.head.extra.set(i.subarray(s,s+c),y)),512&a.flags&&4&a.wrap&&(a.check=H(a.check,i,c,s)),o-=c,s+=c,a.length-=c),a.length))break t;a.length=0,a.mode=16186;case 16186:if(2048&a.flags){if(0===o)break t;c=0;do{y=i[s+c++],a.head&&y&&a.length<65536&&(a.head.name+=String.fromCharCode(y))}while(y&&c<o);if(512&a.flags&&4&a.wrap&&(a.check=H(a.check,i,c,s)),o-=c,s+=c,y)break t}else a.head&&(a.head.name=null);a.length=0,a.mode=16187;case 16187:if(4096&a.flags){if(0===o)break t;c=0;do{y=i[s+c++],a.head&&y&&a.length<65536&&(a.head.comment+=String.fromCharCode(y))}while(y&&c<o);if(512&a.flags&&4&a.wrap&&(a.check=H(a.check,i,c,s)),o-=c,s+=c,y)break t}else a.head&&(a.head.comment=null);a.mode=16188;case 16188:if(512&a.flags){for(;d<16;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}if(4&a.wrap&&h!==(65535&a.check)){t.msg="header crc mismatch",a.mode=Le;break}h=0,d=0}a.head&&(a.head.hcrc=a.flags>>9&1,a.head.done=!0),t.adler=a.check=0,a.mode=Se;break;case 16189:for(;d<32;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}t.adler=a.check=Ne(h),h=0,d=0,a.mode=Ue;case Ue:if(0===a.havedict)return t.next_out=r,t.avail_out=l,t.next_in=s,t.avail_in=o,a.hold=h,a.bits=d,ye;t.adler=a.check=1,a.mode=Se;case Se:if(e===ge||e===pe)break t;case De:if(a.last){h>>>=7&d,d-=7&d,a.mode=Fe;break}for(;d<3;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}switch(a.last=1&h,h>>>=1,d-=1,3&h){case 0:a.mode=16193;break;case 1:if(Xe(a),a.mode=Oe,e===pe){h>>>=2,d-=2;break t}break;case 2:a.mode=16196;break;case 3:t.msg="invalid block type",a.mode=Le}h>>>=2,d-=2;break;case 16193:for(h>>>=7&d,d-=7&d;d<32;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}if((65535&h)!=(h>>>16^65535)){t.msg="invalid stored block lengths",a.mode=Le;break}if(a.length=65535&h,h=0,d=0,a.mode=Te,e===pe)break t;case Te:a.mode=16195;case 16195:if(c=a.length,c){if(c>o&&(c=o),c>l&&(c=l),0===c)break t;n.set(i.subarray(s,s+c),r),o-=c,s+=c,l-=c,r+=c,a.length-=c;break}a.mode=Se;break;case 16196:for(;d<14;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}if(a.nlen=257+(31&h),h>>>=5,d-=5,a.ndist=1+(31&h),h>>>=5,d-=5,a.ncode=4+(15&h),h>>>=4,d-=4,a.nlen>286||a.ndist>30){t.msg="too many length or distance symbols",a.mode=Le;break}a.have=0,a.mode=16197;case 16197:for(;a.have<a.ncode;){for(;d<3;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}a.lens[Z[a.have++]]=7&h,h>>>=3,d-=3}for(;a.have<19;)a.lens[Z[a.have++]]=0;if(a.lencode=a.lendyn,a.lenbits=7,E={bits:a.lenbits},x=me(0,a.lens,0,19,a.lencode,0,a.work,E),a.lenbits=E.bits,x){t.msg="invalid code lengths set",a.mode=Le;break}a.have=0,a.mode=16198;case 16198:for(;a.have<a.nlen+a.ndist;){for(;z=a.lencode[h&(1<<a.lenbits)-1],m=z>>>24,b=z>>>16&255,g=65535&z,!(m<=d);){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}if(g<16)h>>>=m,d-=m,a.lens[a.have++]=g;else{if(16===g){for(R=m+2;d<R;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}if(h>>>=m,d-=m,0===a.have){t.msg="invalid bit length repeat",a.mode=Le;break}y=a.lens[a.have-1],c=3+(3&h),h>>>=2,d-=2}else if(17===g){for(R=m+3;d<R;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}h>>>=m,d-=m,y=0,c=3+(7&h),h>>>=3,d-=3}else{for(R=m+7;d<R;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}h>>>=m,d-=m,y=0,c=11+(127&h),h>>>=7,d-=7}if(a.have+c>a.nlen+a.ndist){t.msg="invalid bit length repeat",a.mode=Le;break}for(;c--;)a.lens[a.have++]=y}}if(a.mode===Le)break;if(0===a.lens[256]){t.msg="invalid code -- missing end-of-block",a.mode=Le;break}if(a.lenbits=9,E={bits:a.lenbits},x=me(1,a.lens,0,a.nlen,a.lencode,0,a.work,E),a.lenbits=E.bits,x){t.msg="invalid literal/lengths set",a.mode=Le;break}if(a.distbits=6,a.distcode=a.distdyn,E={bits:a.distbits},x=me(2,a.lens,a.nlen,a.ndist,a.distcode,0,a.work,E),a.distbits=E.bits,x){t.msg="invalid distances set",a.mode=Le;break}if(a.mode=Oe,e===pe)break t;case Oe:a.mode=Ie;case Ie:if(o>=6&&l>=258){t.next_out=r,t.avail_out=l,t.next_in=s,t.avail_in=o,a.hold=h,a.bits=d,de(t,f),r=t.next_out,n=t.output,l=t.avail_out,s=t.next_in,i=t.input,o=t.avail_in,h=a.hold,d=a.bits,a.mode===Se&&(a.back=-1);break}for(a.back=0;z=a.lencode[h&(1<<a.lenbits)-1],m=z>>>24,b=z>>>16&255,g=65535&z,!(m<=d);){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}if(b&&0==(240&b)){for(p=m,k=b,v=g;z=a.lencode[v+((h&(1<<p+k)-1)>>p)],m=z>>>24,b=z>>>16&255,g=65535&z,!(p+m<=d);){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}h>>>=p,d-=p,a.back+=p}if(h>>>=m,d-=m,a.back+=m,a.length=g,0===b){a.mode=16205;break}if(32&b){a.back=-1,a.mode=Se;break}if(64&b){t.msg="invalid literal/length code",a.mode=Le;break}a.extra=15&b,a.mode=16201;case 16201:if(a.extra){for(R=a.extra;d<R;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}a.length+=h&(1<<a.extra)-1,h>>>=a.extra,d-=a.extra,a.back+=a.extra}a.was=a.length,a.mode=16202;case 16202:for(;z=a.distcode[h&(1<<a.distbits)-1],m=z>>>24,b=z>>>16&255,g=65535&z,!(m<=d);){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}if(0==(240&b)){for(p=m,k=b,v=g;z=a.distcode[v+((h&(1<<p+k)-1)>>p)],m=z>>>24,b=z>>>16&255,g=65535&z,!(p+m<=d);){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}h>>>=p,d-=p,a.back+=p}if(h>>>=m,d-=m,a.back+=m,64&b){t.msg="invalid distance code",a.mode=Le;break}a.offset=g,a.extra=15&b,a.mode=16203;case 16203:if(a.extra){for(R=a.extra;d<R;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}a.offset+=h&(1<<a.extra)-1,h>>>=a.extra,d-=a.extra,a.back+=a.extra}if(a.offset>a.dmax){t.msg="invalid distance too far back",a.mode=Le;break}a.mode=16204;case 16204:if(0===l)break t;if(c=f-l,a.offset>c){if(c=a.offset-c,c>a.whave&&a.sane){t.msg="invalid distance too far back",a.mode=Le;break}c>a.wnext?(c-=a.wnext,u=a.wsize-c):u=a.wnext-c,c>a.length&&(c=a.length),w=a.window}else w=n,u=r-a.offset,c=a.length;c>l&&(c=l),l-=c,a.length-=c;do{n[r++]=w[u++]}while(--c);0===a.length&&(a.mode=Ie);break;case 16205:if(0===l)break t;n[r++]=a.length,l--,a.mode=Ie;break;case Fe:if(a.wrap){for(;d<32;){if(0===o)break t;o--,h|=i[s++]<<d,d+=8}if(f-=l,t.total_out+=f,a.total+=f,4&a.wrap&&f&&(t.adler=a.check=a.flags?H(a.check,n,f,r-f):C(a.check,n,f,r-f)),f=l,4&a.wrap&&(a.flags?h:Ne(h))!==a.check){t.msg="incorrect data check",a.mode=Le;break}h=0,d=0}a.mode=16207;case 16207:if(a.wrap&&a.flags){for(;d<32;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8}if(4&a.wrap&&h!==(4294967295&a.total)){t.msg="incorrect length check",a.mode=Le;break}h=0,d=0}a.mode=16208;case 16208:x=ve;break t;case Le:x=ze;break t;case 16210:return Ae;default:return xe}return t.next_out=r,t.avail_out=l,t.next_in=s,t.avail_in=o,a.hold=h,a.bits=d,(a.wsize||f!==t.avail_out&&a.mode<Le&&(a.mode<Fe||e!==be))&&We(t,t.output,t.next_out,f-t.avail_out),_-=t.avail_in,f-=t.avail_out,t.total_in+=_,t.total_out+=f,a.total+=f,4&a.wrap&&f&&(t.adler=a.check=a.flags?H(a.check,n,f,t.next_out-f):C(a.check,n,f,t.next_out-f)),t.data_type=a.bits+(a.last?64:0)+(a.mode===Se?128:0)+(a.mode===Oe||a.mode===Te?256:0),(0===_&&0===f||e===be)&&x===ke&&(x=Ee),x},inflateEnd:t=>{if(Ce(t))return xe;let e=t.state;return e.window&&(e.window=null),t.state=null,ke},inflateGetHeader:(t,e)=>{if(Ce(t))return xe;const a=t.state;return 0==(2&a.wrap)?xe:(a.head=e,e.done=!1,ke)},inflateSetDictionary:(t,e)=>{const a=e.length;let i,n,s;return Ce(t)?xe:(i=t.state,0!==i.wrap&&i.mode!==Ue?xe:i.mode===Ue&&(n=1,n=C(n,e,a,0),n!==i.check)?ze:(s=We(t,e,a,a),s?(i.mode=16210,Ae):(i.havedict=1,ke)))},inflateInfo:"pako inflate (from Nodeca project)"};var Je=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1};const Qe=Object.prototype.toString,{Z_NO_FLUSH:Ve,Z_FINISH:$e,Z_OK:ta,Z_STREAM_END:ea,Z_NEED_DICT:aa,Z_STREAM_ERROR:ia,Z_DATA_ERROR:na,Z_MEM_ERROR:sa}=K;function ra(t){this.options=jt({chunkSize:65536,windowBits:15,to:""},t||{});const e=this.options;e.raw&&e.windowBits>=0&&e.windowBits<16&&(e.windowBits=-e.windowBits,0===e.windowBits&&(e.windowBits=-15)),!(e.windowBits>=0&&e.windowBits<16)||t&&t.windowBits||(e.windowBits+=32),e.windowBits>15&&e.windowBits<48&&0==(15&e.windowBits)&&(e.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new qt,this.strm.avail_out=0;let a=qe.inflateInit2(this.strm,e.windowBits);if(a!==ta)throw new Error(j[a]);if(this.header=new Je,qe.inflateGetHeader(this.strm,this.header),e.dictionary&&("string"==typeof e.dictionary?e.dictionary=Gt(e.dictionary):"[object ArrayBuffer]"===Qe.call(e.dictionary)&&(e.dictionary=new Uint8Array(e.dictionary)),e.raw&&(a=qe.inflateSetDictionary(this.strm,e.dictionary),a!==ta)))throw new Error(j[a])}function oa(t,e){const a=new ra(e);if(a.push(t),a.err)throw a.msg||j[a.err];return a.result}ra.prototype.push=function(t,e){const a=this.strm,i=this.options.chunkSize,n=this.options.dictionary;let s,r,o;if(this.ended)return!1;for(r=e===~~e?e:!0===e?$e:Ve,"[object ArrayBuffer]"===Qe.call(t)?a.input=new Uint8Array(t):a.input=t,a.next_in=0,a.avail_in=a.input.length;;){for(0===a.avail_out&&(a.output=new Uint8Array(i),a.next_out=0,a.avail_out=i),s=qe.inflate(a,r),s===aa&&n&&(s=qe.inflateSetDictionary(a,n),s===ta?s=qe.inflate(a,r):s===na&&(s=aa));a.avail_in>0&&s===ea&&a.state.wrap>0&&0!==t[a.next_in];)qe.inflateReset(a),s=qe.inflate(a,r);switch(s){case ia:case na:case aa:case sa:return this.onEnd(s),this.ended=!0,!1}if(o=a.avail_out,a.next_out&&(0===a.avail_out||s===ea))if("string"===this.options.to){let t=Wt(a.output,a.next_out),e=a.next_out-t,n=Xt(a.output,t);a.next_out=e,a.avail_out=i-e,e&&a.output.set(a.output.subarray(t,t+e),0),this.onData(n)}else this.onData(a.output.length===a.next_out?a.output:a.output.subarray(0,a.next_out));if(s!==ta||0!==o){if(s===ea)return s=qe.inflateEnd(this.strm),this.onEnd(s),this.ended=!0,!0;if(0===a.avail_in)break}}return!0},ra.prototype.onData=function(t){this.chunks.push(t)},ra.prototype.onEnd=function(t){t===ta&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=Kt(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg};var la={Inflate:ra,inflate:oa,inflateRaw:function(t,e){return(e=e||{}).raw=!0,oa(t,e)},ungzip:oa,constants:K};const{Deflate:ha,deflate:da,deflateRaw:_a,gzip:fa}=le,{Inflate:ca,inflate:ua,inflateRaw:wa,ungzip:ma}=la;var ba=ha,ga=da,pa=_a,ka=fa,va=ca,ya=ua,xa=wa,za=ma,Aa=K,Ea={Deflate:ba,deflate:ga,deflateRaw:pa,gzip:ka,Inflate:va,inflate:ya,inflateRaw:xa,ungzip:za,constants:Aa};t.Deflate=ba,t.Inflate=va,t.constants=Aa,t.default=Ea,t.deflate=ga,t.deflateRaw=pa,t.gzip=ka,t.inflate=ya,t.inflateRaw=xa,t.ungzip=za,Object.defineProperty(t,"__esModule",{value:!0})});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"use strict";const http=require("http");function parseMcpBody(body){const trimmed=(body||"").trim();if(!trimmed)return{};if(trimmed.startsWith("{"))return JSON.parse(trimmed);const data=trimmed.split("\n").filter(line=>line.startsWith("data:")).map(line=>line.slice(5).trim()).join("");if(data)return JSON.parse(data);return{raw:trimmed}}let nextId=1;/**
|
|
2
|
+
* 调同一预览进程上的 MCP assets-refresh。
|
|
3
|
+
* dir 默认 db://assets;CLI 没有磁盘 watch,改文件后必须走这条。
|
|
4
|
+
*/function refreshAssets(port,dir="db://assets",{timeout=60000}={}){const payload=JSON.stringify({jsonrpc:"2.0",id:nextId++,method:"tools/call",params:{name:"assets-refresh",arguments:{dir}}});return new Promise((resolve,reject)=>{const req=http.request({hostname:"127.0.0.1",port,path:"/mcp",method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json, text/event-stream","Content-Length":Buffer.byteLength(payload)},timeout},res=>{const chunks=[];res.on("data",c=>chunks.push(c));res.on("end",()=>{const body=Buffer.concat(chunks).toString("utf8");let parsed={};try{parsed=parseMcpBody(body)}catch{parsed={raw:body}}resolve({status:res.statusCode||0,body,parsed})})});req.on("timeout",()=>{req.destroy();reject(new Error(`MCP assets-refresh timeout :${port}`))});req.on("error",reject);req.write(payload);req.end()})}module.exports={refreshAssets};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";const fs=require("fs");const path=require("path");const{load}=require("cheerio");const{deflate}=require("pako");const{getResourceMapper,getBase64FromFile}=require("./fs");const{TRANSPARENT_GIF}=require("./constants");function readInject(rel){return fs.readFileSync(path.join(__dirname,rel),"utf8")}function paddingStyleTags($,originPkgPath,enableSplash){$("link[type=\"text/css\"]").toArray().forEach(item=>{const href=$(item).attr("href");if(!href)return;const cssPath=path.join(originPkgPath,href);if(!fs.existsSync(cssPath))return;const cssStr=fs.readFileSync(cssPath,"utf-8");$(`<style>${cssStr}</style>`).appendTo("head")});if(!enableSplash){$("<style>#splash .progress-bar{opacity:0;visibility:hidden}</style>").appendTo("head")}$("link[type=\"text/css\"]").remove();$("head").find("style").each((_index,elem)=>{const cssUrlReg=/url\("?'?.*"?'?\)/g;let styleTagStr=$(elem).html()||"";const matchStrList=styleTagStr.match(cssUrlReg);if(!matchStrList)return;matchStrList.forEach(str=>{const imgUrl=str.replace(/"|'|url|\(|\)/g,"");const imgPath=path.join(originPkgPath,imgUrl);const imgBase64=enableSplash&&fs.existsSync(imgPath)?getBase64FromFile(imgPath):TRANSPARENT_GIF;styleTagStr=styleTagStr.replace(str,`url(${imgBase64})`)});$(elem).html(styleTagStr)})}function paddingScriptTags($,originPkgPath){let scriptTags="";$("script[type=\"systemjs-importmap\"]").toArray().forEach(item=>{const href=$(item).attr("src");if(!href)return;const srcPath=path.join(originPkgPath,href);if(!fs.existsSync(srcPath))return;scriptTags+=`<script type="systemjs-importmap">${fs.readFileSync(srcPath,"utf-8")}</script>`});$("head link").remove();$("body script").remove();if(scriptTags)$(scriptTags).appendTo("body")}function getJsListFromSettingsJson(data){const jsonData=JSON.parse(data);jsonData.plugins={jsList:[],...jsonData.plugins};const jsList=[...jsonData.plugins.jsList];jsonData.plugins.jsList=[];return{jsList,settingsData:jsonData}}function getJsListFromSettingsJs(data){const originData={jsList:[],settingsData:data};const settingsStrList=data.split("jsList:");if(settingsStrList.length<2)return originData;const settingsStr=settingsStrList.pop()||"";const jsListStrRegExp=/\[[^\]]*\]/.exec(settingsStr);if(!jsListStrRegExp)return originData;const jsListStr=jsListStrRegExp[0];return{jsList:JSON.parse(jsListStr),settingsData:data.replace(jsListStr,"[]")}}/**
|
|
2
|
+
* Inline a Creator 3.x web-mobile folder into a single HTML file.
|
|
3
|
+
* @param {string} originPkgPath - Absolute path to build/web-mobile
|
|
4
|
+
* @param {string} singleFilePath - Output html path
|
|
5
|
+
* @param {{ enableSplash?: boolean, isZip?: boolean }} [opts]
|
|
6
|
+
*/async function mergeWebMobile(originPkgPath,singleFilePath,opts={}){const enableSplash=opts.enableSplash!==false;const isZip=opts.isZip!==false;const htmlPath=path.join(originPkgPath,"index.html");if(!fs.existsSync(htmlPath)){throw new Error(`[cocos] web-mobile index.html not found: ${htmlPath}`)}const $=load(fs.readFileSync(htmlPath,"utf-8"));paddingStyleTags($,originPkgPath,enableSplash);paddingScriptTags($,originPkgPath);let pluginJsList=[];const{resMapper}=await getResourceMapper({dirPath:originPkgPath,rmHttp:true,mountCbFn:(objKey,data)=>{if(objKey.indexOf("src/settings.json")!==-1){var _settingsData$splashS;const{jsList,settingsData}=getJsListFromSettingsJson(data);pluginJsList=jsList;if(!enableSplash&&settingsData!==null&&settingsData!==void 0&&(_settingsData$splashS=settingsData.splashScreen)!==null&&_settingsData$splashS!==void 0&&_settingsData$splashS.totalTime){settingsData.splashScreen.totalTime=0}return JSON.stringify(settingsData)}if(objKey.indexOf("src/settings.js")!==-1){const{jsList,settingsData}=getJsListFromSettingsJs(data);pluginJsList=jsList;return settingsData}return data}});let resStr=JSON.stringify(resMapper);let compDiff=0;if(isZip){const zip=deflate(resStr);const zipStr=Buffer.from(zip).toString("base64");console.log("[cocos] origin pkg",resStr.length,"compressed",zipStr.length);if(zipStr.length<resStr.length){compDiff=resStr.length-zipStr.length;resStr=zipStr}}if(compDiff>0){$(`<script data-id="jszip">${readInject("injects/libs/pako.js")}</script>`).appendTo("body");$(`<script data-id="adapter-zip-0">window.__adapter_zip__="${resStr}";</script>`).appendTo("body")}else{$(`<script data-id="adapter-resource-0">window.__adapter_resource__=${resStr}</script>`).appendTo("body")}$(`<script data-id="adapter-plugins">window.__adapter_plugins__=${JSON.stringify(pluginJsList)}</script>`).appendTo("body");$(`<script data-id="adapter-init">${readInject("injects/3x/init.js")}</script>`).appendTo("body");$(`<script data-id="adapter-main">${readInject("injects/3x/main.js")}</script>`).appendTo("body");fs.mkdirSync(path.dirname(singleFilePath),{recursive:true});fs.writeFileSync(singleFilePath,$.html());const kb=(fs.statSync(singleFilePath).size/1024).toFixed(1);console.log(`[cocos] single-file template ${kb}kb → ${singleFilePath}`);return{resMapper,compDiff,singleFilePath}}module.exports={mergeWebMobile};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const fs=require("fs");const path=require("path");const{options}=require("../../options.js");const{mergeOptions}=require("../../utils/mergeOptions.js");const{logOptions}=require("../../utils/logOptions.js");const{resolveCreatorOutputDir}=require("./creator-cli");const{runCocosEngineBuild}=require("./cli-build");const{mergeWebMobile}=require("./merge");const{detectCurrentTheme,loadThemePayload,writeGeneratedThemeModule}=require("./theme-assets");const{emitChannel}=require("../../artifacts/emit");const{isSocialMediaNetwork,stripSocialShareFromDir}=require("./strip-social-share");function resolveWebMobileDir(root,buildOptions){const cocos=buildOptions.cocos||{};const fromCreator=resolveCreatorOutputDir(root,cocos.buildConfig||"build-configs/web-mobile.json");const explicit=cocos.webMobileDir?path.resolve(root,cocos.webMobileDir):null;if(cocos.skipEngineBuild){return explicit||fromCreator||path.resolve(root,"dist/web-mobile")}if(fromCreator){if(explicit&&explicit!==fromCreator){console.warn(`[cocos] webMobileDir (${path.relative(root,explicit)}) != Creator output (${path.relative(root,fromCreator)}); using Creator buildPath/outputName`)}return fromCreator}return explicit||path.resolve(root,"dist/web-mobile")}async function mergeTemplate(root,buildOptions){const webMobileDir=resolveWebMobileDir(root,buildOptions);const singleFilePath=path.join(root,"build","single-file-3x.html");await mergeWebMobile(webMobileDir,singleFilePath);return fs.readFileSync(singleFilePath,"utf8")}function resolveThemeName(root,buildOptions,themeConfig){return buildOptions.themeName||detectCurrentTheme(root,themeConfig)||"default"}function loadBuildsThemeConfig(root){const configPath=path.join(root,"builds.config.js");if(!fs.existsSync(configPath))return{sourceDir:"src/theme",entryFile:"src/theme/index.ts"};try{delete require.cache[configPath];const config=require(configPath);return{sourceDir:"src/theme",entryFile:"src/theme/index.ts",...(config.themes||{})}}catch{return{sourceDir:"src/theme",entryFile:"src/theme/index.ts"}}}function stripPackedChannel(outDir,network){if(isSocialMediaNetwork(network)){console.log("[cocos] social_media: keep AiX hooks (inject IIFE later)");return}const packed=stripSocialShareFromDir(outDir);console.log(`[cocos] stripped social-share from ${packed.changed}/${packed.files} files in ${path.relative(process.cwd(),outDir)||"."}`)}async function prepareCocosTemplate(customOptions){const buildOptions=mergeOptions(options,customOptions);const root=process.cwd();await runCocosEngineBuild(root,buildOptions);return mergeTemplate(root,buildOptions)}async function emitCocosChannel(templateHtml,customOptions){const buildOptions=mergeOptions(options,customOptions);const root=process.cwd();const themeConfig=loadBuildsThemeConfig(root);const themeName=resolveThemeName(root,buildOptions,themeConfig);let themePayload={themeName,mergedData:{},i18nOverride:{},assetRecordByPath:{}};try{themePayload=loadThemePayload(root,themeName,themeConfig)}catch(err){console.warn(`[cocos] theme payload skipped: ${err.message}`)}const generated=buildOptions.cocos&&buildOptions.cocos.generatedThemeFile||"assets/scripts/platform/theme.generated.ts";writeGeneratedThemeModule(path.join(root,generated),themePayload);const outDir=path.resolve(root,buildOptions.outDir);await emitChannel({templateHtml,buildOptions,themePayload,outDir});stripPackedChannel(outDir,buildOptions.network)}async function runCocosBuild(customOptions){const buildOptions=mergeOptions(options,customOptions);logOptions(buildOptions);const templateHtml=await prepareCocosTemplate(buildOptions);await emitCocosChannel(templateHtml,customOptions)}async function packCocosBatch({config,themes,tasks,outputDir,projectRoot,isChannelFold2Zip}){const buildOptionsBase=mergeOptions(options,{engine:"cocos",googlePlayUrl:config.googlePlayUrl,appStoreUrl:config.appStoreUrl,isChannelFold2Zip,obfuscateLevel:config.obfuscateLevel,fflateCompression:config.fflateCompression});if(config.cocos)Object.assign(buildOptionsBase.cocos,config.cocos);await runCocosEngineBuild(projectRoot,buildOptionsBase);const templateHtml=await mergeTemplate(projectRoot,buildOptionsBase);const themeConfig=config.themes||loadBuildsThemeConfig(projectRoot);const results=[];for(const theme of themes){let themePayload;try{themePayload=loadThemePayload(projectRoot,theme,themeConfig)}catch(err){console.error(`[cocos] theme ${theme}: ${err.message}`);for(const task of tasks){results.push({success:false,theme,channel:task.channel,orientation:task.orientation,error:err.message})}continue}for(const task of tasks){const orientationValue=task.orientation||"both";const fileName=config.naming&&typeof config.naming.generator==="function"?config.naming.generator(theme,task.channel):`${theme}-${task.channel}`;const tempDir=path.join(projectRoot,`${config.build.tempDirPrefix||"dist-temp"}-cocos-${theme}-${task.channel}-${orientationValue}`);try{const channelOptions=mergeOptions(buildOptionsBase,{network:task.channel,playcraftOrientationValue:orientationValue,filename:fileName||options.filename,outDir:tempDir,isChannelFold2Zip});await emitChannel({templateHtml,buildOptions:channelOptions,themePayload,outDir:tempDir});stripPackedChannel(tempDir,task.channel);const themeDir=path.join(outputDir,theme);fs.mkdirSync(themeDir,{recursive:true});for(const file of fs.readdirSync(tempDir)){const src=path.join(tempDir,file);if(fs.statSync(src).isDirectory())continue;fs.copyFileSync(src,path.join(themeDir,file))}results.push({success:true,theme,channel:task.channel,orientation:orientationValue})}catch(error){results.push({success:false,theme,channel:task.channel,orientation:orientationValue,error:error.message})}finally{if(config.build.cleanTemp!==false&&fs.existsSync(tempDir)){fs.rmSync(tempDir,{recursive:true,force:true})}}}}return results}async function syncThemeForPreview(projectRoot,themeName,themeConfig,generatedRel){const payload=loadThemePayload(projectRoot,themeName,themeConfig);writeGeneratedThemeModule(path.join(projectRoot,generatedRel),payload);return payload}module.exports={runCocosBuild,prepareCocosTemplate,emitCocosChannel,packCocosBatch,mergeTemplate,syncThemeForPreview};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";const fs=require("fs");const path=require("path");/** Creator / cocos CLI 会静态解析这次 import(),不能让 social-share 进模块图。 */const IMPORT_RE=/import\s*\(\s*["']@playcraft\/ads-tracking\/social-share["']\s*\)/g;/** 审核会扫这些硬编码请求;非社媒产物里必须清掉。 */const PACK_TRANSFORMS=[[IMPORT_RE,"Promise.resolve({})"],[/["']@playcraft\/ads-tracking\/social-share["']/g,"\"\""],[/https:\/\/static\.aix\.levelinfinite\.com\/sdk\/aix_track_web_sdk_v2\.js/g,""]];const TEXT_EXTS=new Set([".js",".mjs",".cjs",".html",".htm"]);/** 4.0 预览把 CJS 当严格模块跑,裸 AD_NETWORK 不会落到 window。 */const CJS_DEFINE_KEYS=["AD_NETWORK","AD_PROTOCOL","GOOGLE_PLAY_URL","APP_STORE_URL","BUILD_HASH","LANGUAGE","ORIENTATION","APP","NAME","VERSION"];const CJS_DEFINE_PAD=CJS_DEFINE_KEYS.map(key=>`var ${key} = globalThis.${key};`).join("\n");function padAdsdkCjsGlobals(src){if(src.includes("var AD_NETWORK = globalThis.AD_NETWORK"))return src;if(/^['"]use strict['"];/.test(src)){return src.replace(/^['"]use strict['"];/,line=>`${line}\n${CJS_DEFINE_PAD}`)}return`"use strict";\n${CJS_DEFINE_PAD}\n${src}`}function isSocialMediaNetwork(network){return String(network||"").toLowerCase()==="social_media"}function adsdkCjsPath(projectRoot){return path.join(projectRoot,"node_modules","@playcraft","adsdk","dist","index.js")}/**
|
|
2
|
+
* 把 CJS 里的 social-share import() 收成空 Promise,并垫上 AD_NETWORK 等全局别名。
|
|
3
|
+
* Cocos 4.0 预览按严格模块执行 npm CJS,裸标识符不会落到 window。
|
|
4
|
+
*/function stripAdsdkCjsImport(projectRoot){const file=adsdkCjsPath(projectRoot);if(!fs.existsSync(file)){return{skipped:true,reason:"missing",file}}const src=fs.readFileSync(file,"utf8");const next=padAdsdkCjsGlobals(src.replace(IMPORT_RE,"Promise.resolve({})"));if(src===next){const already=next.includes("Promise.resolve({}).then")&&next.includes("var AD_NETWORK = globalThis.AD_NETWORK");return{skipped:true,reason:already?"already":"not-found",file}}fs.writeFileSync(file,next);return{skipped:false,file}}function stripSocialShareFromText(src){let next=src;for(const[re,replacement]of PACK_TRANSFORMS){next=next.replace(re,replacement)}return next}function walkFiles(dir,out=[]){if(!fs.existsSync(dir))return out;for(const name of fs.readdirSync(dir)){const abs=path.join(dir,name);let stat;try{stat=fs.statSync(abs)}catch{continue}if(stat.isDirectory()){walkFiles(abs,out);continue}if(TEXT_EXTS.has(path.extname(name).toLowerCase()))out.push(abs)}return out}/**
|
|
5
|
+
* 从引擎产物 / 单文件 HTML 里清掉 social-share 与 AiX URL。
|
|
6
|
+
* 仅非 social_media 渠道调用。
|
|
7
|
+
*/function stripSocialShareFromDir(dir){const files=walkFiles(dir);let changed=0;for(const file of files){const src=fs.readFileSync(file,"utf8");const next=stripSocialShareFromText(src);if(src===next)continue;fs.writeFileSync(file,next);changed+=1}return{dir,files:files.length,changed}}module.exports={isSocialMediaNetwork,stripAdsdkCjsImport,padAdsdkCjsGlobals,stripSocialShareFromText,stripSocialShareFromDir};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";const fs=require("fs");const path=require("path");const JSON5=require("json5");const{getBase64FromFile,getAllFilesFromDir}=require("./fs");const{THEME_ASSET_EXT}=require("./constants");const{validateThemeData}=require("../../utils/validateThemeData");function detectCurrentTheme(projectRoot,themeConfig){const entryFile=themeConfig&&themeConfig.entryFile||"src/theme/index.ts";const entryPath=path.join(projectRoot,entryFile);if(!fs.existsSync(entryPath))return null;const content=fs.readFileSync(entryPath,"utf8");const match=content.match(/from\s+['"]\.\/([^'"]+)['"]/);return match?match[1]:null}function collectDirAssets(assetsDir,keyPrefix){const map={};if(!fs.existsSync(assetsDir))return map;const root=assetsDir.replace(/\\/g,"/");for(const filePath of getAllFilesFromDir(assetsDir)){if(!THEME_ASSET_EXT.test(filePath))continue;const rel=filePath.replace(/\\/g,"/").slice(root.length).replace(/^\//,"");map[`${keyPrefix}${rel}`]=getBase64FromFile(filePath)}return map}function collectReferencedFiles(projectRoot,sourceDir,themeName,mergedData,assetRecord){if(!mergedData||typeof mergedData!=="object")return;const themeRoot=path.join(projectRoot,sourceDir,themeName);for(const value of Object.values(mergedData)){if(typeof value==="string"){if(assetRecord[value])continue;const rel=value.replace(/^\.\//,"");const candidates=[path.join(themeRoot,rel),path.join(themeRoot,"assets",path.basename(rel)),path.resolve(projectRoot,rel)];const abs=candidates.find(p=>fs.existsSync(p)&&fs.statSync(p).isFile()&&THEME_ASSET_EXT.test(p));if(abs)assetRecord[value]=getBase64FromFile(abs)}else if(value&&typeof value==="object"&&!Array.isArray(value)){collectReferencedFiles(projectRoot,sourceDir,themeName,value,assetRecord)}}}function loadThemeI18n(projectRoot,sourceDir,themeName){const p=path.join(projectRoot,sourceDir,themeName,"theme.i18n.runtime.json5");if(!fs.existsSync(p))return{};try{return JSON5.parse(fs.readFileSync(p,"utf8"))||{}}catch{return{}}}/**
|
|
2
|
+
* Read src/theme json5 + theme/assets the same way Phaser webpack inlines them.
|
|
3
|
+
*/function loadThemePayload(projectRoot,themeName,themeConfig={}){const sourceDir=themeConfig.sourceDir||"src/theme";const{mergedData,errors}=validateThemeData(themeName,projectRoot,themeConfig);if(errors){throw new Error(`Theme "${themeName}" validation failed:\n${errors.join("\n")}`)}const assetsDir=path.join(projectRoot,sourceDir,themeName,"assets");const assetRecordByPath=collectDirAssets(assetsDir,"./assets/");collectReferencedFiles(projectRoot,sourceDir,themeName,mergedData,assetRecordByPath);return{themeName,mergedData:mergedData||{},i18nOverride:loadThemeI18n(projectRoot,sourceDir,themeName),assetRecordByPath}}function writeGeneratedThemeModule(filePath,payload){const header="/* eslint-disable */\n"+"// Generated from src/theme by playable-scripts. Do not edit.\n";const body=`export const THEME_DATA = ${JSON.stringify(payload.mergedData,null,2)} as Record<string, unknown>;\n`+`export const THEME_I18N_OVERRIDE = ${JSON.stringify(payload.i18nOverride,null,2)} as Record<string, Record<string, string>>;\n`+`export const THEME_ASSETS = ${JSON.stringify(payload.assetRecordByPath)} as Record<string, string>;\n`;const next=header+body;if(fs.existsSync(filePath)&&fs.readFileSync(filePath,"utf8")===next){return false}fs.mkdirSync(path.dirname(filePath),{recursive:true});fs.writeFileSync(filePath,next);return true}function syncGeneratedTheme(projectRoot,options={}){const themeConfig=options.themeConfig||{sourceDir:"src/theme",entryFile:"src/theme/index.ts"};const themeName=options.themeName||detectCurrentTheme(projectRoot,themeConfig);if(!themeName)return null;const payload=loadThemePayload(projectRoot,themeName,themeConfig);const rel=options.generatedRel||"assets/scripts/platform/theme.generated.ts";const changed=writeGeneratedThemeModule(path.join(projectRoot,rel),payload);return{themeName,payload,generatedRel:rel,changed}}module.exports={detectCurrentTheme,loadThemePayload,writeGeneratedThemeModule,syncGeneratedTheme,collectDirAssets};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const{allowedExtensions,webpackCommonConfig}=require("./webpack.common.js");const{runBuild,makeWebpackBuildConfig}=require("./webpack.build.js");const{runDev,makeWebpackDevConfig}=require("./webpack.dev.js");const{runViteDev,makeViteDevConfig,json5Plugin,assetInlinePlugin,fontFamilyPlugin}=require("./vite.dev.js");module.exports={allowedExtensions,webpackCommonConfig,runBuild,makeWebpackBuildConfig,runDev,makeWebpackDevConfig,runViteDev,makeViteDevConfig,json5Plugin,assetInlinePlugin,fontFamilyPlugin};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";const path=require("path");const fs=require("fs");const{options}=require("../../options.js");const{mergeOptions}=require("../../utils/mergeOptions.js");const{buildDefines}=require("../../utils/buildDefines.js");const{logOptions}=require("../../utils/logOptions.js");const{getOrGenerateFontCSS}=require("../../utils/fontResolver.js");const{socialMediaVitePlugin}=require("../../plugins/socialMediaVitePlugin.js");// ── 公共 Vite 插件(供项目 vite.config.ts 直接引用) ──
|
|
2
|
+
/** JSON5 文件加载插件 */function json5Plugin(){return{name:"vite-plugin-json5",transform(code,id){if(id.endsWith(".json5")){const JSON5=require("json5");const raw=fs.readFileSync(id,"utf-8");const parsed=JSON5.parse(raw);return{code:`export default ${JSON.stringify(parsed)};`,map:null}}}}}/** 资源内联插件(模拟 webpack 的 asset/inline 行为) */function assetInlinePlugin(){return{name:"vite-plugin-asset-inline",enforce:"pre",transform(code,id){// .atlas 文件 -> base64 data URL
|
|
3
|
+
if(id.endsWith(".atlas")){const content=fs.readFileSync(id);const base64=content.toString("base64");return{code:`export default "data:text/atlas;base64,${base64}";`,map:null}}// .fnt 文件 -> base64 data URL
|
|
4
|
+
if(id.endsWith(".fnt")){const content=fs.readFileSync(id);const base64=content.toString("base64");return{code:`export default "data:text/plain;base64,${base64}";`,map:null}}// .xml 文件 -> 原始文本
|
|
5
|
+
if(id.endsWith(".xml")){const raw=fs.readFileSync(id,"utf-8");return{code:`export default ${JSON.stringify(raw)};`,map:null}}}}}/** 字体注入插件(dev 模式:读取字体文件 base64 内联到 index.html) */function fontFamilyPlugin(){let _themeName=null;let _themeConfig=null;// 检测当前主题名(与 build.js 中 detectCurrentTheme 逻辑一致)
|
|
6
|
+
function detectTheme(){const root=process.cwd();const buildsConfigPath=path.join(root,"builds.config.js");let config={sourceDir:"src/theme",entryFile:"src/theme/index.ts"};if(fs.existsSync(buildsConfigPath)){try{delete require.cache[require.resolve(buildsConfigPath)];const buildsConfig=require(buildsConfigPath);if(buildsConfig.themes){config={...config,...buildsConfig.themes}}}catch(_){/* ignore */}}let name=null;const entryPath=path.join(root,config.entryFile);if(fs.existsSync(entryPath)){const content=fs.readFileSync(entryPath,"utf8");const match=content.match(/from\s+['"]\.\/([^'"]+)['"]/);if(match)name=match[1]}return{themeName:name,themeConfig:config}}return{name:"vite-plugin-font-family",apply:"serve",transformIndexHtml:{order:"pre",handler(){if(_themeName===null){const detected=detectTheme();_themeName=detected.themeName;_themeConfig=detected.themeConfig}if(!_themeName)return"";const css=getOrGenerateFontCSS({projectRoot:process.cwd(),themeName:_themeName,themeConfig:_themeConfig});return css?[{tag:"style",attrs:{"data-playable-fonts":""},children:css.replace(/<\/?style[^>]*>/g,""),injectTo:"head"}]:[]}}}}// ── makeViteDevConfig / runViteDev ──
|
|
7
|
+
/**
|
|
8
|
+
* 创建 Vite 开发配置
|
|
9
|
+
* @param {Partial<import('./index').CLIOptions>} [customOptions] - 自定义选项,会与默认选项合并
|
|
10
|
+
* @param {Record<string, any>} [customDefines] - 额外的 define 常量
|
|
11
|
+
* @param {import('vite').UserConfig} [viteCustomConfig] - 自定义 Vite 配置,会与默认配置合并
|
|
12
|
+
* @returns {import('vite').UserConfig} 最终的 Vite 开发配置
|
|
13
|
+
*/function makeViteDevConfig(customOptions,customDefines,viteCustomConfig){const devOptions=mergeOptions(options,customOptions);logOptions(devOptions);customDefines=customDefines||{};viteCustomConfig=viteCustomConfig||{};// 构建 define 常量(复用 webpack 的 buildDefines 逻辑)
|
|
14
|
+
const defines={...buildDefines(),...devOptions.defines,__DEV__:JSON.stringify(devOptions["dev"]===undefined?true:devOptions["dev"]),...customDefines};// 解析 tsconfig/jsconfig 路径别名
|
|
15
|
+
const tsConfigPath=path.resolve(devOptions.tsConfig||"tsconfig.json");const jsConfigPath=path.resolve(devOptions.jsConfig||"jsconfig.json");let aliasConfig={};// 尝试从 tsconfig/jsconfig 中读取 paths 配置
|
|
16
|
+
let configFilePath=null;if(fs.existsSync(tsConfigPath)){configFilePath=tsConfigPath}else if(fs.existsSync(jsConfigPath)){configFilePath=jsConfigPath}if(configFilePath){try{var _config$compilerOptio;const JSON5=require("json5");const configContent=fs.readFileSync(configFilePath,"utf-8");const config=JSON5.parse(configContent);const paths=((_config$compilerOptio=config.compilerOptions)===null||_config$compilerOptio===void 0?void 0:_config$compilerOptio.paths)||{};for(const[alias,targets]of Object.entries(paths)){var _targets$;// 将 tsconfig paths 格式 "foo/*" -> ["src/foo/*"] 转换为 vite alias
|
|
17
|
+
const cleanAlias=alias.replace("/*","");const cleanTarget=((_targets$=targets[0])===null||_targets$===void 0?void 0:_targets$.replace("/*",""))||"";if(cleanAlias&&cleanTarget){aliasConfig[cleanAlias]=path.resolve(cleanTarget)}}}catch(err){console.log("\x1B[33m\u26A0\uFE0F \u8BFB\u53D6\u8DEF\u5F84\u914D\u7F6E\u5931\u8D25: "+err.message+"\x1B[0m")}}// 默认别名
|
|
18
|
+
aliasConfig={assets:path.resolve("assets"),"@":path.resolve("src"),...aliasConfig};/** @type {import('vite').UserConfig} */const viteConfig={root:".",resolve:{alias:aliasConfig},plugins:[json5Plugin(),assetInlinePlugin(),fontFamilyPlugin(),socialMediaVitePlugin()],define:defines,server:{port:devOptions["port"]||3000,open:devOptions["open"]||false},build:{outDir:devOptions["outDir"]||"dist",sourcemap:true}};// 合并自定义配置
|
|
19
|
+
if(viteCustomConfig){const{plugins:customPlugins,define:customDefine,resolve:customResolve,server:customServer,build:customBuild,...rest}=viteCustomConfig;if(customPlugins){viteConfig.plugins=[...viteConfig.plugins,...customPlugins]}if(customDefine){viteConfig.define={...viteConfig.define,...customDefine}}if(customResolve){viteConfig.resolve={...viteConfig.resolve,...customResolve,alias:{...viteConfig.resolve.alias,...(customResolve.alias||{})}}}if(customServer){viteConfig.server={...viteConfig.server,...customServer}}if(customBuild){viteConfig.build={...viteConfig.build,...customBuild}}Object.assign(viteConfig,rest)}return viteConfig}/**
|
|
20
|
+
* 深度合并两个 Vite 配置对象。override 覆盖 base。
|
|
21
|
+
* 数组会拼接(plugins),其余字段浅覆盖。
|
|
22
|
+
*/function deepMergeViteConfig(base,override){if(!override||typeof override!=="object")return base;const result={...base};for(const key of Object.keys(override)){const bv=base[key];const ov=override[key];if(key==="plugins"&&Array.isArray(bv)&&Array.isArray(ov)){result[key]=[...bv,...ov]}else if(ov!==null&&typeof ov==="object"&&!Array.isArray(ov)&&bv!==null&&typeof bv==="object"&&!Array.isArray(bv)){result[key]={...bv,...ov}}else{result[key]=ov}}return result}/**
|
|
23
|
+
* 尝试加载项目根目录的 vite.config.ts。
|
|
24
|
+
*/async function loadProjectViteConfig(root){const candidates=["vite.config.ts","vite.config.js","vite.config.mjs"];let configPath=null;for(const c of candidates){const p=path.join(root,c);if(fs.existsSync(p)){configPath=p;break}}if(!configPath)return null;const{createRequire}=require("module");let projRequire;try{projRequire=createRequire(path.join(root,"package.json"))}catch(_){projRequire=createRequire(path.join(root,"noop.js"))}let loadConfigFromFile;try{loadConfigFromFile=projRequire("vite").loadConfigFromFile}catch(_){try{loadConfigFromFile=projRequire("vite/dist/node/config").loadConfigFromFile}catch(_2){console.log("\x1B[33m\u26A0\uFE0F [vite] Cannot load project config (loadConfigFromFile unavailable), using scripts default\x1B[0m");return null}}if(!loadConfigFromFile)return null;try{const result=await loadConfigFromFile({command:"serve",mode:process.env.NODE_ENV||"development"},configPath,root);if(result&&result.config){console.log(`[vite] Loaded project config: ${path.relative(root,configPath)}`);return result.config}return null}catch(err){console.log(`\x1b[33m⚠️ [vite] Failed to load ${path.relative(root,configPath)}: ${err.message}, using scripts default\x1b[0m`);return null}}/**
|
|
25
|
+
* 启动 Vite 开发服务器。
|
|
26
|
+
*
|
|
27
|
+
* 配置优先级(从低到高):
|
|
28
|
+
* 1. makeViteDevConfig 构建的默认配置(fontFamilyPlugin、json5Plugin 等)
|
|
29
|
+
* 2. 项目根目录的 vite.config.ts(如果存在,覆盖/扩充默认配置)
|
|
30
|
+
* 3. 传入的 viteConfig / customOptions / customDefines / viteCustomConfig
|
|
31
|
+
*/async function runViteDev(viteConfig,customOptions,customDefines,viteCustomConfig){if(!viteConfig){viteConfig=makeViteDevConfig(customOptions,customDefines,viteCustomConfig)}const projectRoot=process.cwd();const projectConfig=await loadProjectViteConfig(projectRoot);if(projectConfig){viteConfig=deepMergeViteConfig(viteConfig,projectConfig)}const{createRequire}=require("module");const projRequire=createRequire(path.join(projectRoot,"package.json"));const{createServer}=projRequire("vite");const server=await createServer({...viteConfig,configFile:false});await server.listen();server.printUrls()}// ── 导出 ──
|
|
32
|
+
exports.json5Plugin=json5Plugin;exports.assetInlinePlugin=assetInlinePlugin;exports.fontFamilyPlugin=fontFamilyPlugin;exports.makeViteDevConfig=makeViteDevConfig;exports.runViteDev=runViteDev;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";const{merge}=require("webpack-merge");const{webpackCommonConfig}=require("./webpack.common.js");const webpack=require("webpack");const TerserPlugin=require("terser-webpack-plugin");const CopyWebpackPlugin=require("copy-webpack-plugin");const HtmlInlineScriptPlugin=require("html-inline-script-webpack-plugin");const HtmlWebpackPlugin=require("html-webpack-plugin");const MiniCssExtractPlugin=require("mini-css-extract-plugin");const{ZipPlugin}=require("../../plugins/ZipPlugin.js");const{FflateCompressionPlugin}=require("../../plugins/FflateCompressionPlugin.js");const{generateAdikteevHtmlWebpackPluginConfig}=require("../../utils/generateAdikteevHtmlWebpackPluginConfig.js");const{generateBigabidHtmlWebpackPluginConfig}=require("../../utils/generateBigabidHtmlWebpackPluginConfig.js");const{generateInMobiHtmlWebpackPluginConfig}=require("../../utils/generateInMobiHtmlWebpackPluginConfig.js");const path=require("path");const{mergeOptions}=require("../../utils/mergeOptions.js");const{options}=require("../../options.js");const{buildDefines}=require("../../utils/buildDefines.js");const{buildTemplateString}=require("../../utils/buildTemplateString.js");const{logOptions}=require("../../utils/logOptions.js");const{injectSDKPlugins}=require("../../utils/injectSDKPlugins.js");const{resolveChannelFold2Zip}=require("../../utils/resolveChannelFold2Zip.js");const{getPlaycraftOrientationSuffix}=require("../../utils/getPlaycraftOrientationSuffix.js");const{PlaycraftOrientationInjectorPlugin}=require("../../plugins/PlaycraftOrientationInjectorPlugin.js");const META={COMMON_CHARSET:"utf-8",COMMON_VIEWPORT:"width=device-width,initial-scale=1.0,viewport-fit=cover,maximum-scale=1.0,user-scalable=no",MINTEGRAL_VIEWPORT:"width=device-width,user-scalable=no,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0"};const FontFamily={LIFTOFF:"<style>body{font-family:Roboto,\"Helvetica Neue\",-apple-system,BlinkMacSystemFont,sans-serif}</style>"};/**
|
|
2
|
+
* HtmlWebpackPlugin beforeEmit 钩子。
|
|
3
|
+
* 在最终 HTML 输出前统一修正 meta 标签:
|
|
4
|
+
* - charset → 统一小写 utf-8
|
|
5
|
+
* - viewport → 统一替换为渠道通道规范值
|
|
6
|
+
* 项目模板无需关心 meta 标签,全部由 devkit 构建时自动处理。
|
|
7
|
+
*/class MetaTagOverridePlugin{constructor(adNetwork){this.adNetwork=adNetwork}apply(compiler){compiler.hooks.compilation.tap("MetaTagOverridePlugin",compilation=>{HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tap("MetaTagOverridePlugin",data=>{// charset: 统一小写
|
|
8
|
+
data.html=data.html.replace(/<meta\s+charset=["'][^"']*["']\s*\/?>/i,"<meta charset=\"utf-8\" />");// viewport: Mintegral 需要 minimum-scale,其他渠道通用
|
|
9
|
+
const viewportContent=this.adNetwork==="mintegral"?META.MINTEGRAL_VIEWPORT:META.COMMON_VIEWPORT;data.html=data.html.replace(/<meta\s+name=["']viewport["'][^>]*\/?>/i,`<meta name="viewport" content="${viewportContent}" />`);// font-family: Liftoff 渠道需要指定系统字体
|
|
10
|
+
if(this.adNetwork==="liftoff"){const fontStyle=FontFamily.LIFTOFF;data.html=data.html.replace("</head>",fontStyle+"</head>")}return data})})}}/** @type {AD_NETWORK[]} *//** @type {AD_NETWORK[]} */const zipOutputNetworks=["google","pangle","tiktok","vungle","mytarget","mintegral","adikteev","bigabid","inmobi",// InMobi 支持 ZIP 格式(包含 index.html + 资源文件)
|
|
11
|
+
"snapchat","bigoads","liftoff","facebook",// Facebook 默认 ZIP,包体上限 5MB
|
|
12
|
+
"remerge"// Remerge Rich Media:ZIP + index.html + mraid.js
|
|
13
|
+
];/** @type {AD_NETWORK[]} */const zipOutputAllowedNetworks=["moloco"];/**
|
|
14
|
+
* Creates webpack configuration for production build
|
|
15
|
+
* @param {Partial<import('./index').CLIOptions>} [customOptions] - Custom options to merge with default options
|
|
16
|
+
* @param {Record<string, any>} [customDefines] - Additional defines for webpack.DefinePlugin
|
|
17
|
+
* @param {import('webpack').Configuration} [webpackCustomConfig] - Custom webpack config to merge
|
|
18
|
+
* @returns {import('webpack').Configuration} Final webpack production configuration
|
|
19
|
+
*/function makeWebpackBuildConfig(customOptions,customDefines,webpackCustomConfig){const buildOptions=mergeOptions(options,customOptions);logOptions(buildOptions);customDefines=customDefines||{};webpackCustomConfig=webpackCustomConfig||{};/** @type {AD_NETWORK} */const adNetwork=buildOptions["network"];/** @type {AD_PROTOCOL} */const adProtocol=buildOptions["protocol"];/** @type {'both'|'landscape'|'portrait'} 当前单次构建实际使用的横竖屏方向版本,默认 'both' */const playcraftOrientationValue=buildOptions.playcraftOrientationValue||"both";/** @type {string} 方向版本对应的命名后缀:landscape→'_L',portrait→'_P',both→'' */const orientationSuffix=getPlaycraftOrientationSuffix(playcraftOrientationValue);/** @type {string} 渠道 + 方向后缀组成的产物标识,如 'google_L' */const outputId=`${adNetwork}${orientationSuffix}`;let outDir=buildTemplateString(buildOptions.outDir,buildOptions);function getFileName(){let filename=buildTemplateString(buildOptions.filename,buildOptions);if(adNetwork==="mintegral")return filename.replace(/\s+/g,"").replace(/[^a-zA-Z0-9]/g,"_").replace("_fullhash_6_","[fullhash:6]");return filename}const isZipOutput=zipOutputNetworks.includes(adNetwork)||buildOptions.zip&&zipOutputAllowedNetworks.includes(adNetwork);const{isChannelFold2Zip,isZipOutputFinal}=resolveChannelFold2Zip({isChannelFold2ZipOption:buildOptions.isChannelFold2Zip,adNetwork,isZipOutput});let htmlFileName="";if(adNetwork==="mintegral")htmlFileName="index.html";// 修改为 index.html
|
|
20
|
+
else if(isZipOutputFinal)htmlFileName="index.html";else htmlFileName=`${getFileName()}.html`;const metaTags={viewport:META.COMMON_VIEWPORT};if(adNetwork==="mintegral"){metaTags["viewport"]=META.MINTEGRAL_VIEWPORT}if(!buildOptions.skipRecommendedMeta){metaTags["HandheldFriendly"]="True";metaTags["cleartype"]={"http-equiv":"cleartype",content:"on"};metaTags["apple-mobile-web-app-capable"]="yes";metaTags["mobile-web-app-capable"]="yes";metaTags["X-UA-Compatible"]={"http-equiv":"X-UA-Compatible",content:"IE=10"}}let htmlWebpackPluginConfig={template:path.resolve("src/index.html"),filename:htmlFileName,title:`${buildOptions.name} - ${buildOptions.app}`,inlineSource:".(js|css|png|jpg|webp|svg|xml|atlas|mp3|gif|glb|fbx|obj)$",meta:metaTags};if(adNetwork==="adikteev")htmlWebpackPluginConfig=generateAdikteevHtmlWebpackPluginConfig("src/index.html");else if(adNetwork==="bigabid")htmlWebpackPluginConfig=generateBigabidHtmlWebpackPluginConfig("src/index.html");else if(adNetwork==="inmobi")htmlWebpackPluginConfig=generateInMobiHtmlWebpackPluginConfig("src/index.html",buildOptions);const webpackConfig=merge(webpackCommonConfig,{mode:"production",stats:"errors-only",optimization:{usedExports:true,minimize:(buildOptions.obfuscateLevel!==undefined?buildOptions.obfuscateLevel:2)>=1,minimizer:[new TerserPlugin({extractComments:false,terserOptions:{safari10:true,mangle:{reserved:["$"],// ⚠️ 不要开启 properties: true,会混淆 Phaser 等框架的属性名导致运行时错误
|
|
21
|
+
// properties: true,
|
|
22
|
+
toplevel:true},compress:{drop_console:true,arrows:false,drop_debugger:true,unused:true,dead_code:true,// 🔥 增加优化轮数
|
|
23
|
+
passes:3,// 🔥 激进压缩选项
|
|
24
|
+
inline:3,// 最大内联
|
|
25
|
+
collapse_vars:true,// 折叠变量
|
|
26
|
+
reduce_vars:true,// 减少变量
|
|
27
|
+
hoist_vars:true,// 提升变量
|
|
28
|
+
hoist_funs:true,// 提升函数
|
|
29
|
+
sequences:20,// 更长的序列化
|
|
30
|
+
properties:true,// 优化属性访问
|
|
31
|
+
conditionals:true,// 优化条件
|
|
32
|
+
comparisons:true,// 优化比较
|
|
33
|
+
booleans:true,// 优化布尔
|
|
34
|
+
loops:true,// 优化循环
|
|
35
|
+
if_return:true,// 优化 if-return
|
|
36
|
+
join_vars:true,// 合并变量
|
|
37
|
+
negate_iife:true,// 否定 IIFE
|
|
38
|
+
side_effects:true,// 移除副作用
|
|
39
|
+
switches:true,// 优化 switch
|
|
40
|
+
typeofs:true,// 优化 typeof
|
|
41
|
+
unsafe:false,// 不使用 unsafe(避免破坏框架)
|
|
42
|
+
keep_fargs:false,// 移除未使用参数
|
|
43
|
+
drop_console:true},output:{comments:false,quote_style:3,beautify:false,wrap_iife:true,ecma:2015},toplevel:true,keep_classnames:false,keep_fnames:false}})]},plugins:[new HtmlWebpackPlugin(htmlWebpackPluginConfig),new MetaTagOverridePlugin(adNetwork),// 注入 window.playcraftOrientation 全局变量,标识当前构建产物对应的横竖屏方向版本
|
|
44
|
+
new PlaycraftOrientationInjectorPlugin(playcraftOrientationValue),new webpack.DefinePlugin({...buildDefines(buildOptions),...buildOptions.defines,...customDefines}),// For some reason needed for PIXI v8
|
|
45
|
+
new webpack.optimize.LimitChunkCountPlugin({maxChunks:1})]},webpackCustomConfig);webpackConfig.output.path=path.resolve(outDir);// 根据混淆等级注入 obfuscator loader
|
|
46
|
+
const obfuscateLevel=buildOptions.obfuscateLevel!==undefined?buildOptions.obfuscateLevel:2;// 获取需要排除压缩的目录列表
|
|
47
|
+
const excludeCompressDirs=buildOptions.excludeCompressDirs||[];if(obfuscateLevel>=2){// 构建各等级的 obfuscator 配置
|
|
48
|
+
const obfuscatorOptions={// 通用基础配置
|
|
49
|
+
target:"browser",sourceMap:false,selfDefending:false,renameProperties:false,disableConsoleOutput:true,splitStrings:false,unicodeEscapeSequence:false};if(obfuscateLevel===2){// 等级2:基础混淆(控制流平坦化 + 字符串数组)
|
|
50
|
+
Object.assign(obfuscatorOptions,{controlFlowFlattening:true,controlFlowFlatteningThreshold:0.75,deadCodeInjection:false,stringArray:true,stringArrayThreshold:0.75,stringArrayEncoding:["base64"],stringArrayIndexShift:true,stringArrayRotate:true,stringArrayShuffle:true,stringArrayWrappersCount:2,stringArrayWrappersChainedCalls:true,stringArrayWrappersType:"function",stringArrayCallsTransform:true,stringArrayCallsTransformThreshold:0.75,transformObjectKeys:true,identifierNamesGenerator:"hexadecimal"})}else if(obfuscateLevel===3){// 等级3:在等级2基础上增加死代码注入
|
|
51
|
+
Object.assign(obfuscatorOptions,{controlFlowFlattening:true,controlFlowFlatteningThreshold:0.75,deadCodeInjection:true,deadCodeInjectionThreshold:0.4,stringArray:true,stringArrayThreshold:0.75,stringArrayEncoding:["base64"],stringArrayIndexShift:true,stringArrayRotate:true,stringArrayShuffle:true,stringArrayWrappersCount:2,stringArrayWrappersChainedCalls:true,stringArrayWrappersType:"function",stringArrayCallsTransform:true,stringArrayCallsTransformThreshold:0.75,transformObjectKeys:true,identifierNamesGenerator:"hexadecimal"})}else if(obfuscateLevel===4){// 等级4:最高强度混淆
|
|
52
|
+
Object.assign(obfuscatorOptions,{controlFlowFlattening:true,controlFlowFlatteningThreshold:1,deadCodeInjection:true,deadCodeInjectionThreshold:0.5,stringArray:true,stringArrayThreshold:1,stringArrayEncoding:["rc4"],stringArrayIndexShift:true,stringArrayRotate:true,stringArrayShuffle:true,stringArrayWrappersCount:3,stringArrayWrappersChainedCalls:true,stringArrayWrappersType:"function",stringArrayCallsTransform:true,stringArrayCallsTransformThreshold:1,transformObjectKeys:true,identifierNamesGenerator:"hexadecimal",splitStrings:true,splitStringsChunkLength:5,unicodeEscapeSequence:true})}console.log(`Obfuscation level: ${obfuscateLevel} (${["","terser-only","basic","dead-code","maximum"][obfuscateLevel]})`);// 构建exclude数组,包含node_modules和用户指定的排除目录
|
|
53
|
+
const excludePatterns=[];if(excludeCompressDirs.length>0){excludeCompressDirs.forEach(dir=>{excludePatterns.push(path.resolve(dir))});console.log(`ℹ️ Excluding directories from compression: ${excludeCompressDirs.join(", ")}`)}webpackConfig.module.rules.push({test:/\.(js|ts)$/,include:[path.resolve("src")],exclude:excludePatterns,enforce:"post",use:{loader:require.resolve("webpack-obfuscator/dist/loader"),options:obfuscatorOptions}})}else if(obfuscateLevel===1){console.log("Obfuscation level: 1 (terser-only)")}else{console.log("Obfuscation level: 0 (no minimize/obfuscate)")}// Adikteev 需要单独提取 CSS 为 style.css,替换默认的 style-loader
|
|
54
|
+
if(adNetwork==="adikteev"){const cssRuleIndex=webpackConfig.module.rules.findIndex(rule=>rule.test&&rule.test.toString().includes("\\.css"));if(cssRuleIndex!==-1){webpackConfig.module.rules[cssRuleIndex]={test:/\.css$/,use:[MiniCssExtractPlugin.loader,"css-loader"]};console.log("\u2705 Adikteev: CSS will be extracted to style.css")}}// 决定是否内联 JS 到 HTML
|
|
55
|
+
// 以下渠道需要分离 JS 文件,不使用 HtmlInlineScriptPlugin:
|
|
56
|
+
// - mintegral: 需要独立的 JS 文件
|
|
57
|
+
// - adikteev: 需要 creative.js 上传到 CDN
|
|
58
|
+
// - bigabid: 需要 main.js 上传到 CDN
|
|
59
|
+
// - facebook: ZIP 格式(index.html + build.js,包体上限 5MB)
|
|
60
|
+
if(adNetwork!=="mintegral"&&adNetwork!=="adikteev"&&adNetwork!=="bigabid"&&!(isZipOutputFinal&&adNetwork==="facebook"))webpackConfig.plugins.push(new HtmlInlineScriptPlugin);// 注入渠道 SDK 插件(公共逻辑)
|
|
61
|
+
injectSDKPlugins(webpackConfig,{network:adNetwork,protocol:adProtocol,playcraftOrientationValue});if(isZipOutputFinal){if(adNetwork==="tiktok"){webpackConfig.plugins.push(new CopyWebpackPlugin({patterns:[{from:path.join(__dirname,"../../resources","tiktok-config.json"),to:"config.json"}]}))}else if(adNetwork==="snapchat"){const tmpConfigPath=path.join(__dirname,"../../resources","snapchat-config.json");webpackConfig.plugins.push(new CopyWebpackPlugin({patterns:[{from:tmpConfigPath,to:"config.json"}]}))}else if(adNetwork==="bigoads"){// BigoAds 要求输出 ZIP 包,包含 index.html 和 config.json
|
|
62
|
+
// SDK 注入已在 injectSDKPlugins 中处理
|
|
63
|
+
webpackConfig.plugins.push(new CopyWebpackPlugin({patterns:[{from:path.join(__dirname,"../../resources","bigoads-config.json"),to:"config.json"}]}))}webpackConfig.plugins.push(new ZipPlugin({filename:isChannelFold2Zip?outputId:getFileName(),path:path.resolve(outDir),cleanTempFolder:true// 🗑️ 生成 zip 后删除临时文件夹
|
|
64
|
+
}));webpackConfig.output.path=path.resolve(outDir,outputId);if(adNetwork==="adikteev"){webpackConfig.output.filename="creative.js";// Adikteev 需要将 CSS 单独提取为 style.css 文件
|
|
65
|
+
webpackConfig.plugins.push(new MiniCssExtractPlugin({filename:"style.css"}))}else if(adNetwork==="bigabid")webpackConfig.output.filename="main.js";else if(adNetwork==="inmobi")webpackConfig.output.filename="main.js"}// 添加 fflate 压缩插件(仅在打正式包时生效)
|
|
66
|
+
if(buildOptions.fflateCompression){console.log("\u2705 fflate compression enabled (production build only)");webpackConfig.plugins.push(new FflateCompressionPlugin({enabled:true,level:9,keepOriginal:false,logStats:true,googlePlayUrl:buildOptions.googlePlayUrl,appStoreUrl:buildOptions.appStoreUrl}))}return webpackConfig}/**
|
|
67
|
+
* Runs webpack production build
|
|
68
|
+
* @param {import('webpack').Configuration} [webpackConfig] - Webpack configuration to use, creates default if not provided
|
|
69
|
+
* @param {Partial<import('./index').CLIOptions>} [customOptions] - Custom options to merge with default options
|
|
70
|
+
* @param {Record<string, any>} [customDefines] - Additional defines for webpack.DefinePlugin
|
|
71
|
+
* @param {import('webpack').Configuration} [webpackCustomConfig] - Custom webpack config to merge
|
|
72
|
+
*/function runBuild(webpackConfig,customOptions,customDefines,webpackCustomConfig){return new Promise((resolve,reject)=>{if(!webpackConfig)webpackConfig=makeWebpackBuildConfig(customOptions,customDefines,webpackCustomConfig);const compiler=webpack(webpackConfig);// 必须显式调用 compiler.close() 释放本次编译占用的内存(模块图/资源缓存/
|
|
73
|
+
// Terser 与 obfuscator 等插件持有的引用)。webpack 官方要求:若在同一进程内
|
|
74
|
+
// 多次调用 compiler.run(),每次 run 完成后都要 close,否则上一次编译的内存
|
|
75
|
+
// 无法被回收。playcraftOrientationChannel 会在同一进程里串行构建多个方向
|
|
76
|
+
// 版本(多次调用本函数),若不 close,内存会随构建次数线性累加,最终触发
|
|
77
|
+
// "JavaScript heap out of memory"。
|
|
78
|
+
const finalize=error=>{compiler.close(closeErr=>{if(closeErr){console.error("\u5173\u95ED webpack compiler \u65F6\u51FA\u9519:",closeErr)}if(error){reject(error)}else{resolve()}})};compiler.run((err,stats)=>{if(err){console.error("Build failed:",err.stack||err);if(err.details){console.error("Error details:",err.details)}return finalize(err)}if(stats.hasErrors()){const errors=stats.compilation.errors;console.error(`\n❌ Build finished with ${errors.length} error(s):\n`);// 打印每个错误的详细信息
|
|
79
|
+
errors.forEach((error,index)=>{console.error(`\n[Error ${index+1}/${errors.length}]`);console.error(error.message||error);if(error.stack){console.error(error.stack)}});// 拒绝 Promise 时传递格式化的错误消息
|
|
80
|
+
const errorMessage=errors.map((e,i)=>`[${i+1}] ${e.message||e}`).join("\n");finalize(new Error(`Webpack build failed with ${errors.length} error(s):\n${errorMessage}`))}else{console.log(`Build successful!`);finalize(null)}})})}exports.makeWebpackBuildConfig=makeWebpackBuildConfig;exports.runBuild=runBuild;
|