diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000000000000000000000000000000000000..4b2d34a6be5e0c686841fd50797c220c34b31897
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,9 @@
+node_modules
+**/node_modules
+public
+frontend/dist
+frontend/node_modules
+.vulcan
+.vulcan-error-reporter.js
+*.log
+.git
diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644
index 8b69c9f686d2ee33442940a158bc8a10de069dc2..0000000000000000000000000000000000000000
--- a/.gitattributes
+++ /dev/null
@@ -1,11 +0,0 @@
-*.mp4 filter=lfs diff=lfs merge=lfs -text
-*.MP4 filter=lfs diff=lfs merge=lfs -text
-*.mov filter=lfs diff=lfs merge=lfs -text
-*.MOV filter=lfs diff=lfs merge=lfs -text
-*.mp3 filter=lfs diff=lfs merge=lfs -text
-*.png filter=lfs diff=lfs merge=lfs -text
-*.PNG filter=lfs diff=lfs merge=lfs -text
-*.jpg filter=lfs diff=lfs merge=lfs -text
-*.webp filter=lfs diff=lfs merge=lfs -text
-*.HEIC filter=lfs diff=lfs merge=lfs -text
-BeadQR/docs/source-photo.jpeg filter=lfs diff=lfs merge=lfs -text
diff --git a/BeadQR/README.md b/BeadQR/README.md
deleted file mode 100644
index 58e1c1be66ddca4b41d2a437f4899b49d3837beb..0000000000000000000000000000000000000000
--- a/BeadQR/README.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# 豆维 · 可扫码的拼豆
-
-输入一句话(可以再选一张照片),生成**用微信扫一扫就能读出内容**的 MARD 拼豆图纸,并支持导出 PDF 或图片。
-
-## 本版重点
-
-- **一眼看懂**:首屏直接说明用途,页面按“写一句话 → 选张照片 → 导出图纸”三步走,打开就能看到示例效果。
-- **更快**:配色查表加速,色格数据不再走页面数据通道;PDF 改为矢量直出(毫秒级,文件更小);导出时不再重复绘制。
-- **更好看、更好扫**:
- - 感知更准的配色(OKLab)
- - 照片按面积取平均色,不再有锯齿
- - 相邻色块自动平滑,零散颜色自动合并,所需豆子种类更少
- - 二维码定位图形强制高对比
- - 本机扫码自检:扫不出时一键优化
-- **打印友好**:PDF 为 A4 矢量图纸,大作品会自动分块并附总览页;每一格都印有色号,另附带用量的清单。
-- **精选色板**:除标准 221 色和完整 291 色外,还提供 144/96/72/48/24 色精选套装,方便少买豆。
-
-## 内容安全链路(按微信平台要求)
-
-| 环节 | 措施 |
-| --- | --- |
-| 二维码文字、扫码导入的文字、水印 | 云函数调用 `security.msgSecCheck` v2(带 openid、按场景值检测),结果为 risky 或 review 均拦截 |
-| 照片 | 选图后立即压缩到官方推荐的 750×1334 以内,由云函数调用 `security.imgSecCheck`;**检测通过前不能应用照片** |
-| 检测异常 | 一律视为未通过,不允许生成与导出(fail-closed) |
-| 导出前 | 再次校验全部文本(已通过的走缓存,不增加等待) |
-| 云函数加固 | 必须有 OPENID;只接受 `sec-check/` 目录下的 jpg;通过文件头判断格式;限制 1MB;检测后立即删除云端临时文件 |
-| 隐私 | 已开启 `__usePrivacyCheck__`,内置隐私授权弹窗;页脚设有“隐私保护指引”入口 |
-| 投诉与反馈 | 页脚提供“内容规范”说明及 `open-type="feedback"` 的投诉反馈入口 |
-| 分享 | 分享出去的只是小程序卡片,不带用户内容 |
-
-## 部署步骤
-
-1. 用微信开发者工具打开本目录(appid 已配置)。
-2. 右键 `cloudfunctions/quickstartFunctions` →「上传并部署:云端安装依赖」。**本版云函数有改动,必须重新部署。**
-3. 在云开发控制台 → 存储中确认可以写入 `sec-check/` 目录(默认权限即可)。
-4. 在小程序管理后台 →「设置 → 服务内容声明 → 用户隐私保护指引」中声明:选择图片/拍照(`chooseMedia`)、保存到相册(`saveImageToPhotosAlbum`)、扫码(`scanCode`)。
-5. 真机测试:正常/违规文字、正常/违规图片、断网时的检测异常,确认都会被正确拦截和提示。
-
-## 说明
-
-- 为保证扫码成功率,**二维码默认保留 1 格白边**。如需原来的“无白边”效果,可在「高级设置 → 白边」中选择“无”。
-- 圆豆、中空豆样式只影响图纸的显示效果,实际拼出来的位置与方豆完全一致。
-- 第三方代码:`utils/qrcore`(node-qrcode,MIT)、`utils/vendor/jsqr.js`(jsQR,Apache-2.0)。
-
-## 首屏演示动画 & 宣传视频
-
-- 首次打开(还没写内容)时,预览区播放 12 秒 1:1 演示动画:写一句话 → 编成二维码 → 融进照片 → 微信一扫 → 结尾卡片。
-- 动画由 `miniprogram/utils/intro.js` 纯代码实时绘制,**不含任何视频/图片素材,几乎不占包体积**(约 20KB)。演示作品由真实配色引擎生成,画面里的二维码真的能扫出 “Happy Birthday!”。
-- 滑出屏幕、切到后台、打开裁剪时自动暂停;点一下预览区重新播放;写下内容(或选了照片)后自动切回真实二维码。
-- `docs/promo/` 里是用同一套代码渲染的宣传视频(1080 / 720,含原创合成配乐)和封面图,可直接发公众号。该目录不在 `miniprogram/` 内,不计入小程序包体积。
diff --git a/BeadQR/cloudfunctions/quickstartFunctions/config.json b/BeadQR/cloudfunctions/quickstartFunctions/config.json
deleted file mode 100644
index a1d2eac6ed64d91b41f32dd6a796a2fb91328985..0000000000000000000000000000000000000000
--- a/BeadQR/cloudfunctions/quickstartFunctions/config.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "timeout": 20,
- "permissions": {
- "openapi": [
- "security.msgSecCheck",
- "security.imgSecCheck"
- ]
- }
-}
diff --git a/BeadQR/cloudfunctions/quickstartFunctions/index.js b/BeadQR/cloudfunctions/quickstartFunctions/index.js
deleted file mode 100644
index 24bdb9b2b2dba5b4e592e6b61c46ec3124794dd7..0000000000000000000000000000000000000000
--- a/BeadQR/cloudfunctions/quickstartFunctions/index.js
+++ /dev/null
@@ -1,92 +0,0 @@
-// 豆维 · 内容安全云函数
-// type: checkMessage | checkMessages | checkImage
-// 返回约定:{ risk: boolean, skipped?: boolean };skipped 表示检测未能完成,前端必须拦截
-const cloud = require("wx-server-sdk");
-cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
-
-const MAX_TEXT = 2500;
-const MAX_IMAGE_BYTES = 1024 * 1024;
-const MAX_BATCH = 5;
-
-const extractErrCode = (error) => {
- if (!error) return undefined;
- if (typeof error.errCode === "number") return error.errCode;
- if (typeof error.code === "number") return error.code;
- const match = typeof error.errMsg === "string" ? error.errMsg.match(/-?\d{3,}/) : null;
- return match ? Number(match[0]) : undefined;
-};
-
-// msgSecCheck v2:scene 1 资料 / 2 评论 / 3 论坛 / 4 社交日志
-async function checkOneMessage(content, scene, openid) {
- const value = String(content || "").slice(0, MAX_TEXT);
- if (!value.trim()) return { risk: false };
- const safeScene = [1, 2, 3, 4].includes(Number(scene)) ? Number(scene) : 2;
- try {
- const response = await cloud.openapi.security.msgSecCheck({
- version: 2,
- scene: safeScene,
- openid,
- content: value,
- });
- const suggest = response && response.result && response.result.suggest;
- if (!suggest) return { risk: false, skipped: true };
- // review(疑似)按违规处理,宁严勿松
- return { risk: suggest === "risky" || suggest === "review", verdict: suggest };
- } catch (e) {
- if (extractErrCode(e) === 87014) return { risk: true, verdict: "risky" };
- return { risk: false, skipped: true, errCode: extractErrCode(e) };
- }
-}
-
-// 通过文件头判断真实格式,不信任客户端传入的类型
-function sniffType(buffer) {
- if (buffer.length > 3 && buffer[0] === 0xff && buffer[1] === 0xd8 && buffer[2] === 0xff) return "image/jpeg";
- if (buffer.length > 8 && buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4e && buffer[3] === 0x47) return "image/png";
- return "";
-}
-
-async function checkImage(fileID) {
- // 只允许检测本小程序上传到 sec-check/ 目录的临时文件,防止借接口删除/读取其他文件
- if (typeof fileID !== "string" || !/^cloud:\/\/[^/]+\/sec-check\/[\w.-]+\.jpg$/.test(fileID)) {
- return { risk: false, skipped: true, reason: "INVALID_FILE" };
- }
- try {
- const download = await cloud.downloadFile({ fileID });
- const buffer = download && download.fileContent;
- const contentType = buffer ? sniffType(buffer) : "";
- if (!buffer || !buffer.length || buffer.length > MAX_IMAGE_BYTES || !contentType) {
- return { risk: false, skipped: true, reason: "BAD_IMAGE" };
- }
- await cloud.openapi.security.imgSecCheck({
- media: { contentType, value: buffer },
- });
- return { risk: false };
- } catch (e) {
- if (extractErrCode(e) === 87014) return { risk: true, verdict: "risky" };
- return { risk: false, skipped: true, errCode: extractErrCode(e) };
- } finally {
- try {
- await cloud.deleteFile({ fileList: [fileID] });
- } catch (e) {
- // 清理失败不影响检测结果
- }
- }
-}
-
-exports.main = async (event) => {
- const { OPENID } = cloud.getWXContext();
- if (!OPENID) return { risk: false, skipped: true, reason: "NO_OPENID" };
- const type = event && event.type;
- if (type === "checkMessage") {
- return checkOneMessage(event.content, event.scene, OPENID);
- }
- if (type === "checkMessages") {
- const items = Array.isArray(event.items) ? event.items.slice(0, MAX_BATCH) : [];
- const results = await Promise.all(items.map((it) => checkOneMessage(it && it.value, it && it.scene, OPENID)));
- return { results };
- }
- if (type === "checkImage") {
- return checkImage(event.fileID);
- }
- return { risk: false, skipped: true, reason: "UNKNOWN_TYPE" };
-};
diff --git a/BeadQR/cloudfunctions/quickstartFunctions/package-lock.json b/BeadQR/cloudfunctions/quickstartFunctions/package-lock.json
deleted file mode 100644
index 26d0d9d6e69b043888fa78b3e1a003670970cf1c..0000000000000000000000000000000000000000
--- a/BeadQR/cloudfunctions/quickstartFunctions/package-lock.json
+++ /dev/null
@@ -1,1157 +0,0 @@
-{
- "name": "quickstartFunctions",
- "version": "1.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "quickstartFunctions",
- "version": "1.0.0",
- "license": "ISC",
- "dependencies": {
- "wx-server-sdk": "~4.0.2"
- }
- },
- "node_modules/@cloudbase/adapter-interface": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/@cloudbase/adapter-interface/-/adapter-interface-0.7.1.tgz",
- "integrity": "sha512-BjHTAvIMSLxbp26SeT6qLiSSBygz3kAVno/PMwwBwjgzVkVUvuZGVcvf1mhHxY/BjdRGLrd6X60OgvymV/aAUw==",
- "license": "ISC"
- },
- "node_modules/@cloudbase/adapter-wx_mp": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@cloudbase/adapter-wx_mp/-/adapter-wx_mp-1.3.1.tgz",
- "integrity": "sha512-rS0N1aD1a0zc421ds17/HzM4RChQ6T2ixMz87bhPJ1yveqJt/KUqYxiXJDWhZ803wwTmJs8aqNkgugsNusNhbg==",
- "license": "ISC",
- "dependencies": {
- "@cloudbase/adapter-interface": "^0.7.0",
- "web-streams-polyfill": "^4.0.0"
- }
- },
- "node_modules/@cloudbase/ai": {
- "version": "2.30.0",
- "resolved": "https://registry.npmjs.org/@cloudbase/ai/-/ai-2.30.0.tgz",
- "integrity": "sha512-RtBux47omXWcMhiiDDVJ96d2JlqnQ/bzKC6GG3ROgupYG3ReQyv1IssCpg5cnzmZ+l651IqdOpt27VTuO3kEGQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "@cloudbase/types": "2.30.0",
- "@cloudbase/utilities": "2.30.0",
- "@mattiasbuelens/web-streams-adapter": "^0.1.0",
- "text-encoding-shim": "^1.0.5",
- "web-streams-polyfill": "^4.0.0"
- }
- },
- "node_modules/@cloudbase/ai/node_modules/@cloudbase/types": {
- "version": "2.30.0",
- "resolved": "https://registry.npmjs.org/@cloudbase/types/-/types-2.30.0.tgz",
- "integrity": "sha512-tVapfLLDA1MlmG2OwC5eq5eSra9l3EgpeJnx1kNR4CGh8zQRrVvFRyaRLo4BrzY0p/5xqX3iJliRmcASF7Ip7g==",
- "license": "Apache-2.0",
- "dependencies": {
- "@cloudbase/adapter-interface": "^0.7.1"
- }
- },
- "node_modules/@cloudbase/app": {
- "version": "2.32.0",
- "resolved": "https://registry.npmjs.org/@cloudbase/app/-/app-2.32.0.tgz",
- "integrity": "sha512-78+eSo8OLO4iUiifdynZo4dK4wNlyaz5x9423muSibyl4FLwt5/Xt0t9s7StFmGaBdvB75UYM9dGWxOdIFRzaw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@cloudbase/adapter-interface": "^0.7.1",
- "@cloudbase/adapter-wx_mp": "^1.3.1",
- "@cloudbase/types": "2.32.0",
- "@cloudbase/utilities": "2.32.0"
- },
- "peerDependencies": {
- "@cloudbase/signature-nodejs": ">=1.0.0",
- "jsonwebtoken": ">=8.0.0",
- "ws": "^8.18.0"
- },
- "peerDependenciesMeta": {
- "@cloudbase/signature-nodejs": {
- "optional": true
- },
- "jsonwebtoken": {
- "optional": true
- },
- "ws": {
- "optional": true
- }
- }
- },
- "node_modules/@cloudbase/app/node_modules/@cloudbase/utilities": {
- "version": "2.32.0",
- "resolved": "https://registry.npmjs.org/@cloudbase/utilities/-/utilities-2.32.0.tgz",
- "integrity": "sha512-vYrr1aXOpU+/IrkHMSTxi/k2d4N8raNu+E3IrKtWt4w7Y0Ke3DLvCHeUJcuWECvQBVhzmg1ert4DcXVUymSKlg==",
- "license": "Apache-2.0",
- "dependencies": {
- "@cloudbase/adapter-interface": "^0.7.1",
- "@cloudbase/types": "2.32.0",
- "jwt-decode": "^3.1.2"
- }
- },
- "node_modules/@cloudbase/database": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@cloudbase/database/-/database-1.4.3.tgz",
- "integrity": "sha512-JzmdsGjy9LwzSQQ0Fv4OlNHNK61BRXdJSembTpy4408AQA3q2Ip3N5eB3v9OpAlFMvP/6MGmOQ/ZuUPKfJddJA==",
- "license": "ISC",
- "dependencies": {
- "bson": "^4.0.3",
- "lodash.clonedeep": "4.5.0",
- "lodash.set": "4.3.2",
- "lodash.unset": "4.5.2"
- }
- },
- "node_modules/@cloudbase/node-sdk": {
- "version": "3.17.2",
- "resolved": "https://registry.npmjs.org/@cloudbase/node-sdk/-/node-sdk-3.17.2.tgz",
- "integrity": "sha512-74ekvRsdmeGch9hFHkQnjHPTEfk8k09iQFvI1aAo48ZsbLqK3czqj/3GoVpSkw5+eYe05tZV13Ct/kWiV5tuGg==",
- "license": "MIT",
- "dependencies": {
- "@cloudbase/ai": "^2.23.0",
- "@cloudbase/app": "^2.23.0",
- "@cloudbase/database": "1.4.3",
- "@cloudbase/signature-nodejs": "2.2.0",
- "@cloudbase/types": "^2.23.0",
- "@cloudbase/wx-cloud-client-sdk": "1.7.1",
- "agentkeepalive": "^4.3.0",
- "axios": "0.27.2",
- "form-data": "^4.0.0",
- "http-proxy-agent": "^5.0.0",
- "https-proxy-agent": "^5.0.1",
- "jsonwebtoken": "^9.0.2",
- "retry": "^0.13.1",
- "web-streams-polyfill": "^4.2.0",
- "xml2js": "^0.6.2"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@cloudbase/signature-nodejs": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@cloudbase/signature-nodejs/-/signature-nodejs-2.2.0.tgz",
- "integrity": "sha512-2y2rieOpJNnBA2MW7sLJKek3iFOjgr8TNicw5qjBkcdVczLR0cFzxMhip75NLCwarFTIAONE3oeNxoQ19eVHcA==",
- "dependencies": {
- "@types/clone": "^2.1.0",
- "clone": "^2.1.2",
- "is-stream": "^2.0.0",
- "url": "^0.11.0"
- }
- },
- "node_modules/@cloudbase/types": {
- "version": "2.32.0",
- "resolved": "https://registry.npmjs.org/@cloudbase/types/-/types-2.32.0.tgz",
- "integrity": "sha512-HPsMEHHt5SAyD3tpv/C/v2nYudSawE48ixjK5Y9w3R/82auJag0AUsZGfCExgdPa4Zud9OvGx5127ssEXLgadw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@cloudbase/adapter-interface": "^0.7.1"
- }
- },
- "node_modules/@cloudbase/utilities": {
- "version": "2.30.0",
- "resolved": "https://registry.npmjs.org/@cloudbase/utilities/-/utilities-2.30.0.tgz",
- "integrity": "sha512-52DfQH5qgfOtrwj26KCGw6cz0pUjuJludJ7fccUKCzBtn/QwPudwtXo7gOUTtKKDubW3+VUCjjBm7UiDwFu+ag==",
- "license": "Apache-2.0",
- "dependencies": {
- "@cloudbase/adapter-interface": "^0.7.1",
- "@cloudbase/types": "2.30.0",
- "jwt-decode": "^3.1.2"
- }
- },
- "node_modules/@cloudbase/utilities/node_modules/@cloudbase/types": {
- "version": "2.30.0",
- "resolved": "https://registry.npmjs.org/@cloudbase/types/-/types-2.30.0.tgz",
- "integrity": "sha512-tVapfLLDA1MlmG2OwC5eq5eSra9l3EgpeJnx1kNR4CGh8zQRrVvFRyaRLo4BrzY0p/5xqX3iJliRmcASF7Ip7g==",
- "license": "Apache-2.0",
- "dependencies": {
- "@cloudbase/adapter-interface": "^0.7.1"
- }
- },
- "node_modules/@cloudbase/wx-cloud-client-sdk": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/@cloudbase/wx-cloud-client-sdk/-/wx-cloud-client-sdk-1.7.1.tgz",
- "integrity": "sha512-NzLOoYDAeoRh2lRjCtvr6yXu4KPVHqZtPxyv70e+3b2+dZIDE5S5gtU8daE7xS5u4TwPqKB/E2vmgRTYOsCS9w==",
- "dependencies": {
- "core-js-pure": "^3.45.0"
- }
- },
- "node_modules/@mattiasbuelens/web-streams-adapter": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/@mattiasbuelens/web-streams-adapter/-/web-streams-adapter-0.1.0.tgz",
- "integrity": "sha512-oV4PyZfwJNtmFWhvlJLqYIX1Nn22ML8FZpS16ZUKv0hg7414xV1fjsGqxQzLT2dyK92TKxsJSwMOd7VNHAtPmA==",
- "license": "MIT",
- "engines": {
- "node": ">= 12"
- }
- },
- "node_modules/@protobufjs/aspromise": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
- "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/base64": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
- "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/codegen": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz",
- "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/eventemitter": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz",
- "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/fetch": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz",
- "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "@protobufjs/aspromise": "^1.1.1"
- }
- },
- "node_modules/@protobufjs/float": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
- "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/path": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
- "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/pool": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
- "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/utf8": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz",
- "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@tootallnate/once": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.1.tgz",
- "integrity": "sha512-HqmEUIGRJ5fSXchkVgR5F7qn48bDBzv0kWj/Kfu5e6uci4UlEeng4331LnBkWffb++Ei3FOVLxo8JJWMFBDMeQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@types/clone": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/@types/clone/-/clone-2.1.4.tgz",
- "integrity": "sha512-NKRWaEGaVGVLnGLB2GazvDaZnyweW9FJLLFL5LhywGJB3aqGMT9R/EUoJoSRP4nzofYnZysuDmrEJtJdAqUOtQ==",
- "license": "MIT"
- },
- "node_modules/@types/node": {
- "version": "26.3.0",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-26.3.0.tgz",
- "integrity": "sha512-L3fgrnchriRC2ExBflb8j4uZZURHZfQsmQeyVzhjcHW4kkwVyo8/0h1B2MVzMTrYUJYu6G7EWs14hW/L9putqw==",
- "license": "MIT",
- "dependencies": {
- "undici-types": "~8.3.0"
- }
- },
- "node_modules/agent-base": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
- "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
- "license": "MIT",
- "dependencies": {
- "debug": "4"
- },
- "engines": {
- "node": ">= 6.0.0"
- }
- },
- "node_modules/agentkeepalive": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
- "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
- "license": "MIT",
- "dependencies": {
- "humanize-ms": "^1.2.1"
- },
- "engines": {
- "node": ">= 8.0.0"
- }
- },
- "node_modules/asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
- "license": "MIT"
- },
- "node_modules/axios": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
- "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
- "license": "MIT",
- "dependencies": {
- "follow-redirects": "^1.14.9",
- "form-data": "^4.0.0"
- }
- },
- "node_modules/base64-js": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
- "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/bignumber.js": {
- "version": "9.3.1",
- "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz",
- "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==",
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/bson": {
- "version": "4.7.2",
- "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.2.tgz",
- "integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "buffer": "^5.6.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/buffer": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
- "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "base64-js": "^1.3.1",
- "ieee754": "^1.1.13"
- }
- },
- "node_modules/buffer-equal-constant-time": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
- "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
- "license": "BSD-3-Clause"
- },
- "node_modules/call-bind-apply-helpers": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
- "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/call-bound": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
- "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "get-intrinsic": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/clone": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
- "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
- "license": "MIT",
- "engines": {
- "node": ">=0.8"
- }
- },
- "node_modules/combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "license": "MIT",
- "dependencies": {
- "delayed-stream": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/core-js-pure": {
- "version": "3.50.0",
- "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.50.0.tgz",
- "integrity": "sha512-6GP3Pxz4IKyWjAfa747vIu/jilB5z29JWROLqH/b+pXVcpgh6tM06ZIBwSuglgVqzDYURhOK6oEzTrG0bCHitA==",
- "hasInstallScript": true,
- "license": "MIT",
- "engines": {
- "node": "*"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/core-js"
- }
- },
- "node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/dunder-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
- "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/ecdsa-sig-formatter": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
- "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/es-define-property": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
- "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-object-atoms": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
- "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-set-tostringtag": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
- "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.6",
- "has-tostringtag": "^1.0.2",
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/follow-redirects": {
- "version": "1.16.0",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
- "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/RubenVerborgh"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=4.0"
- },
- "peerDependenciesMeta": {
- "debug": {
- "optional": true
- }
- }
- },
- "node_modules/form-data": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz",
- "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==",
- "license": "MIT",
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "es-set-tostringtag": "^2.1.0",
- "hasown": "^2.0.4",
- "mime-types": "^2.1.35"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-intrinsic": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
- "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.1",
- "function-bind": "^1.1.2",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "has-symbols": "^1.1.0",
- "hasown": "^2.0.2",
- "math-intrinsics": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
- "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
- "license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/gopd": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
- "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-symbols": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-tostringtag": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
- "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
- "license": "MIT",
- "dependencies": {
- "has-symbols": "^1.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
- "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
- "license": "MIT",
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/http-proxy-agent": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
- "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
- "license": "MIT",
- "dependencies": {
- "@tootallnate/once": "2",
- "agent-base": "6",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/https-proxy-agent": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
- "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "6",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/humanize-ms": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
- "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.0.0"
- }
- },
- "node_modules/ieee754": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
- "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "BSD-3-Clause"
- },
- "node_modules/is-stream": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
- "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/json-bigint": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
- "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
- "license": "MIT",
- "dependencies": {
- "bignumber.js": "^9.0.0"
- }
- },
- "node_modules/jsonwebtoken": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz",
- "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==",
- "license": "MIT",
- "dependencies": {
- "jws": "^4.0.1",
- "lodash.includes": "^4.3.0",
- "lodash.isboolean": "^3.0.3",
- "lodash.isinteger": "^4.0.4",
- "lodash.isnumber": "^3.0.3",
- "lodash.isplainobject": "^4.0.6",
- "lodash.isstring": "^4.0.1",
- "lodash.once": "^4.0.0",
- "ms": "^2.1.1",
- "semver": "^7.5.4"
- },
- "engines": {
- "node": ">=12",
- "npm": ">=6"
- }
- },
- "node_modules/jwa": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
- "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
- "license": "MIT",
- "dependencies": {
- "buffer-equal-constant-time": "^1.0.1",
- "ecdsa-sig-formatter": "1.0.11",
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/jws": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
- "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
- "license": "MIT",
- "dependencies": {
- "jwa": "^2.0.1",
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/jwt-decode": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
- "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==",
- "license": "MIT"
- },
- "node_modules/lodash.clonedeep": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
- "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
- "license": "MIT"
- },
- "node_modules/lodash.includes": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
- "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
- "license": "MIT"
- },
- "node_modules/lodash.isboolean": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
- "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
- "license": "MIT"
- },
- "node_modules/lodash.isinteger": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
- "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
- "license": "MIT"
- },
- "node_modules/lodash.isnumber": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
- "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
- "license": "MIT"
- },
- "node_modules/lodash.isplainobject": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
- "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
- "license": "MIT"
- },
- "node_modules/lodash.isstring": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
- "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
- "license": "MIT"
- },
- "node_modules/lodash.once": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
- "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
- "license": "MIT"
- },
- "node_modules/lodash.set": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
- "integrity": "sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==",
- "license": "MIT"
- },
- "node_modules/lodash.unset": {
- "version": "4.5.2",
- "resolved": "https://registry.npmjs.org/lodash.unset/-/lodash.unset-4.5.2.tgz",
- "integrity": "sha512-bwKX88k2JhCV9D1vtE8+naDKlLiGrSmf8zi/Y9ivFHwbmRfA8RxS/aVJ+sIht2XOwqoNr4xUPUkGZpc1sHFEKg==",
- "license": "MIT"
- },
- "node_modules/long": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
- "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
- "license": "Apache-2.0"
- },
- "node_modules/math-intrinsics": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "node_modules/object-inspect": {
- "version": "1.13.4",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
- "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/protobufjs": {
- "version": "7.6.5",
- "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz",
- "integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==",
- "hasInstallScript": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@protobufjs/aspromise": "^1.1.2",
- "@protobufjs/base64": "^1.1.2",
- "@protobufjs/codegen": "^2.0.5",
- "@protobufjs/eventemitter": "^1.1.1",
- "@protobufjs/fetch": "^1.1.1",
- "@protobufjs/float": "^1.0.2",
- "@protobufjs/path": "^1.1.2",
- "@protobufjs/pool": "^1.1.0",
- "@protobufjs/utf8": "^1.1.1",
- "@types/node": ">=13.7.0",
- "long": "^5.3.2"
- },
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/punycode": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
- "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
- "license": "MIT"
- },
- "node_modules/qs": {
- "version": "6.15.3",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz",
- "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "es-define-property": "^1.0.1",
- "side-channel": "^1.1.1"
- },
- "engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/retry": {
- "version": "0.13.1",
- "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
- "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/sax": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.1.tgz",
- "integrity": "sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=11.0.0"
- }
- },
- "node_modules/semver": {
- "version": "7.8.5",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
- "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/side-channel": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz",
- "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.4",
- "side-channel-list": "^1.0.1",
- "side-channel-map": "^1.0.1",
- "side-channel-weakmap": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-list": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
- "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.4"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-map": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
- "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-weakmap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
- "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3",
- "side-channel-map": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/text-encoding-shim": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/text-encoding-shim/-/text-encoding-shim-1.0.5.tgz",
- "integrity": "sha512-H7yYW+jRn4yhu60ygZ2f/eMhXPITRt4QSUTKzLm+eCaDsdX8avmgWpmtmHAzesjBVUTAypz9odu5RKUjX5HNYA==",
- "license": "MIT"
- },
- "node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
- "license": "0BSD"
- },
- "node_modules/undici-types": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz",
- "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==",
- "license": "MIT"
- },
- "node_modules/url": {
- "version": "0.11.4",
- "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz",
- "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==",
- "license": "MIT",
- "dependencies": {
- "punycode": "^1.4.1",
- "qs": "^6.12.3"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/web-streams-polyfill": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.3.0.tgz",
- "integrity": "sha512-/Gnggvj9oSrEvJbDyyPtAnxBt5fGQM2iWOKQNu7ie1OxDgK40iZpyV3TKaRiEzVj1oA1UxKnEy9XPXh6PW3eVw==",
- "license": "MIT",
- "workspaces": [
- "test/benchmark-test",
- "test/rollup-test",
- "test/webpack-test"
- ],
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/wx-server-sdk": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/wx-server-sdk/-/wx-server-sdk-4.0.2.tgz",
- "integrity": "sha512-dgpgWxYvOFWnQdGOb78sU+uQGELoEQSKzmJ7m8Y6eTCJKsfkdIHLMhRrdN5S5oDfAqr8Pc83jZKQeNRMZASIcg==",
- "license": "MIT",
- "dependencies": {
- "@cloudbase/node-sdk": "3.17.2",
- "json-bigint": "^1.0.0",
- "protobufjs": "^7.2.4",
- "tslib": "^1.9.3"
- }
- },
- "node_modules/xml2js": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
- "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
- "license": "MIT",
- "dependencies": {
- "sax": ">=0.6.0",
- "xmlbuilder": "~11.0.0"
- },
- "engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/xmlbuilder": {
- "version": "11.0.1",
- "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
- "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
- "license": "MIT",
- "engines": {
- "node": ">=4.0"
- }
- }
- }
-}
diff --git a/BeadQR/cloudfunctions/quickstartFunctions/package.json b/BeadQR/cloudfunctions/quickstartFunctions/package.json
deleted file mode 100644
index 63727cda9c2e7d038ad78f36ae111268eadd9258..0000000000000000000000000000000000000000
--- a/BeadQR/cloudfunctions/quickstartFunctions/package.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "name": "quickstartFunctions",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "author": "",
- "license": "ISC",
- "dependencies": {
- "wx-server-sdk": "~4.0.2"
- }
-}
diff --git a/BeadQR/docs/promo/douwei-1080-cover.png b/BeadQR/docs/promo/douwei-1080-cover.png
deleted file mode 100644
index f08e99fd0f86d17f8467e6b059637e3b989fc1ec..0000000000000000000000000000000000000000
--- a/BeadQR/docs/promo/douwei-1080-cover.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:aeac46fce4028cbfc2d7bae0dad427ed5f67262582ad411a00ccb2db65f8f03b
-size 319823
diff --git a/BeadQR/docs/promo/douwei-1080.mp4 b/BeadQR/docs/promo/douwei-1080.mp4
deleted file mode 100644
index 8ad3a7bd6f7099c1305b7b42b367c9c7db85cdbb..0000000000000000000000000000000000000000
--- a/BeadQR/docs/promo/douwei-1080.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:89ba1505c4ce4aa36316841c497dc96b8997bac534bb534426c23ca96ce87dcc
-size 3693122
diff --git a/BeadQR/docs/promo/douwei-720-cover.png b/BeadQR/docs/promo/douwei-720-cover.png
deleted file mode 100644
index ccaf575a9b83c1b8b0eb3255f0e3a37673424a67..0000000000000000000000000000000000000000
--- a/BeadQR/docs/promo/douwei-720-cover.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:bdb68c450700c1e65492e708440a29d07c9288606ca0ad7b464133052855fb2a
-size 195403
diff --git a/BeadQR/docs/promo/douwei-720.mp4 b/BeadQR/docs/promo/douwei-720.mp4
deleted file mode 100644
index b95f5525b899e8a0144b1b7da6234149348de007..0000000000000000000000000000000000000000
--- a/BeadQR/docs/promo/douwei-720.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:626ea04f449f33fe29c4ec6c4aa94a2db88600cababab4f5a11b74155b4eee4e
-size 1650037
diff --git a/BeadQR/docs/source-photo.jpeg b/BeadQR/docs/source-photo.jpeg
deleted file mode 100644
index a1c44940c051799c8db7d283a3939078a54d52ba..0000000000000000000000000000000000000000
--- a/BeadQR/docs/source-photo.jpeg
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:ceae6708b13c1c7863c9a73b51f5eb775abcfe6f667b1c86ea993c8fe26995a8
-size 204431
diff --git a/BeadQR/docs/video-script.md b/BeadQR/docs/video-script.md
deleted file mode 100644
index bc42e2b8af7f963da3dc1c90067b2aa461061fcc..0000000000000000000000000000000000000000
--- a/BeadQR/docs/video-script.md
+++ /dev/null
@@ -1,116 +0,0 @@
-# 豆维 · 视频文案与分镜脚本
-
-> 目标:用一个短视频介绍「豆维 · 可扫码的拼豆」小程序,让观众理解它是什么、为什么有趣、怎么做出来。
-> 结构:提出想法 → 实现想法 → 制作例子 → 完成例子。
-
----
-
-## 一、视频定位与调性
-
-| 维度 | 建议 |
-|------|------|
-| 时长 | 主版本 60–90 秒(B站 / 朋友圈 / 公众号),另附 15–30 秒短视频版 |
-| 调性 | 温暖手作 × 科技惊喜,不是冷冰冰的产品演示 |
-| 核心情绪 | 「拼豆不止是一幅画,它是一封能被读到的信」 |
-| 目标观众 | 拼豆爱好者、手工创作者、喜欢送独特礼物的人 |
-| 画面风格 | 暖色调,木桌面,自然光;手机屏幕录制与实物特写交替出现 |
-
----
-
-## 二、核心文案(Slogan / 一句话介绍)
-
-以下任选一条作为标题或结尾定版字:
-
-1. **豆维 · 可扫码的拼豆**
-2. **每一颗珠子,都藏着一句话。**
-3. **拼出来的二维码,扫出来的心意。**
-4. **把想说的话,拼进一幅画里。**
-5. **看得见,也读得到。**
-
-推荐主标题:**看得见,也读得到。——豆维,可扫码的拼豆**
-
----
-
-## 三、主版本分镜脚本(60–90 秒)
-
-> 旁白以第一人称「我」叙述,语气像朋友分享,不念广告稿。
-> 「画面」列标注了你需要准备的素材类型;如果你已有类似镜头,直接对应即可。
-
-| 幕 | 时间 | 画面 | 旁白 / 字幕 | 剪辑提示 |
-|----|------|------|-------------|----------|
-| **第一幕:提出想法** | 0:00–0:08 | 桌面上摆着几幅拼豆作品,阳光照进来。手拿起其中一幅,翻到背面,又翻回来。 | **旁白:** 我做了很多拼豆作品,挂在墙上很好看。但我总在想——它能不能,不止是一幅画? | 慢推镜头,配温暖的钢琴或指弹吉他。最后一帧画面停在作品特写。 |
-| | 0:08–0:14 | 手拿起手机对准拼豆作品「扫一扫」——屏幕弹出一条消息或链接。 | **旁白:** 能不能扫一下,就能看到我想说的话? | 这是全片第一处「惊喜时刻」,音效清脆,屏幕内容要清晰可见。 |
-| **第二幕:实现想法** | 0:14–0:24 | 切到手机屏幕录屏:打开豆维小程序,输入一段文字。 | **旁白:** 所以我做了「豆维」——一个可扫码的拼豆图纸生成器。输入一段话,或者一个链接。 | 屏幕录制加速 2–3 倍,打字过程快放。 |
-| | 0:24–0:34 | 录屏:导入一张照片,裁切、去背景。 | **旁白:** 再选一张你喜欢的照片。它会把照片和二维码,合成一幅完整的拼豆图纸。 | 展示裁切弹窗操作,去背景效果前后对比。 |
-| | 0:34–0:44 | 录屏:拖动滑块调整二维码大小和位置,切换「丰富 / 平衡 / 稳定」模式。 | **旁白:** 二维码可以放大缩小、移到任何位置。颜色会自动匹配 221 色的拼豆色库,还能选择更注重美观、还是更保证能扫出来。 | 滑块操作用慢动作展示,让观众看到图案实时变化。 |
-| **第三幕:制作例子** | 0:44–0:52 | 导出的图纸打印出来,摆在桌上。开始一颗一颗摆珠子。 | **旁白:** 图纸保存下来,打印出来,就可以开始拼了。 | 延时摄影或快剪,展示摆珠过程,保留几秒真实速度的特写。 |
-| | 0:52–0:58 | 熨斗烫过,拼豆板冷却,掀开,成品完成。 | **旁白:** 熨好,冷却,掀开—— | 掀开那一刻音效「叮」,画面干净利落。 |
-| **第四幕:完成例子** | 0:58–1:10 | 手持成品对镜头展示,然后用手机扫描。屏幕上弹出一开始输入的那段话。 | **旁白:** 它不只是一幅画。你把手机对准它——就能读到里面藏着的话。 | 这是全片情绪最高点。扫描过程用真实速度,屏幕内容要清楚。 |
-| | 1:10–1:20 | 多个成品排列展示(不同图案、不同颜色),最后画面淡出到品牌 Logo 和小程序码。 | **旁白:** 豆维,可扫码的拼豆。看得见,也读得到。 | 结尾定格 3 秒,放小程序码,方便观众扫码体验。 |
-
----
-
-## 四、15 秒短视频版(抖音 / 视频号快闪)
-
-| 时间 | 画面 | 字幕(无旁白,纯字幕流) |
-|------|------|--------------------------|
-| 0–3s | 手拿起拼豆作品 → 手机扫描 → 屏幕弹出消息 | 拼豆里,藏着一条消息 |
-| 3–8s | 快剪:输入文字 → 导入照片 → 图纸生成 → 摆珠 | 豆维:输入一句话,选一张图,生成拼豆图纸 |
-| 8–13s | 熨烫 → 掀开 → 成品再扫一次 | 拼好,烫平,扫一下—— |
-| 13–15s | 品牌 Logo + 小程序码 | 消息就出来了。豆维 · 可扫码的拼豆 |
-
-> 快闪版不需要旁白,靠音乐节奏 + 字幕推进。音乐选节奏感强的电子或 Lo-Fi。
-
----
-
-## 五、30 秒版本(朋友圈 / 公众号内嵌)
-
-节奏比 15 秒版稍慢,保留 4 个关键节点:
-
-1. **悬念**(5s):拿起作品 → 扫码 → 弹出内容
-2. **怎么做**(10s):小程序操作快剪(输入 → 导图 → 调整 → 导出)
-3. **手作过程**(8s):摆珠延时 + 熨烫 + 掀开
-4. **结尾**(7s):成品特写 + 再扫一次 + 定版
-
-配乐:轻快指弹吉他或 Lo-Fi,音量压低,让旁白清晰。
-
----
-
-## 六、素材清单
-
-拍摄前对照这份清单,确认已拍到以下镜头(√ 为已有,× 为待补):
-
-| 素材 | 用途 | 状态 |
-|------|------|------|
-| 多幅完成的拼豆作品摆拍(正面 / 斜角 / 背面) | 开头悬念、结尾展示 | ☐ |
-| 手机扫描拼豆作品并弹出内容的实拍 | 全片核心「惊喜时刻」,需拍 2–3 次 | ☐ |
-| 豆维小程序屏幕录制:输入文字、导入图片、裁切、调 QR 位置、切模式 | 第二幕 | ☐ |
-| 图纸导出 / 打印的镜头 | 第三幕开头 | ☐ |
-| 摆珠延时或快剪素材 | 第三幕 | ☐ |
-| 熨斗烫拼豆 + 掀开的特写 | 第三幕高潮 | ☐ |
-| 成品多角度特写(自然光 / 桌面) | 结尾 | ☐ |
-
----
-
-## 七、剪辑建议
-
-- **转场**:幕与幕之间用干净的硬切或快速模糊,不要花哨转场。产品视频要显得克制。
-- **音乐**:主版本选温暖的原声吉他或钢琴;快闪版选节奏感强的 Lo-Fi / 电子。全片一首歌,不要中途换。
-- **节奏**:第三幕(摆珠)可以稍慢,让观众感受手作质感;第二幕(录屏)加速推进。
-- **字幕**:全程加简体中文字幕,关键词用品牌色 `#416d62`(深绿)高亮。
-- **结尾**:小程序码至少停留 3 秒,让观众来得及扫码。
-
----
-
-## 八、旁白全文(主版本,可直接朗读)
-
-> 我做了很多拼豆作品,挂在墙上很好看。但我总在想——它能不能,不止是一幅画?能不能扫一下,就能看到我想说的话?
->
-> 所以我做了「豆维」。输入一段话,或者一个链接,再选一张你喜欢的照片。它会把照片和二维码,合成一幅完整的拼豆图纸。二维码可以放大缩小、移到任何位置,颜色会自动匹配 221 色的拼豆色库,还能选择更注重美观、还是更保证能扫出来。
->
-> 图纸保存下来,打印出来,就可以开始拼了。熨好,冷却,掀开——
->
-> 它不只是一幅画。你把手机对准它,就能读到里面藏着的话。
->
-> 豆维,可扫码的拼豆。看得见,也读得到。
-
diff --git "a/BeadQR/docs/\345\256\241\346\240\270\351\251\263\345\233\236\345\244\204\347\220\206-\346\226\207\346\241\210\344\270\216\346\255\245\351\252\244.md" "b/BeadQR/docs/\345\256\241\346\240\270\351\251\263\345\233\236\345\244\204\347\220\206-\346\226\207\346\241\210\344\270\216\346\255\245\351\252\244.md"
deleted file mode 100644
index 32154ecf4a6048b2035090856a2d3e244d5fcf13..0000000000000000000000000000000000000000
--- "a/BeadQR/docs/\345\256\241\346\240\270\351\251\263\345\233\236\345\244\204\347\220\206-\346\226\207\346\241\210\344\270\216\346\255\245\351\252\244.md"
+++ /dev/null
@@ -1,58 +0,0 @@
-# 审核驳回处理:深度合成误判 — 文案与步骤
-
-> 驳回原因(2026-09-30):小程序服务内容涉及深度合成技术(如 AI 问答、AI 换脸视频、AI 绘画等),属个人主体尚未开放服务类目,建议申请企业主体类型小程序。
-
-## 结论
-
-代码里没有任何 AI 功能:文字是标准二维码编码;"照片转图纸"是确定性本地图像处理(按网格取平均色 → 映射到 221 种固定色号),不用任何模型、不生成新图像。被判"深度合成"大概率是**后台简介 / 服务类目 / 服务内容声明的表述**或审核员看到"照片→生成图纸"产生的误判。
-
-## 路径 A(推荐,最快):修正表述后重新提审
-
-### 1. 检查后台三处(mp.weixin.qq.com)
-
-| 位置 | 检查项 |
-| --- | --- |
-| 服务类目 | 改为 **工具 - 图片处理**(个人主体可选);删除任何 AI / 深度合成相关类目 |
-| 服务内容声明 / 提审问卷 | 凡问"是否提供 AI 生成内容、AI 问答、AI 绘画、深度合成"一律选 **否** |
-| 小程序简介 | 换成下方"新简介",去掉"生成器 / 一键生成 / 智能"等字眼 |
-
-### 2. 新简介(约 90 字,上限 120)
-
-```
-手工拼豆图纸工具:输入一句话或选一张照片,按 MARD 标准色号排成拼豆图纸,拼好微信一扫就能读出内容。支持 A4 矢量 PDF 与图片导出、用量清单。照片仅在本地做取色处理,并经微信内容安全检测。
-```
-
-### 3. 版本描述 / 审核备注(重新提审时填写)
-
-```
-本小程序为拼豆手工图纸工具,不使用任何人工智能或深度合成技术,无 AIGC 功能:
-1. "照片转图纸"为确定性本地图像处理:将用户上传照片按网格取平均色,再映射到固定的 221 种拼豆标准色号(色彩量化 + 最近邻查表),不生成、不合成任何新图像内容,不涉及人脸或生物特征编辑;
-2. 文字功能是将文本编码为标准二维码点阵,非内容生成;
-3. 所有处理均在用户手机本地完成,且已接入微信内容安全接口(security.msgSecCheck / imgSecCheck),检测未通过时禁止生成与导出(fail-closed)。
-请按"工具-图片处理"类目审核。
-```
-
-## 路径 B:申诉
-
-若不想改简介,可直接对本次审核结果发起申诉(审核结果页 → 申诉),粘贴下文:
-
-```
-本小程序为拼豆手工图纸工具,不涉及深度合成技术:
-(1) 不使用 AI 模型 / 神经网络,无 AI 问答、AI 绘画、AI 换脸等 AIGC 功能;
-(2) 照片功能仅做确定性色彩量化:按网格取平均色并映射到 221 种固定标准色号,属于常规图像处理,不生成新图像、不做人脸或生物特征编辑;
-(3) 文字功能为标准二维码编码;
-(4) 已接入微信内容安全检测(msgSecCheck / imgSecCheck),检测未通过不能生成或导出。
-恳请复核,建议按"工具-图片处理"类目审核。
-```
-
-申诉未通过时:修改简介与类目后按路径 A 重新提审(改了表述基本都能过)。
-
-## 路径 C:仅当二次被拒或想保留"生成"叙事
-
-1. **隐藏照片功能**(只保留文字 → 二维码图纸,纯编码无争议)——我可以直接改代码;
-2. **升级主体**:注册个体工商户 / 企业 → 主体变更 → 申请深度合成相关类目 + 算法备案。仅在以后真要做 AI 功能时才值得,当前工具用不到。
-
-## 顺手可做的降风险小改动(可选)
-
-- 首页徽标 `MARD 拼豆图纸生成器` → `MARD 拼豆图纸工具`
-- 分享标题 `豆维 · 可扫码的拼豆图纸生成器` → `豆维 · 可扫码的拼豆图纸`
diff --git a/BeadQR/miniprogram/app.js b/BeadQR/miniprogram/app.js
deleted file mode 100644
index 77c44453096b7460e86e268a5079a6b79c45d25d..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/app.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// 豆维 · 可扫码的拼豆
-App({
- onLaunch() {
- if (!wx.cloud) {
- console.error('当前基础库不支持云开发,内容安全检测不可用')
- return
- }
- wx.cloud.init({
- env: 'cloud1-d6gthxado7f6c9d14',
- traceUser: true,
- })
- },
- globalData: {},
-})
diff --git a/BeadQR/miniprogram/app.json b/BeadQR/miniprogram/app.json
deleted file mode 100644
index c65531905dd809351665a2e54b7406068e24fe14..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/app.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "pages": [
- "pages/index/index"
- ],
- "window": {
- "backgroundColor": "#f6f5f1",
- "backgroundTextStyle": "dark",
- "navigationBarBackgroundColor": "#f6f5f1",
- "navigationBarTitleText": "豆维 · 可扫码的拼豆",
- "navigationBarTextStyle": "black"
- },
- "usingComponents": {
- "privacy-popup": "/components/privacy-popup/index"
- },
- "__usePrivacyCheck__": true,
- "sitemapLocation": "sitemap.json",
- "style": "v2",
- "lazyCodeLoading": "requiredComponents"
-}
diff --git a/BeadQR/miniprogram/app.wxss b/BeadQR/miniprogram/app.wxss
deleted file mode 100644
index 284c483d7c36686985f29a1abfdb8de7b83aead0..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/app.wxss
+++ /dev/null
@@ -1,37 +0,0 @@
-/* 豆维 · 设计变量 */
-page {
- --ink: #16211f;
- --ink-2: #3a4643;
- --muted: #6f7a76;
- --faint: #a4aca8;
- --bg: #f6f5f1;
- --card: #ffffff;
- --line: #ebe8e1;
- --brand: #0f766e;
- --brand-2: #14b8a6;
- --brand-soft: #e6f4f1;
- --brand-deep: #0f3d3a;
- --accent: #ff7a45;
- --accent-soft: #fff1ea;
- --danger: #e5484d;
- --danger-soft: #fdecec;
- --ok: #12a150;
- --ok-soft: #e7f6ed;
- --warn: #c77700;
- --warn-soft: #fff5e0;
- --r-s: 16rpx;
- --r-m: 24rpx;
- --r-l: 36rpx;
- --shadow: 0 8rpx 32rpx rgba(22, 33, 31, 0.06);
-
- background: var(--bg);
- color: var(--ink);
- font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', 'Microsoft YaHei', sans-serif;
- font-size: 28rpx;
- line-height: 1.55;
-}
-
-view, text, textarea, input, button, scroll-view, canvas, image { box-sizing: border-box; }
-
-button { padding: 0; margin: 0; background: none; border: 0; border-radius: 0; line-height: inherit; font-size: inherit; color: inherit; text-align: center; }
-button::after { border: 0; }
diff --git a/BeadQR/miniprogram/assets/icon.png b/BeadQR/miniprogram/assets/icon.png
deleted file mode 100644
index 7d10be4c5227e54d35f75210df674fac3218ff05..0000000000000000000000000000000000000000
Binary files a/BeadQR/miniprogram/assets/icon.png and /dev/null differ
diff --git a/BeadQR/miniprogram/assets/miniprogram-code.png b/BeadQR/miniprogram/assets/miniprogram-code.png
deleted file mode 100644
index 5a295d47d3f983270485c2eefceb296ce2729810..0000000000000000000000000000000000000000
Binary files a/BeadQR/miniprogram/assets/miniprogram-code.png and /dev/null differ
diff --git a/BeadQR/miniprogram/assets/shield.svg b/BeadQR/miniprogram/assets/shield.svg
deleted file mode 100644
index 50456c42007effc88842ab4b474c62b6b64af781..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/assets/shield.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/BeadQR/miniprogram/components/privacy-popup/index.js b/BeadQR/miniprogram/components/privacy-popup/index.js
deleted file mode 100644
index 4e5d889e8cec37f4235f72742b66926a17825115..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/components/privacy-popup/index.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// 隐私保护指引弹窗:用户首次调用相册/相机/保存到相册等隐私接口时由微信触发
-Component({
- data: { visible: false, contractName: '《豆维隐私保护指引》' },
-
- lifetimes: {
- attached() {
- if (!wx.onNeedPrivacyAuthorization) return
- this._listener = (resolve) => {
- this._resolve = resolve
- this.setData({ visible: true })
- }
- wx.onNeedPrivacyAuthorization(this._listener)
- if (wx.getPrivacySetting) {
- wx.getPrivacySetting({
- success: (res) => {
- if (res.privacyContractName) this.setData({ contractName: res.privacyContractName })
- },
- })
- }
- },
- },
-
- methods: {
- openContract() {
- if (wx.openPrivacyContract) wx.openPrivacyContract({})
- },
- handleAgree() {
- if (this._resolve) this._resolve({ buttonId: 'privacy-agree-btn', event: 'agree' })
- this._resolve = null
- this.setData({ visible: false })
- },
- handleDisagree() {
- if (this._resolve) this._resolve({ event: 'disagree' })
- this._resolve = null
- this.setData({ visible: false })
- wx.showToast({ title: '未同意将无法选择照片或保存图纸', icon: 'none' })
- },
- noop() {},
- },
-})
diff --git a/BeadQR/miniprogram/components/privacy-popup/index.json b/BeadQR/miniprogram/components/privacy-popup/index.json
deleted file mode 100644
index a89ef4dbeefa01f5cd7971973aa4db6498d139f7..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/components/privacy-popup/index.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "component": true,
- "usingComponents": {}
-}
diff --git a/BeadQR/miniprogram/components/privacy-popup/index.wxml b/BeadQR/miniprogram/components/privacy-popup/index.wxml
deleted file mode 100644
index 52eb9a5d528a586383b94527a8a6814bea849ea0..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/components/privacy-popup/index.wxml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
- 隐私保护提示
-
- 为了帮你把照片做成拼豆图纸,豆维需要读取你选择的照片、保存图纸到相册。照片仅在本机处理,送检的压缩副本会在内容安全检测后立即删除。使用前请阅读
- {{contractName}}。
-
-
-
-
-
-
-
diff --git a/BeadQR/miniprogram/components/privacy-popup/index.wxss b/BeadQR/miniprogram/components/privacy-popup/index.wxss
deleted file mode 100644
index 0310cb844f9df69a543c3477b2353f044a03cd4a..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/components/privacy-popup/index.wxss
+++ /dev/null
@@ -1,10 +0,0 @@
-.mask { position: fixed; inset: 0; z-index: 999; background: rgba(15, 23, 22, 0.55); display: flex; align-items: flex-end; }
-.sheet { width: 100%; background: #fff; border-radius: 40rpx 40rpx 0 0; padding: 48rpx 40rpx calc(40rpx + env(safe-area-inset-bottom)); box-sizing: border-box; }
-.title { font-size: 36rpx; font-weight: 700; color: #1d2b2a; margin-bottom: 20rpx; }
-.desc { font-size: 28rpx; line-height: 1.7; color: #55615c; }
-.link { color: #0f766e; font-weight: 600; }
-.actions { display: flex; gap: 20rpx; margin-top: 40rpx; }
-.btn { flex: 1; height: 92rpx; line-height: 92rpx; border-radius: 999rpx; font-size: 30rpx; font-weight: 600; margin: 0 !important; padding: 0 !important; width: auto !important; }
-.btn::after { border: 0; }
-.ghost { background: #f1f3f2; color: #55615c; }
-.primary { background: #0f766e; color: #fff; }
diff --git a/BeadQR/miniprogram/pages/index/index.js b/BeadQR/miniprogram/pages/index/index.js
deleted file mode 100644
index 59dd120e7362c0a310d02be21431a930cfd65ba3..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/pages/index/index.js
+++ /dev/null
@@ -1,1073 +0,0 @@
-// 豆维主页面
-// 大数据(色格、图片、画布节点)一律挂在 this._ 上,不进 setData,保证滑动/输入流畅
-const { MATCH_MODES, PRESETS, preparePalette } = require('../../utils/palette')
-const { makeQr, createPlacement, SAMPLE_TEXT } = require('../../utils/qr')
-const { getImageDimensions, drawCropped, sampleImage, removeSimpleBackground } = require('../../utils/imaging')
-const { computeArtwork } = require('../../utils/engine')
-const { selfCheck } = require('../../utils/scancheck')
-const { renderPreview, patternPageLayout, drawPatternPage, buildInfoPages, drawWatermark } = require('../../utils/pattern')
-const { PdfDoc, planPatternPages, addPatternPages, addImagePage } = require('../../utils/pdf')
-const security = require('../../utils/security')
-const { createIntro } = require('../../utils/intro')
-
-const LEVELS = [
- { id: 'M', label: 'M', hint: '格子少' },
- { id: 'Q', label: 'Q', hint: '均衡' },
- { id: 'H', label: 'H', hint: '最耐磨' },
-]
-const QUIET_OPTIONS = [
- { id: 0, label: '无' },
- { id: 1, label: '1 格' },
- { id: 2, label: '2 格' },
-]
-const BEAD_STYLES = [
- { id: 'square', label: '方豆' },
- { id: 'round', label: '圆豆' },
- { id: 'hollow', label: '中空豆' },
-]
-const GRID_COLORS = ['#0f766e', '#16211f', '#e5484d', '#3b82f6', '#a855f7']
-const POSITIONS = [0, 50, 100]
-const MAX_CANVAS_SIDE = 8000
-const MAX_CANVAS_PIXELS = 16000000
-const CROP_SIZE = 640
-const FILE_PREFIX = 'douwei-'
-
-function fitScale(w, h) {
- return Math.min(1, MAX_CANVAS_SIDE / w, MAX_CANVAS_SIDE / h, Math.sqrt(MAX_CANVAS_PIXELS / (w * h)))
-}
-
-function formatNumber(n) {
- return String(n).replace(/\B(?=(\d{3})+(?!\d))/g, ',')
-}
-
-Page({
- data: {
- // 导航
- statusBarHeight: 20,
- navHeight: 44,
- navSolid: false,
- // 1. 内容
- text: '',
- textStatus: 'idle', // idle | checking | pass | risky | error
- scanImportLoading: false,
- // 2. 照片
- hasImage: false,
- imageThumb: '',
- imageMeta: '',
- removeBackground: false,
- bgTolerance: 22,
- // 3. 效果
- qrScale: 100,
- posX: 50,
- posY: 50,
- positions: POSITIONS,
- modeId: 'balanced',
- matchModes: MATCH_MODES,
- advancedOpen: false,
- fineTuneOpen: false,
- presets: PRESETS.map((p) => ({ id: p.id, short: p.short, detail: p.detail })),
- paletteId: '221',
- coherence: 40,
- cleanup: true,
- levels: LEVELS,
- level: 'H',
- quietOptions: QUIET_OPTIONS,
- quiet: 1,
- // 预览与统计
- generating: false,
- isSample: true,
- showIntro: true, // 无内容时播放动态演示,写下内容后切回真实预览
- textFocus: false,
- gridText: '—',
- beadsText: '—',
- colorsText: '—',
- qrGridText: '',
- scanState: 'idle', // idle | checking | ok | fail
- usage: [],
- usageMore: 0,
- usageExpanded: false,
- usageAll: [],
- // 裁切
- cropVisible: false,
- cropCheck: 'idle', // checking | pass | risky | error
- draftFocusX: 50,
- draftFocusY: 50,
- draftZoom: 100,
- draftFlipH: false,
- draftFlipV: false,
- draftRemoveBg: false,
- draftBgTolerance: 22,
- // 导出
- exportVisible: false,
- exportFormat: 'pdf',
- exportLayout: 'combined',
- exportQuality: 'hd',
- beadStyles: BEAD_STYLES,
- beadStyle: 'square',
- gridEnabled: true,
- gridInterval: 10,
- gridColors: GRID_COLORS,
- gridColor: '#0f766e',
- watermark: '',
- watermarkStatus: 'idle',
- exporting: false,
- exportStep: '',
- exportResult: null, // { kind, files: [{ name, path }] }
- },
-
- // —— 生命周期 ——
-
- onLoad() {
- const win = wx.getWindowInfo ? wx.getWindowInfo() : wx.getSystemInfoSync()
- let navHeight = 44
- try {
- const capsule = wx.getMenuButtonBoundingClientRect()
- if (capsule && capsule.top) navHeight = (capsule.top - win.statusBarHeight) * 2 + capsule.height
- } catch (e) { /* 使用默认高度 */ }
- this._dpr = Math.min(3, win.pixelRatio || 2)
- this._timers = {}
- this._nodes = {}
- this._token = 0
- this.setData({ statusBarHeight: win.statusBarHeight || 20, navHeight })
- },
-
- onReady() {
- wx.createSelectorQuery().in(this)
- .select('#preview').fields({ node: true, size: true })
- .select('#work').fields({ node: true })
- .select('#security').fields({ node: true })
- .exec((res) => {
- this._nodes.preview = res[0] && res[0].node
- this._previewCss = (res[0] && res[0].width) || 300
- this._nodes.work = res[1] && res[1].node
- this._nodes.security = res[2] && res[2].node
- this.loadMpCode()
- this.schedule(0)
- })
- },
-
- onUnload() {
- Object.keys(this._timers).forEach((k) => clearTimeout(this._timers[k]))
- this.stopIntro()
- },
-
- onShow() {
- this._hidden = false
- if (this._nodes && this._nodes.preview) this.syncIntro()
- },
-
- onHide() {
- this._hidden = true
- this.pauseIntro()
- },
-
- onPageScroll(e) {
- const solid = e.scrollTop > 40
- if (solid !== this.data.navSolid) this.setData({ navSolid: solid })
- // 演示区滚出屏幕后暂停动画,省电
- const away = e.scrollTop > 650
- if (away !== this._scrolledAway) {
- this._scrolledAway = away
- this.syncIntro()
- }
- },
-
- // 分享的是小程序页面卡片,不携带用户内容
- onShareAppMessage() {
- return { title: '把一句话藏进拼豆里,微信一扫就能读出来', path: '/pages/index/index' }
- },
- onShareTimeline() {
- return { title: '豆维 · 可扫码的拼豆图纸生成器' }
- },
-
- loadMpCode() {
- if (!this._nodes.work) return
- const image = this._nodes.work.createImage()
- image.onload = () => { this._mpCode = image }
- image.onerror = () => { this._mpCode = null }
- image.src = '/assets/miniprogram-code.png'
- },
-
- debounce(key, fn, wait) {
- clearTimeout(this._timers[key])
- this._timers[key] = setTimeout(fn, wait)
- },
-
- noop() {},
-
- openPrivacy() {
- if (wx.openPrivacyContract) {
- wx.openPrivacyContract({ fail: () => wx.showToast({ title: '请在微信内查看隐私保护指引', icon: 'none' }) })
- }
- },
-
- showRules() {
- wx.showModal({
- title: '内容规范',
- content: '二维码内容、水印和照片都会经过微信内容安全检测。请勿输入或上传违法违规、色情低俗、暴力恐怖、侵犯他人权益等内容;检测未通过或检测异常时无法生成与导出。如发现不良内容,可通过页面底部“投诉与反馈”告诉我们。',
- showCancel: false,
- confirmText: '我知道了',
- })
- },
-
- // —— 生成管线 ——
-
- schedule(wait = 120) {
- this.debounce('run', () => this.run(), wait)
- },
-
- run() {
- if (!this._nodes.preview || !this._nodes.work) return
- // 没写内容、也没选照片:示例二维码没有意义,改为播放动态演示
- if (!this.data.text.trim() && !this._source) {
- this._token += 1
- this.setData({
- showIntro: true, generating: false, isSample: true, scanState: 'idle', usage: [], usageAll: [], usageMore: 0,
- }, () => this.syncIntro())
- return
- }
- this.stopIntro()
- if (this.data.showIntro) this.setData({ showIntro: false })
- const token = ++this._token
- this.setData({ generating: true }, () => {
- // 先让“生成中”状态渲染一帧,再做同步计算
- setTimeout(() => {
- if (token !== this._token) return
- try {
- this.compute()
- this.afterCompute(token)
- } catch (error) {
- console.error('生成失败', error)
- this.setData({ generating: false })
- wx.showToast({ title: '内容太长或图片异常,请调整后重试', icon: 'none' })
- }
- }, 16)
- })
- },
-
- compute() {
- const d = this.data
- const text = d.text.trim()
- const qrKey = `${text}|${d.level}`
- if (!this._qr || this._qrKey !== qrKey) {
- this._qr = makeQr(text, d.level)
- this._qrKey = qrKey
- }
- const src = this._source
- const placement = createPlacement(this._qr.size, {
- scale: d.qrScale, posX: d.posX, posY: d.posY, quiet: d.quiet, hasImage: Boolean(src),
- })
- let base = null
- if (src) {
- const c = src.crop
- const baseKey = `${placement.size}|${c.focusX}|${c.focusY}|${c.zoom}|${c.flipH}|${c.flipV}|${d.removeBackground}|${d.bgTolerance}`
- if (this._baseKey !== baseKey) {
- const sampled = sampleImage(this._nodes.work, src.image, placement.size, c)
- if (d.removeBackground) sampled.mask = removeSimpleBackground(sampled.rgb, placement.size, d.bgTolerance)
- this._base = sampled
- this._baseKey = baseKey
- }
- base = this._base
- }
- const pal = preparePalette(d.paletteId)
- this._artwork = computeArtwork(base, this._qr, placement, pal, {
- modeId: d.modeId, coherence: d.coherence, cleanup: d.cleanup,
- })
- },
-
- afterCompute(token) {
- const art = this._artwork
- this.drawPreview()
- const usageAll = art.usage.map((u) => ({ id: u.id, hex: u.hex, count: u.count }))
- this.setData({
- generating: false,
- isSample: this._qr.isSample,
- gridText: `${art.size}×${art.size}`,
- beadsText: formatNumber(art.beads),
- colorsText: String(art.usage.length),
- qrGridText: `${this._qr.size}×${this._qr.size}`,
- usage: usageAll.slice(0, 12),
- usageAll: this.data.usageExpanded ? usageAll : [],
- usageMore: Math.max(0, usageAll.length - 12),
- scanState: 'checking',
- })
- this._usageAll = usageAll
- // 扫码自检放到下一轮,避免阻塞预览出图
- this.debounce('scan', () => {
- if (token !== this._token) return
- const expected = this.data.text.trim() || SAMPLE_TEXT
- const result = selfCheck(art, expected)
- if (token === this._token) this.setData({ scanState: result.ok ? 'ok' : 'fail' })
- }, 60)
- },
-
- drawPreview() {
- const node = this._nodes.preview
- if (!node || !this._artwork) return
- const px = Math.round(this._previewCss * this._dpr)
- renderPreview(node, this._artwork, px, this.data.beadStyle)
- },
-
- // —— 动态演示 ——
-
- syncIntro() {
- const should = this.data.showIntro && !this._hidden && !this._scrolledAway && !this.data.cropVisible
- if (should) this.startIntro()
- else this.pauseIntro()
- },
-
- startIntro() {
- if (this._introPlayer) return
- const node = this._nodes.preview
- if (!node || !this._nodes.work) return
- if (!this._intro) {
- try {
- this._intro = createIntro({ workCanvas: this._nodes.work })
- } catch (error) {
- console.error('演示动画初始化失败', error)
- return
- }
- }
- const px = Math.round(this._previewCss * this._dpr)
- node.width = px
- node.height = px
- const ctx = node.getContext('2d')
- const raf = node.requestAnimationFrame ? (f) => node.requestAnimationFrame(f) : (f) => setTimeout(f, 16)
- const caf = node.cancelAnimationFrame ? (id) => node.cancelAnimationFrame(id) : (id) => clearTimeout(id)
- const player = { start: Date.now() - (this._introElapsed || 0), last: 0, id: 0, caf }
- const tick = () => {
- if (this._introPlayer !== player) return
- const now = Date.now()
- if (now - player.last >= 30) { // 约 30 帧/秒,流畅且省电
- player.last = now
- this._introElapsed = now - player.start
- this._intro.draw(ctx, this._introElapsed / 1000, px)
- }
- player.id = raf(tick)
- }
- this._introPlayer = player
- tick()
- },
-
- pauseIntro() {
- const player = this._introPlayer
- if (!player) return
- this._introPlayer = null
- player.caf(player.id)
- },
-
- stopIntro() {
- this.pauseIntro()
- this._introElapsed = 0
- },
-
- replayIntro() {
- if (!this.data.showIntro) return
- this.stopIntro()
- this.syncIntro()
- },
-
- // 引导用户开始:滚到第 1 步并弹出键盘
- startCreate() {
- wx.pageScrollTo({
- selector: '#step1',
- offsetTop: -(this.data.statusBarHeight + this.data.navHeight + 12),
- duration: 300,
- })
- setTimeout(() => this.setData({ textFocus: true }), 320)
- },
-
- onTextBlur() {
- if (this.data.textFocus) this.setData({ textFocus: false })
- },
-
- // —— 1. 内容 ——
-
- onTextInput(e) {
- const text = e.detail.value
- this.setData({ text, textStatus: text.trim() ? 'checking' : 'idle' })
- this.schedule(220)
- this.debounce('textCheck', () => this.verifyText(text), 650)
- },
-
- clearText() {
- this.setData({ text: '', textStatus: 'idle' })
- this.schedule(0)
- },
-
- verifyText(raw) {
- const value = String(raw || '').trim()
- if (!value) return
- security.checkText(value, 2).then(({ status }) => {
- if (this.data.text.trim() !== value) return
- this.setData({ textStatus: status })
- if (status === 'risky') wx.showToast({ title: security.MESSAGES.risky, icon: 'none' })
- })
- },
-
- scanImport() {
- wx.scanCode({
- onlyFromCamera: false,
- scanType: ['qrCode'],
- success: (res) => {
- const decoded = String(res.result || '').trim().slice(0, 120)
- if (!decoded) { wx.showToast({ title: '二维码里没有内容', icon: 'none' }); return }
- this.setData({ scanImportLoading: true })
- // 扫码得到的内容同样先过内容安全检测,通过后才填入
- security.checkText(decoded, 2).then(({ status }) => {
- this.setData({ scanImportLoading: false })
- if (status !== 'pass') { wx.showToast({ title: security.MESSAGES[status], icon: 'none' }); return }
- this.setData({ text: decoded, textStatus: 'pass' })
- this.schedule(0)
- wx.showToast({ title: '已导入二维码内容', icon: 'none' })
- })
- },
- fail: (err) => {
- if (err && /cancel/i.test(err.errMsg || '')) return
- wx.showToast({ title: '没有识别到二维码', icon: 'none' })
- },
- })
- },
-
- // —— 2. 照片 ——
-
- loadImage(path, info) {
- return new Promise((resolve, reject) => {
- const image = this._nodes.work.createImage()
- image.onload = () => {
- if (info && info.width) { image._w = info.width; image._h = info.height }
- resolve(image)
- }
- image.onerror = () => reject(new Error('IMAGE_LOAD_FAILED'))
- image.src = path
- })
- },
-
- chooseImage() {
- wx.chooseMedia({
- count: 1,
- mediaType: ['image'],
- sizeType: ['compressed'],
- sourceType: ['album', 'camera'],
- success: (res) => {
- const file = res.tempFiles && res.tempFiles[0]
- if (file && file.tempFilePath) this.prepareImage(file.tempFilePath)
- },
- fail: (err) => {
- if (err && /cancel/i.test(err.errMsg || '')) return
- wx.showToast({ title: '没有选到照片', icon: 'none' })
- },
- })
- },
-
- prepareImage(path) {
- wx.showLoading({ title: '读取照片…', mask: true })
- new Promise((resolve) => {
- wx.getImageInfo({ src: path, success: resolve, fail: () => resolve(null) })
- })
- .then((info) => this.loadImage(path, info).then((image) => ({ image, info })))
- .then(({ image }) => {
- wx.hideLoading()
- this._pending = { image, path }
- // 选图后立即在后台做内容安全检测;同时打开构图编辑,检测通过后才能使用
- this.startImageCheck(this._pending)
- this.openCrop(true)
- })
- .catch(() => {
- wx.hideLoading()
- wx.showToast({ title: '照片读取失败,请换一张 JPG / PNG', icon: 'none' })
- })
- },
-
- startImageCheck(pending) {
- pending.status = 'checking'
- this.setData({ cropCheck: 'checking' })
- pending.check = security.checkImage(pending.path, pending.image, this._nodes.security).then(({ status }) => {
- pending.status = status
- if (this._pending === pending) {
- this.setData({ cropCheck: status })
- if (pending.applyWhenPassed && status === 'pass') this.applyCrop()
- pending.applyWhenPassed = false
- }
- return status
- })
- },
-
- retryImageCheck() {
- if (this._pending) this.startImageCheck(this._pending)
- },
-
- editImage() {
- if (!this._source) return
- this._pending = { image: this._source.image, path: this._source.path, status: 'pass' }
- this.setData({ cropCheck: 'pass' })
- this.openCrop(false)
- },
-
- removeImage() {
- this._source = null
- this._base = null
- this._baseKey = ''
- this.setData({ hasImage: false, imageThumb: '', imageMeta: '', removeBackground: false })
- this.schedule(0)
- },
-
- // —— 裁切编辑 ——
-
- openCrop(isNew) {
- const crop = !isNew && this._source ? this._source.crop : null
- this.pauseIntro()
- this.setData({
- cropVisible: true,
- draftFocusX: crop ? crop.focusX : 50,
- draftFocusY: crop ? crop.focusY : 50,
- draftZoom: crop ? Math.round(crop.zoom * 100) : 100,
- draftFlipH: crop ? crop.flipH : false,
- draftFlipV: crop ? crop.flipV : false,
- draftRemoveBg: isNew ? false : this.data.removeBackground,
- draftBgTolerance: isNew ? 22 : this.data.bgTolerance,
- }, () => {
- wx.createSelectorQuery().in(this)
- .select('#crop').fields({ node: true, size: true })
- .select('#crop').boundingClientRect()
- .exec((res) => {
- this._nodes.crop = res[0] && res[0].node
- this._cropCss = (res[0] && res[0].width) || 300
- this._cropRect = res[1] || { left: 0, top: 0 }
- this.drawCrop()
- })
- })
- },
-
- drawCrop() {
- const node = this._nodes.crop
- const pending = this._pending
- if (!node || !pending) return
- node.width = CROP_SIZE
- node.height = CROP_SIZE
- const ctx = node.getContext('2d')
- const d = this.data
- ctx.imageSmoothingEnabled = true
- drawCropped(ctx, pending.image, CROP_SIZE, CROP_SIZE, {
- focusX: d.draftFocusX, focusY: d.draftFocusY, zoom: d.draftZoom / 100, flipH: d.draftFlipH, flipV: d.draftFlipV,
- })
- // 三分线,仅辅助构图
- ctx.strokeStyle = 'rgba(255,255,255,0.5)'
- ctx.lineWidth = 1.5
- ctx.beginPath()
- for (let i = 1; i < 3; i += 1) {
- const p = Math.round(CROP_SIZE * i / 3) + 0.5
- ctx.moveTo(p, 0); ctx.lineTo(p, CROP_SIZE)
- ctx.moveTo(0, p); ctx.lineTo(CROP_SIZE, p)
- }
- ctx.stroke()
- },
-
- touchPoint(t) {
- const rect = this._cropRect || { left: 0, top: 0 }
- const x = t.clientX == null ? (t.pageX == null ? t.x : t.pageX) : t.clientX
- const y = t.clientY == null ? (t.pageY == null ? t.y : t.pageY) : t.clientY
- return { x: x - rect.left, y: y - rect.top }
- },
-
- touchDistance(touches) {
- const a = this.touchPoint(touches[0])
- const b = this.touchPoint(touches[1])
- return Math.hypot(b.x - a.x, b.y - a.y)
- },
-
- onCropStart(e) {
- const touches = e.touches || []
- if (!touches[0]) return
- if (touches.length >= 2) {
- this._gesture = { type: 'pinch', distance: this.touchDistance(touches), zoom: this.data.draftZoom }
- return
- }
- this._gesture = { type: 'drag', ...this.touchPoint(touches[0]), focusX: this.data.draftFocusX, focusY: this.data.draftFocusY }
- },
-
- onCropMove(e) {
- const touches = e.touches || []
- const g = this._gesture
- const pending = this._pending
- if (!touches[0] || !g || !pending) return
- if (touches.length >= 2) {
- if (g.type !== 'pinch') {
- this._gesture = { type: 'pinch', distance: this.touchDistance(touches), zoom: this.data.draftZoom }
- return
- }
- const zoom = Math.max(100, Math.min(400, Math.round(g.zoom * this.touchDistance(touches) / g.distance)))
- this.setData({ draftZoom: zoom })
- this.debounce('crop', () => this.drawCrop(), 16)
- return
- }
- if (g.type !== 'drag') return
- const p = this.touchPoint(touches[0])
- const cssScale = CROP_SIZE / (this._cropCss || CROP_SIZE)
- const src = getImageDimensions(pending.image)
- const scale = Math.max(CROP_SIZE / src.width, CROP_SIZE / src.height) * (this.data.draftZoom / 100)
- const w = src.width * scale
- const h = src.height * scale
- const clamp = (v) => Math.max(0, Math.min(100, v))
- const dirX = this.data.draftFlipH ? -1 : 1
- const dirY = this.data.draftFlipV ? -1 : 1
- const fx = Math.abs(w - CROP_SIZE) < 0.01 ? g.focusX : clamp(g.focusX + dirX * ((p.x - g.x) * cssScale / (CROP_SIZE - w)) * 100)
- const fy = Math.abs(h - CROP_SIZE) < 0.01 ? g.focusY : clamp(g.focusY + dirY * ((p.y - g.y) * cssScale / (CROP_SIZE - h)) * 100)
- this.setData({ draftFocusX: fx, draftFocusY: fy })
- this.debounce('crop', () => this.drawCrop(), 16)
- },
-
- onCropEnd() {
- this._gesture = null
- clearTimeout(this._timers.crop)
- this.drawCrop()
- },
-
- onDraftZoom(e) {
- this.setData({ draftZoom: Number(e.detail.value) })
- this.debounce('crop', () => this.drawCrop(), 16)
- },
- resetCrop() { this.setData({ draftFocusX: 50, draftFocusY: 50, draftZoom: 100 }, () => this.drawCrop()) },
- flipH() { this.setData({ draftFlipH: !this.data.draftFlipH }, () => this.drawCrop()) },
- flipV() { this.setData({ draftFlipV: !this.data.draftFlipV }, () => this.drawCrop()) },
- onDraftRemoveBg(e) { this.setData({ draftRemoveBg: e.detail.value }) },
- onDraftBgTolerance(e) { this.setData({ draftBgTolerance: Number(e.detail.value) }) },
-
- cancelCrop() {
- if (this._pending) this._pending.applyWhenPassed = false
- this.setData({ cropVisible: false }, () => this.syncIntro())
- },
-
- applyCrop() {
- const pending = this._pending
- if (!pending) return
- if (pending.status === 'checking') {
- // 检测未完成:记住用户意图,通过后自动应用
- pending.applyWhenPassed = true
- wx.showToast({ title: '正在做内容安全检测,通过后自动应用', icon: 'none' })
- return
- }
- if (pending.status !== 'pass') {
- wx.showToast({ title: security.MESSAGES[pending.status] || security.MESSAGES.error, icon: 'none' })
- return
- }
- const d = this.data
- const src = getImageDimensions(pending.image)
- this._source = {
- image: pending.image,
- path: pending.path,
- crop: { focusX: d.draftFocusX, focusY: d.draftFocusY, zoom: d.draftZoom / 100, flipH: d.draftFlipH, flipV: d.draftFlipV },
- }
- this._baseKey = ''
- this.setData({
- cropVisible: false,
- hasImage: true,
- imageThumb: pending.path,
- imageMeta: `${src.width}×${src.height} · 已通过安全检测`,
- removeBackground: d.draftRemoveBg,
- bgTolerance: d.draftBgTolerance,
- // 首次导入照片时,二维码默认铺满全图;用户可再缩小
- })
- this.schedule(0)
- },
-
- // —— 3. 效果 ——
-
- onScaleChanging(e) { this.setData({ qrScale: Number(e.detail.value) }); this.schedule(160) },
- onScaleChange(e) { this.setData({ qrScale: Number(e.detail.value) }); this.schedule(0) },
- pickPosition(e) {
- const { x, y } = e.currentTarget.dataset
- this.setData({ posX: Number(x), posY: Number(y) })
- this.schedule(0)
- },
- toggleFineTune() { this.setData({ fineTuneOpen: !this.data.fineTuneOpen }) },
- onPosX(e) { this.setData({ posX: Number(e.detail.value) }); this.schedule(100) },
- onPosY(e) { this.setData({ posY: Number(e.detail.value) }); this.schedule(100) },
- pickMode(e) { this.setData({ modeId: e.currentTarget.dataset.id }); this.schedule(0) },
- toggleAdvanced() { this.setData({ advancedOpen: !this.data.advancedOpen }) },
- pickPalette(e) { this.setData({ paletteId: e.currentTarget.dataset.id }); this.schedule(0) },
- onCoherence(e) { this.setData({ coherence: Number(e.detail.value) }); this.schedule(200) },
- onCleanup(e) { this.setData({ cleanup: e.detail.value }); this.schedule(0) },
- pickLevel(e) { this.setData({ level: e.currentTarget.dataset.id }); this.schedule(0) },
- pickQuiet(e) { this.setData({ quiet: Number(e.currentTarget.dataset.id) }); this.schedule(0) },
- onBgToggle(e) { this.setData({ removeBackground: e.detail.value }); this.schedule(0) },
-
- applyScanFix() {
- // 自检未通过时的一键修复:扫码优先 + 1 格白边 + H 级纠错
- this.setData({ modeId: 'strict', quiet: Math.max(1, this.data.quiet), level: 'H' })
- this.schedule(0)
- wx.showToast({ title: '已切换为扫码优先', icon: 'none' })
- },
-
- toggleUsage() {
- const expanded = !this.data.usageExpanded
- this.setData({ usageExpanded: expanded, usageAll: expanded ? (this._usageAll || []) : [] })
- },
-
- // 生成当前预览图,用微信“识别图中二维码”实测
- verifyScan() {
- const node = this._nodes.preview
- if (!node) return
- wx.canvasToTempFilePath({
- canvas: node,
- fileType: 'png',
- success: (res) => {
- wx.previewImage({ urls: [res.tempFilePath], showmenu: true })
- wx.showToast({ title: '长按图片,选择“识别图中二维码”', icon: 'none', duration: 2500 })
- },
- fail: () => wx.showToast({ title: '预览生成失败,请重试', icon: 'none' }),
- })
- },
-
- // —— 导出 ——
-
- openExport() {
- if (!this.data.text.trim()) {
- this.startCreate()
- return
- }
- if (!this._artwork) return
- if (this.data.textStatus === 'risky') {
- wx.showToast({ title: security.MESSAGES.risky, icon: 'none' })
- return
- }
- this.setData({ exportVisible: true, exportResult: null })
- },
- closeExport() {
- if (this.data.exporting) return
- this.setData({ exportVisible: false })
- },
- pickFormat(e) { this.setData({ exportFormat: e.currentTarget.dataset.id, exportResult: null }) },
- pickLayout(e) { this.setData({ exportLayout: e.currentTarget.dataset.id, exportResult: null }) },
- pickQuality(e) { this.setData({ exportQuality: e.currentTarget.dataset.id, exportResult: null }) },
- pickBeadStyle(e) {
- this.setData({ beadStyle: e.currentTarget.dataset.id, exportResult: null }, () => this.drawPreview())
- },
- onGridToggle(e) { this.setData({ gridEnabled: e.detail.value, exportResult: null }) },
- pickInterval(e) { this.setData({ gridInterval: Number(e.currentTarget.dataset.id), exportResult: null }) },
- pickGridColor(e) { this.setData({ gridColor: e.currentTarget.dataset.color, exportResult: null }) },
- onWatermark(e) {
- const watermark = e.detail.value
- this.setData({ watermark, watermarkStatus: watermark.trim() ? 'checking' : 'idle', exportResult: null })
- this.debounce('wmCheck', () => {
- const value = watermark.trim()
- if (!value) return
- security.checkText(value, 1).then(({ status }) => {
- if (this.data.watermark.trim() === value) this.setData({ watermarkStatus: status })
- })
- }, 650)
- },
-
- gridSettings() {
- return { enabled: this.data.gridEnabled, interval: this.data.gridInterval, color: this.data.gridColor, opacity: 60 }
- },
-
- capture(fileType, quality) {
- return new Promise((resolve, reject) => {
- wx.canvasToTempFilePath({
- canvas: this._nodes.work,
- fileType,
- quality,
- success: (res) => resolve(res.tempFilePath),
- fail: reject,
- })
- })
- },
-
- step(label) {
- return new Promise((resolve) => this.setData({ exportStep: label }, () => setTimeout(resolve, 16)))
- },
-
- async startExport() {
- if (this.data.exporting || !this._artwork) return
- this.setData({ exporting: true, exportResult: null })
- try {
- // 平台合规:导出前再次确认所有用户文本均已通过内容安全检测(已通过的走缓存,无额外等待)
- await this.step('内容安全校验…')
- const check = await security.checkTexts([
- { value: this.data.text, scene: 2 },
- { value: this.data.watermark, scene: 1 },
- ])
- if (check.status !== 'pass') {
- wx.showToast({ title: security.MESSAGES[check.status], icon: 'none' })
- if (check.status === 'risky') this.setData({ textStatus: security.isTextPassed(this.data.text) ? 'pass' : 'risky' })
- return
- }
- if (this._source && !this.data.hasImage) throw new Error('IMAGE_STATE')
- this.cleanOldFiles()
- if (this.data.exportFormat === 'png') await this.exportPng()
- else await this.exportPdf()
- } catch (error) {
- console.error('导出失败', error)
- wx.showToast({ title: '导出失败,请重试(可尝试“标准”清晰度)', icon: 'none' })
- } finally {
- this.setData({ exporting: false, exportStep: '' })
- }
- },
-
- // 按清晰度求每格像素:高清长边约 4000px,标准约 2400px
- pngCellSize() {
- const size = this._artwork.size
- const maxSide = this.data.exportQuality === 'hd' ? 4000 : 2400
- let cell = Math.max(12, Math.min(72, Math.floor(maxSide / (size + 5))))
- while (cell > 12) {
- const L = patternPageLayout(size, cell)
- if (Math.max(L.width, L.height) <= maxSide) break
- cell -= 1
- }
- return cell
- },
-
- patternMeta() {
- const art = this._artwork
- return `${art.size}×${art.size} 格 · ${formatNumber(art.beads)} 颗 · ${art.usage.length} 色 · ${art.pal.label} · 扫码内容:${this.data.text.trim()}`
- },
-
- infoParams(width) {
- return {
- artwork: this._artwork,
- width,
- text: this.data.text.trim(),
- paletteLabel: `${this._artwork.pal.label}(本作品用 ${this._artwork.usage.length} 色)`,
- mpCode: this._mpCode || null,
- thumbnail: true,
- }
- },
-
- async exportPng() {
- const node = this._nodes.work
- const art = this._artwork
- const cell = this.pngCellSize()
- const L = patternPageLayout(art.size, cell)
- const wm = this.data.watermark.trim()
- const drawPattern = (ctx) => drawPatternPage(ctx, art, { cell, style: this.data.beadStyle, grid: this.gridSettings(), meta: this.patternMeta() })
- const files = []
- if (this.data.exportLayout === 'separate') {
- await this.step('绘制图纸…')
- node.width = L.width
- node.height = L.height
- const ctx = node.getContext('2d')
- drawPattern(ctx)
- drawWatermark(ctx, L.width, L.height, wm)
- files.push({ name: '拼豆图纸', path: await this.capture('png') })
- const info = buildInfoPages(this.infoParams(this.data.exportQuality === 'hd' ? 2000 : 1400))
- for (let p = 0; p < info.pageCount; p += 1) {
- await this.step(`绘制用豆清单 ${p + 1}/${info.pageCount}…`)
- node.width = info.width
- node.height = info.height
- const c = node.getContext('2d')
- info.draw(c, p)
- drawWatermark(c, info.width, info.height, wm)
- files.push({ name: info.pageCount > 1 ? `用豆清单 ${p + 1}` : '用豆清单', path: await this.capture('png') })
- }
- } else {
- await this.step('绘制图纸与清单…')
- const info = buildInfoPages(this.infoParams(L.width))
- const gap = Math.round(L.width * 0.02)
- const totalH = L.height + info.pageCount * (info.height + gap)
- const scale = fitScale(L.width, totalH)
- node.width = Math.round(L.width * scale)
- node.height = Math.round(totalH * scale)
- const ctx = node.getContext('2d')
- ctx.fillStyle = '#e8e5de'
- ctx.fillRect(0, 0, node.width, node.height)
- ctx.scale(scale, scale)
- drawPattern(ctx)
- for (let p = 0; p < info.pageCount; p += 1) {
- ctx.save()
- ctx.translate(0, L.height + gap + p * (info.height + gap))
- info.draw(ctx, p)
- ctx.restore()
- }
- ctx.setTransform(1, 0, 0, 1, 0, 0)
- drawWatermark(ctx, node.width, node.height, wm)
- files.push({ name: '图纸 + 用豆清单', path: await this.capture('png') })
- }
- await this.step('保存到相册…')
- const saved = await this.saveImages(files.map((f) => f.path))
- this.setData({ exportResult: { kind: 'png', saved, files } })
- if (saved) wx.showToast({ title: `${files.length} 张图片已保存`, icon: 'success' })
- },
-
- saveImages(paths) {
- return paths.reduce((chain, path) => chain.then((ok) => (ok ? new Promise((resolve) => {
- wx.saveImageToPhotosAlbum({
- filePath: path,
- success: () => resolve(true),
- fail: (err) => {
- if (err && /auth|deny/i.test(err.errMsg || '')) {
- wx.showModal({
- title: '需要相册权限',
- content: '请允许保存到相册,才能把图纸存到手机里',
- confirmText: '去设置',
- success: (r) => { if (r.confirm) wx.openSetting() },
- })
- }
- resolve(false)
- },
- })
- }) : false)), Promise.resolve(true))
- },
-
- previewResult() {
- const result = this.data.exportResult
- if (!result) return
- if (result.kind === 'png') {
- wx.previewImage({ urls: result.files.map((f) => f.path), showmenu: true })
- } else {
- this.openPdf(result.files[0].path)
- }
- },
-
- openResultFile(e) {
- const file = this.data.exportResult.files[Number(e.currentTarget.dataset.index)]
- if (!file) return
- if (this.data.exportResult.kind === 'png') wx.previewImage({ urls: [file.path], showmenu: true })
- else this.openPdf(file.path)
- },
-
- shareResultFile(e) {
- const file = this.data.exportResult.files[Number(e.currentTarget.dataset.index)]
- if (!file || !wx.shareFileMessage) {
- wx.showToast({ title: '当前微信版本不支持,请先打开再转发', icon: 'none' })
- return
- }
- wx.shareFileMessage({ filePath: file.path, fileName: file.fileName || `${file.name}.pdf` })
- },
-
- openPdf(path) {
- wx.openDocument({ filePath: path, fileType: 'pdf', showMenu: true })
- },
-
- cleanOldFiles() {
- try {
- const fs = wx.getFileSystemManager()
- fs.readdirSync(wx.env.USER_DATA_PATH)
- .filter((name) => name.indexOf(FILE_PREFIX) === 0)
- .forEach((name) => { try { fs.unlinkSync(`${wx.env.USER_DATA_PATH}/${name}`) } catch (e) { /* 忽略 */ } })
- } catch (e) { /* 忽略 */ }
- },
-
- async canvasJpeg(width, height, draw, quality = 0.9) {
- const node = this._nodes.work
- node.width = width
- node.height = height
- const ctx = node.getContext('2d')
- draw(ctx)
- const path = await this.capture('jpg', quality)
- return wx.getFileSystemManager().readFileSync(path)
- },
-
- // 页眉(中文)渲染为小图,矢量页面上方使用
- async renderHeader(title, sub) {
- const w = 1540
- const h = 80
- const data = await this.canvasJpeg(w, h, (ctx) => {
- ctx.fillStyle = '#ffffff'
- ctx.fillRect(0, 0, w, h)
- ctx.fillStyle = '#16211f'
- ctx.font = 'bold 34px sans-serif'
- ctx.textBaseline = 'middle'
- ctx.fillText(title, 0, 30)
- ctx.fillStyle = '#6f7a76'
- ctx.font = '22px sans-serif'
- ctx.fillText(sub, 0, 64)
- ctx.fillStyle = '#0f766e'
- ctx.font = 'bold 24px sans-serif'
- ctx.textAlign = 'right'
- ctx.fillText('豆维 · 可扫码的拼豆', w, 30)
- }, 0.92)
- return { data, width: w, height: h }
- },
-
- // 水印转为 1-bit 蒙版,矢量页上以半透明平铺
- watermarkMask(doc, text) {
- const value = String(text || '').trim()
- if (!value) return null
- const node = this._nodes.work
- const fontSize = 64
- node.width = 16
- node.height = 16
- let ctx = node.getContext('2d')
- ctx.font = `bold ${fontSize}px sans-serif`
- const width = Math.min(2000, Math.ceil(ctx.measureText(value).width) + 16)
- const height = Math.round(fontSize * 1.4)
- node.width = width
- node.height = height
- ctx = node.getContext('2d')
- ctx.clearRect(0, 0, width, height)
- ctx.fillStyle = '#000000'
- ctx.font = `bold ${fontSize}px sans-serif`
- ctx.textBaseline = 'middle'
- ctx.fillText(value, 8, height / 2)
- const pixels = ctx.getImageData(0, 0, width, height).data
- const rowBytes = Math.ceil(width / 8)
- const bits = new Uint8Array(rowBytes * height).fill(0xff) // 1 = 不绘制
- for (let y = 0; y < height; y += 1) {
- for (let x = 0; x < width; x += 1) {
- if (pixels[(y * width + x) * 4 + 3] > 110) bits[y * rowBytes + (x >> 3)] &= ~(0x80 >> (x & 7))
- }
- }
- return { id: doc.addImageMask(bits, width, height), width, height }
- },
-
- async buildPatternPdf(doc) {
- const art = this._artwork
- const plan = planPatternPages(art.size)
- const headers = []
- for (let i = 0; i < plan.pages.length; i += 1) {
- const page = plan.pages[i]
- await this.step(`绘制图纸页 ${i + 1}/${plan.pages.length}…`)
- const title = page.kind === 'overview'
- ? (plan.tiled ? `图纸总览 · 共分 ${plan.pages.length - 1} 块` : '拼豆图纸')
- : `第 ${page.tile} 块 · 列 ${page.region.col + 1}–${page.region.col + page.region.cols} · 行 ${page.region.row + 1}–${page.region.row + page.region.rows}`
- const sub = page.kind === 'overview'
- ? `${art.size}×${art.size} 格 · ${formatNumber(art.beads)} 颗 · ${art.usage.length} 色 · ${plan.tiled ? '红框编号对应后续分块页,按块拼更轻松' : '格内为 MARD 色号'}`
- : `第 ${i + 1} / ${plan.pages.length} 页 · 格内为 MARD 色号 · 坐标为整张作品的行列号`
- const header = await this.renderHeader(title, sub)
- headers.push({ id: doc.addJpeg(header.data, header.width, header.height), width: header.width, height: header.height })
- }
- const watermark = this.watermarkMask(doc, this.data.watermark)
- addPatternPages(doc, art, { plan, headers, style: this.data.beadStyle, grid: this.gridSettings(), watermark })
- },
-
- async buildInfoPdf(doc) {
- const info = buildInfoPages(this.infoParams(1654))
- for (let p = 0; p < info.pageCount; p += 1) {
- await this.step(`绘制用豆清单 ${p + 1}/${info.pageCount}…`)
- const data = await this.canvasJpeg(info.width, info.height, (ctx) => {
- info.draw(ctx, p)
- drawWatermark(ctx, info.width, info.height, this.data.watermark)
- }, 0.9)
- addImagePage(doc, doc.addJpeg(data, info.width, info.height), info.width, info.height)
- }
- },
-
- async exportPdf() {
- const fs = wx.getFileSystemManager()
- const stamp = Date.now().toString(36)
- const art = this._artwork
- const base = `${FILE_PREFIX}${art.size}x${art.size}-${stamp}`
- const files = []
- const write = (doc, suffix, name) => {
- const fileName = `豆维-${name}.pdf`
- const path = `${wx.env.USER_DATA_PATH}/${base}-${suffix}.pdf`
- fs.writeFileSync(path, doc.build(), 'binary')
- files.push({ name, fileName, path })
- }
- if (this.data.exportLayout === 'separate') {
- const patternDoc = new PdfDoc()
- await this.buildPatternPdf(patternDoc)
- write(patternDoc, 'pattern', '拼豆图纸')
- const infoDoc = new PdfDoc()
- await this.buildInfoPdf(infoDoc)
- write(infoDoc, 'info', '用豆清单')
- } else {
- const doc = new PdfDoc()
- await this.buildPatternPdf(doc)
- await this.buildInfoPdf(doc)
- write(doc, 'all', '图纸与用豆清单')
- }
- this.setData({ exportResult: { kind: 'pdf', saved: true, files } })
- },
-})
diff --git a/BeadQR/miniprogram/pages/index/index.json b/BeadQR/miniprogram/pages/index/index.json
deleted file mode 100644
index 3a164a5de25f9e3973d37a973c87fb807ef30625..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/pages/index/index.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "navigationStyle": "custom",
- "navigationBarTextStyle": "white",
- "backgroundColorTop": "#0f3d3a",
- "usingComponents": {}
-}
diff --git a/BeadQR/miniprogram/pages/index/index.wxml b/BeadQR/miniprogram/pages/index/index.wxml
deleted file mode 100644
index 7234757764c44cf005156ba6875b418f5495f838..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/pages/index/index.wxml
+++ /dev/null
@@ -1,403 +0,0 @@
-
-
-
-
- 豆维 · 可扫码的拼豆
-
-
-
-
-
-
- MARD 拼豆图纸生成器
- 把一句话藏进拼豆里
- 拼好的作品用微信一扫,就能读出你写的文字或链接
-
- 1写一句话
- ›
- 2选张照片
- ›
- 3导出图纸
-
-
-
-
-
-
-
- 示例二维码 · 写下内容后换成你的
-
-
-
-
-
-
- 上面是演示:写下一句话,这里就会变成你专属的可扫码图纸
-
-
- 221 色MARD 标准色号
- A4打印图纸
- 扫一扫微信直接读出
-
-
- 开始制作 · 写下第一句话
-
-
-
-
-
-
- 写下内容后,自动检查能否扫出
- 正在检查能否扫出…
- ✓ 自检通过,可以扫出内容
- ! 自检未扫出,建议优化
- 生成后自动检查能否扫码
-
- 一键优化
-
-
-
- {{gridText}}格子
- {{beadsText}}颗豆子
- {{colorsText}}种颜色
-
-
-
- 写下内容,生成你的二维码
- 用微信扫一扫验证
-
-
-
-
-
-
-
- 1
-
- 扫码后要看到什么?
- 一句祝福、一个网址,或者你的名字
-
-
-
-
-
-
- 字越少,格子越少,拼起来越快
-
-
-
-
-
- 2
-
- 选一张照片当底图 可选
- 二维码会融进照片里,不选就是纯二维码
-
-
-
- +
- 从相册选择或拍照
- 照片仅在手机上处理,会先经过微信内容安全检测
-
-
-
-
- {{imageMeta}}
-
- 调整
- 换一张
- 移除
-
-
-
-
- 去掉纯色背景
-
-
-
-
-
-
-
- 3
-
- 调整效果
- 默认设置已经很好用,想要更好看再微调
-
-
-
- 风格
-
-
- {{item.label}}
- {{item.hint}}
-
-
-
-
- 二维码大小 {{qrScale}}%
-
-
- 二维码位置 {{fineTuneOpen ? '收起微调' : '微调'}}
-
-
-
-
-
-
- 左右 {{posX}}%
-
- 上下 {{posY}}%
-
-
-
-
-
-
- 高级设置(色板、纠错、白边)
- ›
-
-
- 色板 颜色越少,买豆越省
-
-
-
- {{item.short}}
- {{item.detail}}
-
-
-
-
- 色块平滑 {{coherence}}
-
-
-
-
- 合并零散颜色
- 把只用到一两颗的颜色换成相近色
-
-
-
-
- 纠错等级 等级越高越耐磨损,但格子更多
-
-
- {{item.label}}
- {{item.hint}}
-
-
-
- 白边 留 1 格白边更容易扫出
-
-
- {{item.label}}
-
-
- 二维码本体 {{qrGridText}} 格
-
-
-
-
-
- 需要准备的豆子 MARD 色号 · 按用量排序
-
-
-
- {{item.id}}
- {{item.count}}
-
-
- {{usageExpanded ? '收起' : '展开全部(还有 ' + usageMore + ' 种)'}}
-
-
-
-
-
-
-
-
-
-
- 还没有内容
- 写一句话,马上生成图纸
-
-
- {{gridText}} · {{colorsText}} 色
- 约 {{beadsText}} 颗豆子
-
-
- {{isSample ? '开始制作' : '导出图纸'}}
-
-
-
-
-
-
- 导出图纸
-
-
- 格式
-
-
- PDF 文件A4 打印,大图自动分页
-
-
- 图片存到相册,手机上看
-
-
-
- 内容
-
-
- 合并一份图纸 + 用豆清单
-
-
- 分开两份图纸、清单各一份
-
-
-
-
- 清晰度
-
- 高清
- 标准
-
-
-
- 豆子样式
-
-
- {{item.label}}
-
-
-
-
- 辅助网格线
-
-
-
-
-
- 每 5 格
- 每 10 格
-
-
-
-
-
-
-
- 水印 可选,防止图纸被盗用
-
-
-
-
- 内容安全检测中…
- ✓ 已通过内容安全检测
- 水印内容可能不合规,请修改
- 检测暂不可用,请稍后重试
-
-
-
-
-
-
-
-
- {{exportResult.kind === 'png' && !exportResult.saved ? '已生成,但未存入相册' : '导出完成'}}
- 共 {{exportResult.files.length}} 份 PDF,可直接打印或发给好友
- {{exportResult.files.length}} 张图片已保存到手机相册
- 点「查看」后长按图片即可保存
-
-
-
-
- {{exportResult.kind === 'pdf' ? 'PDF' : 'PNG'}}
-
- {{item.name}}
- {{exportResult.kind === 'pdf' ? 'A4 · 可打印' : '高清图片'}}
-
-
- {{exportResult.kind === 'png' ? '查看' : '打开'}}
- 发送
-
-
-
-
-
-
-
- {{exporting ? (exportStep || '正在导出…') : (exportResult ? '重新导出' : '开始导出')}}
-
-
-
-
-
-
-
-
- 取消
- 调整照片
- 完成
-
-
-
-
-
- 正在进行内容安全检测,你可以先调整构图…
- ✓ 照片已通过内容安全检测
- 这张照片未通过内容安全检测,请换一张
- 检测暂时不可用 重试
-
- 单指拖动调整位置,双指缩放
- 缩放 {{draftZoom}}%
-
-
- 左右翻转
- 上下翻转
- 复位
-
-
-
- 去掉纯色背景
- 适合白底、纯色底的照片
-
-
-
-
- 识别范围 {{draftBgTolerance}}
-
-
- 换一张照片
-
-
-
-
-
-
-
-
-
-
diff --git a/BeadQR/miniprogram/pages/index/index.wxss b/BeadQR/miniprogram/pages/index/index.wxss
deleted file mode 100644
index 6fc68c6752807090b71567e745a932adfc29ad3a..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/pages/index/index.wxss
+++ /dev/null
@@ -1,828 +0,0 @@
-page {
- background: var(--bg);
-}
-
-/* 导航 */
-.nav {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- z-index: 50;
- display: flex;
- align-items: center;
- padding-left: 32rpx;
- box-sizing: content-box;
- background: transparent;
- transition: background 0.2s;
-}
-.nav-solid {
- background: var(--brand-deep);
- box-shadow: 0 4rpx 20rpx rgba(15, 61, 58, 0.25);
-}
-.nav-title {
- display: flex;
- align-items: center;
- gap: 14rpx;
- color: #fff;
- font-size: 34rpx;
- font-weight: 700;
- letter-spacing: 2rpx;
-}
-.nav-logo {
- width: 48rpx;
- height: 48rpx;
- border-radius: 12rpx;
-}
-
-.page {
- padding-bottom: calc(180rpx + env(safe-area-inset-bottom));
- background: linear-gradient(180deg, var(--brand-deep) 0, var(--brand-deep) 560rpx, var(--bg) 560rpx);
-}
-
-/* 首屏 */
-.hero {
- padding: 24rpx 40rpx 150rpx;
- color: #fff;
-}
-.hero-badge {
- display: inline-block;
- padding: 6rpx 18rpx;
- border-radius: 999rpx;
- background: rgba(255, 255, 255, 0.12);
- color: #99f6e4;
- font-size: 22rpx;
- letter-spacing: 1rpx;
-}
-.hero-title {
- margin-top: 20rpx;
- font-size: 56rpx;
- font-weight: 800;
- line-height: 1.25;
-}
-.hero-sub {
- margin-top: 12rpx;
- font-size: 27rpx;
- line-height: 1.6;
- color: rgba(255, 255, 255, 0.78);
-}
-.hero-steps {
- margin-top: 28rpx;
- display: flex;
- align-items: center;
- gap: 10rpx;
-}
-.hero-step {
- display: flex;
- align-items: center;
- gap: 8rpx;
- padding: 10rpx 16rpx 10rpx 10rpx;
- border-radius: 999rpx;
- background: rgba(255, 255, 255, 0.1);
- font-size: 24rpx;
- white-space: nowrap;
-}
-.hero-step .num {
- width: 34rpx;
- height: 34rpx;
- line-height: 34rpx;
- text-align: center;
- border-radius: 50%;
- background: var(--brand-2);
- color: var(--brand-deep);
- font-size: 20rpx;
- font-weight: 800;
-}
-.hero-arrow {
- color: rgba(255, 255, 255, 0.4);
- font-size: 30rpx;
-}
-
-/* 卡片 */
-.card {
- margin: 0 24rpx 24rpx;
- padding: 32rpx;
- background: var(--card);
- border-radius: var(--r-l);
- box-shadow: var(--shadow);
-}
-.card-title {
- font-size: 30rpx;
- font-weight: 700;
- color: var(--ink);
- margin-bottom: 20rpx;
-}
-
-/* 预览 */
-.preview-card {
- margin-top: -120rpx;
- padding: 24rpx;
-}
-.preview-box {
- position: relative;
- width: 100%;
- height: 654rpx;
- border-radius: 24rpx;
- overflow: hidden;
- background: #f1eee7;
-}
-.preview-canvas {
- width: 654rpx;
- height: 654rpx;
- display: block;
- margin: 0 auto;
-}
-.sample-tag {
- position: absolute;
- left: 20rpx;
- top: 20rpx;
- padding: 8rpx 18rpx;
- border-radius: 999rpx;
- background: rgba(22, 33, 31, 0.72);
- color: #fff;
- font-size: 22rpx;
-}
-.generating {
- position: absolute;
- right: 20rpx;
- top: 20rpx;
- width: 52rpx;
- height: 52rpx;
- border-radius: 50%;
- background: rgba(255, 255, 255, 0.9);
- display: flex;
- align-items: center;
- justify-content: center;
-}
-.spinner {
- width: 28rpx;
- height: 28rpx;
- border: 4rpx solid var(--brand-soft);
- border-top-color: var(--brand);
- border-radius: 50%;
- animation: spin 0.7s linear infinite;
-}
-@keyframes spin {
- to { transform: rotate(360deg); }
-}
-
-.scan-row {
- margin-top: 20rpx;
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 16rpx;
-}
-.scan-badge {
- flex: 1;
- padding: 14rpx 20rpx;
- border-radius: 16rpx;
- font-size: 25rpx;
- background: #f1f1ee;
- color: var(--muted);
-}
-.scan-ok { background: var(--ok-soft); color: var(--ok); font-weight: 600; }
-.scan-fail { background: var(--warn-soft); color: var(--warn); font-weight: 600; }
-.scan-checking { background: var(--brand-soft); color: var(--brand); }
-
-.stats {
- margin-top: 20rpx;
- display: flex;
- background: #faf9f6;
- border-radius: 20rpx;
- padding: 20rpx 0;
-}
-.stat {
- flex: 1;
- text-align: center;
-}
-.stat + .stat { border-left: 1rpx solid var(--line); }
-.stat-v {
- font-size: 36rpx;
- font-weight: 800;
- color: var(--ink);
-}
-.stat-k {
- margin-top: 4rpx;
- font-size: 22rpx;
- color: var(--muted);
-}
-.preview-actions {
- margin-top: 20rpx;
-}
-.ghost-btn {
- text-align: center;
- width: 100%;
- height: 84rpx;
- line-height: 84rpx;
- border-radius: 20rpx;
- background: var(--brand-soft);
- color: var(--brand);
- font-size: 28rpx;
- font-weight: 600;
-}
-
-/* 动态演示状态 */
-.intro-tip {
- margin-top: 20rpx;
- display: flex;
- align-items: flex-start;
- gap: 14rpx;
- padding: 16rpx 20rpx;
- border-radius: 16rpx;
- background: var(--brand-soft);
- color: var(--brand-deep);
- font-size: 25rpx;
- line-height: 1.5;
-}
-.intro-dot {
- flex-shrink: 0;
- width: 14rpx;
- height: 14rpx;
- margin-top: 13rpx;
- border-radius: 50%;
- background: var(--brand-2);
- animation: pulse 1.6s ease-in-out infinite;
-}
-@keyframes pulse {
- 0%, 100% { opacity: 1; transform: scale(1); }
- 50% { opacity: 0.35; transform: scale(0.7); }
-}
-.features .stat-v { font-size: 32rpx; color: var(--brand); }
-.cta-btn {
- width: 100%;
- height: 88rpx;
- line-height: 88rpx;
- border-radius: 20rpx;
- text-align: center;
- background: linear-gradient(135deg, var(--brand), var(--brand-2));
- color: #fff;
- font-size: 29rpx;
- font-weight: 700;
- box-shadow: 0 10rpx 24rpx rgba(15, 118, 110, 0.25);
-}
-
-/* 步骤卡 */
-.step-head {
- display: flex;
- align-items: flex-start;
- gap: 20rpx;
- margin-bottom: 24rpx;
-}
-.step-num {
- flex-shrink: 0;
- width: 52rpx;
- height: 52rpx;
- line-height: 52rpx;
- text-align: center;
- border-radius: 16rpx;
- background: var(--brand);
- color: #fff;
- font-weight: 800;
- font-size: 28rpx;
-}
-.step-title {
- font-size: 32rpx;
- font-weight: 700;
- color: var(--ink);
-}
-.optional {
- margin-left: 8rpx;
- padding: 2rpx 12rpx;
- border-radius: 8rpx;
- background: #f1f1ee;
- color: var(--muted);
- font-size: 20rpx;
- font-weight: 500;
- vertical-align: middle;
-}
-.step-desc {
- margin-top: 6rpx;
- font-size: 24rpx;
- color: var(--muted);
-}
-
-.input-wrap {
- border: 2rpx solid var(--line);
- border-radius: 20rpx;
- background: #fbfaf8;
- padding: 20rpx 24rpx;
-}
-.input-bad { border-color: var(--danger); background: var(--danger-soft); }
-.textarea {
- width: 100%;
- min-height: 120rpx;
- font-size: 30rpx;
- line-height: 1.5;
- color: var(--ink);
-}
-.input {
- height: 48rpx;
- font-size: 28rpx;
- color: var(--ink);
-}
-.ph { color: #b5b8b4; }
-.input-foot {
- margin-top: 12rpx;
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-.text-status { font-size: 23rpx; color: var(--muted); }
-.text-status.pad { margin-top: 10rpx; }
-.status-checking { color: var(--brand); }
-.status-pass { color: var(--ok); }
-.status-risky { color: var(--danger); font-weight: 600; }
-.status-error { color: var(--warn); }
-.input-tools { display: flex; gap: 24rpx; }
-.tool { font-size: 25rpx; color: var(--muted); }
-.tool-brand { color: var(--brand); font-weight: 600; }
-.tip {
- margin-top: 16rpx;
- font-size: 23rpx;
- color: var(--muted);
-}
-
-.upload {
- border: 2rpx dashed #c9d6d3;
- border-radius: 24rpx;
- padding: 44rpx 24rpx;
- text-align: center;
- background: #f8fbfa;
-}
-.upload-icon {
- margin: 0 auto;
- width: 80rpx;
- height: 80rpx;
- line-height: 76rpx;
- border-radius: 50%;
- background: var(--brand-soft);
- color: var(--brand);
- font-size: 48rpx;
-}
-.upload-text {
- margin-top: 16rpx;
- font-size: 29rpx;
- font-weight: 600;
- color: var(--ink);
-}
-.upload-hint {
- margin-top: 8rpx;
- font-size: 22rpx;
- color: var(--muted);
-}
-
-.photo {
- display: flex;
- gap: 24rpx;
- align-items: center;
-}
-.photo-thumb {
- width: 150rpx;
- height: 150rpx;
- border-radius: 20rpx;
- background: #eee;
-}
-.photo-info { flex: 1; }
-.photo-meta { font-size: 23rpx; color: var(--ok); }
-.photo-actions {
- margin-top: 16rpx;
- display: flex;
- gap: 12rpx;
-}
-.photo-actions .mini-btn {
- flex: 1;
- padding: 0;
- text-align: center;
-}
-
-.mini-btn {
- display: inline-block;
- text-align: center;
- white-space: nowrap;
- padding: 0 22rpx;
- height: 56rpx;
- line-height: 56rpx;
- border-radius: 14rpx;
- background: #f1f1ee;
- color: var(--ink);
- font-size: 24rpx;
- font-weight: 600;
-}
-.mini-btn.accent { background: var(--accent); color: #fff; }
-.mini-btn.danger { color: var(--danger); background: var(--danger-soft); }
-
-.row {
- margin-top: 24rpx;
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 20rpx;
-}
-.row-label { font-size: 28rpx; color: var(--ink); font-weight: 600; }
-.row-hint { margin-top: 4rpx; font-size: 22rpx; color: var(--muted); }
-
-.field-label {
- margin: 28rpx 0 14rpx;
- font-size: 26rpx;
- font-weight: 600;
- color: var(--ink);
- display: flex;
- align-items: center;
- gap: 12rpx;
-}
-.field-label:first-child { margin-top: 0; }
-.field-val { color: var(--brand); font-weight: 700; }
-.field-hint { font-size: 22rpx; color: var(--muted); font-weight: 400; }
-.mini-label { font-size: 23rpx; color: var(--muted); margin-top: 12rpx; }
-.link-text { color: var(--brand); font-size: 24rpx; font-weight: 600; }
-.link-text.center { display: block; text-align: center; margin-top: 20rpx; }
-
-/* 分段选择 */
-.seg {
- display: flex;
- gap: 12rpx;
-}
-.seg-item {
- flex: 1;
- padding: 18rpx 8rpx;
- border-radius: 18rpx;
- border: 2rpx solid var(--line);
- background: #fbfaf8;
- text-align: center;
- transition: all 0.15s;
-}
-.seg-item.on {
- border-color: var(--brand);
- background: var(--brand-soft);
-}
-.seg-main { font-size: 27rpx; font-weight: 700; color: var(--ink); }
-.seg-item.on .seg-main { color: var(--brand); }
-.seg-sub { margin-top: 4rpx; font-size: 21rpx; color: var(--muted); }
-.seg.small .seg-item { padding: 12rpx 8rpx; }
-
-slider { margin: 0 12rpx; }
-
-.pos-grid {
- width: 216rpx;
- display: flex;
- flex-wrap: wrap;
- gap: 12rpx;
- padding: 12rpx;
- border-radius: 20rpx;
- background: #f4f3ef;
-}
-.pos-cell {
- width: 56rpx;
- height: 56rpx;
- border-radius: 12rpx;
- background: #fff;
- border: 2rpx solid var(--line);
-}
-.pos-cell.on { background: var(--brand); border-color: var(--brand); }
-
-.advanced-toggle {
- margin-top: 32rpx;
- padding-top: 24rpx;
- border-top: 1rpx solid var(--line);
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-size: 26rpx;
- color: var(--muted);
-}
-.chev { font-size: 36rpx; transform: rotate(90deg); transition: transform 0.2s; }
-.chev.open { transform: rotate(-90deg); }
-.advanced { margin-top: 8rpx; }
-
-.chips-scroll { width: 100%; white-space: nowrap; }
-.chips { display: inline-flex; gap: 12rpx; padding-bottom: 4rpx; }
-.chip {
- display: inline-block;
- padding: 16rpx 22rpx;
- border-radius: 18rpx;
- border: 2rpx solid var(--line);
- background: #fbfaf8;
-}
-.chip.on { border-color: var(--brand); background: var(--brand-soft); }
-.chip-main { font-size: 27rpx; font-weight: 700; color: var(--ink); }
-.chip.on .chip-main { color: var(--brand); }
-.chip-sub { margin-top: 4rpx; font-size: 20rpx; color: var(--muted); }
-
-/* 用豆清单 */
-.usage {
- display: grid;
- grid-template-columns: repeat(4, 1fr);
- gap: 12rpx;
-}
-.usage-item {
- display: flex;
- align-items: center;
- gap: 10rpx;
- padding: 12rpx;
- border-radius: 14rpx;
- background: #faf9f6;
-}
-.swatch {
- width: 32rpx;
- height: 32rpx;
- border-radius: 50%;
- box-shadow: inset 0 0 0 1rpx rgba(0, 0, 0, 0.12);
- flex-shrink: 0;
-}
-.usage-id { font-size: 23rpx; font-weight: 700; color: var(--ink); }
-.usage-count { margin-left: auto; font-size: 21rpx; color: var(--muted); }
-
-/* 页脚 */
-.footer {
- padding: 16rpx 48rpx 24rpx;
- text-align: center;
-}
-.footer-safe {
- display: flex;
- align-items: flex-start;
- justify-content: center;
- gap: 10rpx;
- text-align: left;
- font-size: 22rpx;
- line-height: 1.6;
- color: var(--muted);
-}
-.footer-links {
- margin-top: 16rpx;
- display: flex;
- justify-content: center;
- align-items: center;
- gap: 12rpx;
-}
-.footer-link {
- font-size: 23rpx;
- line-height: 1.6;
- color: var(--brand);
-}
-.footer-shield {
- flex-shrink: 0;
- width: 30rpx;
- height: 30rpx;
- margin-top: 3rpx;
-}
-.footer-links .footer-btn {
- display: inline-block;
- width: auto !important;
- min-height: 0;
- padding: 0 !important;
- margin: 0 !important;
- font-size: 23rpx;
- font-weight: 400;
- line-height: 1.6;
- color: var(--brand);
- background: none;
-}
-.dot { color: #c4c7c3; font-size: 22rpx; }
-.footer-copy { margin-top: 12rpx; font-size: 20rpx; color: #b5b8b4; }
-
-/* 底部操作栏 */
-.bottom-bar {
- position: fixed;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: 40;
- display: flex;
- align-items: center;
- gap: 24rpx;
- padding: 20rpx 32rpx calc(20rpx + env(safe-area-inset-bottom));
- background: rgba(255, 255, 255, 0.96);
- box-shadow: 0 -6rpx 30rpx rgba(22, 33, 31, 0.08);
-}
-.bar-info { flex: 1; min-width: 0; }
-.bar-main { font-size: 30rpx; font-weight: 800; color: var(--ink); }
-.bar-sub { margin-top: 2rpx; font-size: 22rpx; color: var(--muted); }
-.primary-btn {
- text-align: center;
- padding: 0 56rpx;
- height: 92rpx;
- line-height: 92rpx;
- border-radius: 999rpx;
- background: linear-gradient(135deg, var(--brand), var(--brand-2));
- color: #fff;
- font-size: 30rpx;
- font-weight: 700;
- box-shadow: 0 10rpx 24rpx rgba(15, 118, 110, 0.3);
-}
-.primary-btn.disabled { opacity: 0.5; box-shadow: none; }
-.primary-btn.block { display: block; width: 100%; padding: 0; }
-
-/* 弹层 */
-.mask {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: 100;
- background: rgba(10, 20, 18, 0.5);
- display: flex;
- align-items: flex-end;
-}
-.sheet {
- width: 100%;
- max-height: 88vh;
- display: flex;
- flex-direction: column;
- background: var(--card);
- border-radius: 36rpx 36rpx 0 0;
- padding: 16rpx 32rpx calc(24rpx + env(safe-area-inset-bottom));
- box-sizing: border-box;
-}
-.sheet-handle {
- margin: 0 auto 16rpx;
- width: 72rpx;
- height: 8rpx;
- border-radius: 8rpx;
- background: #e2e2dd;
-}
-.sheet-title {
- font-size: 34rpx;
- font-weight: 800;
- color: var(--ink);
- margin-bottom: 20rpx;
-}
-.sheet-body {
- flex: 1;
- max-height: 62vh;
- margin-bottom: 24rpx;
-}
-.grid-opts {
- margin-top: 16rpx;
- display: flex;
- align-items: center;
- gap: 24rpx;
-}
-.grid-opts .seg { flex: 1; }
-.colors { display: flex; gap: 14rpx; }
-.color-dot {
- width: 44rpx;
- height: 44rpx;
- border-radius: 50%;
- border: 4rpx solid #fff;
- box-shadow: 0 0 0 2rpx var(--line);
-}
-.color-dot.on { box-shadow: 0 0 0 4rpx var(--brand); }
-
-.result {
- margin-top: 32rpx;
- border-radius: 24rpx;
- background: #fff;
- border: 2rpx solid var(--line);
- overflow: hidden;
-}
-.result-head {
- display: flex;
- align-items: center;
- gap: 20rpx;
- padding: 28rpx;
- background: linear-gradient(135deg, var(--ok-soft), #ffffff);
-}
-.result-icon {
- flex-shrink: 0;
- width: 64rpx;
- height: 64rpx;
- border-radius: 50%;
- background: var(--ok);
- display: flex;
- align-items: center;
- justify-content: center;
- box-shadow: 0 8rpx 18rpx rgba(21, 128, 61, 0.25);
-}
-.result-icon.warn { background: var(--warn); box-shadow: none; }
-.result-tick {
- width: 16rpx;
- height: 28rpx;
- margin-top: -6rpx;
- border-right: 5rpx solid #fff;
- border-bottom: 5rpx solid #fff;
- transform: rotate(45deg);
-}
-.result-text { flex: 1; min-width: 0; }
-.result-title { font-size: 30rpx; font-weight: 800; color: var(--ink); }
-.result-sub { margin-top: 6rpx; font-size: 23rpx; color: var(--muted); line-height: 1.5; }
-.result-list { padding: 8rpx 28rpx; }
-.result-file {
- display: flex;
- align-items: center;
- gap: 20rpx;
- padding: 20rpx 0;
-}
-.result-file + .result-file { border-top: 1rpx solid var(--line); }
-.file-badge {
- flex-shrink: 0;
- width: 72rpx;
- height: 84rpx;
- line-height: 84rpx;
- border-radius: 12rpx;
- text-align: center;
- font-size: 20rpx;
- font-weight: 800;
- letter-spacing: 1rpx;
- color: #fff;
- background: #e5484d;
-}
-.file-badge.png { background: #3b82f6; }
-.file-info { flex: 1; min-width: 0; }
-.file-name {
- font-size: 27rpx;
- font-weight: 700;
- color: var(--ink);
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
-}
-.file-desc { margin-top: 4rpx; font-size: 22rpx; color: var(--muted); }
-.file-actions { flex-shrink: 0; display: flex; gap: 12rpx; }
-.file-btn {
- min-width: 100rpx;
- height: 60rpx;
- line-height: 60rpx;
- padding: 0 20rpx;
- border-radius: 999rpx;
- text-align: center;
- font-size: 24rpx;
- font-weight: 700;
- color: var(--brand);
- background: var(--brand-soft);
-}
-.file-btn.primary { color: #fff; background: var(--brand); }
-
-/* 裁切 */
-.crop-mask { align-items: stretch; background: #0b1413; }
-.crop-panel {
- width: 100%;
- padding: calc(env(safe-area-inset-top) + 100rpx) 40rpx 40rpx;
- box-sizing: border-box;
- overflow-y: auto;
- color: #fff;
-}
-.crop-head {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 28rpx;
-}
-.crop-title { font-size: 32rpx; font-weight: 700; }
-.crop-cancel { font-size: 28rpx; color: rgba(255, 255, 255, 0.7); }
-.crop-ok {
- padding: 10rpx 28rpx;
- border-radius: 999rpx;
- background: var(--brand-2);
- color: var(--brand-deep);
- font-size: 28rpx;
- font-weight: 700;
-}
-.crop-ok.wait { opacity: 0.55; }
-.crop-box {
- width: 670rpx;
- height: 670rpx;
- margin: 0 auto;
- border-radius: 20rpx;
- overflow: hidden;
- background: #1a2523;
-}
-.crop-canvas { width: 670rpx; height: 670rpx; }
-.crop-check {
- margin-top: 20rpx;
- padding: 14rpx 20rpx;
- border-radius: 14rpx;
- font-size: 24rpx;
- background: rgba(255, 255, 255, 0.08);
- color: rgba(255, 255, 255, 0.8);
-}
-.check-pass { color: #6ee7b7; }
-.check-risky { background: rgba(229, 72, 77, 0.2); color: #fca5a5; }
-.check-error { color: #fcd34d; }
-.crop-hint { margin-top: 12rpx; font-size: 22rpx; color: rgba(255, 255, 255, 0.5); text-align: center; }
-.field-label.light, .row.light .row-label { color: #fff; }
-.row.light .row-hint, .mini-label.light { color: rgba(255, 255, 255, 0.55); }
-.crop-tools { margin-top: 24rpx; display: flex; gap: 16rpx; }
-.crop-tool {
- text-align: center;
- flex: 1;
- height: 72rpx;
- line-height: 72rpx;
- border-radius: 16rpx;
- background: rgba(255, 255, 255, 0.1);
- color: #fff;
- font-size: 25rpx;
-}
-.crop-replace { margin-top: 32rpx; }
-
-/* 离屏画布:不能 display:none,否则取不到节点 */
-.offscreen {
- position: fixed;
- left: -9999px;
- top: 0;
- width: 10px;
- height: 10px;
- overflow: hidden;
-}
-.off-canvas { width: 10px; height: 10px; }
diff --git a/BeadQR/miniprogram/sitemap.json b/BeadQR/miniprogram/sitemap.json
deleted file mode 100644
index 27b2b26d379bc328ebf87b99d643ac2d374e0730..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/sitemap.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
- "rules": [{
- "action": "allow",
- "page": "*"
- }]
-}
\ No newline at end of file
diff --git a/BeadQR/miniprogram/utils/color.js b/BeadQR/miniprogram/utils/color.js
deleted file mode 100644
index 96622d027f9a3bf80ad933d587fd03d20e819714..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/color.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// 颜色基础:HEX/RGB 转换、OKLab 感知色彩空间、亮度
-// OKLab 比 RGB 欧氏距离更接近人眼感受,配色更自然;距离统一放大 100 倍便于调参
-
-function hexToRgb(hex) {
- const value = String(hex || '').replace('#', '')
- const full = value.length === 3 ? value.split('').map((c) => c + c).join('') : value
- const num = parseInt(full, 16) || 0
- return [(num >> 16) & 255, (num >> 8) & 255, num & 255]
-}
-
-function rgbToHex(r, g, b) {
- const h = (v) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0')
- return `#${h(r)}${h(g)}${h(b)}`
-}
-
-// sRGB 伽马解码查表,避免每次调用 Math.pow
-const SRGB_TO_LINEAR = new Float32Array(256)
-for (let i = 0; i < 256; i += 1) {
- const c = i / 255
- SRGB_TO_LINEAR[i] = c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)
-}
-
-// 写入 out[offset..offset+2](L, a, b,均 ×100)
-function rgbToOklabInto(r, g, b, out, offset) {
- const lr = SRGB_TO_LINEAR[r]
- const lg = SRGB_TO_LINEAR[g]
- const lb = SRGB_TO_LINEAR[b]
- const l = Math.cbrt(0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb)
- const m = Math.cbrt(0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb)
- const s = Math.cbrt(0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb)
- out[offset] = (0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s) * 100
- out[offset + 1] = (1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s) * 100
- out[offset + 2] = (0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s) * 100
-}
-
-// 感知亮度(与旧版一致的 Rec.601 加权,0~1),用于二维码深/浅模块约束
-function luma(r, g, b) {
- return (r * 0.299 + g * 0.587 + b * 0.114) / 255
-}
-
-function lumaHex(hex) {
- const [r, g, b] = hexToRgb(hex)
- return luma(r, g, b)
-}
-
-module.exports = { hexToRgb, rgbToHex, rgbToOklabInto, luma, lumaHex }
diff --git a/BeadQR/miniprogram/utils/engine.js b/BeadQR/miniprogram/utils/engine.js
deleted file mode 100644
index c519e60276bf694327e1dd07f4aedbcc247e60bb..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/engine.js
+++ /dev/null
@@ -1,225 +0,0 @@
-// 配色引擎:把底图 + 二维码合成为 MARD 色号网格
-// 性能要点:
-// 1. 5bit 量化桶 → 候选 Top-K 查找表(懒加载),每格只精算约 10 个候选,而非整套 291 色
-// 2. OKLab 感知距离 + 色间距离矩阵,全部 Typed Array,无对象分配
-// 3. “颜色连贯度”参考已选中的左/上邻居色号,减少零碎杂色,拼起来更省事
-// 4. 定位/时序/对齐等功能区使用更严格的深浅阈值,显著提升扫码成功率
-const { rgbToOklabInto } = require('./color')
-const { MATCH_MODES } = require('./palette')
-const { PAPER } = require('./imaging')
-
-const TOP_K = 10
-const C_ANY = 0
-const C_DARK = 1
-const C_LIGHT = 2
-const C_FDARK = 3
-const C_FLIGHT = 4
-const C_QUIET = 5
-const C_EMPTY = 6
-
-function subsetFor(pal, mode, kind) {
- const key = `${mode.id}:${kind}`
- if (pal.subsets[key]) return pal.subsets[key]
- const { n, lum } = pal
- let test
- if (kind === C_DARK) test = (i) => lum[i] <= mode.darkMax
- else if (kind === C_LIGHT) test = (i) => lum[i] >= mode.lightMin
- else if (kind === C_FDARK) test = (i) => lum[i] <= Math.min(mode.darkMax, 0.3)
- else if (kind === C_FLIGHT) test = (i) => lum[i] >= Math.max(mode.lightMin, 0.82)
- else test = () => true
- let list = []
- for (let i = 0; i < n; i += 1) if (test(i)) list.push(i)
- if (!list.length) {
- // 色库太小时退化为最深/最浅的 3 个颜色
- const order = Array.from({ length: n }, (_, i) => i).sort((a, b) => lum[a] - lum[b])
- list = kind === C_DARK || kind === C_FDARK ? order.slice(0, 3) : order.slice(-3)
- }
- const member = new Uint8Array(n)
- list.forEach((i) => { member[i] = 1 })
- const subset = { key, list: Int16Array.from(list), member, lut: new Map() }
- pal.subsets[key] = subset
- return subset
-}
-
-const tmpLab = new Float32Array(3)
-
-function topKForBucket(pal, subset, bucket) {
- let hit = subset.lut.get(bucket)
- if (hit) return hit
- const r = ((bucket >> 10) & 31) * 8 + 4
- const g = ((bucket >> 5) & 31) * 8 + 4
- const b = (bucket & 31) * 8 + 4
- rgbToOklabInto(r, g, b, tmpLab, 0)
- const { lab } = pal
- const list = subset.list
- const k = Math.min(TOP_K, list.length)
- const bestIdx = new Int16Array(k).fill(-1)
- const bestDist = new Float32Array(k).fill(Infinity)
- for (let t = 0; t < list.length; t += 1) {
- const i = list[t]
- const dl = lab[i * 3] - tmpLab[0]
- const da = lab[i * 3 + 1] - tmpLab[1]
- const db = lab[i * 3 + 2] - tmpLab[2]
- const d = dl * dl + da * da + db * db
- if (d >= bestDist[k - 1]) continue
- let p = k - 1
- while (p > 0 && bestDist[p - 1] > d) { bestDist[p] = bestDist[p - 1]; bestIdx[p] = bestIdx[p - 1]; p -= 1 }
- bestDist[p] = d
- bestIdx[p] = i
- }
- hit = bestIdx
- subset.lut.set(bucket, hit)
- return hit
-}
-
-/**
- * @param base { size, rgb: Uint8Array, mask?: Uint8Array } 或 null(无底图)
- * @param qr makeQr() 结果
- * @param placement createPlacement() 结果
- * @param pal preparePalette() 结果
- * @param options { modeId, coherence(0-100), cleanup(bool) }
- */
-function computeArtwork(base, qr, placement, pal, options = {}) {
- const mode = MATCH_MODES.find((m) => m.id === options.modeId) || MATCH_MODES[1]
- const size = placement.size
- const total = size * size
- const lab = new Float32Array(total * 3)
- const bucket = new Int32Array(total)
- const kind = new Uint8Array(total)
- const { left, top, quiet } = placement
-
- for (let y = 0; y < size; y += 1) {
- for (let x = 0; x < size; x += 1) {
- const i = y * size + x
- const qx = x - left
- const qy = y - top
- const inQr = qx >= 0 && qy >= 0 && qx < qr.size && qy < qr.size
- const inQuiet = !inQr && x >= left - quiet && x < left + qr.size + quiet && y >= top - quiet && y < top + qr.size + quiet
- let r; let g; let b
- if (inQr) {
- const q = qy * qr.size + qx
- const isDark = qr.dark[q]
- const isFunc = qr.func[q]
- kind[i] = isFunc ? (isDark ? C_FDARK : C_FLIGHT) : (isDark ? C_DARK : C_LIGHT)
- if (base && !(base.mask && base.mask[i])) {
- r = base.rgb[i * 3]; g = base.rgb[i * 3 + 1]; b = base.rgb[i * 3 + 2]
- } else if (base) {
- r = PAPER[0]; g = PAPER[1]; b = PAPER[2]
- } else {
- r = g = b = isDark ? 0 : 255
- }
- } else if (inQuiet || !base) {
- kind[i] = C_QUIET
- continue
- } else if (base.mask && base.mask[i]) {
- kind[i] = C_EMPTY
- continue
- } else {
- kind[i] = C_ANY
- r = base.rgb[i * 3]; g = base.rgb[i * 3 + 1]; b = base.rgb[i * 3 + 2]
- }
- rgbToOklabInto(r, g, b, lab, i * 3)
- bucket[i] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3)
- }
- }
-
- const n = pal.n
- const plab = pal.lab
- const pair = pal.pair
- const weight = (Math.max(0, Math.min(100, options.coherence == null ? 40 : options.coherence)) / 100) * 0.6
- const subsets = [C_ANY, C_DARK, C_LIGHT, C_FDARK, C_FLIGHT].map((k) => subsetFor(pal, mode, k))
- const cells = new Int16Array(total).fill(-1)
-
- const distTo = (c, i) => {
- const dl = plab[c * 3] - lab[i * 3]
- const da = plab[c * 3 + 1] - lab[i * 3 + 1]
- const db = plab[c * 3 + 2] - lab[i * 3 + 2]
- return Math.sqrt(dl * dl + da * da + db * db)
- }
-
- for (let y = 0; y < size; y += 1) {
- for (let x = 0; x < size; x += 1) {
- const i = y * size + x
- const k = kind[i]
- if (k >= C_QUIET) continue
- const subset = subsets[k]
- const cands = topKForBucket(pal, subset, bucket[i])
- const nl = x > 0 ? cells[i - 1] : -1
- const nu = y > 0 ? cells[i - size] : -1
- const nbCount = (nl >= 0 ? 1 : 0) + (nu >= 0 ? 1 : 0)
- let best = -1
- let bestScore = Infinity
- const consider = (c) => {
- let score = distTo(c, i)
- if (weight > 0 && nbCount) {
- let s = 0
- if (nl >= 0) s += pair[c * n + nl]
- if (nu >= 0) s += pair[c * n + nu]
- score += weight * (s / nbCount)
- }
- if (score < bestScore) { bestScore = score; best = c }
- }
- for (let t = 0; t < cands.length; t += 1) if (cands[t] >= 0) consider(cands[t])
- if (weight > 0) {
- if (nl >= 0 && subset.member[nl]) consider(nl)
- if (nu >= 0 && nu !== nl && subset.member[nu]) consider(nu)
- }
- cells[i] = best
- }
- }
-
- // 合并零散色:只用了 1~2 颗的色号并入最接近的常用色,减少需要购买的色号
- const counts = new Int32Array(n)
- for (let i = 0; i < total; i += 1) if (cells[i] >= 0) counts[cells[i]] += 1
- if (options.cleanup !== false) {
- const kept = []
- for (let c = 0; c < n; c += 1) if (counts[c] >= 3) kept.push(c)
- if (kept.length) {
- for (let i = 0; i < total; i += 1) {
- const c = cells[i]
- if (c < 0 || counts[c] >= 3) continue
- const member = subsets[kind[i]].member
- let best = -1
- let bestD = Infinity
- for (let t = 0; t < kept.length; t += 1) {
- const kc = kept[t]
- if (!member[kc]) continue
- const d = distTo(kc, i)
- if (d < bestD) { bestD = d; best = kc }
- }
- // 与原色差别过大时保留原色,避免破坏画面
- if (best >= 0 && bestD <= distTo(c, i) + 12) cells[i] = best
- }
- counts.fill(0)
- for (let i = 0; i < total; i += 1) if (cells[i] >= 0) counts[cells[i]] += 1
- }
- }
-
- // 二维码留白区:使用画面中最常用的浅色;没有则用色库里最浅的颜色
- let quietColor = -1
- let quietCount = -1
- for (let c = 0; c < n; c += 1) {
- if (pal.lum[c] >= Math.max(0.8, mode.lightMin) && counts[c] > quietCount) { quietColor = c; quietCount = counts[c] }
- }
- if (quietCount <= 0) {
- quietColor = 0
- for (let c = 1; c < n; c += 1) if (pal.lum[c] > pal.lum[quietColor]) quietColor = c
- }
- for (let i = 0; i < total; i += 1) {
- if (kind[i] === C_QUIET) { cells[i] = quietColor; counts[quietColor] += 1 }
- }
-
- const usage = []
- let beads = 0
- for (let c = 0; c < n; c += 1) {
- if (counts[c] > 0) {
- usage.push({ index: c, id: pal.ids[c], hex: pal.hexes[c], count: counts[c] })
- beads += counts[c]
- }
- }
- usage.sort((a, b) => b.count - a.count)
-
- return { size, cells, usage, beads, pal, qr, placement }
-}
-
-module.exports = { computeArtwork }
diff --git a/BeadQR/miniprogram/utils/imaging.js b/BeadQR/miniprogram/utils/imaging.js
deleted file mode 100644
index 16608b11a75931b0d41fd2758a92f449091a5854..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/imaging.js
+++ /dev/null
@@ -1,95 +0,0 @@
-// 图像取样:超采样 + 区域平均,得到干净的格子颜色(旧版一次性缩放会产生噪点和锯齿色)
-// 所有结果都用 Typed Array 表示,不再生成 HEX 字符串再反解析
-
-const PAPER = [247, 241, 230]
-
-function getImageDimensions(image) {
- const width = Number(image.width) || Number(image.naturalWidth) || Number(image._w)
- const height = Number(image.height) || Number(image.naturalHeight) || Number(image._h)
- if (!width || !height) throw new Error('IMAGE_DIMENSIONS_UNAVAILABLE')
- return { width, height }
-}
-
-// 把图片按裁切参数画到 context 上(cover 语义,zoom≥1)
-function drawCropped(context, image, width, height, crop) {
- const source = getImageDimensions(image)
- const scale = Math.max(width / source.width, height / source.height) * (crop.zoom || 1)
- const w = source.width * scale
- const h = source.height * scale
- const offsetX = (width - w) * ((crop.focusX == null ? 50 : crop.focusX) / 100)
- const offsetY = (height - h) * ((crop.focusY == null ? 50 : crop.focusY) / 100)
- context.fillStyle = `rgb(${PAPER[0]},${PAPER[1]},${PAPER[2]})`
- context.fillRect(0, 0, width, height)
- context.save()
- context.translate(crop.flipH ? width : 0, crop.flipV ? height : 0)
- context.scale(crop.flipH ? -1 : 1, crop.flipV ? -1 : 1)
- context.drawImage(image, offsetX, offsetY, w, h)
- context.restore()
-}
-
-// 返回 { size, rgb: Uint8Array(size*size*3) }
-function sampleImage(canvas, image, size, crop) {
- // 超采样到约 700px 再按块平均,等价于高质量面积缩放
- const factor = Math.max(1, Math.min(24, Math.floor(720 / size)))
- const big = size * factor
- canvas.width = big
- canvas.height = big
- const context = canvas.getContext('2d')
- context.imageSmoothingEnabled = true
- try { context.imageSmoothingQuality = 'high' } catch (e) { /* 部分基础库不支持 */ }
- drawCropped(context, image, big, big, crop || {})
- const pixels = context.getImageData(0, 0, big, big).data
- const rgb = new Uint8Array(size * size * 3)
- const area = factor * factor
- for (let gy = 0; gy < size; gy += 1) {
- for (let gx = 0; gx < size; gx += 1) {
- let r = 0; let g = 0; let b = 0
- for (let sy = 0; sy < factor; sy += 1) {
- let p = ((gy * factor + sy) * big + gx * factor) * 4
- for (let sx = 0; sx < factor; sx += 1) {
- r += pixels[p]; g += pixels[p + 1]; b += pixels[p + 2]
- p += 4
- }
- }
- const o = (gy * size + gx) * 3
- rgb[o] = (r / area + 0.5) | 0
- rgb[o + 1] = (g / area + 0.5) | 0
- rgb[o + 2] = (b / area + 0.5) | 0
- }
- }
- return { size, rgb }
-}
-
-// 去除简单纯色背景:四角均色为背景色,从边缘洪泛填充相近颜色(主体内部不受影响)
-// 返回 Uint8Array 掩码:1 = 背景(空钉位,不放豆)
-function removeSimpleBackground(rgb, size, tolerance) {
- const corners = [0, size - 1, (size - 1) * size, size * size - 1]
- let br = 0; let bg = 0; let bb = 0
- corners.forEach((i) => { br += rgb[i * 3]; bg += rgb[i * 3 + 1]; bb += rgb[i * 3 + 2] })
- br /= 4; bg /= 4; bb /= 4
- const threshold = (tolerance / 100) * 441.673
- const limit = threshold * threshold
- const mask = new Uint8Array(size * size)
- const isBg = (i) => {
- const dr = rgb[i * 3] - br; const dg = rgb[i * 3 + 1] - bg; const db = rgb[i * 3 + 2] - bb
- return dr * dr + dg * dg + db * db <= limit
- }
- const stack = []
- const push = (x, y) => {
- if (x < 0 || y < 0 || x >= size || y >= size) return
- const i = y * size + x
- if (mask[i] || !isBg(i)) return
- mask[i] = 1
- stack.push(i)
- }
- for (let i = 0; i < size; i += 1) { push(i, 0); push(i, size - 1); push(0, i); push(size - 1, i) }
- while (stack.length) {
- const i = stack.pop()
- const x = i % size
- const y = (i - x) / size
- push(x + 1, y); push(x - 1, y); push(x, y + 1); push(x, y - 1)
- }
- return mask
-}
-
-module.exports = { PAPER, getImageDimensions, drawCropped, sampleImage, removeSimpleBackground }
diff --git a/BeadQR/miniprogram/utils/intro.js b/BeadQR/miniprogram/utils/intro.js
deleted file mode 100644
index d8cf6fea218e501859c403a42bb2ecc597ca6ede..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/intro.js
+++ /dev/null
@@ -1,703 +0,0 @@
-// 首屏动态演示(1:1)
-// 纯代码绘制:不占包体积(无视频/图片资源),小程序实时播放与宣传视频渲染共用同一条时间轴。
-// 演示用的拼豆作品由真实配色引擎实时生成,并且确实可以被微信扫出 “Happy Birthday!”。
-const { makeQr, createPlacement } = require('./qr')
-const { preparePalette } = require('./palette')
-const { computeArtwork } = require('./engine')
-
-const DEMO_TEXT = 'Happy Birthday!'
-const DURATION = 12
-const U = 1080 // 设计稿边长,绘制时按实际像素缩放
-const TAU = Math.PI * 2
-const FLIGHT = 0.85
-// 豆子半径(相对格宽):略大于 0.5,相邻豆子轻微相接,像熨烫后的成品,扫码更稳
-const BEAD_R = 0.52
-
-const C = {
- bg: '#f4efe6',
- ink: '#16211f',
- muted: '#6b7471',
- brand: '#0f766e',
- brand2: '#14b8a6',
- brandSoft: '#dcf1ec',
- board: '#fffdf8',
- dark: '#22302e',
- light: '#fbf8f1',
- wechat: '#07c160',
-}
-
-const SCENES = [
- { a: 0, b: 2.6, title: '写一句话', sub: '扫码后想让人看到的话' },
- { a: 2.6, b: 5.0, title: '自动编成二维码', sub: '每一颗拼豆,都是一个像素' },
- { a: 5.0, b: 7.6, title: '融进你的照片', sub: '换上照片的颜色,依然能扫' },
- { a: 7.6, b: 10.0, title: '微信扫一扫', sub: '拼好的作品,一扫就读出这句话' },
-]
-
-const CONFETTI = [
- [0.17, 0.19, 0.045, '#ffd166'], [0.85, 0.2, 0.04, '#4cc9f0'], [0.13, 0.8, 0.04, '#2ec4b6'],
- [0.86, 0.82, 0.045, '#ffd166'], [0.5, 0.11, 0.03, '#2ec4b6'], [0.91, 0.51, 0.03, '#ff9f1c'], [0.08, 0.5, 0.03, '#4cc9f0'],
-]
-
-const DECOR = [
- [90, 150, 22, '#14b8a6'], [990, 120, 16, '#ffb703'], [60, 960, 18, '#ff7a45'], [1010, 930, 24, '#8ecae6'],
- [170, 1040, 12, '#ffb703'], [930, 330, 12, '#ff7a45'], [120, 520, 10, '#8ecae6'], [980, 700, 14, '#14b8a6'],
-]
-
-// —— 工具 ——
-const clamp01 = (v) => (v < 0 ? 0 : v > 1 ? 1 : v)
-const lerp = (a, b, t) => a + (b - a) * t
-const prog = (t, a, b) => clamp01((t - a) / (b - a))
-const easeOut = (t) => 1 - Math.pow(1 - t, 3)
-const easeIn = (t) => t * t * t
-const easeInOut = (t) => (t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2)
-const easeBack = (t) => { const c1 = 1.70158; const c3 = c1 + 1; return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2) }
-const bump = (t, a, b) => { const p = prog(t, a, b); return p > 0 && p < 1 ? Math.sin(Math.PI * p) : 0 }
-
-function rng(seed) {
- let a = seed >>> 0
- return () => {
- a = (a + 0x6D2B79F5) >>> 0
- let t = a
- t = Math.imul(t ^ (t >>> 15), t | 1)
- t ^= t + Math.imul(t ^ (t >>> 7), t | 61)
- return ((t ^ (t >>> 14)) >>> 0) / 4294967296
- }
-}
-
-function rr(ctx, x, y, w, h, r) {
- r = Math.max(0, Math.min(r, w / 2, h / 2))
- ctx.moveTo(x + r, y)
- ctx.arcTo(x + w, y, x + w, y + h, r)
- ctx.arcTo(x + w, y + h, x, y + h, r)
- ctx.arcTo(x, y + h, x, y, r)
- ctx.arcTo(x, y, x + w, y, r)
- ctx.closePath()
-}
-
-// 三层叠加的柔和阴影:比 shadowBlur 便宜得多,手机上逐帧绘制也流畅
-function softShadow(ctx, x, y, w, h, r, alpha) {
- for (let i = 3; i >= 1; i -= 1) {
- const g = i * 8
- ctx.fillStyle = `rgba(52,38,18,${(alpha / (i + 1)).toFixed(3)})`
- ctx.beginPath()
- rr(ctx, x - g / 2, y - g / 2 + g * 0.8, w + g, h + g, r + g / 2)
- ctx.fill()
- }
-}
-
-function heartPath(ctx, cx, cy, s) {
- ctx.moveTo(cx, cy + s * 0.9)
- ctx.bezierCurveTo(cx - s * 1.3, cy + s * 0.05, cx - s * 0.95, cy - s * 1.0, cx, cy - s * 0.42)
- ctx.bezierCurveTo(cx + s * 0.95, cy - s * 1.0, cx + s * 1.3, cy + s * 0.05, cx, cy + s * 0.9)
- ctx.closePath()
-}
-
-// 演示“照片”:暖色渐变 + 爱心 + 彩纸屑(矢量绘制,任意尺寸都清晰)
-function drawIllustration(ctx, x, y, s) {
- ctx.save()
- ctx.beginPath()
- ctx.rect(x, y, s, s)
- ctx.clip()
- let g = ctx.createLinearGradient(x, y, x, y + s)
- g.addColorStop(0, '#63c7b8')
- g.addColorStop(1, '#4aa3c9')
- ctx.fillStyle = g
- ctx.fillRect(x, y, s, s)
- g = ctx.createRadialGradient(x + s * 0.5, y + s * 0.48, 0, x + s * 0.5, y + s * 0.48, s * 0.55)
- g.addColorStop(0, 'rgba(255,255,255,0.35)')
- g.addColorStop(1, 'rgba(255,255,255,0)')
- ctx.fillStyle = g
- ctx.fillRect(x, y, s, s)
- CONFETTI.forEach(([cx, cy, r, col]) => {
- ctx.fillStyle = col
- ctx.beginPath()
- ctx.arc(x + cx * s, y + cy * s, r * s, 0, TAU)
- ctx.fill()
- })
- g = ctx.createLinearGradient(x, y + s * 0.2, x, y + s * 0.85)
- g.addColorStop(0, '#ff6b88')
- g.addColorStop(1, '#d42a55')
- ctx.fillStyle = g
- ctx.beginPath()
- heartPath(ctx, x + s * 0.5, y + s * 0.55, s * 0.34)
- ctx.fill()
- ctx.fillStyle = 'rgba(255,255,255,0.55)'
- ctx.save()
- ctx.translate(x + s * 0.37, y + s * 0.42)
- ctx.rotate(-0.6)
- ctx.scale(1, 0.55)
- ctx.beginPath()
- ctx.arc(0, 0, s * 0.06, 0, TAU)
- ctx.fill()
- ctx.restore()
- ctx.restore()
-}
-
-// 用真实引擎生成演示作品:插画按格面积取平均色 → 配色引擎
-function buildDemo(workCanvas, createCanvas) {
- const qr = makeQr(DEMO_TEXT, 'H')
- const placement = createPlacement(qr.size, { scale: 100, quiet: 1, hasImage: true })
- const size = placement.size
- const k = 6
- const px = size * k
- const canvas = createCanvas ? createCanvas(px, px) : workCanvas
- canvas.width = px
- canvas.height = px
- const ctx = canvas.getContext('2d')
- ctx.setTransform(1, 0, 0, 1, 0, 0)
- ctx.clearRect(0, 0, px, px)
- drawIllustration(ctx, 0, 0, px)
- const data = ctx.getImageData(0, 0, px, px).data
- const rgb = new Uint8Array(size * size * 3)
- for (let r = 0; r < size; r += 1) {
- for (let c = 0; c < size; c += 1) {
- let sr = 0; let sg = 0; let sb = 0
- for (let y = 0; y < k; y += 1) {
- let o = ((r * k + y) * px + c * k) * 4
- for (let x = 0; x < k; x += 1, o += 4) { sr += data[o]; sg += data[o + 1]; sb += data[o + 2] }
- }
- const i = (r * size + c) * 3
- rgb[i] = sr / (k * k); rgb[i + 1] = sg / (k * k); rgb[i + 2] = sb / (k * k)
- }
- }
- const art = computeArtwork({ size, rgb }, qr, placement, preparePalette('221'), { modeId: 'balanced', coherence: 40, cleanup: true })
- return { qr, placement, art }
-}
-
-// —— 豆子批量绘制:按颜色合并路径,每帧只需十几次填充 ——
-function addBead(groups, hex, x, y, r) {
- let list = groups.get(hex)
- if (!list) { list = []; groups.set(hex, list) }
- list.push(x, y, r)
-}
-
-// 小批量合并路径:一条路径里子路径太多时,部分渲染引擎反而更慢,每 12 颗提交一次最稳
-const CHUNK = 12
-function fillCircles(ctx, list, rs, ox, oy) {
- let n = 0
- ctx.beginPath()
- for (let i = 0; i < list.length; i += 3) {
- const r = list[i + 2] * rs
- const x = list[i] + list[i + 2] * ox
- const y = list[i + 1] + list[i + 2] * oy
- ctx.moveTo(x + r, y)
- ctx.arc(x, y, r, 0, TAU)
- n += 1
- if (n === CHUNK) { ctx.fill(); ctx.beginPath(); n = 0 }
- }
- if (n) ctx.fill()
-}
-
-function flushBeads(ctx, groups) {
- const all = []
- groups.forEach((list, hex) => {
- ctx.fillStyle = hex
- fillCircles(ctx, list, 1, 0, 0)
- all.push(list)
- })
- // 中孔:拼豆是一颗颗小管子
- ctx.fillStyle = 'rgba(70,48,24,0.17)'
- all.forEach((list) => fillCircles(ctx, list, 0.3, 0, 0))
- // 高光
- ctx.fillStyle = 'rgba(255,255,255,0.4)'
- all.forEach((list) => fillCircles(ctx, list, 0.2, -0.42, -0.42))
- groups.clear()
-}
-
-/**
- * @param opts { workCanvas?, createCanvas?(w,h), font?, loop? }
- * @returns { duration, text, artwork, draw(ctx, t, pixelWidth) }
- */
-function createIntro(opts = {}) {
- const font = opts.font || 'sans-serif'
- const loop = opts.loop !== false
- const F = (weight, px) => `${weight} ${Math.round(px)}px ${font}`
- const { qr, placement, art } = buildDemo(opts.workCanvas, opts.createCanvas)
- const size = art.size
- const R = rng(20260929)
- const cells = []
- for (let r = 0; r < size; r += 1) {
- for (let c = 0; c < size; c += 1) {
- const qc = c - placement.left
- const qrow = r - placement.top
- const dark = qc >= 0 && qrow >= 0 && qc < qr.size && qrow < qr.size && qr.dark[qrow * qr.size + qc] === 1
- const idx = art.cells[r * size + c]
- cells.push({
- c,
- r,
- qrHex: dark ? C.dark : C.light,
- finalHex: idx >= 0 ? art.pal.hexes[idx] : C.board,
- k: Math.max(0, Math.min(DEMO_TEXT.length - 1, Math.floor((c / size) * DEMO_TEXT.length + (R() - 0.5) * 2.5))),
- jx: R(),
- jy: R() - 0.5,
- bend: R() - 0.5,
- t0: 2.72 + (c / size) * 0.55 + R() * 0.55,
- tw: 5.95 + ((c + r) / (2 * (size - 1))) * 0.95 + R() * 0.08,
- })
- }
- }
- const finders = [[0, 0], [qr.size - 7, 0], [0, qr.size - 7]].map(([x, y]) => [placement.left + x, placement.top + y])
- const topColors = art.usage.slice(0, 8).map((u) => u.hex)
- const burst = Array.from({ length: 26 }, () => ({
- a: -Math.PI / 2 + (R() - 0.5) * 2.2,
- v: 520 + R() * 520,
- r: 9 + R() * 8,
- hex: topColors[Math.floor(R() * topColors.length)] || C.brand2,
- }))
- const groups = new Map()
- const pegDots = []
- for (let y = 20; y < U; y += 40) for (let x = 20; x < U; x += 40) pegDots.push(x, y, 2.4)
- let layout = null // 文本排版缓存(首帧测量)
-
- const textLayout = (ctx) => {
- if (layout) return layout
- ctx.font = F('bold', 64)
- const x0 = 170
- const charX = []
- for (let i = 0; i <= DEMO_TEXT.length; i += 1) charX.push(x0 + ctx.measureText(DEMO_TEXT.slice(0, i)).width)
- layout = { charX, y: 616 }
- return layout
- }
-
- const boardAt = (t) => {
- let cx = 540; let cy = 590; let B = 640
- const a = easeInOut(prog(t, 7.6, 8.2))
- cx = lerp(cx, 356, a); B = lerp(B, 560, a)
- const b = easeInOut(prog(t, 10.05, 10.75))
- cx = lerp(cx, 540, b); cy = lerp(cy, 410, b); B = lerp(B, 450, b)
- return { cx, cy, B }
- }
- const gridOf = (L) => {
- const pad = L.B * 0.05
- const cell = (L.B - pad * 2) / size
- return { cell, ox: L.cx - L.B / 2 + pad, oy: L.cy - L.B / 2 + pad }
- }
-
- const drawPlate = (ctx, L, alpha) => {
- const x = L.cx - L.B / 2
- const y = L.cy - L.B / 2
- const r = L.B * 0.045
- ctx.globalAlpha = alpha
- softShadow(ctx, x, y, L.B, L.B, r, 0.16)
- ctx.fillStyle = C.board
- ctx.beginPath(); rr(ctx, x, y, L.B, L.B, r); ctx.fill()
- ctx.globalAlpha = 1
- }
-
- // 背景:米色钉板 + 缓慢漂浮的装饰豆
- const drawBackground = (ctx, t) => {
- ctx.fillStyle = C.bg
- ctx.fillRect(0, 0, U, U)
- ctx.fillStyle = 'rgba(60,45,25,0.065)'
- fillCircles(ctx, pegDots, 1, 0, 0)
- DECOR.forEach(([x, y, r, hex], i) => {
- const dx = Math.sin(t * 0.9 + i * 1.7) * 10
- const dy = Math.cos(t * 0.7 + i * 2.3) * 12
- ctx.globalAlpha = 0.55
- addBead(groups, hex, x + dx, y + dy, r)
- })
- flushBeads(ctx, groups)
- ctx.globalAlpha = 1
- }
-
- const drawCaption = (ctx, t) => {
- ctx.textAlign = 'center'
- ctx.textBaseline = 'middle'
- SCENES.forEach((s, i) => {
- if (t < s.a || t > s.b) return
- const inP = easeOut(prog(t, s.a + 0.05, s.a + 0.5))
- const outP = easeIn(prog(t, s.b - 0.32, s.b))
- const alpha = inP * (1 - outP)
- if (alpha <= 0) return
- const dy = (1 - inP) * 26 - outP * 14
- ctx.globalAlpha = alpha
- ctx.font = F('bold', 24)
- const label = `第 ${i + 1} 步`
- const w = ctx.measureText(label).width + 40
- ctx.fillStyle = C.brandSoft
- ctx.beginPath(); rr(ctx, 540 - w / 2, 70 + dy, w, 46, 23); ctx.fill()
- ctx.fillStyle = C.brand
- ctx.fillText(label, 540, 94 + dy)
- ctx.fillStyle = C.ink
- ctx.font = F('bold', 60)
- ctx.fillText(s.title, 540, 170 + dy * 1.3)
- ctx.fillStyle = C.muted
- ctx.font = F('normal', 30)
- ctx.fillText(s.sub, 540, 232 + dy * 1.6)
- })
- ctx.globalAlpha = 1
- }
-
- const drawProgress = (ctx, t) => {
- const alpha = prog(t, 0, 0.35) * (1 - prog(t, 10.0, 10.4))
- if (alpha <= 0) return
- ctx.globalAlpha = alpha
- const w = 110; const gap = 16; const x0 = 540 - (w * 4 + gap * 3) / 2
- SCENES.forEach((s, i) => {
- const x = x0 + i * (w + gap)
- ctx.fillStyle = 'rgba(22,33,31,0.1)'
- ctx.beginPath(); rr(ctx, x, 1010, w, 8, 4); ctx.fill()
- const p = prog(t, s.a, s.b)
- if (p > 0) {
- ctx.fillStyle = C.brand
- ctx.beginPath(); rr(ctx, x, 1010, Math.max(8, w * p), 8, 4); ctx.fill()
- }
- })
- ctx.globalAlpha = 1
- }
-
- // 第 1 幕:输入框 + 打字
- const drawInput = (ctx, t) => {
- if (t > 3.35) return
- const inP = easeBack(prog(t, 0.1, 0.65))
- const outP = easeInOut(prog(t, 2.6, 3.15))
- const alpha = prog(t, 0.1, 0.4)
- if (alpha <= 0) return
- const L = textLayout(ctx)
- const press = 1 - 0.08 * bump(t, 2.1, 2.4)
- const scale = lerp(0.88, 1, inP) * lerp(1, 0.95, outP)
- ctx.save()
- ctx.translate(540, 590)
- ctx.scale(scale, scale)
- ctx.translate(-540, -590)
- ctx.globalAlpha = alpha * (1 - outP)
- softShadow(ctx, 130, 495, 820, 190, 40, 0.14)
- ctx.fillStyle = '#ffffff'
- ctx.beginPath(); rr(ctx, 130, 495, 820, 190, 40); ctx.fill()
- ctx.textAlign = 'left'
- ctx.textBaseline = 'middle'
- ctx.fillStyle = C.muted
- ctx.font = F('normal', 24)
- ctx.fillText('扫码后显示的内容', 170, 548)
- // 发送按钮
- ctx.save()
- ctx.translate(880, 590)
- ctx.scale(press, press)
- ctx.fillStyle = C.brand
- ctx.beginPath(); ctx.arc(0, 0, 44, 0, TAU); ctx.fill()
- ctx.strokeStyle = '#fff'
- ctx.lineWidth = 7
- ctx.lineCap = 'round'
- ctx.lineJoin = 'round'
- ctx.beginPath(); ctx.moveTo(-14, 0); ctx.lineTo(14, 0); ctx.moveTo(2, -13); ctx.lineTo(15, 0); ctx.lineTo(2, 13); ctx.stroke()
- ctx.restore()
- ctx.restore()
- // 文字逐字出现,随后逐字化作豆子
- const count = Math.floor(prog(t, 0.55, 1.9) * DEMO_TEXT.length + 0.0001)
- ctx.font = F('bold', 64)
- ctx.textAlign = 'left'
- ctx.fillStyle = C.ink
- for (let i = 0; i < count; i += 1) {
- const start = 2.7 + (i / DEMO_TEXT.length) * 0.55
- const a = alpha * (1 - prog(t, start, start + 0.35))
- if (a <= 0) continue
- ctx.globalAlpha = a
- ctx.fillText(DEMO_TEXT[i], L.charX[i], L.y)
- }
- const typing = t >= 0.55 && t <= 1.9
- if (t < 2.55 && (typing || Math.floor(t / 0.4) % 2 === 0)) {
- ctx.globalAlpha = alpha
- ctx.fillStyle = C.brand2
- ctx.fillRect(L.charX[count] + 4, L.y - 34, 5, 68)
- }
- ctx.globalAlpha = 1
- }
-
- // 主画板上的豆子:飞入 → 黑白二维码 → 扫过换色
- const drawMainBeads = (ctx, t, L) => {
- const G = gridOf(L)
- const TL = textLayout(ctx)
- const baseR = G.cell * BEAD_R
- for (let i = 0; i < cells.length; i += 1) {
- const b = cells[i]
- if (t < b.t0) continue
- const dx = G.ox + (b.c + 0.5) * G.cell
- const dy = G.oy + (b.r + 0.5) * G.cell
- let x = dx; let y = dy; let s = 1
- const f = prog(t, b.t0, b.t0 + FLIGHT)
- if (f < 1) {
- const sx = TL.charX[b.k] + b.jx * (TL.charX[b.k + 1] - TL.charX[b.k])
- const sy = TL.y + b.jy * 44
- const cx = (sx + dx) / 2 + b.bend * 220
- const cy = Math.min(sy, dy) - 110 - Math.abs(b.bend) * 160
- const e = easeInOut(f)
- const u = 1 - e
- x = u * u * sx + 2 * u * e * cx + e * e * dx
- y = u * u * sy + 2 * u * e * cy + e * e * dy
- s = lerp(0.55, 1, easeOut(f))
- } else {
- s = 1 + 0.16 * bump(t, b.t0 + FLIGHT, b.t0 + FLIGHT + 0.2)
- }
- s += 0.3 * bump(t, b.tw - 0.05, b.tw + 0.25)
- addBead(groups, t >= b.tw ? b.finalHex : b.qrHex, x, y, baseR * s)
- }
- flushBeads(ctx, groups)
- }
-
- const drawFinalBeads = (ctx, L) => {
- const G = gridOf(L)
- const r = G.cell * BEAD_R
- for (let i = 0; i < cells.length; i += 1) {
- const b = cells[i]
- addBead(groups, b.finalHex, G.ox + (b.c + 0.5) * G.cell, G.oy + (b.r + 0.5) * G.cell, r)
- }
- flushBeads(ctx, groups)
- }
-
- // 二维码定位图形高亮
- const drawFinders = (ctx, t, L) => {
- const p = prog(t, 4.15, 4.95)
- if (p <= 0 || p >= 1) return
- const G = gridOf(L)
- const alpha = Math.sin(Math.PI * p)
- const grow = (1 - easeOut(p)) * 18
- ctx.strokeStyle = C.brand2
- ctx.lineWidth = 6
- ctx.globalAlpha = alpha
- finders.forEach(([c, r]) => {
- const x = G.ox + c * G.cell - 6 - grow
- const y = G.oy + r * G.cell - 6 - grow
- const w = 7 * G.cell + 12 + grow * 2
- ctx.beginPath(); rr(ctx, x, y, w, w, 16); ctx.stroke()
- })
- ctx.globalAlpha = 1
- }
-
- // 沿对角线扫过的光带
- const drawGleam = (ctx, L, p, strength) => {
- if (p <= 0 || p >= 1) return
- const x = L.cx - L.B / 2
- const y = L.cy - L.B / 2
- const g = ctx.createLinearGradient(x, y, x + L.B, y + L.B)
- const s0 = clamp01(p - 0.12); const s1 = clamp01(p); const s2 = clamp01(p + 0.04)
- g.addColorStop(0, 'rgba(255,255,255,0)')
- if (s0 > 0) g.addColorStop(s0, 'rgba(255,255,255,0)')
- g.addColorStop(s1, `rgba(255,255,255,${strength})`)
- if (s2 < 1) g.addColorStop(s2, 'rgba(255,255,255,0)')
- g.addColorStop(1, 'rgba(255,255,255,0)')
- ctx.save()
- ctx.beginPath(); rr(ctx, x, y, L.B, L.B, L.B * 0.045); ctx.clip()
- ctx.fillStyle = g
- ctx.fillRect(x, y, L.B, L.B)
- ctx.restore()
- }
-
- // 第 3 幕:照片飞入并铺到画板上
- const drawPhoto = (ctx, t, L) => {
- if (t < 4.95 || t > 6.65) return
- const a = easeOut(prog(t, 5.0, 5.55))
- const b = easeInOut(prog(t, 5.6, 6.05))
- let x = lerp(1320, 800, a); let y = lerp(250, 330, a); let rot = lerp(0.4, -0.12, a); let s = 300
- x = lerp(x, L.cx, b); y = lerp(y, L.cy, b); rot = lerp(rot, 0, b); s = lerp(s, L.B * 0.9, b)
- const frame = lerp(14, 0, b)
- const alpha = 1 - prog(t, 6.0, 6.6)
- ctx.save()
- ctx.globalAlpha = alpha
- ctx.translate(x, y)
- ctx.rotate(rot)
- const half = s / 2 + frame
- if (b < 1) softShadow(ctx, -half, -half, half * 2, half * 2, 18, 0.2 * (1 - b))
- ctx.fillStyle = '#ffffff'
- ctx.beginPath(); rr(ctx, -half, -half, half * 2, half * 2, 18); ctx.fill()
- ctx.beginPath(); rr(ctx, -s / 2, -s / 2, s, s, 10); ctx.clip()
- drawIllustration(ctx, -s / 2, -s / 2, s)
- ctx.restore()
- ctx.globalAlpha = 1
- }
-
- // 第 4 幕:手机扫码
- const drawPhone = (ctx, t) => {
- const enter = easeOut(prog(t, 7.75, 8.35))
- const exit = easeIn(prog(t, 9.95, 10.4))
- if (enter <= 0 || exit >= 1) return
- const w = 340; const h = 660
- const px = 800
- const py = 590 + (1 - enter) * 860 + exit * 860
- const rot = lerp(0.16, -0.035, enter)
- ctx.save()
- ctx.translate(px, py)
- ctx.rotate(rot)
- softShadow(ctx, -w / 2, -h / 2, w, h, 60, 0.28)
- ctx.fillStyle = '#1b2321'
- ctx.beginPath(); rr(ctx, -w / 2, -h / 2, w, h, 60); ctx.fill()
- ctx.fillStyle = '#2c3633'
- ctx.fillRect(w / 2 - 1, -h / 2 + 150, 5, 70)
- // 屏幕
- const sw = w - 24; const sh = h - 24
- ctx.save()
- ctx.beginPath(); rr(ctx, -sw / 2, -sh / 2, sw, sh, 48); ctx.clip()
- ctx.fillStyle = '#0e1312'
- ctx.fillRect(-sw / 2, -sh / 2, sw, sh)
- const jx = Math.sin(t * 3.1) * 3
- const jy = Math.cos(t * 2.3) * 3
- const cam = { cx: jx, cy: -30 + jy, B: 250 }
- ctx.globalAlpha = 0.92
- ctx.fillStyle = C.bg
- ctx.fillRect(-sw / 2, -sh / 2, sw, sh)
- ctx.globalAlpha = 1
- drawPlate(ctx, cam, 1)
- drawFinalBeads(ctx, cam)
- ctx.fillStyle = 'rgba(10,15,14,0.45)'
- ctx.fillRect(-sw / 2, -sh / 2, sw, sh)
- // 取景框
- const detect = prog(t, 9.0, 9.3)
- const snap = t >= 9.0 ? 1 + 0.1 * (1 - easeOut(detect)) : 1
- const half = 146 * snap
- ctx.strokeStyle = t >= 9.0 ? C.wechat : '#ffffff'
- ctx.lineWidth = 6
- ctx.lineCap = 'round'
- const arm = 34
- ctx.beginPath()
- ;[[-1, -1], [1, -1], [1, 1], [-1, 1]].forEach(([sx, sy]) => {
- const x = cam.cx + sx * half
- const y = cam.cy + sy * half
- ctx.moveTo(x, y - sy * arm); ctx.lineTo(x, y); ctx.lineTo(x - sx * arm, y)
- })
- ctx.stroke()
- // 扫描线
- const sp = prog(t, 8.3, 9.0)
- if (sp > 0 && sp < 1) {
- const top = cam.cy - 140
- const y = lerp(top, cam.cy + 140, easeInOut(sp))
- const g = ctx.createLinearGradient(0, y - 80, 0, y)
- g.addColorStop(0, 'rgba(7,193,96,0)')
- g.addColorStop(1, 'rgba(7,193,96,0.35)')
- ctx.fillStyle = g
- ctx.fillRect(cam.cx - 140, Math.max(top, y - 80), 280, y - Math.max(top, y - 80))
- ctx.fillStyle = C.wechat
- ctx.fillRect(cam.cx - 140, y - 2, 280, 4)
- }
- ctx.textAlign = 'center'
- ctx.textBaseline = 'middle'
- ctx.fillStyle = '#ffffff'
- ctx.font = F('bold', 24)
- ctx.fillText('扫一扫', 0, -sh / 2 + 78)
- if (t < 9.0) {
- ctx.globalAlpha = 0.7
- ctx.font = F('normal', 19)
- ctx.fillText('将二维码放入框内', 0, cam.cy + 185)
- ctx.globalAlpha = 1
- }
- const flash = t >= 9.0 ? 0.35 * (1 - prog(t, 9.0, 9.25)) : 0
- if (flash > 0) {
- ctx.fillStyle = `rgba(255,255,255,${flash.toFixed(3)})`
- ctx.fillRect(-sw / 2, -sh / 2, sw, sh)
- }
- // 识别结果卡片
- const rp = prog(t, 9.1, 9.5)
- if (rp > 0) {
- const cw = sw - 36; const ch = 170
- const cy = sh / 2 - 18 - ch + (1 - easeBack(rp)) * 220
- ctx.fillStyle = '#ffffff'
- ctx.beginPath(); rr(ctx, -cw / 2, cy, cw, ch, 28); ctx.fill()
- ctx.fillStyle = C.wechat
- ctx.beginPath(); ctx.arc(0, cy + 44, 22, 0, TAU); ctx.fill()
- ctx.strokeStyle = '#fff'
- ctx.lineWidth = 5
- ctx.lineJoin = 'round'
- ctx.beginPath(); ctx.moveTo(-9, cy + 44); ctx.lineTo(-2, cy + 51); ctx.lineTo(10, cy + 37); ctx.stroke()
- ctx.fillStyle = C.ink
- ctx.font = F('bold', 30)
- ctx.fillText(DEMO_TEXT, 0, cy + 100)
- ctx.fillStyle = C.muted
- ctx.font = F('normal', 18)
- ctx.fillText('扫码结果', 0, cy + 138)
- }
- ctx.restore()
- // 灵动岛
- ctx.fillStyle = '#000'
- ctx.beginPath(); rr(ctx, -52, -h / 2 + 26, 104, 30, 15); ctx.fill()
- ctx.restore()
-
- // 识别成功:豆子礼花
- const bt = t - 9.2
- if (bt > 0 && bt < 1.4) {
- const ox = px; const oy = py + 200
- const fade = 1 - prog(bt, 0.9, 1.4)
- ctx.globalAlpha = fade
- burst.forEach((p) => {
- const x = ox + Math.cos(p.a) * p.v * bt
- const y = oy + Math.sin(p.a) * p.v * bt + 900 * bt * bt
- addBead(groups, p.hex, x, y, p.r)
- })
- flushBeads(ctx, groups)
- ctx.globalAlpha = 1
- }
- }
-
- // 片尾
- const drawEnd = (ctx, t) => {
- if (t < 10.4) return
- ctx.textAlign = 'center'
- ctx.textBaseline = 'middle'
- const a = easeOut(prog(t, 10.45, 10.95))
- ctx.globalAlpha = a
- ctx.fillStyle = C.ink
- ctx.font = F('bold', 64)
- ctx.fillText('豆维 · 可扫码的拼豆', 540, 745 + (1 - a) * 30)
- const b = easeOut(prog(t, 10.6, 11.1))
- ctx.globalAlpha = b
- ctx.fillStyle = C.muted
- ctx.font = F('normal', 32)
- ctx.fillText('把一句话藏进拼豆里,微信一扫就能读出来', 540, 812 + (1 - b) * 30)
- const chips = ['MARD 标准色号', 'A4 打印图纸', '微信一扫即读']
- ctx.font = F('bold', 26)
- const widths = chips.map((s) => ctx.measureText(s).width + 44)
- const total = widths.reduce((s, v) => s + v, 0) + 18 * (chips.length - 1)
- let x = 540 - total / 2
- chips.forEach((label, i) => {
- const p = easeBack(prog(t, 10.85 + i * 0.12, 11.3 + i * 0.12))
- if (p > 0) {
- ctx.globalAlpha = clamp01(p)
- const cy = 892 + (1 - p) * 24
- ctx.fillStyle = C.brandSoft
- ctx.beginPath(); rr(ctx, x, cy - 26, widths[i], 52, 26); ctx.fill()
- ctx.fillStyle = C.brand
- ctx.fillText(label, x + widths[i] / 2, cy)
- }
- x += widths[i] + 18
- })
- ctx.globalAlpha = 1
- }
-
- const draw = (ctx, time, pixelWidth) => {
- const t = loop ? ((time % DURATION) + DURATION) % DURATION : Math.min(time, DURATION)
- const k = pixelWidth / U
- ctx.setTransform(k, 0, 0, k, 0, 0)
- ctx.globalAlpha = 1
- drawBackground(ctx, t)
- const L = boardAt(t)
- if (t >= 2.65) {
- const p = easeBack(prog(t, 2.65, 3.15))
- const s = lerp(0.92, 1, p)
- const LS = { cx: L.cx, cy: L.cy, B: L.B * s }
- drawPlate(ctx, LS, prog(t, 2.65, 3.0))
- }
- drawInput(ctx, t)
- if (t >= 2.72) drawMainBeads(ctx, t, L)
- drawFinders(ctx, t, L)
- drawGleam(ctx, L, prog(t, 5.9, 7.0), 0.55)
- drawGleam(ctx, L, prog(t, 11.0, 11.7), 0.4)
- drawPhoto(ctx, t, L)
- drawPhone(ctx, t)
- drawCaption(ctx, t)
- drawProgress(ctx, t)
- drawEnd(ctx, t)
- if (loop) {
- const fade = easeInOut(prog(t, 11.45, 12))
- if (fade > 0) {
- ctx.globalAlpha = fade
- ctx.fillStyle = C.bg
- ctx.fillRect(0, 0, U, U)
- ctx.globalAlpha = 1
- }
- }
- ctx.setTransform(1, 0, 0, 1, 0, 0)
- }
-
- // 关键时间点(供视频配乐对齐)
- const timeline = { landings: cells.map((b) => b.t0 + FLIGHT), wipes: cells.map((b) => b.tw) }
- return { duration: DURATION, text: DEMO_TEXT, artwork: art, draw, timeline }
-}
-
-module.exports = { createIntro, DEMO_TEXT, DURATION }
diff --git a/BeadQR/miniprogram/utils/palette-data.js b/BeadQR/miniprogram/utils/palette-data.js
deleted file mode 100644
index 03c30718d7d65fbea2a205a75fabd95cbeb2e398..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/palette-data.js
+++ /dev/null
@@ -1,48 +0,0 @@
-// MARD reference palette from the public 2026 color chart.
-// 291 colors = standard 221 (A-H, M) + 70 extended (P, Q, R, T, Y, ZG).
-const MARD_HEX = {
- A1:"#f9f0cd", A2:"#fbfbd4", A3:"#fafc9f", A4:"#ffe953", A5:"#f4d738", A6:"#fdad49", A7:"#ff7c2f", A8:"#eaca49",
- A9:"#ff995a", A10:"#ff9d55", A11:"#ffdd99", A12:"#fcb58f", A13:"#ffbb59", A14:"#ff6d40", A15:"#fdff44", A16:"#fef9ae",
- A17:"#ffe36e", A18:"#fecf98", A19:"#fd7b72", A20:"#efcd67", A21:"#ffe395", A22:"#fff3a4", A23:"#f3d5bf", A24:"#fbf8c9",
- A25:"#ffd67d", A26:"#ffbb27", B1:"#e6ee32", B2:"#5be419", B3:"#7cee9d", B4:"#1ef942", B5:"#00bd35", B6:"#5ae8ba",
- B7:"#03ac88", B8:"#029d26", B9:"#26523a", B10:"#95d3c2", B11:"#5d722a", B12:"#156f40", B13:"#d9f794", B14:"#ade945",
- B15:"#2e5132", B16:"#c6ed9c", B17:"#9bb13a", B18:"#e6ee49", B19:"#25b88c", B20:"#c2f0cc", B21:"#146a6b", B22:"#0b3c43",
- B23:"#303921", B24:"#eefca5", B25:"#4e846d", B26:"#8c7a36", B27:"#d1dcc1", B28:"#9ee5b9", B29:"#c5e254", B30:"#ecfbd0",
- B31:"#c4e6b5", B32:"#9bab5a", C1:"#e8ffe7", C2:"#bcf9f6", C3:"#a0e2fb", C4:"#42ccff", C5:"#01aceb", C6:"#50a9f0",
- C7:"#0188d3", C8:"#1054c0", C9:"#314bca", C10:"#3ebce2", C11:"#03b9b9", C12:"#1c334d", C13:"#cde8ff", C14:"#d5fdff",
- C15:"#23c4c6", C16:"#1757a8", C17:"#50d3ec", C18:"#1c3344", C19:"#1787a2", C20:"#0082be", C21:"#beddff", C22:"#67b4be",
- C23:"#c2dceb", C24:"#7dc4ff", C25:"#a9e5e5", C26:"#2f99b3", C27:"#ebf5fc", C28:"#bbcfed", C29:"#4b5ba3", D1:"#aeb4f2",
- D2:"#858edd", D3:"#3054af", D4:"#182a84", D5:"#b843c5", D6:"#ac7bde", D7:"#6e399a", D8:"#e2d3ff", D9:"#d5b9f8",
- D10:"#361b50", D11:"#b9bae1", D12:"#de9ad4", D13:"#b90295", D14:"#8b279b", D15:"#2f1f90", D16:"#e2e1ee", D17:"#c4d4f6",
- D18:"#a45ec7", D19:"#d8c3d7", D20:"#9c32b2", D21:"#9a009b", D22:"#333995", D23:"#eadafc", D24:"#7786e5", D25:"#484fc7",
- D26:"#e9c3f6", E1:"#fdd3cc", E2:"#fecddf", E3:"#ff97c3", E4:"#e8649e", E5:"#f551a2", E6:"#ff346b", E7:"#c63578",
- E8:"#ffdbe9", E9:"#e970cc", E10:"#d33893", E11:"#fcddd2", E12:"#ffa1c5", E13:"#b6006d", E14:"#ffd1ba", E15:"#f2cfd0",
- E16:"#ffecde", E17:"#ffe2ea", E18:"#ffc9d6", E19:"#ffd2e7", E20:"#d8c7d1", E21:"#bd9da1", E22:"#cc78a7", E23:"#937a8d",
- E24:"#f6e4f9", F1:"#fd957b", F2:"#fc3d45", F3:"#f74941", F4:"#fc283c", F5:"#d80127", F6:"#b0443d", F7:"#971937",
- F8:"#bc0127", F9:"#e2677a", F10:"#a74d22", F11:"#6f201f", F12:"#fd4d6a", F13:"#dd422f", F14:"#ffa9ad", F15:"#c80020",
- F16:"#ffd9c8", F17:"#f79b71", F18:"#d37c46", F19:"#c1444a", F20:"#cd9391", F21:"#f4b1b4", F22:"#ffd0cb", F23:"#f57e66",
- F24:"#fcc1c4", F25:"#e54b4f", G1:"#ffe2ce", G2:"#ffcaaa", G3:"#f4c3a5", G4:"#e1b383", G5:"#ed9435", G6:"#f59734",
- G7:"#9d5b3e", G8:"#592a21", G9:"#e6b483", G10:"#c88135", G11:"#e0c593", G12:"#ebbb83", G13:"#b7714a", G14:"#8d614c",
- G15:"#fcf9e0", G16:"#f2d9ba", G17:"#56403c", G18:"#ffe4cc", G19:"#e1943a", G20:"#a94023", G21:"#cb8e77", H1:"#e2e2e2",
- H2:"#ffffff", H3:"#b3b3b3", H4:"#868686", H5:"#474747", H6:"#2c2c2c", H7:"#000000", H8:"#e7d6db", H9:"#e4e7e3",
- H10:"#eee9ea", H11:"#cecdd5", H12:"#fff5ed", H13:"#f3e1c9", H14:"#cfd7d3", H15:"#98a6a8", H16:"#3b2f23", H17:"#f1eded",
- H18:"#fffdf0", H19:"#f6efe2", H20:"#949fa3", H21:"#f7f3e4", H22:"#cacad5", H23:"#9a9d94", M1:"#bcc6b8", M2:"#8aa385",
- M3:"#697d80", M4:"#dacebe", M5:"#d0ccaa", M6:"#b0a782", M7:"#b4a497", M8:"#b38281", M9:"#a58767", M10:"#c5b1bc",
- M11:"#9f7494", M12:"#644749", M13:"#d19066", M14:"#c77361", M15:"#757d7b", P1:"#fcf8f9", P2:"#bda9ab", P3:"#aedda9",
- P4:"#fda49e", P5:"#ec8d3d", P6:"#60cfa8", P7:"#eb9271", P8:"#f0d958", P9:"#d9d9d9", P10:"#d5c8e9", P11:"#f3ecc8",
- P12:"#e6eef1", P13:"#a9cbf1", P14:"#3177b0", P15:"#668575", P16:"#ffbe46", P17:"#ffa324", P18:"#feb89f", P19:"#ffe0e8",
- P20:"#febecf", P21:"#ecbec0", P22:"#e4a89e", P23:"#a56269", Q1:"#f2a5e8", Q2:"#73b29e", Q3:"#ffff00", Q4:"#ffebfa",
- Q5:"#4f5e5b", R1:"#d50e21", R2:"#f92e83", R3:"#fd8225", R4:"#f8ec31", R5:"#34c75b", R6:"#25b891", R7:"#17779d",
- R8:"#1b60c3", R9:"#9a56b4", R10:"#ffdb4d", R11:"#ffebfa", R12:"#d8d5ce", R13:"#55514c", R14:"#9ee4df", R15:"#77cee9",
- R16:"#3dcfca", R17:"#4a867a", R18:"#7fcd9d", R19:"#cde55d", R20:"#e8c7b4", R21:"#ad6f3c", R22:"#6c372f", R23:"#feb872",
- R24:"#f2c1c0", R25:"#c9675d", R26:"#d293be", R27:"#ea8cb1", R28:"#9c87d6", T1:"#e2dfd7", Y1:"#fd6fb4", Y2:"#feb481",
- Y3:"#d7faa0", Y4:"#8bdbfa", Y5:"#e987ea", ZG1:"#daabb3", ZG2:"#d6aa87", ZG3:"#c1bd8d", ZG4:"#96869f", ZG5:"#8490a6",
- ZG6:"#94bfe2", ZG7:"#e2a9d2", ZG8:"#ab91c0",
-}
-
-const MARD_PALETTE = Object.entries(MARD_HEX).map(([id, hex]) => ({ id, hex }))
-
-// 智能近色色库的“远点优先”排序(离线预计算,避免真机启动时 2000 万次距离运算)
-const MARD_SMART_ORDER = ["A4","A7","B5","B9","C4","C8","C12","D7","E5","F3","G5","G8","H2","H3","H5","H7","M3","M12","P3","P14","Q1","R5","R13","ZG6","E13","B17","Q3","B2","A22","C11","D18","P6","G20","F5","P4","M8","D15","C2","D24","A19","B4","B14","G13","B21","R12","E7","C7","D21","E9","B19","D25","M2","D8","D20","R16","R23","B26","B11","E6","F7","E22","F19","ZG2","A26","A2","C5","B3","C28","E2","M13","B1","B13","ZG4","C6","R19","R28","G2","ZG1","E3","P23","A8","A9","R14","C29","C24","H6","M6","B7","G7","Q2","M5","D10","B8","B20","B10","F9","C22","C26","B12","B25","F4","D5","C19","B32","F13","A25","H15","D13","G10","B6","Y5","H10","Y1","D14","D1","D3","D12","E21","E10","M9","D9","R27","C10","R18","H13","H4","P21","ZG3","G11","C15","ZG8","P7","D4","C3","M14","A20","F8","R22","C14","D22","A15","A6","R26","R2","C16","B31","F12","R15","F20","C17","A11","F11","P17","A5","C9","P22","E4","B18","C1","C21","M11","B16","R9","F25","A12","A14","Y4","G14","B28","H23","P20","C20","C27","ZG5","B22","G12","M1","D6","F6","A13","P10","D11","F18","F1","Q5","Q4","M10","G17","H8","A17","D26","F21","P19","B24","P8","H22","P13","C13","F22","G21","R4","D2","H16","M4","P16","R21","E14","R7","R8","P18","H12","B27","D19","ZG7","E16","P2","B30","R20","F14","G16","R10","M7","E23","B23","D16","C23","F23","R1","Y2","A18","E15","G3","F15","P15","R17","D17","F2","E11","A1","F10","F17","G19","M15","G4","R25","C25","Y3","B29","H9","G15","R3","P9","P12","A16","F24","A3","E24","B15","D23","T1","P5","H14","H19","E12"]
-
-module.exports = { MARD_PALETTE, MARD_SMART_ORDER }
diff --git a/BeadQR/miniprogram/utils/palette.js b/BeadQR/miniprogram/utils/palette.js
deleted file mode 100644
index d4c42ce2d3f3846eb7b9e57dea88c2746e91b455..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/palette.js
+++ /dev/null
@@ -1,74 +0,0 @@
-// MARD 色库预设 + 预处理(Typed Array 结构,供匹配引擎高速读取)
-const { MARD_PALETTE, MARD_SMART_ORDER } = require('./palette-data')
-const { hexToRgb, rgbToOklabInto, luma } = require('./color')
-
-// 颜色匹配模式:darkMax/lightMin 为二维码深/浅模块允许的亮度范围
-const MATCH_MODES = [
- { id: 'rich', label: '色彩优先', hint: '更像原图', darkMax: 0.4, lightMin: 0.74 },
- { id: 'balanced', label: '均衡', hint: '推荐', darkMax: 0.36, lightMin: 0.78 },
- { id: 'strict', label: '扫码优先', hint: '最稳', darkMax: 0.3, lightMin: 0.84 },
-]
-
-const byId = new Map(MARD_PALETTE.map((c) => [c.id, c]))
-const pick = (ids) => ids.map((id) => byId.get(id)).filter(Boolean)
-const STANDARD_221 = MARD_PALETTE.filter((c) => /^[A-HM]\d+$/.test(c.id))
-
-const PRESETS = [
- { id: '221', label: '标准 221 色', short: '221 色', detail: 'MARD 标准色,最常见', list: () => STANDARD_221 },
- { id: '291', label: '完整 291 色', short: '291 色', detail: '含扩展色,颜色最全', list: () => MARD_PALETTE },
- ...[144, 96, 72, 48, 24].map((n) => ({
- id: String(n),
- label: `精选 ${n} 色`,
- short: `${n} 色`,
- detail: n <= 48 ? '入门套装,买豆更省' : '常用色,兼顾效果与成本',
- list: () => pick(MARD_SMART_ORDER.slice(0, n)),
- })),
-]
-
-const cache = {}
-
-function preparePalette(presetId) {
- if (cache[presetId]) return cache[presetId]
- const preset = PRESETS.find((p) => p.id === presetId) || PRESETS[0]
- const list = preset.list()
- const n = list.length
- const rgb = new Uint8Array(n * 3)
- const lab = new Float32Array(n * 3)
- const lum = new Float32Array(n)
- list.forEach((c, i) => {
- const [r, g, b] = hexToRgb(c.hex)
- rgb[i * 3] = r; rgb[i * 3 + 1] = g; rgb[i * 3 + 2] = b
- rgbToOklabInto(r, g, b, lab, i * 3)
- lum[i] = luma(r, g, b)
- })
- // 色与色之间的距离矩阵(291² ≈ 8.5 万项,一次性计算)
- const pair = new Float32Array(n * n)
- for (let i = 0; i < n; i += 1) {
- for (let j = i + 1; j < n; j += 1) {
- const dl = lab[i * 3] - lab[j * 3]
- const da = lab[i * 3 + 1] - lab[j * 3 + 1]
- const db = lab[i * 3 + 2] - lab[j * 3 + 2]
- const d = Math.sqrt(dl * dl + da * da + db * db)
- pair[i * n + j] = d
- pair[j * n + i] = d
- }
- }
- const prepared = {
- id: preset.id,
- label: preset.label,
- short: preset.short,
- n,
- ids: list.map((c) => c.id),
- hexes: list.map((c) => c.hex),
- rgb,
- lab,
- lum,
- pair,
- subsets: {},
- luts: {},
- }
- cache[presetId] = prepared
- return prepared
-}
-
-module.exports = { MATCH_MODES, PRESETS, preparePalette }
diff --git a/BeadQR/miniprogram/utils/pattern.js b/BeadQR/miniprogram/utils/pattern.js
deleted file mode 100644
index bc570ad3b7ec7f0a2d3a3dc71041bd8d0944169c..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/pattern.js
+++ /dev/null
@@ -1,381 +0,0 @@
-// Canvas 绘制:预览、PNG 图纸页、作品信息页、水印
-// 性能要点:按颜色批量合并路径,每种颜色只 fill 一次;字体只设置一次;网格线合并成单条路径
-const { lumaHex } = require('./color')
-
-const BOARD = '#f1eee7' // 钉板底色
-const PEG = '#d9d3c7' // 空钉位
-const INK = '#1d2b2a'
-const MUTED = '#6b7671'
-const BRAND = '#0f766e'
-
-function roundRectPath(ctx, x, y, w, h, r) {
- const rr = Math.min(r, w / 2, h / 2)
- ctx.moveTo(x + rr, y)
- ctx.arcTo(x + w, y, x + w, y + h, rr)
- ctx.arcTo(x + w, y + h, x, y + h, rr)
- ctx.arcTo(x, y + h, x, y, rr)
- ctx.arcTo(x, y, x + w, y, rr)
- ctx.closePath()
-}
-
-function fitText(ctx, value, maxWidth) {
- const text = String(value || '')
- if (ctx.measureText(text).width <= maxWidth) return text
- let end = text.length
- while (end > 0 && ctx.measureText(`${text.slice(0, end)}…`).width > maxWidth) end -= 1
- return `${text.slice(0, end)}…`
-}
-
-// 把同色格子分组:返回 Map
-function groupCells(artwork, region) {
- const { size, cells } = artwork
- const r = region || { col: 0, row: 0, cols: size, rows: size }
- const groups = new Map()
- const empty = []
- for (let y = r.row; y < r.row + r.rows; y += 1) {
- for (let x = r.col; x < r.col + r.cols; x += 1) {
- const c = cells[y * size + x]
- if (c < 0) { empty.push(y * size + x); continue }
- let list = groups.get(c)
- if (!list) { list = []; groups.set(c, list) }
- list.push(y * size + x)
- }
- }
- return { groups, empty, region: r }
-}
-
-/**
- * 绘制珠子
- * opts: { x0, y0, cell, style: square|round|hollow, region }
- */
-function drawBeads(ctx, artwork, opts) {
- const { x0, y0, cell, style = 'square' } = opts
- const { size, pal } = artwork
- const { groups, empty, region } = groupCells(artwork, opts.region)
- const ARC_CHUNK = 12
- const pos = (i) => {
- const x = i % size
- const y = (i - x) / size
- return [x0 + (x - region.col) * cell, y0 + (y - region.row) * cell]
- }
- ctx.fillStyle = BOARD
- ctx.fillRect(x0, y0, region.cols * cell, region.rows * cell)
- // 空钉位:小圆点,提示“这里不放豆”
- if (empty.length) {
- ctx.fillStyle = PEG
- ctx.beginPath()
- const r = cell * 0.14
- empty.forEach((i, n) => {
- const [x, y] = pos(i)
- ctx.moveTo(x + cell / 2 + r, y + cell / 2)
- ctx.arc(x + cell / 2, y + cell / 2, r, 0, Math.PI * 2)
- if (n % ARC_CHUNK === ARC_CHUNK - 1) { ctx.fill(); ctx.beginPath() }
- })
- ctx.fill()
- }
- const radius = cell * 0.46
- const hole = cell * 0.2
- groups.forEach((list, c) => {
- ctx.fillStyle = pal.hexes[c]
- ctx.beginPath()
- if (style === 'square') {
- list.forEach((i) => {
- const [x, y] = pos(i)
- // 取整边界避免相邻方块之间出现发丝缝
- const lx = Math.round(x); const ty = Math.round(y)
- ctx.rect(lx, ty, Math.round(x + cell) - lx, Math.round(y + cell) - ty)
- })
- } else {
- // 圆形子路径过多时渲染引擎会明显变慢,按小批提交(大图从数秒降到几十毫秒)
- list.forEach((i, n) => {
- const [x, y] = pos(i)
- const cx = x + cell / 2; const cy = y + cell / 2
- ctx.moveTo(cx + radius, cy)
- ctx.arc(cx, cy, radius, 0, Math.PI * 2)
- if (style === 'hollow') {
- ctx.moveTo(cx + hole, cy)
- ctx.arc(cx, cy, hole, 0, Math.PI * 2, true)
- }
- if (n % ARC_CHUNK === ARC_CHUNK - 1) { ctx.fill(); ctx.beginPath() }
- })
- }
- ctx.fill()
- })
-}
-
-// 色号文字:先按深/浅文字颜色分两批
-function drawCodes(ctx, artwork, opts) {
- const { x0, y0, cell, style = 'square' } = opts
- const { size, cells, pal } = artwork
- const region = opts.region || { col: 0, row: 0, cols: size, rows: size }
- const light = pal.hexes.map((hex) => lumaHex(hex) > 0.56)
- const fontSize = Math.max(8, Math.round(cell * (style === 'hollow' ? 0.26 : 0.32)))
- ctx.font = `bold ${fontSize}px sans-serif`
- ctx.textAlign = 'center'
- ctx.textBaseline = 'middle'
- const pass = (wantLight) => {
- ctx.fillStyle = wantLight ? INK : '#ffffff'
- for (let y = region.row; y < region.row + region.rows; y += 1) {
- for (let x = region.col; x < region.col + region.cols; x += 1) {
- const c = cells[y * size + x]
- if (c < 0) continue
- const useInk = style === 'hollow' ? true : light[c]
- if (useInk !== wantLight) continue
- ctx.fillText(pal.ids[c], x0 + (x - region.col + 0.5) * cell, y0 + (y - region.row + 0.5) * cell + fontSize * 0.04)
- }
- }
- }
- pass(true)
- pass(false)
- ctx.textAlign = 'start'
- ctx.textBaseline = 'alphabetic'
-}
-
-function rgba(hex, alpha) {
- const v = parseInt(hex.slice(1), 16)
- return `rgba(${(v >> 16) & 255},${(v >> 8) & 255},${v & 255},${alpha})`
-}
-
-// 网格 + 坐标:细线每格一条,粗线每 interval 格一条(按全局坐标对齐)
-function drawGrid(ctx, opts) {
- const { x0, y0, cell, region, interval = 10, color = BRAND, opacity = 60, labels = true } = opts
- const w = region.cols * cell
- const h = region.rows * cell
- const alpha = opacity / 100
- ctx.lineWidth = Math.max(1, cell * 0.02)
- ctx.strokeStyle = rgba(color, alpha * 0.28)
- ctx.beginPath()
- for (let i = 0; i <= region.cols; i += 1) { const x = Math.round(x0 + i * cell) + 0.5; ctx.moveTo(x, y0); ctx.lineTo(x, y0 + h) }
- for (let i = 0; i <= region.rows; i += 1) { const y = Math.round(y0 + i * cell) + 0.5; ctx.moveTo(x0, y); ctx.lineTo(x0 + w, y) }
- ctx.stroke()
- ctx.lineWidth = Math.max(2, cell * 0.06)
- ctx.strokeStyle = rgba(color, alpha)
- ctx.beginPath()
- for (let i = 0; i <= region.cols; i += 1) {
- const g = region.col + i
- if (g % interval !== 0 && i !== 0 && i !== region.cols) continue
- const x = x0 + i * cell; ctx.moveTo(x, y0); ctx.lineTo(x, y0 + h)
- }
- for (let i = 0; i <= region.rows; i += 1) {
- const g = region.row + i
- if (g % interval !== 0 && i !== 0 && i !== region.rows) continue
- const y = y0 + i * cell; ctx.moveTo(x0, y); ctx.lineTo(x0 + w, y)
- }
- ctx.stroke()
- if (!labels) return
- const fontSize = Math.max(10, Math.round(Math.min(cell * 0.42, 34)))
- ctx.font = `${fontSize}px sans-serif`
- ctx.fillStyle = rgba(color, Math.max(0.7, alpha))
- ctx.textAlign = 'center'
- ctx.textBaseline = 'middle'
- const step = cell < 22 ? interval : (cell < 36 ? 5 : 1)
- for (let i = 0; i < region.cols; i += 1) {
- const g = region.col + i + 1
- if (g % step !== 0 && g !== 1) continue
- ctx.fillText(String(g), x0 + (i + 0.5) * cell, y0 - fontSize * 0.9)
- }
- for (let i = 0; i < region.rows; i += 1) {
- const g = region.row + i + 1
- if (g % step !== 0 && g !== 1) continue
- ctx.fillText(String(g), x0 - fontSize * 1.1, y0 + (i + 0.5) * cell)
- }
- ctx.textAlign = 'start'
- ctx.textBaseline = 'alphabetic'
-}
-
-// 屏幕预览:整张作品,不带坐标(清爽)
-function renderPreview(canvas, artwork, pixelWidth, style) {
- const size = artwork.size
- const pad = Math.round(pixelWidth * 0.03)
- const cell = (pixelWidth - pad * 2) / size
- canvas.width = pixelWidth
- canvas.height = pixelWidth
- const ctx = canvas.getContext('2d')
- ctx.fillStyle = BOARD
- ctx.fillRect(0, 0, pixelWidth, pixelWidth)
- drawBeads(ctx, artwork, { x0: pad, y0: pad, cell, style })
-}
-
-// —— PNG 图纸页 ——
-function patternPageLayout(size, cell) {
- const axis = Math.max(48, Math.round(cell * 1.1))
- const pad = Math.max(48, Math.round(cell * 0.9))
- const header = Math.max(120, Math.round(cell * 2.4))
- const grid = size * cell
- return { axis, pad, header, width: grid + axis + pad * 2, height: header + axis + grid + pad * 2 }
-}
-
-function drawPatternPage(ctx, artwork, opts) {
- const { cell, style, grid, meta } = opts
- const L = patternPageLayout(artwork.size, cell)
- ctx.fillStyle = '#fbfaf7'
- ctx.fillRect(0, 0, L.width, L.height)
- // 头部
- const unit = L.header / 120
- ctx.fillStyle = INK
- ctx.font = `bold ${Math.round(40 * unit)}px sans-serif`
- ctx.textBaseline = 'middle'
- ctx.fillText('豆维 · 拼豆图纸', L.pad, L.pad * 0.6 + L.header * 0.36)
- ctx.font = `${Math.round(22 * unit)}px sans-serif`
- ctx.fillStyle = MUTED
- ctx.fillText(fitText(ctx, meta, L.width - L.pad * 2), L.pad, L.pad * 0.6 + L.header * 0.74)
- ctx.textBaseline = 'alphabetic'
- const x0 = L.pad + L.axis
- const y0 = L.header + L.pad * 0.6 + L.axis
- const region = { col: 0, row: 0, cols: artwork.size, rows: artwork.size }
- drawBeads(ctx, artwork, { x0, y0, cell, style, region })
- if (cell >= 16) drawCodes(ctx, artwork, { x0, y0, cell, style, region })
- if (grid.enabled) drawGrid(ctx, { x0, y0, cell, region, interval: grid.interval, color: grid.color, opacity: grid.opacity })
- return L
-}
-
-// —— 作品信息页(A4 比例,可分页)——
-function buildInfoPages({ artwork, width, text, paletteLabel, mpCode, thumbnail }) {
- const height = Math.round(width * 297 / 210)
- const u = width / 1600
- const pad = 96 * u
- const colors = artwork.usage.slice().sort((a, b) => a.id.localeCompare(b.id, undefined, { numeric: true }))
- const columns = 4
- const gap = 24 * u
- const cardW = (width - pad * 2 - gap * (columns - 1)) / columns
- const cardH = 124 * u
- const headerH = 300 * u
- // 缩略图区:headerH+64 起,高 400;清单标题与说明各占一行,避免与上方重叠
- const listTitleY = headerH + 64 * u + 400 * u + 96 * u
- const firstTop = listTitleY + 88 * u
- const nextTop = 200 * u
- const bottom = height - 110 * u
- const rowsFirst = Math.max(1, Math.floor((bottom - firstTop + gap) / (cardH + gap)))
- const rowsNext = Math.max(1, Math.floor((bottom - nextTop + gap) / (cardH + gap)))
- const pages = []
- let rest = colors.length
- let first = true
- do {
- const take = Math.min(rest, (first ? rowsFirst : rowsNext) * columns)
- pages.push(take)
- rest -= take
- first = false
- } while (rest > 0)
-
- const drawCard = (ctx, color, x, y) => {
- ctx.fillStyle = '#ffffff'
- ctx.beginPath(); roundRectPath(ctx, x, y, cardW, cardH, 18 * u); ctx.fill()
- ctx.strokeStyle = '#e7e2d8'; ctx.lineWidth = 2 * u; ctx.stroke()
- const sw = 76 * u
- ctx.fillStyle = color.hex
- ctx.beginPath(); ctx.arc(x + 24 * u + sw / 2, y + cardH / 2, sw / 2, 0, Math.PI * 2); ctx.fill()
- ctx.strokeStyle = 'rgba(0,0,0,0.12)'; ctx.stroke()
- ctx.fillStyle = INK
- ctx.font = `bold ${Math.round(34 * u)}px sans-serif`
- ctx.fillText(color.id, x + 24 * u + sw + 20 * u, y + 56 * u)
- ctx.fillStyle = BRAND
- ctx.font = `${Math.round(26 * u)}px sans-serif`
- ctx.fillText(`${color.count} 颗`, x + 24 * u + sw + 20 * u, y + 96 * u)
- }
-
- const draw = (ctx, page) => {
- ctx.textAlign = 'start'
- ctx.textBaseline = 'alphabetic'
- ctx.fillStyle = '#fbfaf7'
- ctx.fillRect(0, 0, width, height)
- let top = nextTop
- if (page === 0) {
- ctx.fillStyle = INK
- ctx.fillRect(0, 0, width, headerH)
- ctx.fillStyle = '#ffffff'
- ctx.font = `bold ${Math.round(62 * u)}px sans-serif`
- ctx.fillText('豆维 · 作品信息与用豆清单', pad, 132 * u)
- ctx.fillStyle = '#9fd3c7'
- ctx.font = `${Math.round(28 * u)}px sans-serif`
- ctx.fillText('照着清单备豆,照着图纸拼,拼完用微信扫一扫', pad, 200 * u)
- if (mpCode) {
- const s = 200 * u
- const x = width - pad - s
- const y = (headerH - s) / 2
- ctx.fillStyle = '#ffffff'
- ctx.beginPath(); roundRectPath(ctx, x - 10 * u, y - 10 * u, s + 20 * u, s + 20 * u, 20 * u); ctx.fill()
- ctx.drawImage(mpCode, x, y, s, s)
- }
- // 缩略图 + 参数
- const thumbS = 400 * u
- const ty = headerH + 64 * u
- if (thumbnail) {
- ctx.fillStyle = '#ffffff'
- ctx.beginPath(); roundRectPath(ctx, pad, ty, thumbS, thumbS, 24 * u); ctx.fill()
- const inner = thumbS - 32 * u
- const cell = inner / artwork.size
- drawBeads(ctx, artwork, { x0: pad + 16 * u, y0: ty + 16 * u, cell, style: 'square' })
- }
- const mx = thumbnail ? pad + thumbS + 56 * u : pad
- const rows = [
- ['扫码内容', text],
- ['作品尺寸', `${artwork.size} × ${artwork.size} 格`],
- ['用豆总数', `${artwork.beads.toLocaleString()} 颗 · ${artwork.usage.length} 个色号`],
- ['二维码', `${artwork.qr.size} × ${artwork.qr.size} 格 · 纠错 ${artwork.qr.level}`],
- ['色库', paletteLabel],
- ]
- rows.forEach(([k, v], idx) => {
- const y = ty + 52 * u + idx * 74 * u
- ctx.fillStyle = MUTED
- ctx.font = `${Math.round(26 * u)}px sans-serif`
- ctx.fillText(k, mx, y)
- ctx.fillStyle = INK
- ctx.font = `bold ${Math.round(28 * u)}px sans-serif`
- ctx.fillText(fitText(ctx, v, width - pad - mx - 150 * u), mx + 150 * u, y)
- })
- ctx.fillStyle = INK
- ctx.font = `bold ${Math.round(42 * u)}px sans-serif`
- ctx.fillText('用豆清单', pad, listTitleY)
- ctx.fillStyle = MUTED
- ctx.font = `${Math.round(24 * u)}px sans-serif`
- ctx.fillText('按色号排序 · 建议每色多备 5% 以防掉落', pad, listTitleY + 44 * u)
- top = firstTop
- } else {
- ctx.fillStyle = INK
- ctx.font = `bold ${Math.round(36 * u)}px sans-serif`
- ctx.fillText(`用豆清单(续 ${page + 1}/${pages.length})`, pad, 120 * u)
- }
- const offset = pages.slice(0, page).reduce((s, v) => s + v, 0)
- for (let i = 0; i < pages[page]; i += 1) {
- const col = i % columns
- const row = Math.floor(i / columns)
- drawCard(ctx, colors[offset + i], pad + col * (cardW + gap), top + row * (cardH + gap))
- }
- ctx.fillStyle = '#a3aaa5'
- ctx.font = `${Math.round(22 * u)}px sans-serif`
- ctx.fillText(`豆维 · 可扫码的拼豆 第 ${page + 1} / ${pages.length} 页`, pad, height - 56 * u)
- }
- return { width, height, pageCount: pages.length, draw }
-}
-
-// 轻度斜向平铺水印
-function drawWatermark(ctx, w, h, text) {
- const value = String(text || '').trim()
- if (!value) return
- const fontSize = Math.max(18, Math.round(w * 0.018))
- const stepX = Math.max(fontSize * value.length * 1.6, w / 4)
- const stepY = Math.max(fontSize * 6, w / 6)
- ctx.save()
- ctx.globalAlpha = 0.08
- ctx.fillStyle = INK
- ctx.font = `${fontSize}px sans-serif`
- ctx.textAlign = 'center'
- ctx.textBaseline = 'middle'
- ctx.translate(w / 2, h / 2)
- ctx.rotate(-Math.PI / 9)
- const r = Math.hypot(w, h) / 2
- for (let y = -r; y <= r; y += stepY) for (let x = -r; x <= r; x += stepX) ctx.fillText(value, x, y)
- ctx.restore()
-}
-
-module.exports = {
- BOARD,
- drawBeads,
- drawCodes,
- drawGrid,
- renderPreview,
- patternPageLayout,
- drawPatternPage,
- buildInfoPages,
- drawWatermark,
-}
diff --git a/BeadQR/miniprogram/utils/pdf.js b/BeadQR/miniprogram/utils/pdf.js
deleted file mode 100644
index 34805d1053fe171327a272f9993ecb4d7bdd5906..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/pdf.js
+++ /dev/null
@@ -1,373 +0,0 @@
-// 轻量 PDF 生成器(无依赖)
-// - 图纸页为纯矢量:珠子、色号、网格都是矢量指令,任意放大都清晰,文件小、生成快
-// - 中文(页眉、信息页)以 JPEG 图片嵌入
-// - 支持 1-bit 蒙版图片(用于矢量页上的半透明水印)
-
-const A4 = { w: 595.28, h: 841.89 }
-
-// Helvetica / Helvetica-Bold 字宽(AFM,1/1000 em),色号只含 A-Z 0-9
-const W_BOLD = { ' ': 278, '-': 333, '/': 278 }
-const W_REG = { ' ': 278, '-': 333, '/': 278 }
-'0123456789'.split('').forEach((c) => { W_BOLD[c] = 556; W_REG[c] = 556 })
-const UPPER_BOLD = [722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611]
-const UPPER_REG = [667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611]
-for (let i = 0; i < 26; i += 1) {
- W_BOLD[String.fromCharCode(65 + i)] = UPPER_BOLD[i]
- W_REG[String.fromCharCode(65 + i)] = UPPER_REG[i]
-}
-function textWidth(text, size, bold = true) {
- const table = bold ? W_BOLD : W_REG
- let w = 0
- for (let i = 0; i < text.length; i += 1) w += table[text[i]] || 556
- return (w / 1000) * size
-}
-
-const n2 = (v) => (Math.round(v * 100) / 100).toString()
-const esc = (s) => String(s).replace(/[\\()]/g, (m) => `\\${m}`).replace(/[^\x20-\x7e]/g, '?')
-
-function ascii(text) {
- const out = new Uint8Array(text.length)
- for (let i = 0; i < text.length; i += 1) out[i] = text.charCodeAt(i) & 0xff
- return out
-}
-
-class PdfDoc {
- constructor() {
- this.objects = [null, null, null] // 1: Catalog, 2: Pages(0 号占位)
- this.pageIds = []
- this.fontRegular = this.add(['<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >>'])
- this.fontBold = this.add(['<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding >>'])
- this.forms = {}
- this.gstates = {}
- }
-
- add(parts) {
- this.objects.push(parts)
- return this.objects.length - 1
- }
-
- stream(dict, data) {
- const bytes = typeof data === 'string' ? ascii(data) : new Uint8Array(data)
- return this.add([`<< ${dict} /Length ${bytes.length} >>\nstream\n`, bytes, '\nendstream'])
- }
-
- addJpeg(buffer, width, height) {
- return this.stream(`/Type /XObject /Subtype /Image /Width ${width} /Height ${height} /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode`, buffer)
- }
-
- // bits:每行按字节对齐,0 = 绘制
- addImageMask(bits, width, height) {
- return this.stream(`/Type /XObject /Subtype /Image /Width ${width} /Height ${height} /ImageMask true /BitsPerComponent 1`, bits)
- }
-
- // 单位圆(直径 1)表单:不设颜色,继承外部填充色
- form(kind) {
- if (this.forms[kind]) return this.forms[kind]
- const k = 0.5523
- const circle = (r) => {
- const c = r * k
- return `${n2(0.5 + r)} 0.5 m ${n2(0.5 + r)} ${n2(0.5 + c)} ${n2(0.5 + c)} ${n2(0.5 + r)} 0.5 ${n2(0.5 + r)} c `
- + `${n2(0.5 - c)} ${n2(0.5 + r)} ${n2(0.5 - r)} ${n2(0.5 + c)} ${n2(0.5 - r)} 0.5 c `
- + `${n2(0.5 - r)} ${n2(0.5 - c)} ${n2(0.5 - c)} ${n2(0.5 - r)} 0.5 ${n2(0.5 - r)} c `
- + `${n2(0.5 + c)} ${n2(0.5 - r)} ${n2(0.5 + r)} ${n2(0.5 - c)} ${n2(0.5 + r)} 0.5 c h `
- }
- let body
- if (kind === 'round') body = `${circle(0.46)}f`
- else if (kind === 'hollow') body = `${circle(0.46)}${circle(0.2)}f*`
- else body = `${circle(0.14)}f` // peg 空钉位
- const id = this.stream('/Type /XObject /Subtype /Form /BBox [0 0 1 1]', body)
- this.forms[kind] = id
- return id
- }
-
- gstate(alpha) {
- const key = String(alpha)
- if (!this.gstates[key]) this.gstates[key] = this.add([`<< /Type /ExtGState /ca ${alpha} /CA ${alpha} >>`])
- return this.gstates[key]
- }
-
- addPage(content, { images = {} } = {}) {
- const contentId = this.stream('', content)
- const xobjects = Object.assign({}, images)
- Object.keys(this.forms).forEach((k) => { xobjects[`Fm_${k}`] = this.forms[k] })
- const xo = Object.keys(xobjects).map((k) => `/${k} ${xobjects[k]} 0 R`).join(' ')
- const gs = Object.keys(this.gstates).map((k) => `/GS${k.replace('.', '_')} ${this.gstates[k]} 0 R`).join(' ')
- const id = this.add([`<< /Type /Page /Parent 2 0 R /MediaBox [0 0 ${A4.w} ${A4.h}] /Resources << /ProcSet [/PDF /Text /ImageB /ImageC] /Font << /F1 ${this.fontRegular} 0 R /F2 ${this.fontBold} 0 R >> /XObject << ${xo} >> /ExtGState << ${gs} >> >> /Contents ${contentId} 0 R >>`])
- this.pageIds.push(id)
- return id
- }
-
- build() {
- this.objects[1] = ['<< /Type /Catalog /Pages 2 0 R >>']
- this.objects[2] = [`<< /Type /Pages /Kids [${this.pageIds.map((id) => `${id} 0 R`).join(' ')}] /Count ${this.pageIds.length} >>`]
- const chunks = []
- let pos = 0
- const push = (part) => {
- const bytes = typeof part === 'string' ? ascii(part) : part
- chunks.push(bytes)
- pos += bytes.length
- }
- push('%PDF-1.4\n%\xe2\xe3\xcf\xd3\n')
- const offsets = []
- for (let id = 1; id < this.objects.length; id += 1) {
- offsets[id] = pos
- push(`${id} 0 obj\n`)
- this.objects[id].forEach(push)
- push('\nendobj\n')
- }
- const xref = pos
- let table = `xref\n0 ${this.objects.length}\n0000000000 65535 f \n`
- for (let id = 1; id < this.objects.length; id += 1) table += `${String(offsets[id]).padStart(10, '0')} 00000 n \n`
- push(table)
- push(`trailer\n<< /Size ${this.objects.length} /Root 1 0 R >>\nstartxref\n${xref}\n%%EOF\n`)
- const out = new Uint8Array(pos)
- let cursor = 0
- chunks.forEach((c) => { out.set(c, cursor); cursor += c.length })
- return out.buffer
- }
-}
-
-// —— 矢量图纸 ——
-// 使用“左上角原点、y 向下”的坐标系(页面开头统一翻转),文字与图片局部再翻回来
-
-function hexToPdf(hex) {
- const v = parseInt(hex.slice(1), 16)
- return `${n2(((v >> 16) & 255) / 255)} ${n2(((v >> 8) & 255) / 255)} ${n2((v & 255) / 255)}`
-}
-
-function lumaOf(hex) {
- const v = parseInt(hex.slice(1), 16)
- return (((v >> 16) & 255) * 0.299 + ((v >> 8) & 255) * 0.587 + (v & 255) * 0.114) / 255
-}
-
-function vectorSheet(doc, artwork, { x0, y0, cell, region, style, codes, grid }) {
- const { size, cells, pal } = artwork
- const out = []
- out.push(`${hexToPdf('#f1eee7')} rg ${n2(x0)} ${n2(y0)} ${n2(region.cols * cell)} ${n2(region.rows * cell)} re f`)
- const groups = new Map()
- const empty = []
- for (let y = region.row; y < region.row + region.rows; y += 1) {
- for (let x = region.col; x < region.col + region.cols; x += 1) {
- const c = cells[y * size + x]
- const px = x0 + (x - region.col) * cell
- const py = y0 + (y - region.row) * cell
- if (c < 0) { empty.push([px, py]); continue }
- if (!groups.has(c)) groups.set(c, [])
- groups.get(c).push([px, py])
- }
- }
- if (empty.length) {
- doc.form('peg')
- out.push(`${hexToPdf('#d9d3c7')} rg`)
- empty.forEach(([x, y]) => out.push(`q ${n2(cell)} 0 0 ${n2(cell)} ${n2(x)} ${n2(y)} cm /Fm_peg Do Q`))
- }
- if (style !== 'square') doc.form(style)
- groups.forEach((list, c) => {
- out.push(`${hexToPdf(pal.hexes[c])} rg`)
- if (style === 'square') {
- // 略微外扩 0.05pt 消除阅读器抗锯齿造成的白缝
- list.forEach(([x, y]) => out.push(`${n2(x - 0.05)} ${n2(y - 0.05)} ${n2(cell + 0.1)} ${n2(cell + 0.1)} re`))
- out.push('f')
- } else {
- list.forEach(([x, y]) => out.push(`q ${n2(cell)} 0 0 ${n2(cell)} ${n2(x)} ${n2(y)} cm /Fm_${style} Do Q`))
- }
- })
- if (codes) {
- const fs = cell * (style === 'hollow' ? 0.27 : 0.34)
- const writeGroup = (ink) => {
- const lines = []
- groups.forEach((list, c) => {
- const useInk = style === 'hollow' || lumaOf(pal.hexes[c]) > 0.56
- if (useInk !== ink) return
- const id = pal.ids[c]
- const tw = textWidth(id, fs)
- list.forEach(([x, y]) => lines.push(`1 0 0 -1 ${n2(x + (cell - tw) / 2)} ${n2(y + cell / 2 + fs * 0.35)} Tm (${id}) Tj`))
- })
- if (!lines.length) return
- out.push(`${ink ? hexToPdf('#1d2b2a') : '1 1 1'} rg BT /F2 ${n2(fs)} Tf`)
- out.push(...lines)
- out.push('ET')
- }
- writeGroup(true)
- writeGroup(false)
- }
- if (grid && grid.enabled) {
- const w = region.cols * cell
- const h = region.rows * cell
- const color = hexToPdf(grid.color)
- const alpha = grid.opacity / 100
- const thin = []
- for (let i = 0; i <= region.cols; i += 1) thin.push(`${n2(x0 + i * cell)} ${n2(y0)} m ${n2(x0 + i * cell)} ${n2(y0 + h)} l`)
- for (let i = 0; i <= region.rows; i += 1) thin.push(`${n2(x0)} ${n2(y0 + i * cell)} m ${n2(x0 + w)} ${n2(y0 + i * cell)} l`)
- doc.gstate(Math.round(alpha * 30) / 100)
- doc.gstate(alpha)
- out.push(`q /GS${String(Math.round(alpha * 30) / 100).replace('.', '_')} gs ${color} RG ${n2(Math.max(0.2, cell * 0.02))} w`, ...thin, 'S Q')
- const thick = []
- for (let i = 0; i <= region.cols; i += 1) {
- const g = region.col + i
- if (g % grid.interval && i && i !== region.cols) continue
- thick.push(`${n2(x0 + i * cell)} ${n2(y0)} m ${n2(x0 + i * cell)} ${n2(y0 + h)} l`)
- }
- for (let i = 0; i <= region.rows; i += 1) {
- const g = region.row + i
- if (g % grid.interval && i && i !== region.rows) continue
- thick.push(`${n2(x0)} ${n2(y0 + i * cell)} m ${n2(x0 + w)} ${n2(y0 + i * cell)} l`)
- }
- out.push(`q /GS${String(alpha).replace('.', '_')} gs ${color} RG ${n2(Math.max(0.6, cell * 0.06))} w`, ...thick, 'S Q')
- // 坐标数字
- const fs = Math.min(7, Math.max(4, cell * 0.42))
- const step = cell < 8 ? grid.interval : (cell < 13 ? 5 : 1)
- const labels = []
- for (let i = 0; i < region.cols; i += 1) {
- const g = region.col + i + 1
- if (g % step && g !== 1 && i !== 0) continue
- const t = String(g)
- labels.push(`1 0 0 -1 ${n2(x0 + (i + 0.5) * cell - textWidth(t, fs, false) / 2)} ${n2(y0 - fs * 0.5)} Tm (${t}) Tj`)
- }
- for (let i = 0; i < region.rows; i += 1) {
- const g = region.row + i + 1
- if (g % step && g !== 1 && i !== 0) continue
- const t = String(g)
- labels.push(`1 0 0 -1 ${n2(x0 - textWidth(t, fs, false) - fs * 0.4)} ${n2(y0 + (i + 0.5) * cell + fs * 0.35)} Tm (${t}) Tj`)
- }
- out.push(`${color} rg BT /F1 ${n2(fs)} Tf`, ...labels, 'ET')
- }
- return out.join('\n')
-}
-
-// 页眉图片 + 水印蒙版的放置
-function imageCmd(name, x, y, w, h) {
- return `q ${n2(w)} 0 0 ${n2(-h)} ${n2(x)} ${n2(y + h)} cm /${name} Do Q`
-}
-
-function watermarkCmd(mask) {
- if (!mask) return ''
- const h = 16
- const w = h * mask.width / mask.height
- const out = [`q /GS0_08 gs ${hexToPdf('#1d2b2a')} rg`]
- const stepX = w + 90
- const stepY = 120
- for (let row = 0, y = -200; y < A4.h + 200; y += stepY, row += 1) {
- for (let x = -200; x < A4.w + 200; x += stepX) {
- // 旋转 -20°:cos=0.94 sin=0.342;y 轴已翻转,所以蒙版局部再翻回
- out.push(`q 0.94 -0.342 0.342 0.94 ${n2(x + (row % 2) * stepX / 2)} ${n2(y)} cm ${n2(w)} 0 0 ${n2(-h)} 0 ${n2(h)} cm /WM Do Q`)
- }
- }
- out.push('Q')
- return out.join('\n')
-}
-
-const MARGIN = 28.35 // 10mm
-const HEADER_H = 34
-
-const AXIS = 14
-const TARGET_CELL = 18 // 约 6.4mm/格,打印后色号清晰可读
-const AREA_W = A4.w - MARGIN * 2
-const AREA_H = A4.h - MARGIN * 2 - HEADER_H
-
-/**
- * 规划图纸页:小图一页搞定;大图 = 总览页 + 若干分块页
- * 返回 { tiled, fitCell, tilesX, tilesY, tileCols, tileRows, pages: [{ kind, tile, region }] }
- */
-function planPatternPages(size) {
- const fitCell = Math.min((AREA_W - AXIS) / size, (AREA_H - AXIS) / size)
- const tiled = fitCell < 11
- const full = { col: 0, row: 0, cols: size, rows: size }
- const pages = [{ kind: 'overview', tile: 0, region: full }]
- let tilesX = 1
- let tilesY = 1
- let tileCols = size
- let tileRows = size
- if (tiled) {
- tilesX = Math.ceil(size / Math.floor((AREA_W - AXIS) / TARGET_CELL))
- tilesY = Math.ceil(size / Math.floor((AREA_H - AXIS) / TARGET_CELL))
- tileCols = Math.ceil(size / tilesX)
- tileRows = Math.ceil(size / tilesY)
- let n = 1
- for (let ty = 0; ty < tilesY; ty += 1) {
- for (let tx = 0; tx < tilesX; tx += 1) {
- const col = tx * tileCols
- const row = ty * tileRows
- if (col >= size || row >= size) continue
- pages.push({ kind: 'tile', tile: n, region: { col, row, cols: Math.min(tileCols, size - col), rows: Math.min(tileRows, size - row) } })
- n += 1
- }
- }
- }
- return { tiled, fitCell, tilesX, tilesY, tileCols, tileRows, pages }
-}
-
-/**
- * 生成图纸页(矢量)。
- * opts: { plan, headers: [{ id, width, height }](按页序), style, grid, watermark }
- */
-function addPatternPages(doc, artwork, opts) {
- const size = artwork.size
- const plan = opts.plan || planPatternPages(size)
- const headers = opts.headers || []
- const flip = `1 0 0 -1 0 ${A4.h} cm`
- const wm = opts.watermark ? watermarkCmd(opts.watermark) : ''
- if (opts.watermark) doc.gstate(0.08)
- if (plan.tiled) doc.gstate(0.85)
- const images = (header) => {
- const map = {}
- if (header) map.HD = header.id
- if (opts.watermark) map.WM = opts.watermark.id
- return map
- }
- const headerCmd = (header) => (header ? imageCmd('HD', MARGIN, MARGIN, AREA_W, AREA_W * header.height / header.width) : '')
-
- plan.pages.forEach((page, i) => {
- const header = headers[i] || null
- const content = [flip, headerCmd(header)]
- if (page.kind === 'overview') {
- const fitCell = plan.fitCell
- const gridW = fitCell * size
- const x0 = MARGIN + AXIS + (AREA_W - AXIS - gridW) / 2
- const y0 = MARGIN + HEADER_H + AXIS
- content.push(vectorSheet(doc, artwork, {
- x0, y0, cell: fitCell, region: page.region, style: opts.style, codes: !plan.tiled, grid: opts.grid,
- }))
- if (plan.tiled) {
- const lines = [`q ${hexToPdf('#e11d48')} RG 1.2 w`]
- const labels = []
- plan.pages.forEach((tp) => {
- if (tp.kind !== 'tile') return
- const r = tp.region
- const cx = x0 + r.col * fitCell
- const cy = y0 + r.row * fitCell
- const cw = r.cols * fitCell
- const ch = r.rows * fitCell
- lines.push(`${n2(cx)} ${n2(cy)} ${n2(cw)} ${n2(ch)} re S`)
- const t = String(tp.tile)
- labels.push(`1 0 0 -1 ${n2(cx + cw / 2 - textWidth(t, 22) / 2)} ${n2(cy + ch / 2 + 8)} Tm (${t}) Tj`)
- })
- lines.push('Q')
- content.push(lines.join('\n'))
- content.push(`q /GS0_85 gs ${hexToPdf('#e11d48')} rg BT /F2 22 Tf\n${labels.join('\n')}\nET Q`)
- }
- } else {
- const cell = Math.min((AREA_W - AXIS) / plan.tileCols, (AREA_H - AXIS) / plan.tileRows)
- content.push(vectorSheet(doc, artwork, {
- x0: MARGIN + AXIS, y0: MARGIN + HEADER_H + AXIS, cell, region: page.region, style: opts.style, codes: true, grid: opts.grid,
- }))
- }
- content.push(wm)
- doc.addPage(content.join('\n'), { images: images(header) })
- })
- return plan.pages.length
-}
-
-// 整页图片(信息页)
-function addImagePage(doc, jpegId, pixelW, pixelH) {
- const areaW = A4.w - MARGIN * 2
- const areaH = A4.h - MARGIN * 2
- const scale = Math.min(areaW / pixelW, areaH / pixelH)
- const w = pixelW * scale
- const h = pixelH * scale
- const x = (A4.w - w) / 2
- const y = (A4.h - h) / 2
- doc.addPage(`1 0 0 -1 0 ${A4.h} cm\n${imageCmd('IM', x, y, w, h)}`, { images: { IM: jpegId } })
-}
-
-module.exports = { A4, PdfDoc, planPatternPages, addPatternPages, addImagePage, vectorSheet, textWidth, HEADER_H, MARGIN }
diff --git a/BeadQR/miniprogram/utils/qr.js b/BeadQR/miniprogram/utils/qr.js
deleted file mode 100644
index ca09a381bd088091e12070039e5409846e62593c..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qr.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// 二维码生成、功能区识别与摆放
-const QRCodeCore = require('./qrcore/qrcode')
-const AlignmentPattern = require('./qrcore/alignment-pattern')
-
-const SAMPLE_TEXT = '豆维·可扫码的拼豆'
-
-// 功能区(定位/时序/对齐/格式/版本)直接决定能否扫出,配色时强制高对比
-function buildFunctionMask(size, version) {
- const mask = new Uint8Array(size * size)
- const mark = (x, y) => { if (x >= 0 && y >= 0 && x < size && y < size) mask[y * size + x] = 1 }
- for (let y = 0; y < size; y += 1) {
- for (let x = 0; x < size; x += 1) {
- const finder = (x <= 8 && y <= 8) || (x >= size - 8 && y <= 8) || (x <= 8 && y >= size - 8)
- if (finder || x === 6 || y === 6) mark(x, y)
- }
- }
- const positions = AlignmentPattern.getPositions(version) || []
- positions.forEach(([row, col]) => {
- for (let dy = -2; dy <= 2; dy += 1) for (let dx = -2; dx <= 2; dx += 1) mark(col + dx, row + dy)
- })
- if (version >= 7) {
- for (let i = 0; i < 6; i += 1) {
- for (let j = size - 11; j < size - 8; j += 1) { mark(i, j); mark(j, i) }
- }
- }
- return mask
-}
-
-function makeQr(text, level) {
- const value = String(text || '').trim() || SAMPLE_TEXT
- const qr = QRCodeCore.create(value, { errorCorrectionLevel: level || 'H' })
- const size = qr.modules.size
- const version = qr.version || Math.round((size - 17) / 4)
- return {
- size,
- version,
- level: level || 'H',
- dark: Uint8Array.from(qr.modules.data),
- func: buildFunctionMask(size, version),
- isSample: !String(text || '').trim(),
- }
-}
-
-// scale:二维码占整张作品边长的百分比;quiet:二维码四周留白格数
-function createPlacement(qrSize, { scale = 100, posX = 50, posY = 50, quiet = 0, hasImage = true } = {}) {
- const block = qrSize + quiet * 2
- const size = hasImage ? Math.max(block, Math.ceil(block * 100 / scale)) : block
- const free = size - block
- return {
- size,
- left: quiet + Math.round(free * posX / 100),
- top: quiet + Math.round(free * posY / 100),
- quiet,
- scale: hasImage ? scale : 100,
- }
-}
-
-module.exports = { SAMPLE_TEXT, makeQr, createPlacement }
diff --git a/BeadQR/miniprogram/utils/qrcore/alignment-pattern.js b/BeadQR/miniprogram/utils/qrcore/alignment-pattern.js
deleted file mode 100644
index 63c3154e976ca3894f16ebe60e9ead0f448c7ee1..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/alignment-pattern.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * Alignment pattern are fixed reference pattern in defined positions
- * in a matrix symbology, which enables the decode software to re-synchronise
- * the coordinate mapping of the image modules in the event of moderate amounts
- * of distortion of the image.
- *
- * Alignment patterns are present only in QR Code symbols of version 2 or larger
- * and their number depends on the symbol version.
- */
-
-const getSymbolSize = require('./utils').getSymbolSize
-
-/**
- * Calculate the row/column coordinates of the center module of each alignment pattern
- * for the specified QR Code version.
- *
- * The alignment patterns are positioned symmetrically on either side of the diagonal
- * running from the top left corner of the symbol to the bottom right corner.
- *
- * Since positions are simmetrical only half of the coordinates are returned.
- * Each item of the array will represent in turn the x and y coordinate.
- * @see {@link getPositions}
- *
- * @param {Number} version QR Code version
- * @return {Array} Array of coordinate
- */
-exports.getRowColCoords = function getRowColCoords (version) {
- if (version === 1) return []
-
- const posCount = Math.floor(version / 7) + 2
- const size = getSymbolSize(version)
- const intervals = size === 145 ? 26 : Math.ceil((size - 13) / (2 * posCount - 2)) * 2
- const positions = [size - 7] // Last coord is always (size - 7)
-
- for (let i = 1; i < posCount - 1; i++) {
- positions[i] = positions[i - 1] - intervals
- }
-
- positions.push(6) // First coord is always 6
-
- return positions.reverse()
-}
-
-/**
- * Returns an array containing the positions of each alignment pattern.
- * Each array's element represent the center point of the pattern as (x, y) coordinates
- *
- * Coordinates are calculated expanding the row/column coordinates returned by {@link getRowColCoords}
- * and filtering out the items that overlaps with finder pattern
- *
- * @example
- * For a Version 7 symbol {@link getRowColCoords} returns values 6, 22 and 38.
- * The alignment patterns, therefore, are to be centered on (row, column)
- * positions (6,22), (22,6), (22,22), (22,38), (38,22), (38,38).
- * Note that the coordinates (6,6), (6,38), (38,6) are occupied by finder patterns
- * and are not therefore used for alignment patterns.
- *
- * let pos = getPositions(7)
- * // [[6,22], [22,6], [22,22], [22,38], [38,22], [38,38]]
- *
- * @param {Number} version QR Code version
- * @return {Array} Array of coordinates
- */
-exports.getPositions = function getPositions (version) {
- const coords = []
- const pos = exports.getRowColCoords(version)
- const posLength = pos.length
-
- for (let i = 0; i < posLength; i++) {
- for (let j = 0; j < posLength; j++) {
- // Skip if position is occupied by finder patterns
- if ((i === 0 && j === 0) || // top-left
- (i === 0 && j === posLength - 1) || // bottom-left
- (i === posLength - 1 && j === 0)) { // top-right
- continue
- }
-
- coords.push([pos[i], pos[j]])
- }
- }
-
- return coords
-}
diff --git a/BeadQR/miniprogram/utils/qrcore/alphanumeric-data.js b/BeadQR/miniprogram/utils/qrcore/alphanumeric-data.js
deleted file mode 100644
index 29ddf50c3ad1f02beb0f8dc79f6b10e3d207ea36..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/alphanumeric-data.js
+++ /dev/null
@@ -1,59 +0,0 @@
-const Mode = require('./mode')
-
-/**
- * Array of characters available in alphanumeric mode
- *
- * As per QR Code specification, to each character
- * is assigned a value from 0 to 44 which in this case coincides
- * with the array index
- *
- * @type {Array}
- */
-const ALPHA_NUM_CHARS = [
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- ' ', '$', '%', '*', '+', '-', '.', '/', ':'
-]
-
-function AlphanumericData (data) {
- this.mode = Mode.ALPHANUMERIC
- this.data = data
-}
-
-AlphanumericData.getBitsLength = function getBitsLength (length) {
- return 11 * Math.floor(length / 2) + 6 * (length % 2)
-}
-
-AlphanumericData.prototype.getLength = function getLength () {
- return this.data.length
-}
-
-AlphanumericData.prototype.getBitsLength = function getBitsLength () {
- return AlphanumericData.getBitsLength(this.data.length)
-}
-
-AlphanumericData.prototype.write = function write (bitBuffer) {
- let i
-
- // Input data characters are divided into groups of two characters
- // and encoded as 11-bit binary codes.
- for (i = 0; i + 2 <= this.data.length; i += 2) {
- // The character value of the first character is multiplied by 45
- let value = ALPHA_NUM_CHARS.indexOf(this.data[i]) * 45
-
- // The character value of the second digit is added to the product
- value += ALPHA_NUM_CHARS.indexOf(this.data[i + 1])
-
- // The sum is then stored as 11-bit binary number
- bitBuffer.put(value, 11)
- }
-
- // If the number of input data characters is not a multiple of two,
- // the character value of the final character is encoded as a 6-bit binary number.
- if (this.data.length % 2) {
- bitBuffer.put(ALPHA_NUM_CHARS.indexOf(this.data[i]), 6)
- }
-}
-
-module.exports = AlphanumericData
diff --git a/BeadQR/miniprogram/utils/qrcore/bit-buffer.js b/BeadQR/miniprogram/utils/qrcore/bit-buffer.js
deleted file mode 100644
index 5b41d3d920ed97d04aabdc7d115302709ca42ae5..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/bit-buffer.js
+++ /dev/null
@@ -1,37 +0,0 @@
-function BitBuffer () {
- this.buffer = []
- this.length = 0
-}
-
-BitBuffer.prototype = {
-
- get: function (index) {
- const bufIndex = Math.floor(index / 8)
- return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) === 1
- },
-
- put: function (num, length) {
- for (let i = 0; i < length; i++) {
- this.putBit(((num >>> (length - i - 1)) & 1) === 1)
- }
- },
-
- getLengthInBits: function () {
- return this.length
- },
-
- putBit: function (bit) {
- const bufIndex = Math.floor(this.length / 8)
- if (this.buffer.length <= bufIndex) {
- this.buffer.push(0)
- }
-
- if (bit) {
- this.buffer[bufIndex] |= (0x80 >>> (this.length % 8))
- }
-
- this.length++
- }
-}
-
-module.exports = BitBuffer
diff --git a/BeadQR/miniprogram/utils/qrcore/bit-matrix.js b/BeadQR/miniprogram/utils/qrcore/bit-matrix.js
deleted file mode 100644
index 439138b99a746c0f22b432c7bfad608965fea3e9..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/bit-matrix.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * Helper class to handle QR Code symbol modules
- *
- * @param {Number} size Symbol size
- */
-function BitMatrix (size) {
- if (!size || size < 1) {
- throw new Error('BitMatrix size must be defined and greater than 0')
- }
-
- this.size = size
- this.data = new Uint8Array(size * size)
- this.reservedBit = new Uint8Array(size * size)
-}
-
-/**
- * Set bit value at specified location
- * If reserved flag is set, this bit will be ignored during masking process
- *
- * @param {Number} row
- * @param {Number} col
- * @param {Boolean} value
- * @param {Boolean} reserved
- */
-BitMatrix.prototype.set = function (row, col, value, reserved) {
- const index = row * this.size + col
- this.data[index] = value
- if (reserved) this.reservedBit[index] = true
-}
-
-/**
- * Returns bit value at specified location
- *
- * @param {Number} row
- * @param {Number} col
- * @return {Boolean}
- */
-BitMatrix.prototype.get = function (row, col) {
- return this.data[row * this.size + col]
-}
-
-/**
- * Applies xor operator at specified location
- * (used during masking process)
- *
- * @param {Number} row
- * @param {Number} col
- * @param {Boolean} value
- */
-BitMatrix.prototype.xor = function (row, col, value) {
- this.data[row * this.size + col] ^= value
-}
-
-/**
- * Check if bit at specified location is reserved
- *
- * @param {Number} row
- * @param {Number} col
- * @return {Boolean}
- */
-BitMatrix.prototype.isReserved = function (row, col) {
- return this.reservedBit[row * this.size + col]
-}
-
-module.exports = BitMatrix
diff --git a/BeadQR/miniprogram/utils/qrcore/byte-data.js b/BeadQR/miniprogram/utils/qrcore/byte-data.js
deleted file mode 100644
index b94666ae13ee529fb92de3e07df2235439118a97..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/byte-data.js
+++ /dev/null
@@ -1,61 +0,0 @@
-const Mode = require('./mode')
-
-// 微信部分真机运行时没有 TextEncoder。二维码 BYTE 段只需要 UTF-8 字节,
-// 在此实现最小兼容编码器,且与 TextEncoder 对无效代理对的处理一致。
-function encodeUtf8 (value) {
- const bytes = []
- for (let index = 0; index < value.length; index += 1) {
- let codePoint = value.charCodeAt(index)
- if (codePoint >= 0xd800 && codePoint <= 0xdbff) {
- const next = value.charCodeAt(index + 1)
- if (next >= 0xdc00 && next <= 0xdfff) {
- codePoint = 0x10000 + ((codePoint - 0xd800) << 10) + (next - 0xdc00)
- index += 1
- } else {
- codePoint = 0xfffd
- }
- } else if (codePoint >= 0xdc00 && codePoint <= 0xdfff) {
- codePoint = 0xfffd
- }
-
- if (codePoint <= 0x7f) {
- bytes.push(codePoint)
- } else if (codePoint <= 0x7ff) {
- bytes.push(0xc0 | (codePoint >> 6), 0x80 | (codePoint & 0x3f))
- } else if (codePoint <= 0xffff) {
- bytes.push(0xe0 | (codePoint >> 12), 0x80 | ((codePoint >> 6) & 0x3f), 0x80 | (codePoint & 0x3f))
- } else {
- bytes.push(0xf0 | (codePoint >> 18), 0x80 | ((codePoint >> 12) & 0x3f), 0x80 | ((codePoint >> 6) & 0x3f), 0x80 | (codePoint & 0x3f))
- }
- }
- return new Uint8Array(bytes)
-}
-
-function ByteData (data) {
- this.mode = Mode.BYTE
- if (typeof (data) === 'string') {
- this.data = encodeUtf8(data)
- } else {
- this.data = new Uint8Array(data)
- }
-}
-
-ByteData.getBitsLength = function getBitsLength (length) {
- return length * 8
-}
-
-ByteData.prototype.getLength = function getLength () {
- return this.data.length
-}
-
-ByteData.prototype.getBitsLength = function getBitsLength () {
- return ByteData.getBitsLength(this.data.length)
-}
-
-ByteData.prototype.write = function (bitBuffer) {
- for (let i = 0, l = this.data.length; i < l; i++) {
- bitBuffer.put(this.data[i], 8)
- }
-}
-
-module.exports = ByteData
diff --git a/BeadQR/miniprogram/utils/qrcore/dijkstrajs.js b/BeadQR/miniprogram/utils/qrcore/dijkstrajs.js
deleted file mode 100644
index 4f83f1f25913a94273a788e24185d8a18e0a7396..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/dijkstrajs.js
+++ /dev/null
@@ -1,165 +0,0 @@
-'use strict';
-
-/******************************************************************************
- * Created 2008-08-19.
- *
- * Dijkstra path-finding functions. Adapted from the Dijkstar Python project.
- *
- * Copyright (C) 2008
- * Wyatt Baldwin
- * All rights reserved
- *
- * Licensed under the MIT license.
- *
- * http://www.opensource.org/licenses/mit-license.php
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *****************************************************************************/
-var dijkstra = {
- single_source_shortest_paths: function(graph, s, d) {
- // Predecessor map for each node that has been encountered.
- // node ID => predecessor node ID
- var predecessors = {};
-
- // Costs of shortest paths from s to all nodes encountered.
- // node ID => cost
- var costs = {};
- costs[s] = 0;
-
- // Costs of shortest paths from s to all nodes encountered; differs from
- // `costs` in that it provides easy access to the node that currently has
- // the known shortest path from s.
- // XXX: Do we actually need both `costs` and `open`?
- var open = dijkstra.PriorityQueue.make();
- open.push(s, 0);
-
- var closest,
- u, v,
- cost_of_s_to_u,
- adjacent_nodes,
- cost_of_e,
- cost_of_s_to_u_plus_cost_of_e,
- cost_of_s_to_v,
- first_visit;
- while (!open.empty()) {
- // In the nodes remaining in graph that have a known cost from s,
- // find the node, u, that currently has the shortest path from s.
- closest = open.pop();
- u = closest.value;
- cost_of_s_to_u = closest.cost;
-
- // Get nodes adjacent to u...
- adjacent_nodes = graph[u] || {};
-
- // ...and explore the edges that connect u to those nodes, updating
- // the cost of the shortest paths to any or all of those nodes as
- // necessary. v is the node across the current edge from u.
- for (v in adjacent_nodes) {
- if (adjacent_nodes.hasOwnProperty(v)) {
- // Get the cost of the edge running from u to v.
- cost_of_e = adjacent_nodes[v];
-
- // Cost of s to u plus the cost of u to v across e--this is *a*
- // cost from s to v that may or may not be less than the current
- // known cost to v.
- cost_of_s_to_u_plus_cost_of_e = cost_of_s_to_u + cost_of_e;
-
- // If we haven't visited v yet OR if the current known cost from s to
- // v is greater than the new cost we just found (cost of s to u plus
- // cost of u to v across e), update v's cost in the cost list and
- // update v's predecessor in the predecessor list (it's now u).
- cost_of_s_to_v = costs[v];
- first_visit = (typeof costs[v] === 'undefined');
- if (first_visit || cost_of_s_to_v > cost_of_s_to_u_plus_cost_of_e) {
- costs[v] = cost_of_s_to_u_plus_cost_of_e;
- open.push(v, cost_of_s_to_u_plus_cost_of_e);
- predecessors[v] = u;
- }
- }
- }
- }
-
- if (typeof d !== 'undefined' && typeof costs[d] === 'undefined') {
- var msg = ['Could not find a path from ', s, ' to ', d, '.'].join('');
- throw new Error(msg);
- }
-
- return predecessors;
- },
-
- extract_shortest_path_from_predecessor_list: function(predecessors, d) {
- var nodes = [];
- var u = d;
- var predecessor;
- while (u) {
- nodes.push(u);
- predecessor = predecessors[u];
- u = predecessors[u];
- }
- nodes.reverse();
- return nodes;
- },
-
- find_path: function(graph, s, d) {
- var predecessors = dijkstra.single_source_shortest_paths(graph, s, d);
- return dijkstra.extract_shortest_path_from_predecessor_list(
- predecessors, d);
- },
-
- /**
- * A very naive priority queue implementation.
- */
- PriorityQueue: {
- make: function (opts) {
- var T = dijkstra.PriorityQueue,
- t = {},
- key;
- opts = opts || {};
- for (key in T) {
- if (T.hasOwnProperty(key)) {
- t[key] = T[key];
- }
- }
- t.queue = [];
- t.sorter = opts.sorter || T.default_sorter;
- return t;
- },
-
- default_sorter: function (a, b) {
- return a.cost - b.cost;
- },
-
- /**
- * Add a new item to the queue and ensure the highest priority element
- * is at the front of the queue.
- */
- push: function (value, cost) {
- var item = {value: value, cost: cost};
- this.queue.push(item);
- this.queue.sort(this.sorter);
- },
-
- /**
- * Return the highest priority element in the queue.
- */
- pop: function () {
- return this.queue.shift();
- },
-
- empty: function () {
- return this.queue.length === 0;
- }
- }
-};
-
-
-// node.js module exports
-if (typeof module !== 'undefined') {
- module.exports = dijkstra;
-}
diff --git a/BeadQR/miniprogram/utils/qrcore/error-correction-code.js b/BeadQR/miniprogram/utils/qrcore/error-correction-code.js
deleted file mode 100644
index 7a4aeae92af8819c272370434d614b8e086ea8bc..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/error-correction-code.js
+++ /dev/null
@@ -1,135 +0,0 @@
-const ECLevel = require('./error-correction-level')
-
-const EC_BLOCKS_TABLE = [
-// L M Q H
- 1, 1, 1, 1,
- 1, 1, 1, 1,
- 1, 1, 2, 2,
- 1, 2, 2, 4,
- 1, 2, 4, 4,
- 2, 4, 4, 4,
- 2, 4, 6, 5,
- 2, 4, 6, 6,
- 2, 5, 8, 8,
- 4, 5, 8, 8,
- 4, 5, 8, 11,
- 4, 8, 10, 11,
- 4, 9, 12, 16,
- 4, 9, 16, 16,
- 6, 10, 12, 18,
- 6, 10, 17, 16,
- 6, 11, 16, 19,
- 6, 13, 18, 21,
- 7, 14, 21, 25,
- 8, 16, 20, 25,
- 8, 17, 23, 25,
- 9, 17, 23, 34,
- 9, 18, 25, 30,
- 10, 20, 27, 32,
- 12, 21, 29, 35,
- 12, 23, 34, 37,
- 12, 25, 34, 40,
- 13, 26, 35, 42,
- 14, 28, 38, 45,
- 15, 29, 40, 48,
- 16, 31, 43, 51,
- 17, 33, 45, 54,
- 18, 35, 48, 57,
- 19, 37, 51, 60,
- 19, 38, 53, 63,
- 20, 40, 56, 66,
- 21, 43, 59, 70,
- 22, 45, 62, 74,
- 24, 47, 65, 77,
- 25, 49, 68, 81
-]
-
-const EC_CODEWORDS_TABLE = [
-// L M Q H
- 7, 10, 13, 17,
- 10, 16, 22, 28,
- 15, 26, 36, 44,
- 20, 36, 52, 64,
- 26, 48, 72, 88,
- 36, 64, 96, 112,
- 40, 72, 108, 130,
- 48, 88, 132, 156,
- 60, 110, 160, 192,
- 72, 130, 192, 224,
- 80, 150, 224, 264,
- 96, 176, 260, 308,
- 104, 198, 288, 352,
- 120, 216, 320, 384,
- 132, 240, 360, 432,
- 144, 280, 408, 480,
- 168, 308, 448, 532,
- 180, 338, 504, 588,
- 196, 364, 546, 650,
- 224, 416, 600, 700,
- 224, 442, 644, 750,
- 252, 476, 690, 816,
- 270, 504, 750, 900,
- 300, 560, 810, 960,
- 312, 588, 870, 1050,
- 336, 644, 952, 1110,
- 360, 700, 1020, 1200,
- 390, 728, 1050, 1260,
- 420, 784, 1140, 1350,
- 450, 812, 1200, 1440,
- 480, 868, 1290, 1530,
- 510, 924, 1350, 1620,
- 540, 980, 1440, 1710,
- 570, 1036, 1530, 1800,
- 570, 1064, 1590, 1890,
- 600, 1120, 1680, 1980,
- 630, 1204, 1770, 2100,
- 660, 1260, 1860, 2220,
- 720, 1316, 1950, 2310,
- 750, 1372, 2040, 2430
-]
-
-/**
- * Returns the number of error correction block that the QR Code should contain
- * for the specified version and error correction level.
- *
- * @param {Number} version QR Code version
- * @param {Number} errorCorrectionLevel Error correction level
- * @return {Number} Number of error correction blocks
- */
-exports.getBlocksCount = function getBlocksCount (version, errorCorrectionLevel) {
- switch (errorCorrectionLevel) {
- case ECLevel.L:
- return EC_BLOCKS_TABLE[(version - 1) * 4 + 0]
- case ECLevel.M:
- return EC_BLOCKS_TABLE[(version - 1) * 4 + 1]
- case ECLevel.Q:
- return EC_BLOCKS_TABLE[(version - 1) * 4 + 2]
- case ECLevel.H:
- return EC_BLOCKS_TABLE[(version - 1) * 4 + 3]
- default:
- return undefined
- }
-}
-
-/**
- * Returns the number of error correction codewords to use for the specified
- * version and error correction level.
- *
- * @param {Number} version QR Code version
- * @param {Number} errorCorrectionLevel Error correction level
- * @return {Number} Number of error correction codewords
- */
-exports.getTotalCodewordsCount = function getTotalCodewordsCount (version, errorCorrectionLevel) {
- switch (errorCorrectionLevel) {
- case ECLevel.L:
- return EC_CODEWORDS_TABLE[(version - 1) * 4 + 0]
- case ECLevel.M:
- return EC_CODEWORDS_TABLE[(version - 1) * 4 + 1]
- case ECLevel.Q:
- return EC_CODEWORDS_TABLE[(version - 1) * 4 + 2]
- case ECLevel.H:
- return EC_CODEWORDS_TABLE[(version - 1) * 4 + 3]
- default:
- return undefined
- }
-}
diff --git a/BeadQR/miniprogram/utils/qrcore/error-correction-level.js b/BeadQR/miniprogram/utils/qrcore/error-correction-level.js
deleted file mode 100644
index 07433d6bff7692d37f5747976545150a8893f0da..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/error-correction-level.js
+++ /dev/null
@@ -1,50 +0,0 @@
-exports.L = { bit: 1 }
-exports.M = { bit: 0 }
-exports.Q = { bit: 3 }
-exports.H = { bit: 2 }
-
-function fromString (string) {
- if (typeof string !== 'string') {
- throw new Error('Param is not a string')
- }
-
- const lcStr = string.toLowerCase()
-
- switch (lcStr) {
- case 'l':
- case 'low':
- return exports.L
-
- case 'm':
- case 'medium':
- return exports.M
-
- case 'q':
- case 'quartile':
- return exports.Q
-
- case 'h':
- case 'high':
- return exports.H
-
- default:
- throw new Error('Unknown EC Level: ' + string)
- }
-}
-
-exports.isValid = function isValid (level) {
- return level && typeof level.bit !== 'undefined' &&
- level.bit >= 0 && level.bit < 4
-}
-
-exports.from = function from (value, defaultValue) {
- if (exports.isValid(value)) {
- return value
- }
-
- try {
- return fromString(value)
- } catch (e) {
- return defaultValue
- }
-}
diff --git a/BeadQR/miniprogram/utils/qrcore/finder-pattern.js b/BeadQR/miniprogram/utils/qrcore/finder-pattern.js
deleted file mode 100644
index 4613c041a972ea603b56deda6b85488c44ba1443..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/finder-pattern.js
+++ /dev/null
@@ -1,22 +0,0 @@
-const getSymbolSize = require('./utils').getSymbolSize
-const FINDER_PATTERN_SIZE = 7
-
-/**
- * Returns an array containing the positions of each finder pattern.
- * Each array's element represent the top-left point of the pattern as (x, y) coordinates
- *
- * @param {Number} version QR Code version
- * @return {Array} Array of coordinates
- */
-exports.getPositions = function getPositions (version) {
- const size = getSymbolSize(version)
-
- return [
- // top-left
- [0, 0],
- // top-right
- [size - FINDER_PATTERN_SIZE, 0],
- // bottom-left
- [0, size - FINDER_PATTERN_SIZE]
- ]
-}
diff --git a/BeadQR/miniprogram/utils/qrcore/format-info.js b/BeadQR/miniprogram/utils/qrcore/format-info.js
deleted file mode 100644
index 11fe9efaacdd292fb39698e341e0df3ef8fe95e7..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/format-info.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const Utils = require('./utils')
-
-const G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0)
-const G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1)
-const G15_BCH = Utils.getBCHDigit(G15)
-
-/**
- * Returns format information with relative error correction bits
- *
- * The format information is a 15-bit sequence containing 5 data bits,
- * with 10 error correction bits calculated using the (15, 5) BCH code.
- *
- * @param {Number} errorCorrectionLevel Error correction level
- * @param {Number} mask Mask pattern
- * @return {Number} Encoded format information bits
- */
-exports.getEncodedBits = function getEncodedBits (errorCorrectionLevel, mask) {
- const data = ((errorCorrectionLevel.bit << 3) | mask)
- let d = data << 10
-
- while (Utils.getBCHDigit(d) - G15_BCH >= 0) {
- d ^= (G15 << (Utils.getBCHDigit(d) - G15_BCH))
- }
-
- // xor final data with mask pattern in order to ensure that
- // no combination of Error Correction Level and data mask pattern
- // will result in an all-zero data string
- return ((data << 10) | d) ^ G15_MASK
-}
diff --git a/BeadQR/miniprogram/utils/qrcore/galois-field.js b/BeadQR/miniprogram/utils/qrcore/galois-field.js
deleted file mode 100644
index 8125179c058e1b130c551dc04c12e3292311e751..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/galois-field.js
+++ /dev/null
@@ -1,69 +0,0 @@
-const EXP_TABLE = new Uint8Array(512)
-const LOG_TABLE = new Uint8Array(256)
-/**
- * Precompute the log and anti-log tables for faster computation later
- *
- * For each possible value in the galois field 2^8, we will pre-compute
- * the logarithm and anti-logarithm (exponential) of this value
- *
- * ref {@link https://en.wikiversity.org/wiki/Reed%E2%80%93Solomon_codes_for_coders#Introduction_to_mathematical_fields}
- */
-;(function initTables () {
- let x = 1
- for (let i = 0; i < 255; i++) {
- EXP_TABLE[i] = x
- LOG_TABLE[x] = i
-
- x <<= 1 // multiply by 2
-
- // The QR code specification says to use byte-wise modulo 100011101 arithmetic.
- // This means that when a number is 256 or larger, it should be XORed with 0x11D.
- if (x & 0x100) { // similar to x >= 256, but a lot faster (because 0x100 == 256)
- x ^= 0x11D
- }
- }
-
- // Optimization: double the size of the anti-log table so that we don't need to mod 255 to
- // stay inside the bounds (because we will mainly use this table for the multiplication of
- // two GF numbers, no more).
- // @see {@link mul}
- for (let i = 255; i < 512; i++) {
- EXP_TABLE[i] = EXP_TABLE[i - 255]
- }
-}())
-
-/**
- * Returns log value of n inside Galois Field
- *
- * @param {Number} n
- * @return {Number}
- */
-exports.log = function log (n) {
- if (n < 1) throw new Error('log(' + n + ')')
- return LOG_TABLE[n]
-}
-
-/**
- * Returns anti-log value of n inside Galois Field
- *
- * @param {Number} n
- * @return {Number}
- */
-exports.exp = function exp (n) {
- return EXP_TABLE[n]
-}
-
-/**
- * Multiplies two number inside Galois Field
- *
- * @param {Number} x
- * @param {Number} y
- * @return {Number}
- */
-exports.mul = function mul (x, y) {
- if (x === 0 || y === 0) return 0
-
- // should be EXP_TABLE[(LOG_TABLE[x] + LOG_TABLE[y]) % 255] if EXP_TABLE wasn't oversized
- // @see {@link initTables}
- return EXP_TABLE[LOG_TABLE[x] + LOG_TABLE[y]]
-}
diff --git a/BeadQR/miniprogram/utils/qrcore/kanji-data.js b/BeadQR/miniprogram/utils/qrcore/kanji-data.js
deleted file mode 100644
index a1d9a6922d8e91cd90d89ea301d2531145b129f2..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/kanji-data.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const Mode = require('./mode')
-const Utils = require('./utils')
-
-function KanjiData (data) {
- this.mode = Mode.KANJI
- this.data = data
-}
-
-KanjiData.getBitsLength = function getBitsLength (length) {
- return length * 13
-}
-
-KanjiData.prototype.getLength = function getLength () {
- return this.data.length
-}
-
-KanjiData.prototype.getBitsLength = function getBitsLength () {
- return KanjiData.getBitsLength(this.data.length)
-}
-
-KanjiData.prototype.write = function (bitBuffer) {
- let i
-
- // In the Shift JIS system, Kanji characters are represented by a two byte combination.
- // These byte values are shifted from the JIS X 0208 values.
- // JIS X 0208 gives details of the shift coded representation.
- for (i = 0; i < this.data.length; i++) {
- let value = Utils.toSJIS(this.data[i])
-
- // For characters with Shift JIS values from 0x8140 to 0x9FFC:
- if (value >= 0x8140 && value <= 0x9FFC) {
- // Subtract 0x8140 from Shift JIS value
- value -= 0x8140
-
- // For characters with Shift JIS values from 0xE040 to 0xEBBF
- } else if (value >= 0xE040 && value <= 0xEBBF) {
- // Subtract 0xC140 from Shift JIS value
- value -= 0xC140
- } else {
- throw new Error(
- 'Invalid SJIS character: ' + this.data[i] + '\n' +
- 'Make sure your charset is UTF-8')
- }
-
- // Multiply most significant byte of result by 0xC0
- // and add least significant byte to product
- value = (((value >>> 8) & 0xff) * 0xC0) + (value & 0xff)
-
- // Convert result to a 13-bit binary string
- bitBuffer.put(value, 13)
- }
-}
-
-module.exports = KanjiData
diff --git a/BeadQR/miniprogram/utils/qrcore/mask-pattern.js b/BeadQR/miniprogram/utils/qrcore/mask-pattern.js
deleted file mode 100644
index f5f8900eb19c94a30b74d795177f1d3fa32184d9..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/mask-pattern.js
+++ /dev/null
@@ -1,234 +0,0 @@
-/**
- * Data mask pattern reference
- * @type {Object}
- */
-exports.Patterns = {
- PATTERN000: 0,
- PATTERN001: 1,
- PATTERN010: 2,
- PATTERN011: 3,
- PATTERN100: 4,
- PATTERN101: 5,
- PATTERN110: 6,
- PATTERN111: 7
-}
-
-/**
- * Weighted penalty scores for the undesirable features
- * @type {Object}
- */
-const PenaltyScores = {
- N1: 3,
- N2: 3,
- N3: 40,
- N4: 10
-}
-
-/**
- * Check if mask pattern value is valid
- *
- * @param {Number} mask Mask pattern
- * @return {Boolean} true if valid, false otherwise
- */
-exports.isValid = function isValid (mask) {
- return mask != null && mask !== '' && !isNaN(mask) && mask >= 0 && mask <= 7
-}
-
-/**
- * Returns mask pattern from a value.
- * If value is not valid, returns undefined
- *
- * @param {Number|String} value Mask pattern value
- * @return {Number} Valid mask pattern or undefined
- */
-exports.from = function from (value) {
- return exports.isValid(value) ? parseInt(value, 10) : undefined
-}
-
-/**
-* Find adjacent modules in row/column with the same color
-* and assign a penalty value.
-*
-* Points: N1 + i
-* i is the amount by which the number of adjacent modules of the same color exceeds 5
-*/
-exports.getPenaltyN1 = function getPenaltyN1 (data) {
- const size = data.size
- let points = 0
- let sameCountCol = 0
- let sameCountRow = 0
- let lastCol = null
- let lastRow = null
-
- for (let row = 0; row < size; row++) {
- sameCountCol = sameCountRow = 0
- lastCol = lastRow = null
-
- for (let col = 0; col < size; col++) {
- let module = data.get(row, col)
- if (module === lastCol) {
- sameCountCol++
- } else {
- if (sameCountCol >= 5) points += PenaltyScores.N1 + (sameCountCol - 5)
- lastCol = module
- sameCountCol = 1
- }
-
- module = data.get(col, row)
- if (module === lastRow) {
- sameCountRow++
- } else {
- if (sameCountRow >= 5) points += PenaltyScores.N1 + (sameCountRow - 5)
- lastRow = module
- sameCountRow = 1
- }
- }
-
- if (sameCountCol >= 5) points += PenaltyScores.N1 + (sameCountCol - 5)
- if (sameCountRow >= 5) points += PenaltyScores.N1 + (sameCountRow - 5)
- }
-
- return points
-}
-
-/**
- * Find 2x2 blocks with the same color and assign a penalty value
- *
- * Points: N2 * (m - 1) * (n - 1)
- */
-exports.getPenaltyN2 = function getPenaltyN2 (data) {
- const size = data.size
- let points = 0
-
- for (let row = 0; row < size - 1; row++) {
- for (let col = 0; col < size - 1; col++) {
- const last = data.get(row, col) +
- data.get(row, col + 1) +
- data.get(row + 1, col) +
- data.get(row + 1, col + 1)
-
- if (last === 4 || last === 0) points++
- }
- }
-
- return points * PenaltyScores.N2
-}
-
-/**
- * Find 1:1:3:1:1 ratio (dark:light:dark:light:dark) pattern in row/column,
- * preceded or followed by light area 4 modules wide
- *
- * Points: N3 * number of pattern found
- */
-exports.getPenaltyN3 = function getPenaltyN3 (data) {
- const size = data.size
- let points = 0
- let bitsCol = 0
- let bitsRow = 0
-
- for (let row = 0; row < size; row++) {
- bitsCol = bitsRow = 0
- for (let col = 0; col < size; col++) {
- bitsCol = ((bitsCol << 1) & 0x7FF) | data.get(row, col)
- if (col >= 10 && (bitsCol === 0x5D0 || bitsCol === 0x05D)) points++
-
- bitsRow = ((bitsRow << 1) & 0x7FF) | data.get(col, row)
- if (col >= 10 && (bitsRow === 0x5D0 || bitsRow === 0x05D)) points++
- }
- }
-
- return points * PenaltyScores.N3
-}
-
-/**
- * Calculate proportion of dark modules in entire symbol
- *
- * Points: N4 * k
- *
- * k is the rating of the deviation of the proportion of dark modules
- * in the symbol from 50% in steps of 5%
- */
-exports.getPenaltyN4 = function getPenaltyN4 (data) {
- let darkCount = 0
- const modulesCount = data.data.length
-
- for (let i = 0; i < modulesCount; i++) darkCount += data.data[i]
-
- const k = Math.abs(Math.ceil((darkCount * 100 / modulesCount) / 5) - 10)
-
- return k * PenaltyScores.N4
-}
-
-/**
- * Return mask value at given position
- *
- * @param {Number} maskPattern Pattern reference value
- * @param {Number} i Row
- * @param {Number} j Column
- * @return {Boolean} Mask value
- */
-function getMaskAt (maskPattern, i, j) {
- switch (maskPattern) {
- case exports.Patterns.PATTERN000: return (i + j) % 2 === 0
- case exports.Patterns.PATTERN001: return i % 2 === 0
- case exports.Patterns.PATTERN010: return j % 3 === 0
- case exports.Patterns.PATTERN011: return (i + j) % 3 === 0
- case exports.Patterns.PATTERN100: return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 === 0
- case exports.Patterns.PATTERN101: return (i * j) % 2 + (i * j) % 3 === 0
- case exports.Patterns.PATTERN110: return ((i * j) % 2 + (i * j) % 3) % 2 === 0
- case exports.Patterns.PATTERN111: return ((i * j) % 3 + (i + j) % 2) % 2 === 0
-
- default: throw new Error('bad maskPattern:' + maskPattern)
- }
-}
-
-/**
- * Apply a mask pattern to a BitMatrix
- *
- * @param {Number} pattern Pattern reference number
- * @param {BitMatrix} data BitMatrix data
- */
-exports.applyMask = function applyMask (pattern, data) {
- const size = data.size
-
- for (let col = 0; col < size; col++) {
- for (let row = 0; row < size; row++) {
- if (data.isReserved(row, col)) continue
- data.xor(row, col, getMaskAt(pattern, row, col))
- }
- }
-}
-
-/**
- * Returns the best mask pattern for data
- *
- * @param {BitMatrix} data
- * @return {Number} Mask pattern reference number
- */
-exports.getBestMask = function getBestMask (data, setupFormatFunc) {
- const numPatterns = Object.keys(exports.Patterns).length
- let bestPattern = 0
- let lowerPenalty = Infinity
-
- for (let p = 0; p < numPatterns; p++) {
- setupFormatFunc(p)
- exports.applyMask(p, data)
-
- // Calculate penalty
- const penalty =
- exports.getPenaltyN1(data) +
- exports.getPenaltyN2(data) +
- exports.getPenaltyN3(data) +
- exports.getPenaltyN4(data)
-
- // Undo previously applied mask
- exports.applyMask(p, data)
-
- if (penalty < lowerPenalty) {
- lowerPenalty = penalty
- bestPattern = p
- }
- }
-
- return bestPattern
-}
diff --git a/BeadQR/miniprogram/utils/qrcore/mode.js b/BeadQR/miniprogram/utils/qrcore/mode.js
deleted file mode 100644
index fd95a6ef72b2414042cb9cf73fd7f4fe7ce054fe..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/mode.js
+++ /dev/null
@@ -1,167 +0,0 @@
-const VersionCheck = require('./version-check')
-const Regex = require('./regex')
-
-/**
- * Numeric mode encodes data from the decimal digit set (0 - 9)
- * (byte values 30HEX to 39HEX).
- * Normally, 3 data characters are represented by 10 bits.
- *
- * @type {Object}
- */
-exports.NUMERIC = {
- id: 'Numeric',
- bit: 1 << 0,
- ccBits: [10, 12, 14]
-}
-
-/**
- * Alphanumeric mode encodes data from a set of 45 characters,
- * i.e. 10 numeric digits (0 - 9),
- * 26 alphabetic characters (A - Z),
- * and 9 symbols (SP, $, %, *, +, -, ., /, :).
- * Normally, two input characters are represented by 11 bits.
- *
- * @type {Object}
- */
-exports.ALPHANUMERIC = {
- id: 'Alphanumeric',
- bit: 1 << 1,
- ccBits: [9, 11, 13]
-}
-
-/**
- * In byte mode, data is encoded at 8 bits per character.
- *
- * @type {Object}
- */
-exports.BYTE = {
- id: 'Byte',
- bit: 1 << 2,
- ccBits: [8, 16, 16]
-}
-
-/**
- * The Kanji mode efficiently encodes Kanji characters in accordance with
- * the Shift JIS system based on JIS X 0208.
- * The Shift JIS values are shifted from the JIS X 0208 values.
- * JIS X 0208 gives details of the shift coded representation.
- * Each two-byte character value is compacted to a 13-bit binary codeword.
- *
- * @type {Object}
- */
-exports.KANJI = {
- id: 'Kanji',
- bit: 1 << 3,
- ccBits: [8, 10, 12]
-}
-
-/**
- * Mixed mode will contain a sequences of data in a combination of any of
- * the modes described above
- *
- * @type {Object}
- */
-exports.MIXED = {
- bit: -1
-}
-
-/**
- * Returns the number of bits needed to store the data length
- * according to QR Code specifications.
- *
- * @param {Mode} mode Data mode
- * @param {Number} version QR Code version
- * @return {Number} Number of bits
- */
-exports.getCharCountIndicator = function getCharCountIndicator (mode, version) {
- if (!mode.ccBits) throw new Error('Invalid mode: ' + mode)
-
- if (!VersionCheck.isValid(version)) {
- throw new Error('Invalid version: ' + version)
- }
-
- if (version >= 1 && version < 10) return mode.ccBits[0]
- else if (version < 27) return mode.ccBits[1]
- return mode.ccBits[2]
-}
-
-/**
- * Returns the most efficient mode to store the specified data
- *
- * @param {String} dataStr Input data string
- * @return {Mode} Best mode
- */
-exports.getBestModeForData = function getBestModeForData (dataStr) {
- if (Regex.testNumeric(dataStr)) return exports.NUMERIC
- else if (Regex.testAlphanumeric(dataStr)) return exports.ALPHANUMERIC
- else if (Regex.testKanji(dataStr)) return exports.KANJI
- else return exports.BYTE
-}
-
-/**
- * Return mode name as string
- *
- * @param {Mode} mode Mode object
- * @returns {String} Mode name
- */
-exports.toString = function toString (mode) {
- if (mode && mode.id) return mode.id
- throw new Error('Invalid mode')
-}
-
-/**
- * Check if input param is a valid mode object
- *
- * @param {Mode} mode Mode object
- * @returns {Boolean} True if valid mode, false otherwise
- */
-exports.isValid = function isValid (mode) {
- return mode && mode.bit && mode.ccBits
-}
-
-/**
- * Get mode object from its name
- *
- * @param {String} string Mode name
- * @returns {Mode} Mode object
- */
-function fromString (string) {
- if (typeof string !== 'string') {
- throw new Error('Param is not a string')
- }
-
- const lcStr = string.toLowerCase()
-
- switch (lcStr) {
- case 'numeric':
- return exports.NUMERIC
- case 'alphanumeric':
- return exports.ALPHANUMERIC
- case 'kanji':
- return exports.KANJI
- case 'byte':
- return exports.BYTE
- default:
- throw new Error('Unknown mode: ' + string)
- }
-}
-
-/**
- * Returns mode from a value.
- * If value is not a valid mode, returns defaultValue
- *
- * @param {Mode|String} value Encoding mode
- * @param {Mode} defaultValue Fallback value
- * @return {Mode} Encoding mode
- */
-exports.from = function from (value, defaultValue) {
- if (exports.isValid(value)) {
- return value
- }
-
- try {
- return fromString(value)
- } catch (e) {
- return defaultValue
- }
-}
diff --git a/BeadQR/miniprogram/utils/qrcore/numeric-data.js b/BeadQR/miniprogram/utils/qrcore/numeric-data.js
deleted file mode 100644
index 5223991c6a7378509b5ab9701fb31e28c68c6faf..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/numeric-data.js
+++ /dev/null
@@ -1,43 +0,0 @@
-const Mode = require('./mode')
-
-function NumericData (data) {
- this.mode = Mode.NUMERIC
- this.data = data.toString()
-}
-
-NumericData.getBitsLength = function getBitsLength (length) {
- return 10 * Math.floor(length / 3) + ((length % 3) ? ((length % 3) * 3 + 1) : 0)
-}
-
-NumericData.prototype.getLength = function getLength () {
- return this.data.length
-}
-
-NumericData.prototype.getBitsLength = function getBitsLength () {
- return NumericData.getBitsLength(this.data.length)
-}
-
-NumericData.prototype.write = function write (bitBuffer) {
- let i, group, value
-
- // The input data string is divided into groups of three digits,
- // and each group is converted to its 10-bit binary equivalent.
- for (i = 0; i + 3 <= this.data.length; i += 3) {
- group = this.data.substr(i, 3)
- value = parseInt(group, 10)
-
- bitBuffer.put(value, 10)
- }
-
- // If the number of input digits is not an exact multiple of three,
- // the final one or two digits are converted to 4 or 7 bits respectively.
- const remainingNum = this.data.length - i
- if (remainingNum > 0) {
- group = this.data.substr(i)
- value = parseInt(group, 10)
-
- bitBuffer.put(value, remainingNum * 3 + 1)
- }
-}
-
-module.exports = NumericData
diff --git a/BeadQR/miniprogram/utils/qrcore/polynomial.js b/BeadQR/miniprogram/utils/qrcore/polynomial.js
deleted file mode 100644
index c6ed9c2e9173b5e494d488e99b72e03eb55fcd2f..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/polynomial.js
+++ /dev/null
@@ -1,62 +0,0 @@
-const GF = require('./galois-field')
-
-/**
- * Multiplies two polynomials inside Galois Field
- *
- * @param {Uint8Array} p1 Polynomial
- * @param {Uint8Array} p2 Polynomial
- * @return {Uint8Array} Product of p1 and p2
- */
-exports.mul = function mul (p1, p2) {
- const coeff = new Uint8Array(p1.length + p2.length - 1)
-
- for (let i = 0; i < p1.length; i++) {
- for (let j = 0; j < p2.length; j++) {
- coeff[i + j] ^= GF.mul(p1[i], p2[j])
- }
- }
-
- return coeff
-}
-
-/**
- * Calculate the remainder of polynomials division
- *
- * @param {Uint8Array} divident Polynomial
- * @param {Uint8Array} divisor Polynomial
- * @return {Uint8Array} Remainder
- */
-exports.mod = function mod (divident, divisor) {
- let result = new Uint8Array(divident)
-
- while ((result.length - divisor.length) >= 0) {
- const coeff = result[0]
-
- for (let i = 0; i < divisor.length; i++) {
- result[i] ^= GF.mul(divisor[i], coeff)
- }
-
- // remove all zeros from buffer head
- let offset = 0
- while (offset < result.length && result[offset] === 0) offset++
- result = result.slice(offset)
- }
-
- return result
-}
-
-/**
- * Generate an irreducible generator polynomial of specified degree
- * (used by Reed-Solomon encoder)
- *
- * @param {Number} degree Degree of the generator polynomial
- * @return {Uint8Array} Buffer containing polynomial coefficients
- */
-exports.generateECPolynomial = function generateECPolynomial (degree) {
- let poly = new Uint8Array([1])
- for (let i = 0; i < degree; i++) {
- poly = exports.mul(poly, new Uint8Array([1, GF.exp(i)]))
- }
-
- return poly
-}
diff --git a/BeadQR/miniprogram/utils/qrcore/qrcode.js b/BeadQR/miniprogram/utils/qrcore/qrcode.js
deleted file mode 100644
index f76df54b3c595e831d70c189e446479dbe8ac75a..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/qrcode.js
+++ /dev/null
@@ -1,495 +0,0 @@
-const Utils = require('./utils')
-const ECLevel = require('./error-correction-level')
-const BitBuffer = require('./bit-buffer')
-const BitMatrix = require('./bit-matrix')
-const AlignmentPattern = require('./alignment-pattern')
-const FinderPattern = require('./finder-pattern')
-const MaskPattern = require('./mask-pattern')
-const ECCode = require('./error-correction-code')
-const ReedSolomonEncoder = require('./reed-solomon-encoder')
-const Version = require('./version')
-const FormatInfo = require('./format-info')
-const Mode = require('./mode')
-const Segments = require('./segments')
-
-/**
- * QRCode for JavaScript
- *
- * modified by Ryan Day for nodejs support
- * Copyright (c) 2011 Ryan Day
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/mit-license.php
- *
-//---------------------------------------------------------------------
-// QRCode for JavaScript
-//
-// Copyright (c) 2009 Kazuhiko Arase
-//
-// URL: http://www.d-project.com/
-//
-// Licensed under the MIT license:
-// http://www.opensource.org/licenses/mit-license.php
-//
-// The word "QR Code" is registered trademark of
-// DENSO WAVE INCORPORATED
-// http://www.denso-wave.com/qrcode/faqpatent-e.html
-//
-//---------------------------------------------------------------------
-*/
-
-/**
- * Add finder patterns bits to matrix
- *
- * @param {BitMatrix} matrix Modules matrix
- * @param {Number} version QR Code version
- */
-function setupFinderPattern (matrix, version) {
- const size = matrix.size
- const pos = FinderPattern.getPositions(version)
-
- for (let i = 0; i < pos.length; i++) {
- const row = pos[i][0]
- const col = pos[i][1]
-
- for (let r = -1; r <= 7; r++) {
- if (row + r <= -1 || size <= row + r) continue
-
- for (let c = -1; c <= 7; c++) {
- if (col + c <= -1 || size <= col + c) continue
-
- if ((r >= 0 && r <= 6 && (c === 0 || c === 6)) ||
- (c >= 0 && c <= 6 && (r === 0 || r === 6)) ||
- (r >= 2 && r <= 4 && c >= 2 && c <= 4)) {
- matrix.set(row + r, col + c, true, true)
- } else {
- matrix.set(row + r, col + c, false, true)
- }
- }
- }
- }
-}
-
-/**
- * Add timing pattern bits to matrix
- *
- * Note: this function must be called before {@link setupAlignmentPattern}
- *
- * @param {BitMatrix} matrix Modules matrix
- */
-function setupTimingPattern (matrix) {
- const size = matrix.size
-
- for (let r = 8; r < size - 8; r++) {
- const value = r % 2 === 0
- matrix.set(r, 6, value, true)
- matrix.set(6, r, value, true)
- }
-}
-
-/**
- * Add alignment patterns bits to matrix
- *
- * Note: this function must be called after {@link setupTimingPattern}
- *
- * @param {BitMatrix} matrix Modules matrix
- * @param {Number} version QR Code version
- */
-function setupAlignmentPattern (matrix, version) {
- const pos = AlignmentPattern.getPositions(version)
-
- for (let i = 0; i < pos.length; i++) {
- const row = pos[i][0]
- const col = pos[i][1]
-
- for (let r = -2; r <= 2; r++) {
- for (let c = -2; c <= 2; c++) {
- if (r === -2 || r === 2 || c === -2 || c === 2 ||
- (r === 0 && c === 0)) {
- matrix.set(row + r, col + c, true, true)
- } else {
- matrix.set(row + r, col + c, false, true)
- }
- }
- }
- }
-}
-
-/**
- * Add version info bits to matrix
- *
- * @param {BitMatrix} matrix Modules matrix
- * @param {Number} version QR Code version
- */
-function setupVersionInfo (matrix, version) {
- const size = matrix.size
- const bits = Version.getEncodedBits(version)
- let row, col, mod
-
- for (let i = 0; i < 18; i++) {
- row = Math.floor(i / 3)
- col = i % 3 + size - 8 - 3
- mod = ((bits >> i) & 1) === 1
-
- matrix.set(row, col, mod, true)
- matrix.set(col, row, mod, true)
- }
-}
-
-/**
- * Add format info bits to matrix
- *
- * @param {BitMatrix} matrix Modules matrix
- * @param {ErrorCorrectionLevel} errorCorrectionLevel Error correction level
- * @param {Number} maskPattern Mask pattern reference value
- */
-function setupFormatInfo (matrix, errorCorrectionLevel, maskPattern) {
- const size = matrix.size
- const bits = FormatInfo.getEncodedBits(errorCorrectionLevel, maskPattern)
- let i, mod
-
- for (i = 0; i < 15; i++) {
- mod = ((bits >> i) & 1) === 1
-
- // vertical
- if (i < 6) {
- matrix.set(i, 8, mod, true)
- } else if (i < 8) {
- matrix.set(i + 1, 8, mod, true)
- } else {
- matrix.set(size - 15 + i, 8, mod, true)
- }
-
- // horizontal
- if (i < 8) {
- matrix.set(8, size - i - 1, mod, true)
- } else if (i < 9) {
- matrix.set(8, 15 - i - 1 + 1, mod, true)
- } else {
- matrix.set(8, 15 - i - 1, mod, true)
- }
- }
-
- // fixed module
- matrix.set(size - 8, 8, 1, true)
-}
-
-/**
- * Add encoded data bits to matrix
- *
- * @param {BitMatrix} matrix Modules matrix
- * @param {Uint8Array} data Data codewords
- */
-function setupData (matrix, data) {
- const size = matrix.size
- let inc = -1
- let row = size - 1
- let bitIndex = 7
- let byteIndex = 0
-
- for (let col = size - 1; col > 0; col -= 2) {
- if (col === 6) col--
-
- while (true) {
- for (let c = 0; c < 2; c++) {
- if (!matrix.isReserved(row, col - c)) {
- let dark = false
-
- if (byteIndex < data.length) {
- dark = (((data[byteIndex] >>> bitIndex) & 1) === 1)
- }
-
- matrix.set(row, col - c, dark)
- bitIndex--
-
- if (bitIndex === -1) {
- byteIndex++
- bitIndex = 7
- }
- }
- }
-
- row += inc
-
- if (row < 0 || size <= row) {
- row -= inc
- inc = -inc
- break
- }
- }
- }
-}
-
-/**
- * Create encoded codewords from data input
- *
- * @param {Number} version QR Code version
- * @param {ErrorCorrectionLevel} errorCorrectionLevel Error correction level
- * @param {ByteData} data Data input
- * @return {Uint8Array} Buffer containing encoded codewords
- */
-function createData (version, errorCorrectionLevel, segments) {
- // Prepare data buffer
- const buffer = new BitBuffer()
-
- segments.forEach(function (data) {
- // prefix data with mode indicator (4 bits)
- buffer.put(data.mode.bit, 4)
-
- // Prefix data with character count indicator.
- // The character count indicator is a string of bits that represents the
- // number of characters that are being encoded.
- // The character count indicator must be placed after the mode indicator
- // and must be a certain number of bits long, depending on the QR version
- // and data mode
- // @see {@link Mode.getCharCountIndicator}.
- buffer.put(data.getLength(), Mode.getCharCountIndicator(data.mode, version))
-
- // add binary data sequence to buffer
- data.write(buffer)
- })
-
- // Calculate required number of bits
- const totalCodewords = Utils.getSymbolTotalCodewords(version)
- const ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel)
- const dataTotalCodewordsBits = (totalCodewords - ecTotalCodewords) * 8
-
- // Add a terminator.
- // If the bit string is shorter than the total number of required bits,
- // a terminator of up to four 0s must be added to the right side of the string.
- // If the bit string is more than four bits shorter than the required number of bits,
- // add four 0s to the end.
- if (buffer.getLengthInBits() + 4 <= dataTotalCodewordsBits) {
- buffer.put(0, 4)
- }
-
- // If the bit string is fewer than four bits shorter, add only the number of 0s that
- // are needed to reach the required number of bits.
-
- // After adding the terminator, if the number of bits in the string is not a multiple of 8,
- // pad the string on the right with 0s to make the string's length a multiple of 8.
- while (buffer.getLengthInBits() % 8 !== 0) {
- buffer.putBit(0)
- }
-
- // Add pad bytes if the string is still shorter than the total number of required bits.
- // Extend the buffer to fill the data capacity of the symbol corresponding to
- // the Version and Error Correction Level by adding the Pad Codewords 11101100 (0xEC)
- // and 00010001 (0x11) alternately.
- const remainingByte = (dataTotalCodewordsBits - buffer.getLengthInBits()) / 8
- for (let i = 0; i < remainingByte; i++) {
- buffer.put(i % 2 ? 0x11 : 0xEC, 8)
- }
-
- return createCodewords(buffer, version, errorCorrectionLevel)
-}
-
-/**
- * Encode input data with Reed-Solomon and return codewords with
- * relative error correction bits
- *
- * @param {BitBuffer} bitBuffer Data to encode
- * @param {Number} version QR Code version
- * @param {ErrorCorrectionLevel} errorCorrectionLevel Error correction level
- * @return {Uint8Array} Buffer containing encoded codewords
- */
-function createCodewords (bitBuffer, version, errorCorrectionLevel) {
- // Total codewords for this QR code version (Data + Error correction)
- const totalCodewords = Utils.getSymbolTotalCodewords(version)
-
- // Total number of error correction codewords
- const ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel)
-
- // Total number of data codewords
- const dataTotalCodewords = totalCodewords - ecTotalCodewords
-
- // Total number of blocks
- const ecTotalBlocks = ECCode.getBlocksCount(version, errorCorrectionLevel)
-
- // Calculate how many blocks each group should contain
- const blocksInGroup2 = totalCodewords % ecTotalBlocks
- const blocksInGroup1 = ecTotalBlocks - blocksInGroup2
-
- const totalCodewordsInGroup1 = Math.floor(totalCodewords / ecTotalBlocks)
-
- const dataCodewordsInGroup1 = Math.floor(dataTotalCodewords / ecTotalBlocks)
- const dataCodewordsInGroup2 = dataCodewordsInGroup1 + 1
-
- // Number of EC codewords is the same for both groups
- const ecCount = totalCodewordsInGroup1 - dataCodewordsInGroup1
-
- // Initialize a Reed-Solomon encoder with a generator polynomial of degree ecCount
- const rs = new ReedSolomonEncoder(ecCount)
-
- let offset = 0
- const dcData = new Array(ecTotalBlocks)
- const ecData = new Array(ecTotalBlocks)
- let maxDataSize = 0
- const buffer = new Uint8Array(bitBuffer.buffer)
-
- // Divide the buffer into the required number of blocks
- for (let b = 0; b < ecTotalBlocks; b++) {
- const dataSize = b < blocksInGroup1 ? dataCodewordsInGroup1 : dataCodewordsInGroup2
-
- // extract a block of data from buffer
- dcData[b] = buffer.slice(offset, offset + dataSize)
-
- // Calculate EC codewords for this data block
- ecData[b] = rs.encode(dcData[b])
-
- offset += dataSize
- maxDataSize = Math.max(maxDataSize, dataSize)
- }
-
- // Create final data
- // Interleave the data and error correction codewords from each block
- const data = new Uint8Array(totalCodewords)
- let index = 0
- let i, r
-
- // Add data codewords
- for (i = 0; i < maxDataSize; i++) {
- for (r = 0; r < ecTotalBlocks; r++) {
- if (i < dcData[r].length) {
- data[index++] = dcData[r][i]
- }
- }
- }
-
- // Apped EC codewords
- for (i = 0; i < ecCount; i++) {
- for (r = 0; r < ecTotalBlocks; r++) {
- data[index++] = ecData[r][i]
- }
- }
-
- return data
-}
-
-/**
- * Build QR Code symbol
- *
- * @param {String} data Input string
- * @param {Number} version QR Code version
- * @param {ErrorCorretionLevel} errorCorrectionLevel Error level
- * @param {MaskPattern} maskPattern Mask pattern
- * @return {Object} Object containing symbol data
- */
-function createSymbol (data, version, errorCorrectionLevel, maskPattern) {
- let segments
-
- if (Array.isArray(data)) {
- segments = Segments.fromArray(data)
- } else if (typeof data === 'string') {
- let estimatedVersion = version
-
- if (!estimatedVersion) {
- const rawSegments = Segments.rawSplit(data)
-
- // Estimate best version that can contain raw splitted segments
- estimatedVersion = Version.getBestVersionForData(rawSegments, errorCorrectionLevel)
- }
-
- // Build optimized segments
- // If estimated version is undefined, try with the highest version
- segments = Segments.fromString(data, estimatedVersion || 40)
- } else {
- throw new Error('Invalid data')
- }
-
- // Get the min version that can contain data
- const bestVersion = Version.getBestVersionForData(segments, errorCorrectionLevel)
-
- // If no version is found, data cannot be stored
- if (!bestVersion) {
- throw new Error('The amount of data is too big to be stored in a QR Code')
- }
-
- // If not specified, use min version as default
- if (!version) {
- version = bestVersion
-
- // Check if the specified version can contain the data
- } else if (version < bestVersion) {
- throw new Error('\n' +
- 'The chosen QR Code version cannot contain this amount of data.\n' +
- 'Minimum version required to store current data is: ' + bestVersion + '.\n'
- )
- }
-
- const dataBits = createData(version, errorCorrectionLevel, segments)
-
- // Allocate matrix buffer
- const moduleCount = Utils.getSymbolSize(version)
- const modules = new BitMatrix(moduleCount)
-
- // Add function modules
- setupFinderPattern(modules, version)
- setupTimingPattern(modules)
- setupAlignmentPattern(modules, version)
-
- // Add temporary dummy bits for format info just to set them as reserved.
- // This is needed to prevent these bits from being masked by {@link MaskPattern.applyMask}
- // since the masking operation must be performed only on the encoding region.
- // These blocks will be replaced with correct values later in code.
- setupFormatInfo(modules, errorCorrectionLevel, 0)
-
- if (version >= 7) {
- setupVersionInfo(modules, version)
- }
-
- // Add data codewords
- setupData(modules, dataBits)
-
- if (isNaN(maskPattern)) {
- // Find best mask pattern
- maskPattern = MaskPattern.getBestMask(modules,
- setupFormatInfo.bind(null, modules, errorCorrectionLevel))
- }
-
- // Apply mask pattern
- MaskPattern.applyMask(maskPattern, modules)
-
- // Replace format info bits with correct values
- setupFormatInfo(modules, errorCorrectionLevel, maskPattern)
-
- return {
- modules: modules,
- version: version,
- errorCorrectionLevel: errorCorrectionLevel,
- maskPattern: maskPattern,
- segments: segments
- }
-}
-
-/**
- * QR Code
- *
- * @param {String | Array} data Input data
- * @param {Object} options Optional configurations
- * @param {Number} options.version QR Code version
- * @param {String} options.errorCorrectionLevel Error correction level
- * @param {Function} options.toSJISFunc Helper func to convert utf8 to sjis
- */
-exports.create = function create (data, options) {
- if (typeof data === 'undefined' || data === '') {
- throw new Error('No input text')
- }
-
- let errorCorrectionLevel = ECLevel.M
- let version
- let mask
-
- if (typeof options !== 'undefined') {
- // Use higher error correction level as default
- errorCorrectionLevel = ECLevel.from(options.errorCorrectionLevel, ECLevel.M)
- version = Version.from(options.version)
- mask = MaskPattern.from(options.maskPattern)
-
- if (options.toSJISFunc) {
- Utils.setToSJISFunction(options.toSJISFunc)
- }
- }
-
- return createSymbol(data, version, errorCorrectionLevel, mask)
-}
diff --git a/BeadQR/miniprogram/utils/qrcore/reed-solomon-encoder.js b/BeadQR/miniprogram/utils/qrcore/reed-solomon-encoder.js
deleted file mode 100644
index c19842279cd54c8a09cd821aaeb36ff2c1229101..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/reed-solomon-encoder.js
+++ /dev/null
@@ -1,56 +0,0 @@
-const Polynomial = require('./polynomial')
-
-function ReedSolomonEncoder (degree) {
- this.genPoly = undefined
- this.degree = degree
-
- if (this.degree) this.initialize(this.degree)
-}
-
-/**
- * Initialize the encoder.
- * The input param should correspond to the number of error correction codewords.
- *
- * @param {Number} degree
- */
-ReedSolomonEncoder.prototype.initialize = function initialize (degree) {
- // create an irreducible generator polynomial
- this.degree = degree
- this.genPoly = Polynomial.generateECPolynomial(this.degree)
-}
-
-/**
- * Encodes a chunk of data
- *
- * @param {Uint8Array} data Buffer containing input data
- * @return {Uint8Array} Buffer containing encoded data
- */
-ReedSolomonEncoder.prototype.encode = function encode (data) {
- if (!this.genPoly) {
- throw new Error('Encoder not initialized')
- }
-
- // Calculate EC for this data block
- // extends data size to data+genPoly size
- const paddedData = new Uint8Array(data.length + this.degree)
- paddedData.set(data)
-
- // The error correction codewords are the remainder after dividing the data codewords
- // by a generator polynomial
- const remainder = Polynomial.mod(paddedData, this.genPoly)
-
- // return EC data blocks (last n byte, where n is the degree of genPoly)
- // If coefficients number in remainder are less than genPoly degree,
- // pad with 0s to the left to reach the needed number of coefficients
- const start = this.degree - remainder.length
- if (start > 0) {
- const buff = new Uint8Array(this.degree)
- buff.set(remainder, start)
-
- return buff
- }
-
- return remainder
-}
-
-module.exports = ReedSolomonEncoder
diff --git a/BeadQR/miniprogram/utils/qrcore/regex.js b/BeadQR/miniprogram/utils/qrcore/regex.js
deleted file mode 100644
index 9dd13a4231a1a88d66652ac1249a316c0265c9d8..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/regex.js
+++ /dev/null
@@ -1,31 +0,0 @@
-const numeric = '[0-9]+'
-const alphanumeric = '[A-Z $%*+\\-./:]+'
-let kanji = '(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|' +
- '[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|' +
- '[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|' +
- '[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+'
-kanji = kanji.replace(/u/g, '\\u')
-
-const byte = '(?:(?![A-Z0-9 $%*+\\-./:]|' + kanji + ')(?:.|[\r\n]))+'
-
-exports.KANJI = new RegExp(kanji, 'g')
-exports.BYTE_KANJI = new RegExp('[^A-Z0-9 $%*+\\-./:]+', 'g')
-exports.BYTE = new RegExp(byte, 'g')
-exports.NUMERIC = new RegExp(numeric, 'g')
-exports.ALPHANUMERIC = new RegExp(alphanumeric, 'g')
-
-const TEST_KANJI = new RegExp('^' + kanji + '$')
-const TEST_NUMERIC = new RegExp('^' + numeric + '$')
-const TEST_ALPHANUMERIC = new RegExp('^[A-Z0-9 $%*+\\-./:]+$')
-
-exports.testKanji = function testKanji (str) {
- return TEST_KANJI.test(str)
-}
-
-exports.testNumeric = function testNumeric (str) {
- return TEST_NUMERIC.test(str)
-}
-
-exports.testAlphanumeric = function testAlphanumeric (str) {
- return TEST_ALPHANUMERIC.test(str)
-}
diff --git a/BeadQR/miniprogram/utils/qrcore/segments.js b/BeadQR/miniprogram/utils/qrcore/segments.js
deleted file mode 100644
index 9254178d4e2d899092cb452724dee66fe90cdf39..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/segments.js
+++ /dev/null
@@ -1,330 +0,0 @@
-const Mode = require('./mode')
-const NumericData = require('./numeric-data')
-const AlphanumericData = require('./alphanumeric-data')
-const ByteData = require('./byte-data')
-const KanjiData = require('./kanji-data')
-const Regex = require('./regex')
-const Utils = require('./utils')
-const dijkstra = require('./dijkstrajs')
-
-/**
- * Returns UTF8 byte length
- *
- * @param {String} str Input string
- * @return {Number} Number of byte
- */
-function getStringByteLength (str) {
- return unescape(encodeURIComponent(str)).length
-}
-
-/**
- * Get a list of segments of the specified mode
- * from a string
- *
- * @param {Mode} mode Segment mode
- * @param {String} str String to process
- * @return {Array} Array of object with segments data
- */
-function getSegments (regex, mode, str) {
- const segments = []
- let result
-
- while ((result = regex.exec(str)) !== null) {
- segments.push({
- data: result[0],
- index: result.index,
- mode: mode,
- length: result[0].length
- })
- }
-
- return segments
-}
-
-/**
- * Extracts a series of segments with the appropriate
- * modes from a string
- *
- * @param {String} dataStr Input string
- * @return {Array} Array of object with segments data
- */
-function getSegmentsFromString (dataStr) {
- const numSegs = getSegments(Regex.NUMERIC, Mode.NUMERIC, dataStr)
- const alphaNumSegs = getSegments(Regex.ALPHANUMERIC, Mode.ALPHANUMERIC, dataStr)
- let byteSegs
- let kanjiSegs
-
- if (Utils.isKanjiModeEnabled()) {
- byteSegs = getSegments(Regex.BYTE, Mode.BYTE, dataStr)
- kanjiSegs = getSegments(Regex.KANJI, Mode.KANJI, dataStr)
- } else {
- byteSegs = getSegments(Regex.BYTE_KANJI, Mode.BYTE, dataStr)
- kanjiSegs = []
- }
-
- const segs = numSegs.concat(alphaNumSegs, byteSegs, kanjiSegs)
-
- return segs
- .sort(function (s1, s2) {
- return s1.index - s2.index
- })
- .map(function (obj) {
- return {
- data: obj.data,
- mode: obj.mode,
- length: obj.length
- }
- })
-}
-
-/**
- * Returns how many bits are needed to encode a string of
- * specified length with the specified mode
- *
- * @param {Number} length String length
- * @param {Mode} mode Segment mode
- * @return {Number} Bit length
- */
-function getSegmentBitsLength (length, mode) {
- switch (mode) {
- case Mode.NUMERIC:
- return NumericData.getBitsLength(length)
- case Mode.ALPHANUMERIC:
- return AlphanumericData.getBitsLength(length)
- case Mode.KANJI:
- return KanjiData.getBitsLength(length)
- case Mode.BYTE:
- return ByteData.getBitsLength(length)
- }
-}
-
-/**
- * Merges adjacent segments which have the same mode
- *
- * @param {Array} segs Array of object with segments data
- * @return {Array} Array of object with segments data
- */
-function mergeSegments (segs) {
- return segs.reduce(function (acc, curr) {
- const prevSeg = acc.length - 1 >= 0 ? acc[acc.length - 1] : null
- if (prevSeg && prevSeg.mode === curr.mode) {
- acc[acc.length - 1].data += curr.data
- return acc
- }
-
- acc.push(curr)
- return acc
- }, [])
-}
-
-/**
- * Generates a list of all possible nodes combination which
- * will be used to build a segments graph.
- *
- * Nodes are divided by groups. Each group will contain a list of all the modes
- * in which is possible to encode the given text.
- *
- * For example the text '12345' can be encoded as Numeric, Alphanumeric or Byte.
- * The group for '12345' will contain then 3 objects, one for each
- * possible encoding mode.
- *
- * Each node represents a possible segment.
- *
- * @param {Array} segs Array of object with segments data
- * @return {Array} Array of object with segments data
- */
-function buildNodes (segs) {
- const nodes = []
- for (let i = 0; i < segs.length; i++) {
- const seg = segs[i]
-
- switch (seg.mode) {
- case Mode.NUMERIC:
- nodes.push([seg,
- { data: seg.data, mode: Mode.ALPHANUMERIC, length: seg.length },
- { data: seg.data, mode: Mode.BYTE, length: seg.length }
- ])
- break
- case Mode.ALPHANUMERIC:
- nodes.push([seg,
- { data: seg.data, mode: Mode.BYTE, length: seg.length }
- ])
- break
- case Mode.KANJI:
- nodes.push([seg,
- { data: seg.data, mode: Mode.BYTE, length: getStringByteLength(seg.data) }
- ])
- break
- case Mode.BYTE:
- nodes.push([
- { data: seg.data, mode: Mode.BYTE, length: getStringByteLength(seg.data) }
- ])
- }
- }
-
- return nodes
-}
-
-/**
- * Builds a graph from a list of nodes.
- * All segments in each node group will be connected with all the segments of
- * the next group and so on.
- *
- * At each connection will be assigned a weight depending on the
- * segment's byte length.
- *
- * @param {Array} nodes Array of object with segments data
- * @param {Number} version QR Code version
- * @return {Object} Graph of all possible segments
- */
-function buildGraph (nodes, version) {
- const table = {}
- const graph = { start: {} }
- let prevNodeIds = ['start']
-
- for (let i = 0; i < nodes.length; i++) {
- const nodeGroup = nodes[i]
- const currentNodeIds = []
-
- for (let j = 0; j < nodeGroup.length; j++) {
- const node = nodeGroup[j]
- const key = '' + i + j
-
- currentNodeIds.push(key)
- table[key] = { node: node, lastCount: 0 }
- graph[key] = {}
-
- for (let n = 0; n < prevNodeIds.length; n++) {
- const prevNodeId = prevNodeIds[n]
-
- if (table[prevNodeId] && table[prevNodeId].node.mode === node.mode) {
- graph[prevNodeId][key] =
- getSegmentBitsLength(table[prevNodeId].lastCount + node.length, node.mode) -
- getSegmentBitsLength(table[prevNodeId].lastCount, node.mode)
-
- table[prevNodeId].lastCount += node.length
- } else {
- if (table[prevNodeId]) table[prevNodeId].lastCount = node.length
-
- graph[prevNodeId][key] = getSegmentBitsLength(node.length, node.mode) +
- 4 + Mode.getCharCountIndicator(node.mode, version) // switch cost
- }
- }
- }
-
- prevNodeIds = currentNodeIds
- }
-
- for (let n = 0; n < prevNodeIds.length; n++) {
- graph[prevNodeIds[n]].end = 0
- }
-
- return { map: graph, table: table }
-}
-
-/**
- * Builds a segment from a specified data and mode.
- * If a mode is not specified, the more suitable will be used.
- *
- * @param {String} data Input data
- * @param {Mode | String} modesHint Data mode
- * @return {Segment} Segment
- */
-function buildSingleSegment (data, modesHint) {
- let mode
- const bestMode = Mode.getBestModeForData(data)
-
- mode = Mode.from(modesHint, bestMode)
-
- // Make sure data can be encoded
- if (mode !== Mode.BYTE && mode.bit < bestMode.bit) {
- throw new Error('"' + data + '"' +
- ' cannot be encoded with mode ' + Mode.toString(mode) +
- '.\n Suggested mode is: ' + Mode.toString(bestMode))
- }
-
- // Use Mode.BYTE if Kanji support is disabled
- if (mode === Mode.KANJI && !Utils.isKanjiModeEnabled()) {
- mode = Mode.BYTE
- }
-
- switch (mode) {
- case Mode.NUMERIC:
- return new NumericData(data)
-
- case Mode.ALPHANUMERIC:
- return new AlphanumericData(data)
-
- case Mode.KANJI:
- return new KanjiData(data)
-
- case Mode.BYTE:
- return new ByteData(data)
- }
-}
-
-/**
- * Builds a list of segments from an array.
- * Array can contain Strings or Objects with segment's info.
- *
- * For each item which is a string, will be generated a segment with the given
- * string and the more appropriate encoding mode.
- *
- * For each item which is an object, will be generated a segment with the given
- * data and mode.
- * Objects must contain at least the property "data".
- * If property "mode" is not present, the more suitable mode will be used.
- *
- * @param {Array} array Array of objects with segments data
- * @return {Array} Array of Segments
- */
-exports.fromArray = function fromArray (array) {
- return array.reduce(function (acc, seg) {
- if (typeof seg === 'string') {
- acc.push(buildSingleSegment(seg, null))
- } else if (seg.data) {
- acc.push(buildSingleSegment(seg.data, seg.mode))
- }
-
- return acc
- }, [])
-}
-
-/**
- * Builds an optimized sequence of segments from a string,
- * which will produce the shortest possible bitstream.
- *
- * @param {String} data Input string
- * @param {Number} version QR Code version
- * @return {Array} Array of segments
- */
-exports.fromString = function fromString (data, version) {
- const segs = getSegmentsFromString(data, Utils.isKanjiModeEnabled())
-
- const nodes = buildNodes(segs)
- const graph = buildGraph(nodes, version)
- const path = dijkstra.find_path(graph.map, 'start', 'end')
-
- const optimizedSegs = []
- for (let i = 1; i < path.length - 1; i++) {
- optimizedSegs.push(graph.table[path[i]].node)
- }
-
- return exports.fromArray(mergeSegments(optimizedSegs))
-}
-
-/**
- * Splits a string in various segments with the modes which
- * best represent their content.
- * The produced segments are far from being optimized.
- * The output of this function is only used to estimate a QR Code version
- * which may contain the data.
- *
- * @param {string} data Input string
- * @return {Array} Array of segments
- */
-exports.rawSplit = function rawSplit (data) {
- return exports.fromArray(
- getSegmentsFromString(data, Utils.isKanjiModeEnabled())
- )
-}
diff --git a/BeadQR/miniprogram/utils/qrcore/utils.js b/BeadQR/miniprogram/utils/qrcore/utils.js
deleted file mode 100644
index 8a0b87ba5ad14a058d81ebc9d9439f87f271a2e7..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/utils.js
+++ /dev/null
@@ -1,63 +0,0 @@
-let toSJISFunction
-const CODEWORDS_COUNT = [
- 0, // Not used
- 26, 44, 70, 100, 134, 172, 196, 242, 292, 346,
- 404, 466, 532, 581, 655, 733, 815, 901, 991, 1085,
- 1156, 1258, 1364, 1474, 1588, 1706, 1828, 1921, 2051, 2185,
- 2323, 2465, 2611, 2761, 2876, 3034, 3196, 3362, 3532, 3706
-]
-
-/**
- * Returns the QR Code size for the specified version
- *
- * @param {Number} version QR Code version
- * @return {Number} size of QR code
- */
-exports.getSymbolSize = function getSymbolSize (version) {
- if (!version) throw new Error('"version" cannot be null or undefined')
- if (version < 1 || version > 40) throw new Error('"version" should be in range from 1 to 40')
- return version * 4 + 17
-}
-
-/**
- * Returns the total number of codewords used to store data and EC information.
- *
- * @param {Number} version QR Code version
- * @return {Number} Data length in bits
- */
-exports.getSymbolTotalCodewords = function getSymbolTotalCodewords (version) {
- return CODEWORDS_COUNT[version]
-}
-
-/**
- * Encode data with Bose-Chaudhuri-Hocquenghem
- *
- * @param {Number} data Value to encode
- * @return {Number} Encoded value
- */
-exports.getBCHDigit = function (data) {
- let digit = 0
-
- while (data !== 0) {
- digit++
- data >>>= 1
- }
-
- return digit
-}
-
-exports.setToSJISFunction = function setToSJISFunction (f) {
- if (typeof f !== 'function') {
- throw new Error('"toSJISFunc" is not a valid function.')
- }
-
- toSJISFunction = f
-}
-
-exports.isKanjiModeEnabled = function () {
- return typeof toSJISFunction !== 'undefined'
-}
-
-exports.toSJIS = function toSJIS (kanji) {
- return toSJISFunction(kanji)
-}
diff --git a/BeadQR/miniprogram/utils/qrcore/version-check.js b/BeadQR/miniprogram/utils/qrcore/version-check.js
deleted file mode 100644
index dd32b5aced810559e5ef974d483cb0660996737e..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/version-check.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * Check if QR Code version is valid
- *
- * @param {Number} version QR Code version
- * @return {Boolean} true if valid version, false otherwise
- */
-exports.isValid = function isValid (version) {
- return !isNaN(version) && version >= 1 && version <= 40
-}
diff --git a/BeadQR/miniprogram/utils/qrcore/version.js b/BeadQR/miniprogram/utils/qrcore/version.js
deleted file mode 100644
index 32b846615722615db5b68f422bb46eae885246c6..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/qrcore/version.js
+++ /dev/null
@@ -1,163 +0,0 @@
-const Utils = require('./utils')
-const ECCode = require('./error-correction-code')
-const ECLevel = require('./error-correction-level')
-const Mode = require('./mode')
-const VersionCheck = require('./version-check')
-
-// Generator polynomial used to encode version information
-const G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0)
-const G18_BCH = Utils.getBCHDigit(G18)
-
-function getBestVersionForDataLength (mode, length, errorCorrectionLevel) {
- for (let currentVersion = 1; currentVersion <= 40; currentVersion++) {
- if (length <= exports.getCapacity(currentVersion, errorCorrectionLevel, mode)) {
- return currentVersion
- }
- }
-
- return undefined
-}
-
-function getReservedBitsCount (mode, version) {
- // Character count indicator + mode indicator bits
- return Mode.getCharCountIndicator(mode, version) + 4
-}
-
-function getTotalBitsFromDataArray (segments, version) {
- let totalBits = 0
-
- segments.forEach(function (data) {
- const reservedBits = getReservedBitsCount(data.mode, version)
- totalBits += reservedBits + data.getBitsLength()
- })
-
- return totalBits
-}
-
-function getBestVersionForMixedData (segments, errorCorrectionLevel) {
- for (let currentVersion = 1; currentVersion <= 40; currentVersion++) {
- const length = getTotalBitsFromDataArray(segments, currentVersion)
- if (length <= exports.getCapacity(currentVersion, errorCorrectionLevel, Mode.MIXED)) {
- return currentVersion
- }
- }
-
- return undefined
-}
-
-/**
- * Returns version number from a value.
- * If value is not a valid version, returns defaultValue
- *
- * @param {Number|String} value QR Code version
- * @param {Number} defaultValue Fallback value
- * @return {Number} QR Code version number
- */
-exports.from = function from (value, defaultValue) {
- if (VersionCheck.isValid(value)) {
- return parseInt(value, 10)
- }
-
- return defaultValue
-}
-
-/**
- * Returns how much data can be stored with the specified QR code version
- * and error correction level
- *
- * @param {Number} version QR Code version (1-40)
- * @param {Number} errorCorrectionLevel Error correction level
- * @param {Mode} mode Data mode
- * @return {Number} Quantity of storable data
- */
-exports.getCapacity = function getCapacity (version, errorCorrectionLevel, mode) {
- if (!VersionCheck.isValid(version)) {
- throw new Error('Invalid QR Code version')
- }
-
- // Use Byte mode as default
- if (typeof mode === 'undefined') mode = Mode.BYTE
-
- // Total codewords for this QR code version (Data + Error correction)
- const totalCodewords = Utils.getSymbolTotalCodewords(version)
-
- // Total number of error correction codewords
- const ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel)
-
- // Total number of data codewords
- const dataTotalCodewordsBits = (totalCodewords - ecTotalCodewords) * 8
-
- if (mode === Mode.MIXED) return dataTotalCodewordsBits
-
- const usableBits = dataTotalCodewordsBits - getReservedBitsCount(mode, version)
-
- // Return max number of storable codewords
- switch (mode) {
- case Mode.NUMERIC:
- return Math.floor((usableBits / 10) * 3)
-
- case Mode.ALPHANUMERIC:
- return Math.floor((usableBits / 11) * 2)
-
- case Mode.KANJI:
- return Math.floor(usableBits / 13)
-
- case Mode.BYTE:
- default:
- return Math.floor(usableBits / 8)
- }
-}
-
-/**
- * Returns the minimum version needed to contain the amount of data
- *
- * @param {Segment} data Segment of data
- * @param {Number} [errorCorrectionLevel=H] Error correction level
- * @param {Mode} mode Data mode
- * @return {Number} QR Code version
- */
-exports.getBestVersionForData = function getBestVersionForData (data, errorCorrectionLevel) {
- let seg
-
- const ecl = ECLevel.from(errorCorrectionLevel, ECLevel.M)
-
- if (Array.isArray(data)) {
- if (data.length > 1) {
- return getBestVersionForMixedData(data, ecl)
- }
-
- if (data.length === 0) {
- return 1
- }
-
- seg = data[0]
- } else {
- seg = data
- }
-
- return getBestVersionForDataLength(seg.mode, seg.getLength(), ecl)
-}
-
-/**
- * Returns version information with relative error correction bits
- *
- * The version information is included in QR Code symbols of version 7 or larger.
- * It consists of an 18-bit sequence containing 6 data bits,
- * with 12 error correction bits calculated using the (18, 6) Golay code.
- *
- * @param {Number} version QR Code version
- * @return {Number} Encoded version info bits
- */
-exports.getEncodedBits = function getEncodedBits (version) {
- if (!VersionCheck.isValid(version) || version < 7) {
- throw new Error('Invalid QR Code version')
- }
-
- let d = version << 12
-
- while (Utils.getBCHDigit(d) - G18_BCH >= 0) {
- d ^= (G18 << (Utils.getBCHDigit(d) - G18_BCH))
- }
-
- return (version << 12) | d
-}
diff --git a/BeadQR/miniprogram/utils/scancheck.js b/BeadQR/miniprogram/utils/scancheck.js
deleted file mode 100644
index b09829aa94c3019160125d11eb6510be3c48f21b..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/scancheck.js
+++ /dev/null
@@ -1,36 +0,0 @@
-// 本地扫码自检:把生成的色号网格渲染成像素,用 jsQR 解码并比对内容
-// jsQR 比微信扫码更“挑剔”,自检通过基本可以放心;未通过时提示用户调整
-const jsQR = require('./vendor/jsqr')
-const { hexToRgb } = require('./color')
-
-function selfCheck(artwork, expectedText) {
- const { size, cells, pal } = artwork
- const px = size > 90 ? 4 : 5
- const margin = 4
- const dim = (size + margin * 2) * px
- const data = new Uint8ClampedArray(dim * dim * 4).fill(255)
- const colors = pal.hexes.map(hexToRgb)
- for (let y = 0; y < size; y += 1) {
- for (let x = 0; x < size; x += 1) {
- const c = cells[y * size + x]
- if (c < 0) continue // 空钉位视为白底
- const [r, g, b] = colors[c]
- for (let dy = 0; dy < px; dy += 1) {
- let o = (((y + margin) * px + dy) * dim + (x + margin) * px) * 4
- for (let dx = 0; dx < px; dx += 1) {
- data[o] = r; data[o + 1] = g; data[o + 2] = b
- o += 4
- }
- }
- }
- }
- try {
- const result = jsQR(data, dim, dim, { inversionAttempts: 'dontInvert' })
- if (!result) return { ok: false, reason: 'unreadable' }
- return { ok: result.data === expectedText, reason: result.data === expectedText ? '' : 'mismatch' }
- } catch (e) {
- return { ok: false, reason: 'error' }
- }
-}
-
-module.exports = { selfCheck }
diff --git a/BeadQR/miniprogram/utils/security.js b/BeadQR/miniprogram/utils/security.js
deleted file mode 100644
index e7e78d8934ac4f2c621017910fab917142d2ba27..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/security.js
+++ /dev/null
@@ -1,134 +0,0 @@
-// 内容安全链路(微信平台规范)
-// 文本:security.msgSecCheck v2(二维码内容 / 扫码导入内容 / 水印)
-// 图片:先按官方建议压缩到 750×1334 内、1MB 内的 JPG,再上传云存储由云函数调用 security.imgSecCheck
-// 约定返回:{ status: 'pass' | 'risky' | 'error' }
-// - risky:命中违规,必须拦截
-// - error:检测服务不可用,同样拦截(禁止静默放行)
-// 通过结果按内容缓存,导出时无需重复请求,显著提升导出速度
-
-const FUNCTION_NAME = 'quickstartFunctions'
-const MAX_W = 750
-const MAX_H = 1334
-const textCache = new Map() // value -> 'pass' | 'risky'
-const pending = new Map() // value -> Promise
-
-function callFunction(data) {
- return new Promise((resolve) => {
- if (!wx.cloud) { resolve(null); return }
- wx.cloud.callFunction({
- name: FUNCTION_NAME,
- data,
- success: (res) => resolve((res && res.result) || null),
- fail: () => resolve(null),
- })
- })
-}
-
-function normalize(result) {
- if (!result) return 'error'
- if (result.risk) return 'risky'
- if (result.skipped) return 'error'
- return 'pass'
-}
-
-function checkText(content, scene = 2) {
- const value = String(content || '').trim().slice(0, 2500)
- if (!value) return Promise.resolve({ status: 'pass' })
- const cached = textCache.get(value)
- if (cached) return Promise.resolve({ status: cached, cached: true })
- if (pending.has(value)) return pending.get(value)
- const task = callFunction({ type: 'checkMessage', content: value, scene }).then((result) => {
- const status = normalize(result)
- if (status !== 'error') textCache.set(value, status)
- pending.delete(value)
- return { status }
- })
- pending.set(value, task)
- return task
-}
-
-// 导出前一次性校验多段文本(已缓存的直接复用,未缓存的合并为一次云函数调用)
-function checkTexts(items) {
- const list = items.map((it) => ({ value: String(it.value || '').trim().slice(0, 2500), scene: it.scene || 2 })).filter((it) => it.value)
- const results = list.map((it) => textCache.get(it.value))
- if (results.includes('risky')) return Promise.resolve({ status: 'risky' })
- const missing = list.filter((it, i) => !results[i])
- if (!missing.length) return Promise.resolve({ status: 'pass' })
- return callFunction({ type: 'checkMessages', items: missing }).then((res) => {
- if (!res || !Array.isArray(res.results)) return { status: 'error' }
- let status = 'pass'
- res.results.forEach((r, i) => {
- const s = normalize(r)
- if (s !== 'error') textCache.set(missing[i].value, s)
- if (s === 'risky') status = 'risky'
- else if (s === 'error' && status === 'pass') status = 'error'
- })
- return { status }
- })
-}
-
-function isTextPassed(value) {
- const v = String(value || '').trim()
- return !v || textCache.get(v) === 'pass'
-}
-
-// 按官方尺寸建议压缩(同时加快上传)
-function compressForCheck(canvas, image, path) {
- return new Promise((resolve) => {
- if (!canvas || !image) { resolve(path); return }
- try {
- const w0 = image.width || image._w
- const h0 = image.height || image._h
- const scale = Math.min(1, MAX_W / w0, MAX_H / h0)
- canvas.width = Math.max(1, Math.round(w0 * scale))
- canvas.height = Math.max(1, Math.round(h0 * scale))
- const ctx = canvas.getContext('2d')
- ctx.fillStyle = '#ffffff'
- ctx.fillRect(0, 0, canvas.width, canvas.height)
- ctx.drawImage(image, 0, 0, canvas.width, canvas.height)
- wx.canvasToTempFilePath({
- canvas,
- fileType: 'jpg',
- quality: 0.82,
- destWidth: canvas.width,
- destHeight: canvas.height,
- success: (res) => resolve(res.tempFilePath),
- fail: () => resolve(path),
- })
- } catch (e) {
- resolve(path)
- }
- })
-}
-
-function upload(filePath) {
- return new Promise((resolve) => {
- if (!wx.cloud) { resolve(''); return }
- wx.cloud.uploadFile({
- cloudPath: `sec-check/${Date.now()}-${Math.random().toString(36).slice(2, 10)}.jpg`,
- filePath,
- success: (res) => resolve((res && res.fileID) || ''),
- fail: () => resolve(''),
- })
- })
-}
-
-// image:已加载的 CanvasImage(用于压缩);path:本地临时路径
-function checkImage(path, image, canvas) {
- if (!path) return Promise.resolve({ status: 'error' })
- return compressForCheck(canvas, image, path)
- .then(upload)
- .then((fileID) => {
- if (!fileID) return { status: 'error' }
- // 云函数检测完毕后会立即删除该临时文件
- return callFunction({ type: 'checkImage', fileID }).then((result) => ({ status: normalize(result) }))
- })
- .catch(() => ({ status: 'error' }))
-}
-
-const MESSAGES = {
- risky: '内容含违规信息,请修改后再试',
- error: '安全检测暂不可用,请检查网络后重试',
-}
-
-module.exports = { checkText, checkTexts, isTextPassed, checkImage, MESSAGES }
diff --git a/BeadQR/miniprogram/utils/vendor/jsqr.js b/BeadQR/miniprogram/utils/vendor/jsqr.js
deleted file mode 100644
index 1b99db54d44f69a7262e1900adf7fcb4b54f6e65..0000000000000000000000000000000000000000
--- a/BeadQR/miniprogram/utils/vendor/jsqr.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/*! jsQR 1.4.0 | Apache-2.0 | https://github.com/cozmo/jsQR — 用于本地扫码自检,不联网 */
-(function(y,g){typeof exports=="object"&&typeof module=="object"?module.exports=g():typeof define=="function"&&define.amd?define([],g):typeof exports=="object"?exports.jsQR=g():y.jsQR=g()})(typeof self<"u"?self:exports,function(){return function(G){var y={};function g(p){if(y[p])return y[p].exports;var m=y[p]={i:p,l:!1,exports:{}};return G[p].call(m.exports,m,m.exports,g),m.l=!0,m.exports}return g.m=G,g.c=y,g.d=function(p,m,l){g.o(p,m)||Object.defineProperty(p,m,{configurable:!1,enumerable:!0,get:l})},g.n=function(p){var m=p&&p.__esModule?function(){return p.default}:function(){return p};return g.d(m,"a",m),m},g.o=function(p,m){return Object.prototype.hasOwnProperty.call(p,m)},g.p="",g(g.s=3)}([function(G,y,g){"use strict";Object.defineProperty(y,"__esModule",{value:!0});var p=function(){function m(l,s){this.width=s,this.height=l.length/s,this.data=l}return m.createEmpty=function(l,s){return new m(new Uint8ClampedArray(l*s),l)},m.prototype.get=function(l,s){return l<0||l>=this.width||s<0||s>=this.height?!1:!!this.data[s*this.width+l]},m.prototype.set=function(l,s,c){this.data[s*this.width+l]=c?1:0},m.prototype.setRegion=function(l,s,c,o,E){for(var r=s;r=this.size&&(r=(r^this.primitive)&this.size-1);for(var a=0;a1&&c[0]===0){for(var E=1;EE.length&&(c=[E,o],o=c[0],E=c[1]);for(var r=new Uint8ClampedArray(E.length),a=E.length-o.length,F=0;Fa?a:E}var c=function(){function E(r,a){this.width=r,this.data=new Uint8ClampedArray(r*a)}return E.prototype.get=function(r,a){return this.data[a*this.width+r]},E.prototype.set=function(r,a,F){this.data[a*this.width+r]=F},E}();function o(E,r,a,F){if(E.length!==r*a*4)throw new Error("Malformed data passed to binarizer.");for(var d=new c(r,a),D=0;D0&&n>0)){var w=(C.get(n,t-1)+2*C.get(n-1,t)+C.get(n-1,t-1))/4;u6&&(e.setRegion(B-11,0,3,6,!0),e.setRegion(0,B-11,6,3,!0)),e}function F(x,B,e){for(var C=r[e.dataMask],t=x.height,n=a(B),k=[],u=0,f=0,M=!0,b=t-1;b>0;b-=2){b===6&&b--;for(var w=0;w=0;t--)for(var n=B-9;n>=B-11;n--)C=o(x.get(n,t),C);for(var k=0,n=5;n>=0;n--)for(var t=B-9;t>=B-11;t--)k=o(x.get(n,t),k);for(var u=1/0,f,M=0,b=s.VERSIONS;M=0;C--)C!==6&&(B=o(x.get(8,C),B));for(var t=x.height,n=0,C=t-1;C>=t-7;C--)n=o(x.get(8,C),n);for(var e=t-8;e1)for(var w=C.ecBlocks[0].numBlocks,I=C.ecBlocks[1].numBlocks,u=0;u0;)for(var h=0,N=t;h=3;){var B=d.readBits(10);if(B>=1e3)throw new Error("Invalid numeric value above 999");var e=Math.floor(B/100),C=Math.floor(B/10)%10,t=B%10;i.push(48+e,48+C,48+t),v+=e.toString()+C.toString()+t.toString(),x-=3}if(x===2){var B=d.readBits(7);if(B>=100)throw new Error("Invalid numeric value above 99");var e=Math.floor(B/10),C=B%10;i.push(48+e,48+C),v+=e.toString()+C.toString()}else if(x===1){var B=d.readBits(4);if(B>=10)throw new Error("Invalid numeric value above 9");i.push(48+B),v+=B.toString()}return{bytes:i,text:v}}var o=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"," ","$","%","*","+","-",".","/",":"];function E(d,D){for(var i=[],v="",A=[9,11,13][D],x=d.readBits(A);x>=2;){var B=d.readBits(11),e=Math.floor(B/45),C=B%45;i.push(o[e].charCodeAt(0),o[C].charCodeAt(0)),v+=o[e]+o[C],x-=2}if(x===1){var e=d.readBits(6);i.push(o[e].charCodeAt(0)),v+=o[e]}return{bytes:i,text:v}}function r(d,D){for(var i=[],v="",A=[8,16,16][D],x=d.readBits(A),B=0;B>8,C&255),v+=String.fromCharCode(m.shiftJISTable[C])}return{bytes:i,text:v}}function F(d,D){for(var i,v,A,x,B=new p.BitStream(d),e=D<=9?0:D<=26?1:2,C={text:"",bytes:[],chunks:[],version:D};B.available()>=4;){var t=B.readBits(4);if(t===s.Terminator)return C;if(t===s.ECI)B.readBits(1)===0?C.chunks.push({type:l.ECI,assignmentNumber:B.readBits(7)}):B.readBits(1)===0?C.chunks.push({type:l.ECI,assignmentNumber:B.readBits(14)}):B.readBits(1)===0?C.chunks.push({type:l.ECI,assignmentNumber:B.readBits(21)}):C.chunks.push({type:l.ECI,assignmentNumber:-1});else if(t===s.Numeric){var n=c(B,e);C.text+=n.text,(i=C.bytes).push.apply(i,n.bytes),C.chunks.push({type:l.Numeric,text:n.text})}else if(t===s.Alphanumeric){var k=E(B,e);C.text+=k.text,(v=C.bytes).push.apply(v,k.bytes),C.chunks.push({type:l.Alphanumeric,text:k.text})}else if(t===s.Byte){var u=r(B,e);C.text+=u.text,(A=C.bytes).push.apply(A,u.bytes),C.chunks.push({type:l.Byte,bytes:u.bytes,text:u.text})}else if(t===s.Kanji){var f=a(B,e);C.text+=f.text,(x=C.bytes).push.apply(x,f.bytes),C.chunks.push({type:l.Kanji,bytes:f.bytes,text:f.text})}}if(B.available()===0||B.readBits(B.available())===0)return C}y.decode=F},function(G,y,g){"use strict";Object.defineProperty(y,"__esModule",{value:!0});var p=function(){function m(l){this.byteOffset=0,this.bitOffset=0,this.bytes=l}return m.prototype.readBits=function(l){if(l<1||l>32||l>this.available())throw new Error("Cannot read "+l.toString()+" bits");var s=0;if(this.bitOffset>0){var c=8-this.bitOffset,o=l>8-o<>E,l-=o,this.bitOffset+=o,this.bitOffset===8&&(this.bitOffset=0,this.byteOffset++)}if(l>0){for(;l>=8;)s=s<<8|this.bytes[this.byteOffset]&255,this.byteOffset++,l-=8;if(l>0){var E=8-l,r=255>>E<>E,this.bitOffset+=l}}return s},m.prototype.available=function(){return 8*(this.bytes.length-this.byteOffset)-this.bitOffset},m}();y.BitStream=p},function(G,y,g){"use strict";Object.defineProperty(y,"__esModule",{value:!0}),y.shiftJISTable={32:32,33:33,34:34,35:35,36:36,37:37,38:38,39:39,40:40,41:41,42:42,43:43,44:44,45:45,46:46,47:47,48:48,49:49,50:50,51:51,52:52,53:53,54:54,55:55,56:56,57:57,58:58,59:59,60:60,61:61,62:62,63:63,64:64,65:65,66:66,67:67,68:68,69:69,70:70,71:71,72:72,73:73,74:74,75:75,76:76,77:77,78:78,79:79,80:80,81:81,82:82,83:83,84:84,85:85,86:86,87:87,88:88,89:89,90:90,91:91,92:165,93:93,94:94,95:95,96:96,97:97,98:98,99:99,100:100,101:101,102:102,103:103,104:104,105:105,106:106,107:107,108:108,109:109,110:110,111:111,112:112,113:113,114:114,115:115,116:116,117:117,118:118,119:119,120:120,121:121,122:122,123:123,124:124,125:125,126:8254,33088:12288,33089:12289,33090:12290,33091:65292,33092:65294,33093:12539,33094:65306,33095:65307,33096:65311,33097:65281,33098:12443,33099:12444,33100:180,33101:65344,33102:168,33103:65342,33104:65507,33105:65343,33106:12541,33107:12542,33108:12445,33109:12446,33110:12291,33111:20189,33112:12293,33113:12294,33114:12295,33115:12540,33116:8213,33117:8208,33118:65295,33119:92,33120:12316,33121:8214,33122:65372,33123:8230,33124:8229,33125:8216,33126:8217,33127:8220,33128:8221,33129:65288,33130:65289,33131:12308,33132:12309,33133:65339,33134:65341,33135:65371,33136:65373,33137:12296,33138:12297,33139:12298,33140:12299,33141:12300,33142:12301,33143:12302,33144:12303,33145:12304,33146:12305,33147:65291,33148:8722,33149:177,33150:215,33152:247,33153:65309,33154:8800,33155:65308,33156:65310,33157:8806,33158:8807,33159:8734,33160:8756,33161:9794,33162:9792,33163:176,33164:8242,33165:8243,33166:8451,33167:65509,33168:65284,33169:162,33170:163,33171:65285,33172:65283,33173:65286,33174:65290,33175:65312,33176:167,33177:9734,33178:9733,33179:9675,33180:9679,33181:9678,33182:9671,33183:9670,33184:9633,33185:9632,33186:9651,33187:9650,33188:9661,33189:9660,33190:8251,33191:12306,33192:8594,33193:8592,33194:8593,33195:8595,33196:12307,33208:8712,33209:8715,33210:8838,33211:8839,33212:8834,33213:8835,33214:8746,33215:8745,33224:8743,33225:8744,33226:172,33227:8658,33228:8660,33229:8704,33230:8707,33242:8736,33243:8869,33244:8978,33245:8706,33246:8711,33247:8801,33248:8786,33249:8810,33250:8811,33251:8730,33252:8765,33253:8733,33254:8757,33255:8747,33256:8748,33264:8491,33265:8240,33266:9839,33267:9837,33268:9834,33269:8224,33270:8225,33271:182,33276:9711,33359:65296,33360:65297,33361:65298,33362:65299,33363:65300,33364:65301,33365:65302,33366:65303,33367:65304,33368:65305,33376:65313,33377:65314,33378:65315,33379:65316,33380:65317,33381:65318,33382:65319,33383:65320,33384:65321,33385:65322,33386:65323,33387:65324,33388:65325,33389:65326,33390:65327,33391:65328,33392:65329,33393:65330,33394:65331,33395:65332,33396:65333,33397:65334,33398:65335,33399:65336,33400:65337,33401:65338,33409:65345,33410:65346,33411:65347,33412:65348,33413:65349,33414:65350,33415:65351,33416:65352,33417:65353,33418:65354,33419:65355,33420:65356,33421:65357,33422:65358,33423:65359,33424:65360,33425:65361,33426:65362,33427:65363,33428:65364,33429:65365,33430:65366,33431:65367,33432:65368,33433:65369,33434:65370,33439:12353,33440:12354,33441:12355,33442:12356,33443:12357,33444:12358,33445:12359,33446:12360,33447:12361,33448:12362,33449:12363,33450:12364,33451:12365,33452:12366,33453:12367,33454:12368,33455:12369,33456:12370,33457:12371,33458:12372,33459:12373,33460:12374,33461:12375,33462:12376,33463:12377,33464:12378,33465:12379,33466:12380,33467:12381,33468:12382,33469:12383,33470:12384,33471:12385,33472:12386,33473:12387,33474:12388,33475:12389,33476:12390,33477:12391,33478:12392,33479:12393,33480:12394,33481:12395,33482:12396,33483:12397,33484:12398,33485:12399,33486:12400,33487:12401,33488:12402,33489:12403,33490:12404,33491:12405,33492:12406,33493:12407,33494:12408,33495:12409,33496:12410,33497:12411,33498:12412,33499:12413,33500:12414,33501:12415,33502:12416,33503:12417,33504:12418,33505:12419,33506:12420,33507:12421,33508:12422,33509:12423,33510:12424,33511:12425,33512:12426,33513:12427,33514:12428,33515:12429,33516:12430,33517:12431,33518:12432,33519:12433,33520:12434,33521:12435,33600:12449,33601:12450,33602:12451,33603:12452,33604:12453,33605:12454,33606:12455,33607:12456,33608:12457,33609:12458,33610:12459,33611:12460,33612:12461,33613:12462,33614:12463,33615:12464,33616:12465,33617:12466,33618:12467,33619:12468,33620:12469,33621:12470,33622:12471,33623:12472,33624:12473,33625:12474,33626:12475,33627:12476,33628:12477,33629:12478,33630:12479,33631:12480,33632:12481,33633:12482,33634:12483,33635:12484,33636:12485,33637:12486,33638:12487,33639:12488,33640:12489,33641:12490,33642:12491,33643:12492,33644:12493,33645:12494,33646:12495,33647:12496,33648:12497,33649:12498,33650:12499,33651:12500,33652:12501,33653:12502,33654:12503,33655:12504,33656:12505,33657:12506,33658:12507,33659:12508,33660:12509,33661:12510,33662:12511,33664:12512,33665:12513,33666:12514,33667:12515,33668:12516,33669:12517,33670:12518,33671:12519,33672:12520,33673:12521,33674:12522,33675:12523,33676:12524,33677:12525,33678:12526,33679:12527,33680:12528,33681:12529,33682:12530,33683:12531,33684:12532,33685:12533,33686:12534,33695:913,33696:914,33697:915,33698:916,33699:917,33700:918,33701:919,33702:920,33703:921,33704:922,33705:923,33706:924,33707:925,33708:926,33709:927,33710:928,33711:929,33712:931,33713:932,33714:933,33715:934,33716:935,33717:936,33718:937,33727:945,33728:946,33729:947,33730:948,33731:949,33732:950,33733:951,33734:952,33735:953,33736:954,33737:955,33738:956,33739:957,33740:958,33741:959,33742:960,33743:961,33744:963,33745:964,33746:965,33747:966,33748:967,33749:968,33750:969,33856:1040,33857:1041,33858:1042,33859:1043,33860:1044,33861:1045,33862:1025,33863:1046,33864:1047,33865:1048,33866:1049,33867:1050,33868:1051,33869:1052,33870:1053,33871:1054,33872:1055,33873:1056,33874:1057,33875:1058,33876:1059,33877:1060,33878:1061,33879:1062,33880:1063,33881:1064,33882:1065,33883:1066,33884:1067,33885:1068,33886:1069,33887:1070,33888:1071,33904:1072,33905:1073,33906:1074,33907:1075,33908:1076,33909:1077,33910:1105,33911:1078,33912:1079,33913:1080,33914:1081,33915:1082,33916:1083,33917:1084,33918:1085,33920:1086,33921:1087,33922:1088,33923:1089,33924:1090,33925:1091,33926:1092,33927:1093,33928:1094,33929:1095,33930:1096,33931:1097,33932:1098,33933:1099,33934:1100,33935:1101,33936:1102,33937:1103,33951:9472,33952:9474,33953:9484,33954:9488,33955:9496,33956:9492,33957:9500,33958:9516,33959:9508,33960:9524,33961:9532,33962:9473,33963:9475,33964:9487,33965:9491,33966:9499,33967:9495,33968:9507,33969:9523,33970:9515,33971:9531,33972:9547,33973:9504,33974:9519,33975:9512,33976:9527,33977:9535,33978:9501,33979:9520,33980:9509,33981:9528,33982:9538,34975:20124,34976:21782,34977:23043,34978:38463,34979:21696,34980:24859,34981:25384,34982:23030,34983:36898,34984:33909,34985:33564,34986:31312,34987:24746,34988:25569,34989:28197,34990:26093,34991:33894,34992:33446,34993:39925,34994:26771,34995:22311,34996:26017,34997:25201,34998:23451,34999:22992,35e3:34427,35001:39156,35002:32098,35003:32190,35004:39822,35005:25110,35006:31903,35007:34999,35008:23433,35009:24245,35010:25353,35011:26263,35012:26696,35013:38343,35014:38797,35015:26447,35016:20197,35017:20234,35018:20301,35019:20381,35020:20553,35021:22258,35022:22839,35023:22996,35024:23041,35025:23561,35026:24799,35027:24847,35028:24944,35029:26131,35030:26885,35031:28858,35032:30031,35033:30064,35034:31227,35035:32173,35036:32239,35037:32963,35038:33806,35039:34915,35040:35586,35041:36949,35042:36986,35043:21307,35044:20117,35045:20133,35046:22495,35047:32946,35048:37057,35049:30959,35050:19968,35051:22769,35052:28322,35053:36920,35054:31282,35055:33576,35056:33419,35057:39983,35058:20801,35059:21360,35060:21693,35061:21729,35062:22240,35063:23035,35064:24341,35065:39154,35066:28139,35067:32996,35068:34093,35136:38498,35137:38512,35138:38560,35139:38907,35140:21515,35141:21491,35142:23431,35143:28879,35144:32701,35145:36802,35146:38632,35147:21359,35148:40284,35149:31418,35150:19985,35151:30867,35152:33276,35153:28198,35154:22040,35155:21764,35156:27421,35157:34074,35158:39995,35159:23013,35160:21417,35161:28006,35162:29916,35163:38287,35164:22082,35165:20113,35166:36939,35167:38642,35168:33615,35169:39180,35170:21473,35171:21942,35172:23344,35173:24433,35174:26144,35175:26355,35176:26628,35177:27704,35178:27891,35179:27945,35180:29787,35181:30408,35182:31310,35183:38964,35184:33521,35185:34907,35186:35424,35187:37613,35188:28082,35189:30123,35190:30410,35191:39365,35192:24742,35193:35585,35194:36234,35195:38322,35196:27022,35197:21421,35198:20870,35200:22290,35201:22576,35202:22852,35203:23476,35204:24310,35205:24616,35206:25513,35207:25588,35208:27839,35209:28436,35210:28814,35211:28948,35212:29017,35213:29141,35214:29503,35215:32257,35216:33398,35217:33489,35218:34199,35219:36960,35220:37467,35221:40219,35222:22633,35223:26044,35224:27738,35225:29989,35226:20985,35227:22830,35228:22885,35229:24448,35230:24540,35231:25276,35232:26106,35233:27178,35234:27431,35235:27572,35236:29579,35237:32705,35238:35158,35239:40236,35240:40206,35241:40644,35242:23713,35243:27798,35244:33659,35245:20740,35246:23627,35247:25014,35248:33222,35249:26742,35250:29281,35251:20057,35252:20474,35253:21368,35254:24681,35255:28201,35256:31311,35257:38899,35258:19979,35259:21270,35260:20206,35261:20309,35262:20285,35263:20385,35264:20339,35265:21152,35266:21487,35267:22025,35268:22799,35269:23233,35270:23478,35271:23521,35272:31185,35273:26247,35274:26524,35275:26550,35276:27468,35277:27827,35278:28779,35279:29634,35280:31117,35281:31166,35282:31292,35283:31623,35284:33457,35285:33499,35286:33540,35287:33655,35288:33775,35289:33747,35290:34662,35291:35506,35292:22057,35293:36008,35294:36838,35295:36942,35296:38686,35297:34442,35298:20420,35299:23784,35300:25105,35301:29273,35302:30011,35303:33253,35304:33469,35305:34558,35306:36032,35307:38597,35308:39187,35309:39381,35310:20171,35311:20250,35312:35299,35313:22238,35314:22602,35315:22730,35316:24315,35317:24555,35318:24618,35319:24724,35320:24674,35321:25040,35322:25106,35323:25296,35324:25913,35392:39745,35393:26214,35394:26800,35395:28023,35396:28784,35397:30028,35398:30342,35399:32117,35400:33445,35401:34809,35402:38283,35403:38542,35404:35997,35405:20977,35406:21182,35407:22806,35408:21683,35409:23475,35410:23830,35411:24936,35412:27010,35413:28079,35414:30861,35415:33995,35416:34903,35417:35442,35418:37799,35419:39608,35420:28012,35421:39336,35422:34521,35423:22435,35424:26623,35425:34510,35426:37390,35427:21123,35428:22151,35429:21508,35430:24275,35431:25313,35432:25785,35433:26684,35434:26680,35435:27579,35436:29554,35437:30906,35438:31339,35439:35226,35440:35282,35441:36203,35442:36611,35443:37101,35444:38307,35445:38548,35446:38761,35447:23398,35448:23731,35449:27005,35450:38989,35451:38990,35452:25499,35453:31520,35454:27179,35456:27263,35457:26806,35458:39949,35459:28511,35460:21106,35461:21917,35462:24688,35463:25324,35464:27963,35465:28167,35466:28369,35467:33883,35468:35088,35469:36676,35470:19988,35471:39993,35472:21494,35473:26907,35474:27194,35475:38788,35476:26666,35477:20828,35478:31427,35479:33970,35480:37340,35481:37772,35482:22107,35483:40232,35484:26658,35485:33541,35486:33841,35487:31909,35488:21e3,35489:33477,35490:29926,35491:20094,35492:20355,35493:20896,35494:23506,35495:21002,35496:21208,35497:21223,35498:24059,35499:21914,35500:22570,35501:23014,35502:23436,35503:23448,35504:23515,35505:24178,35506:24185,35507:24739,35508:24863,35509:24931,35510:25022,35511:25563,35512:25954,35513:26577,35514:26707,35515:26874,35516:27454,35517:27475,35518:27735,35519:28450,35520:28567,35521:28485,35522:29872,35523:29976,35524:30435,35525:30475,35526:31487,35527:31649,35528:31777,35529:32233,35530:32566,35531:32752,35532:32925,35533:33382,35534:33694,35535:35251,35536:35532,35537:36011,35538:36996,35539:37969,35540:38291,35541:38289,35542:38306,35543:38501,35544:38867,35545:39208,35546:33304,35547:20024,35548:21547,35549:23736,35550:24012,35551:29609,35552:30284,35553:30524,35554:23721,35555:32747,35556:36107,35557:38593,35558:38929,35559:38996,35560:39e3,35561:20225,35562:20238,35563:21361,35564:21916,35565:22120,35566:22522,35567:22855,35568:23305,35569:23492,35570:23696,35571:24076,35572:24190,35573:24524,35574:25582,35575:26426,35576:26071,35577:26082,35578:26399,35579:26827,35580:26820,35648:27231,35649:24112,35650:27589,35651:27671,35652:27773,35653:30079,35654:31048,35655:23395,35656:31232,35657:32e3,35658:24509,35659:35215,35660:35352,35661:36020,35662:36215,35663:36556,35664:36637,35665:39138,35666:39438,35667:39740,35668:20096,35669:20605,35670:20736,35671:22931,35672:23452,35673:25135,35674:25216,35675:25836,35676:27450,35677:29344,35678:30097,35679:31047,35680:32681,35681:34811,35682:35516,35683:35696,35684:25516,35685:33738,35686:38816,35687:21513,35688:21507,35689:21931,35690:26708,35691:27224,35692:35440,35693:30759,35694:26485,35695:40653,35696:21364,35697:23458,35698:33050,35699:34384,35700:36870,35701:19992,35702:20037,35703:20167,35704:20241,35705:21450,35706:21560,35707:23470,35708:24339,35709:24613,35710:25937,35712:26429,35713:27714,35714:27762,35715:27875,35716:28792,35717:29699,35718:31350,35719:31406,35720:31496,35721:32026,35722:31998,35723:32102,35724:26087,35725:29275,35726:21435,35727:23621,35728:24040,35729:25298,35730:25312,35731:25369,35732:28192,35733:34394,35734:35377,35735:36317,35736:37624,35737:28417,35738:31142,35739:39770,35740:20136,35741:20139,35742:20140,35743:20379,35744:20384,35745:20689,35746:20807,35747:31478,35748:20849,35749:20982,35750:21332,35751:21281,35752:21375,35753:21483,35754:21932,35755:22659,35756:23777,35757:24375,35758:24394,35759:24623,35760:24656,35761:24685,35762:25375,35763:25945,35764:27211,35765:27841,35766:29378,35767:29421,35768:30703,35769:33016,35770:33029,35771:33288,35772:34126,35773:37111,35774:37857,35775:38911,35776:39255,35777:39514,35778:20208,35779:20957,35780:23597,35781:26241,35782:26989,35783:23616,35784:26354,35785:26997,35786:29577,35787:26704,35788:31873,35789:20677,35790:21220,35791:22343,35792:24062,35793:37670,35794:26020,35795:27427,35796:27453,35797:29748,35798:31105,35799:31165,35800:31563,35801:32202,35802:33465,35803:33740,35804:34943,35805:35167,35806:35641,35807:36817,35808:37329,35809:21535,35810:37504,35811:20061,35812:20534,35813:21477,35814:21306,35815:29399,35816:29590,35817:30697,35818:33510,35819:36527,35820:39366,35821:39368,35822:39378,35823:20855,35824:24858,35825:34398,35826:21936,35827:31354,35828:20598,35829:23507,35830:36935,35831:38533,35832:20018,35833:27355,35834:37351,35835:23633,35836:23624,35904:25496,35905:31391,35906:27795,35907:38772,35908:36705,35909:31402,35910:29066,35911:38536,35912:31874,35913:26647,35914:32368,35915:26705,35916:37740,35917:21234,35918:21531,35919:34219,35920:35347,35921:32676,35922:36557,35923:37089,35924:21350,35925:34952,35926:31041,35927:20418,35928:20670,35929:21009,35930:20804,35931:21843,35932:22317,35933:29674,35934:22411,35935:22865,35936:24418,35937:24452,35938:24693,35939:24950,35940:24935,35941:25001,35942:25522,35943:25658,35944:25964,35945:26223,35946:26690,35947:28179,35948:30054,35949:31293,35950:31995,35951:32076,35952:32153,35953:32331,35954:32619,35955:33550,35956:33610,35957:34509,35958:35336,35959:35427,35960:35686,35961:36605,35962:38938,35963:40335,35964:33464,35965:36814,35966:39912,35968:21127,35969:25119,35970:25731,35971:28608,35972:38553,35973:26689,35974:20625,35975:27424,35976:27770,35977:28500,35978:31348,35979:32080,35980:34880,35981:35363,35982:26376,35983:20214,35984:20537,35985:20518,35986:20581,35987:20860,35988:21048,35989:21091,35990:21927,35991:22287,35992:22533,35993:23244,35994:24314,35995:25010,35996:25080,35997:25331,35998:25458,35999:26908,36e3:27177,36001:29309,36002:29356,36003:29486,36004:30740,36005:30831,36006:32121,36007:30476,36008:32937,36009:35211,36010:35609,36011:36066,36012:36562,36013:36963,36014:37749,36015:38522,36016:38997,36017:39443,36018:40568,36019:20803,36020:21407,36021:21427,36022:24187,36023:24358,36024:28187,36025:28304,36026:29572,36027:29694,36028:32067,36029:33335,36030:35328,36031:35578,36032:38480,36033:20046,36034:20491,36035:21476,36036:21628,36037:22266,36038:22993,36039:23396,36040:24049,36041:24235,36042:24359,36043:25144,36044:25925,36045:26543,36046:28246,36047:29392,36048:31946,36049:34996,36050:32929,36051:32993,36052:33776,36053:34382,36054:35463,36055:36328,36056:37431,36057:38599,36058:39015,36059:40723,36060:20116,36061:20114,36062:20237,36063:21320,36064:21577,36065:21566,36066:23087,36067:24460,36068:24481,36069:24735,36070:26791,36071:27278,36072:29786,36073:30849,36074:35486,36075:35492,36076:35703,36077:37264,36078:20062,36079:39881,36080:20132,36081:20348,36082:20399,36083:20505,36084:20502,36085:20809,36086:20844,36087:21151,36088:21177,36089:21246,36090:21402,36091:21475,36092:21521,36160:21518,36161:21897,36162:22353,36163:22434,36164:22909,36165:23380,36166:23389,36167:23439,36168:24037,36169:24039,36170:24055,36171:24184,36172:24195,36173:24218,36174:24247,36175:24344,36176:24658,36177:24908,36178:25239,36179:25304,36180:25511,36181:25915,36182:26114,36183:26179,36184:26356,36185:26477,36186:26657,36187:26775,36188:27083,36189:27743,36190:27946,36191:28009,36192:28207,36193:28317,36194:30002,36195:30343,36196:30828,36197:31295,36198:31968,36199:32005,36200:32024,36201:32094,36202:32177,36203:32789,36204:32771,36205:32943,36206:32945,36207:33108,36208:33167,36209:33322,36210:33618,36211:34892,36212:34913,36213:35611,36214:36002,36215:36092,36216:37066,36217:37237,36218:37489,36219:30783,36220:37628,36221:38308,36222:38477,36224:38917,36225:39321,36226:39640,36227:40251,36228:21083,36229:21163,36230:21495,36231:21512,36232:22741,36233:25335,36234:28640,36235:35946,36236:36703,36237:40633,36238:20811,36239:21051,36240:21578,36241:22269,36242:31296,36243:37239,36244:40288,36245:40658,36246:29508,36247:28425,36248:33136,36249:29969,36250:24573,36251:24794,36252:39592,36253:29403,36254:36796,36255:27492,36256:38915,36257:20170,36258:22256,36259:22372,36260:22718,36261:23130,36262:24680,36263:25031,36264:26127,36265:26118,36266:26681,36267:26801,36268:28151,36269:30165,36270:32058,36271:33390,36272:39746,36273:20123,36274:20304,36275:21449,36276:21766,36277:23919,36278:24038,36279:24046,36280:26619,36281:27801,36282:29811,36283:30722,36284:35408,36285:37782,36286:35039,36287:22352,36288:24231,36289:25387,36290:20661,36291:20652,36292:20877,36293:26368,36294:21705,36295:22622,36296:22971,36297:23472,36298:24425,36299:25165,36300:25505,36301:26685,36302:27507,36303:28168,36304:28797,36305:37319,36306:29312,36307:30741,36308:30758,36309:31085,36310:25998,36311:32048,36312:33756,36313:35009,36314:36617,36315:38555,36316:21092,36317:22312,36318:26448,36319:32618,36320:36001,36321:20916,36322:22338,36323:38442,36324:22586,36325:27018,36326:32948,36327:21682,36328:23822,36329:22524,36330:30869,36331:40442,36332:20316,36333:21066,36334:21643,36335:25662,36336:26152,36337:26388,36338:26613,36339:31364,36340:31574,36341:32034,36342:37679,36343:26716,36344:39853,36345:31545,36346:21273,36347:20874,36348:21047,36416:23519,36417:25334,36418:25774,36419:25830,36420:26413,36421:27578,36422:34217,36423:38609,36424:30352,36425:39894,36426:25420,36427:37638,36428:39851,36429:30399,36430:26194,36431:19977,36432:20632,36433:21442,36434:23665,36435:24808,36436:25746,36437:25955,36438:26719,36439:29158,36440:29642,36441:29987,36442:31639,36443:32386,36444:34453,36445:35715,36446:36059,36447:37240,36448:39184,36449:26028,36450:26283,36451:27531,36452:20181,36453:20180,36454:20282,36455:20351,36456:21050,36457:21496,36458:21490,36459:21987,36460:22235,36461:22763,36462:22987,36463:22985,36464:23039,36465:23376,36466:23629,36467:24066,36468:24107,36469:24535,36470:24605,36471:25351,36472:25903,36473:23388,36474:26031,36475:26045,36476:26088,36477:26525,36478:27490,36480:27515,36481:27663,36482:29509,36483:31049,36484:31169,36485:31992,36486:32025,36487:32043,36488:32930,36489:33026,36490:33267,36491:35222,36492:35422,36493:35433,36494:35430,36495:35468,36496:35566,36497:36039,36498:36060,36499:38604,36500:39164,36501:27503,36502:20107,36503:20284,36504:20365,36505:20816,36506:23383,36507:23546,36508:24904,36509:25345,36510:26178,36511:27425,36512:28363,36513:27835,36514:29246,36515:29885,36516:30164,36517:30913,36518:31034,36519:32780,36520:32819,36521:33258,36522:33940,36523:36766,36524:27728,36525:40575,36526:24335,36527:35672,36528:40235,36529:31482,36530:36600,36531:23437,36532:38635,36533:19971,36534:21489,36535:22519,36536:22833,36537:23241,36538:23460,36539:24713,36540:28287,36541:28422,36542:30142,36543:36074,36544:23455,36545:34048,36546:31712,36547:20594,36548:26612,36549:33437,36550:23649,36551:34122,36552:32286,36553:33294,36554:20889,36555:23556,36556:25448,36557:36198,36558:26012,36559:29038,36560:31038,36561:32023,36562:32773,36563:35613,36564:36554,36565:36974,36566:34503,36567:37034,36568:20511,36569:21242,36570:23610,36571:26451,36572:28796,36573:29237,36574:37196,36575:37320,36576:37675,36577:33509,36578:23490,36579:24369,36580:24825,36581:20027,36582:21462,36583:23432,36584:25163,36585:26417,36586:27530,36587:29417,36588:29664,36589:31278,36590:33131,36591:36259,36592:37202,36593:39318,36594:20754,36595:21463,36596:21610,36597:23551,36598:25480,36599:27193,36600:32172,36601:38656,36602:22234,36603:21454,36604:21608,36672:23447,36673:23601,36674:24030,36675:20462,36676:24833,36677:25342,36678:27954,36679:31168,36680:31179,36681:32066,36682:32333,36683:32722,36684:33261,36685:33311,36686:33936,36687:34886,36688:35186,36689:35728,36690:36468,36691:36655,36692:36913,36693:37195,36694:37228,36695:38598,36696:37276,36697:20160,36698:20303,36699:20805,36700:21313,36701:24467,36702:25102,36703:26580,36704:27713,36705:28171,36706:29539,36707:32294,36708:37325,36709:37507,36710:21460,36711:22809,36712:23487,36713:28113,36714:31069,36715:32302,36716:31899,36717:22654,36718:29087,36719:20986,36720:34899,36721:36848,36722:20426,36723:23803,36724:26149,36725:30636,36726:31459,36727:33308,36728:39423,36729:20934,36730:24490,36731:26092,36732:26991,36733:27529,36734:28147,36736:28310,36737:28516,36738:30462,36739:32020,36740:24033,36741:36981,36742:37255,36743:38918,36744:20966,36745:21021,36746:25152,36747:26257,36748:26329,36749:28186,36750:24246,36751:32210,36752:32626,36753:26360,36754:34223,36755:34295,36756:35576,36757:21161,36758:21465,36759:22899,36760:24207,36761:24464,36762:24661,36763:37604,36764:38500,36765:20663,36766:20767,36767:21213,36768:21280,36769:21319,36770:21484,36771:21736,36772:21830,36773:21809,36774:22039,36775:22888,36776:22974,36777:23100,36778:23477,36779:23558,36780:23567,36781:23569,36782:23578,36783:24196,36784:24202,36785:24288,36786:24432,36787:25215,36788:25220,36789:25307,36790:25484,36791:25463,36792:26119,36793:26124,36794:26157,36795:26230,36796:26494,36797:26786,36798:27167,36799:27189,36800:27836,36801:28040,36802:28169,36803:28248,36804:28988,36805:28966,36806:29031,36807:30151,36808:30465,36809:30813,36810:30977,36811:31077,36812:31216,36813:31456,36814:31505,36815:31911,36816:32057,36817:32918,36818:33750,36819:33931,36820:34121,36821:34909,36822:35059,36823:35359,36824:35388,36825:35412,36826:35443,36827:35937,36828:36062,36829:37284,36830:37478,36831:37758,36832:37912,36833:38556,36834:38808,36835:19978,36836:19976,36837:19998,36838:20055,36839:20887,36840:21104,36841:22478,36842:22580,36843:22732,36844:23330,36845:24120,36846:24773,36847:25854,36848:26465,36849:26454,36850:27972,36851:29366,36852:30067,36853:31331,36854:33976,36855:35698,36856:37304,36857:37664,36858:22065,36859:22516,36860:39166,36928:25325,36929:26893,36930:27542,36931:29165,36932:32340,36933:32887,36934:33394,36935:35302,36936:39135,36937:34645,36938:36785,36939:23611,36940:20280,36941:20449,36942:20405,36943:21767,36944:23072,36945:23517,36946:23529,36947:24515,36948:24910,36949:25391,36950:26032,36951:26187,36952:26862,36953:27035,36954:28024,36955:28145,36956:30003,36957:30137,36958:30495,36959:31070,36960:31206,36961:32051,36962:33251,36963:33455,36964:34218,36965:35242,36966:35386,36967:36523,36968:36763,36969:36914,36970:37341,36971:38663,36972:20154,36973:20161,36974:20995,36975:22645,36976:22764,36977:23563,36978:29978,36979:23613,36980:33102,36981:35338,36982:36805,36983:38499,36984:38765,36985:31525,36986:35535,36987:38920,36988:37218,36989:22259,36990:21416,36992:36887,36993:21561,36994:22402,36995:24101,36996:25512,36997:27700,36998:28810,36999:30561,37e3:31883,37001:32736,37002:34928,37003:36930,37004:37204,37005:37648,37006:37656,37007:38543,37008:29790,37009:39620,37010:23815,37011:23913,37012:25968,37013:26530,37014:36264,37015:38619,37016:25454,37017:26441,37018:26905,37019:33733,37020:38935,37021:38592,37022:35070,37023:28548,37024:25722,37025:23544,37026:19990,37027:28716,37028:30045,37029:26159,37030:20932,37031:21046,37032:21218,37033:22995,37034:24449,37035:24615,37036:25104,37037:25919,37038:25972,37039:26143,37040:26228,37041:26866,37042:26646,37043:27491,37044:28165,37045:29298,37046:29983,37047:30427,37048:31934,37049:32854,37050:22768,37051:35069,37052:35199,37053:35488,37054:35475,37055:35531,37056:36893,37057:37266,37058:38738,37059:38745,37060:25993,37061:31246,37062:33030,37063:38587,37064:24109,37065:24796,37066:25114,37067:26021,37068:26132,37069:26512,37070:30707,37071:31309,37072:31821,37073:32318,37074:33034,37075:36012,37076:36196,37077:36321,37078:36447,37079:30889,37080:20999,37081:25305,37082:25509,37083:25666,37084:25240,37085:35373,37086:31363,37087:31680,37088:35500,37089:38634,37090:32118,37091:33292,37092:34633,37093:20185,37094:20808,37095:21315,37096:21344,37097:23459,37098:23554,37099:23574,37100:24029,37101:25126,37102:25159,37103:25776,37104:26643,37105:26676,37106:27849,37107:27973,37108:27927,37109:26579,37110:28508,37111:29006,37112:29053,37113:26059,37114:31359,37115:31661,37116:32218,37184:32330,37185:32680,37186:33146,37187:33307,37188:33337,37189:34214,37190:35438,37191:36046,37192:36341,37193:36984,37194:36983,37195:37549,37196:37521,37197:38275,37198:39854,37199:21069,37200:21892,37201:28472,37202:28982,37203:20840,37204:31109,37205:32341,37206:33203,37207:31950,37208:22092,37209:22609,37210:23720,37211:25514,37212:26366,37213:26365,37214:26970,37215:29401,37216:30095,37217:30094,37218:30990,37219:31062,37220:31199,37221:31895,37222:32032,37223:32068,37224:34311,37225:35380,37226:38459,37227:36961,37228:40736,37229:20711,37230:21109,37231:21452,37232:21474,37233:20489,37234:21930,37235:22766,37236:22863,37237:29245,37238:23435,37239:23652,37240:21277,37241:24803,37242:24819,37243:25436,37244:25475,37245:25407,37246:25531,37248:25805,37249:26089,37250:26361,37251:24035,37252:27085,37253:27133,37254:28437,37255:29157,37256:20105,37257:30185,37258:30456,37259:31379,37260:31967,37261:32207,37262:32156,37263:32865,37264:33609,37265:33624,37266:33900,37267:33980,37268:34299,37269:35013,37270:36208,37271:36865,37272:36973,37273:37783,37274:38684,37275:39442,37276:20687,37277:22679,37278:24974,37279:33235,37280:34101,37281:36104,37282:36896,37283:20419,37284:20596,37285:21063,37286:21363,37287:24687,37288:25417,37289:26463,37290:28204,37291:36275,37292:36895,37293:20439,37294:23646,37295:36042,37296:26063,37297:32154,37298:21330,37299:34966,37300:20854,37301:25539,37302:23384,37303:23403,37304:23562,37305:25613,37306:26449,37307:36956,37308:20182,37309:22810,37310:22826,37311:27760,37312:35409,37313:21822,37314:22549,37315:22949,37316:24816,37317:25171,37318:26561,37319:33333,37320:26965,37321:38464,37322:39364,37323:39464,37324:20307,37325:22534,37326:23550,37327:32784,37328:23729,37329:24111,37330:24453,37331:24608,37332:24907,37333:25140,37334:26367,37335:27888,37336:28382,37337:32974,37338:33151,37339:33492,37340:34955,37341:36024,37342:36864,37343:36910,37344:38538,37345:40667,37346:39899,37347:20195,37348:21488,37349:22823,37350:31532,37351:37261,37352:38988,37353:40441,37354:28381,37355:28711,37356:21331,37357:21828,37358:23429,37359:25176,37360:25246,37361:25299,37362:27810,37363:28655,37364:29730,37365:35351,37366:37944,37367:28609,37368:35582,37369:33592,37370:20967,37371:34552,37372:21482,37440:21481,37441:20294,37442:36948,37443:36784,37444:22890,37445:33073,37446:24061,37447:31466,37448:36799,37449:26842,37450:35895,37451:29432,37452:40008,37453:27197,37454:35504,37455:20025,37456:21336,37457:22022,37458:22374,37459:25285,37460:25506,37461:26086,37462:27470,37463:28129,37464:28251,37465:28845,37466:30701,37467:31471,37468:31658,37469:32187,37470:32829,37471:32966,37472:34507,37473:35477,37474:37723,37475:22243,37476:22727,37477:24382,37478:26029,37479:26262,37480:27264,37481:27573,37482:30007,37483:35527,37484:20516,37485:30693,37486:22320,37487:24347,37488:24677,37489:26234,37490:27744,37491:30196,37492:31258,37493:32622,37494:33268,37495:34584,37496:36933,37497:39347,37498:31689,37499:30044,37500:31481,37501:31569,37502:33988,37504:36880,37505:31209,37506:31378,37507:33590,37508:23265,37509:30528,37510:20013,37511:20210,37512:23449,37513:24544,37514:25277,37515:26172,37516:26609,37517:27880,37518:34411,37519:34935,37520:35387,37521:37198,37522:37619,37523:39376,37524:27159,37525:28710,37526:29482,37527:33511,37528:33879,37529:36015,37530:19969,37531:20806,37532:20939,37533:21899,37534:23541,37535:24086,37536:24115,37537:24193,37538:24340,37539:24373,37540:24427,37541:24500,37542:25074,37543:25361,37544:26274,37545:26397,37546:28526,37547:29266,37548:30010,37549:30522,37550:32884,37551:33081,37552:33144,37553:34678,37554:35519,37555:35548,37556:36229,37557:36339,37558:37530,37559:38263,37560:38914,37561:40165,37562:21189,37563:25431,37564:30452,37565:26389,37566:27784,37567:29645,37568:36035,37569:37806,37570:38515,37571:27941,37572:22684,37573:26894,37574:27084,37575:36861,37576:37786,37577:30171,37578:36890,37579:22618,37580:26626,37581:25524,37582:27131,37583:20291,37584:28460,37585:26584,37586:36795,37587:34086,37588:32180,37589:37716,37590:26943,37591:28528,37592:22378,37593:22775,37594:23340,37595:32044,37596:29226,37597:21514,37598:37347,37599:40372,37600:20141,37601:20302,37602:20572,37603:20597,37604:21059,37605:35998,37606:21576,37607:22564,37608:23450,37609:24093,37610:24213,37611:24237,37612:24311,37613:24351,37614:24716,37615:25269,37616:25402,37617:25552,37618:26799,37619:27712,37620:30855,37621:31118,37622:31243,37623:32224,37624:33351,37625:35330,37626:35558,37627:36420,37628:36883,37696:37048,37697:37165,37698:37336,37699:40718,37700:27877,37701:25688,37702:25826,37703:25973,37704:28404,37705:30340,37706:31515,37707:36969,37708:37841,37709:28346,37710:21746,37711:24505,37712:25764,37713:36685,37714:36845,37715:37444,37716:20856,37717:22635,37718:22825,37719:23637,37720:24215,37721:28155,37722:32399,37723:29980,37724:36028,37725:36578,37726:39003,37727:28857,37728:20253,37729:27583,37730:28593,37731:3e4,37732:38651,37733:20814,37734:21520,37735:22581,37736:22615,37737:22956,37738:23648,37739:24466,37740:26007,37741:26460,37742:28193,37743:30331,37744:33759,37745:36077,37746:36884,37747:37117,37748:37709,37749:30757,37750:30778,37751:21162,37752:24230,37753:22303,37754:22900,37755:24594,37756:20498,37757:20826,37758:20908,37760:20941,37761:20992,37762:21776,37763:22612,37764:22616,37765:22871,37766:23445,37767:23798,37768:23947,37769:24764,37770:25237,37771:25645,37772:26481,37773:26691,37774:26812,37775:26847,37776:30423,37777:28120,37778:28271,37779:28059,37780:28783,37781:29128,37782:24403,37783:30168,37784:31095,37785:31561,37786:31572,37787:31570,37788:31958,37789:32113,37790:21040,37791:33891,37792:34153,37793:34276,37794:35342,37795:35588,37796:35910,37797:36367,37798:36867,37799:36879,37800:37913,37801:38518,37802:38957,37803:39472,37804:38360,37805:20685,37806:21205,37807:21516,37808:22530,37809:23566,37810:24999,37811:25758,37812:27934,37813:30643,37814:31461,37815:33012,37816:33796,37817:36947,37818:37509,37819:23776,37820:40199,37821:21311,37822:24471,37823:24499,37824:28060,37825:29305,37826:30563,37827:31167,37828:31716,37829:27602,37830:29420,37831:35501,37832:26627,37833:27233,37834:20984,37835:31361,37836:26932,37837:23626,37838:40182,37839:33515,37840:23493,37841:37193,37842:28702,37843:22136,37844:23663,37845:24775,37846:25958,37847:27788,37848:35930,37849:36929,37850:38931,37851:21585,37852:26311,37853:37389,37854:22856,37855:37027,37856:20869,37857:20045,37858:20970,37859:34201,37860:35598,37861:28760,37862:25466,37863:37707,37864:26978,37865:39348,37866:32260,37867:30071,37868:21335,37869:26976,37870:36575,37871:38627,37872:27741,37873:20108,37874:23612,37875:24336,37876:36841,37877:21250,37878:36049,37879:32905,37880:34425,37881:24319,37882:26085,37883:20083,37884:20837,37952:22914,37953:23615,37954:38894,37955:20219,37956:22922,37957:24525,37958:35469,37959:28641,37960:31152,37961:31074,37962:23527,37963:33905,37964:29483,37965:29105,37966:24180,37967:24565,37968:25467,37969:25754,37970:29123,37971:31896,37972:20035,37973:24316,37974:20043,37975:22492,37976:22178,37977:24745,37978:28611,37979:32013,37980:33021,37981:33075,37982:33215,37983:36786,37984:35223,37985:34468,37986:24052,37987:25226,37988:25773,37989:35207,37990:26487,37991:27874,37992:27966,37993:29750,37994:30772,37995:23110,37996:32629,37997:33453,37998:39340,37999:20467,38e3:24259,38001:25309,38002:25490,38003:25943,38004:26479,38005:30403,38006:29260,38007:32972,38008:32954,38009:36649,38010:37197,38011:20493,38012:22521,38013:23186,38014:26757,38016:26995,38017:29028,38018:29437,38019:36023,38020:22770,38021:36064,38022:38506,38023:36889,38024:34687,38025:31204,38026:30695,38027:33833,38028:20271,38029:21093,38030:21338,38031:25293,38032:26575,38033:27850,38034:30333,38035:31636,38036:31893,38037:33334,38038:34180,38039:36843,38040:26333,38041:28448,38042:29190,38043:32283,38044:33707,38045:39361,38046:40614,38047:20989,38048:31665,38049:30834,38050:31672,38051:32903,38052:31560,38053:27368,38054:24161,38055:32908,38056:30033,38057:30048,38058:20843,38059:37474,38060:28300,38061:30330,38062:37271,38063:39658,38064:20240,38065:32624,38066:25244,38067:31567,38068:38309,38069:40169,38070:22138,38071:22617,38072:34532,38073:38588,38074:20276,38075:21028,38076:21322,38077:21453,38078:21467,38079:24070,38080:25644,38081:26001,38082:26495,38083:27710,38084:27726,38085:29256,38086:29359,38087:29677,38088:30036,38089:32321,38090:33324,38091:34281,38092:36009,38093:31684,38094:37318,38095:29033,38096:38930,38097:39151,38098:25405,38099:26217,38100:30058,38101:30436,38102:30928,38103:34115,38104:34542,38105:21290,38106:21329,38107:21542,38108:22915,38109:24199,38110:24444,38111:24754,38112:25161,38113:25209,38114:25259,38115:26e3,38116:27604,38117:27852,38118:30130,38119:30382,38120:30865,38121:31192,38122:32203,38123:32631,38124:32933,38125:34987,38126:35513,38127:36027,38128:36991,38129:38750,38130:39131,38131:27147,38132:31800,38133:20633,38134:23614,38135:24494,38136:26503,38137:27608,38138:29749,38139:30473,38140:32654,38208:40763,38209:26570,38210:31255,38211:21305,38212:30091,38213:39661,38214:24422,38215:33181,38216:33777,38217:32920,38218:24380,38219:24517,38220:30050,38221:31558,38222:36924,38223:26727,38224:23019,38225:23195,38226:32016,38227:30334,38228:35628,38229:20469,38230:24426,38231:27161,38232:27703,38233:28418,38234:29922,38235:31080,38236:34920,38237:35413,38238:35961,38239:24287,38240:25551,38241:30149,38242:31186,38243:33495,38244:37672,38245:37618,38246:33948,38247:34541,38248:39981,38249:21697,38250:24428,38251:25996,38252:27996,38253:28693,38254:36007,38255:36051,38256:38971,38257:25935,38258:29942,38259:19981,38260:20184,38261:22496,38262:22827,38263:23142,38264:23500,38265:20904,38266:24067,38267:24220,38268:24598,38269:25206,38270:25975,38272:26023,38273:26222,38274:28014,38275:29238,38276:31526,38277:33104,38278:33178,38279:33433,38280:35676,38281:36e3,38282:36070,38283:36212,38284:38428,38285:38468,38286:20398,38287:25771,38288:27494,38289:33310,38290:33889,38291:34154,38292:37096,38293:23553,38294:26963,38295:39080,38296:33914,38297:34135,38298:20239,38299:21103,38300:24489,38301:24133,38302:26381,38303:31119,38304:33145,38305:35079,38306:35206,38307:28149,38308:24343,38309:25173,38310:27832,38311:20175,38312:29289,38313:39826,38314:20998,38315:21563,38316:22132,38317:22707,38318:24996,38319:25198,38320:28954,38321:22894,38322:31881,38323:31966,38324:32027,38325:38640,38326:25991,38327:32862,38328:19993,38329:20341,38330:20853,38331:22592,38332:24163,38333:24179,38334:24330,38335:26564,38336:20006,38337:34109,38338:38281,38339:38491,38340:31859,38341:38913,38342:20731,38343:22721,38344:30294,38345:30887,38346:21029,38347:30629,38348:34065,38349:31622,38350:20559,38351:22793,38352:29255,38353:31687,38354:32232,38355:36794,38356:36820,38357:36941,38358:20415,38359:21193,38360:23081,38361:24321,38362:38829,38363:20445,38364:33303,38365:37610,38366:22275,38367:25429,38368:27497,38369:29995,38370:35036,38371:36628,38372:31298,38373:21215,38374:22675,38375:24917,38376:25098,38377:26286,38378:27597,38379:31807,38380:33769,38381:20515,38382:20472,38383:21253,38384:21574,38385:22577,38386:22857,38387:23453,38388:23792,38389:23791,38390:23849,38391:24214,38392:25265,38393:25447,38394:25918,38395:26041,38396:26379,38464:27861,38465:27873,38466:28921,38467:30770,38468:32299,38469:32990,38470:33459,38471:33804,38472:34028,38473:34562,38474:35090,38475:35370,38476:35914,38477:37030,38478:37586,38479:39165,38480:40179,38481:40300,38482:20047,38483:20129,38484:20621,38485:21078,38486:22346,38487:22952,38488:24125,38489:24536,38490:24537,38491:25151,38492:26292,38493:26395,38494:26576,38495:26834,38496:20882,38497:32033,38498:32938,38499:33192,38500:35584,38501:35980,38502:36031,38503:37502,38504:38450,38505:21536,38506:38956,38507:21271,38508:20693,38509:21340,38510:22696,38511:25778,38512:26420,38513:29287,38514:30566,38515:31302,38516:37350,38517:21187,38518:27809,38519:27526,38520:22528,38521:24140,38522:22868,38523:26412,38524:32763,38525:20961,38526:30406,38528:25705,38529:30952,38530:39764,38531:40635,38532:22475,38533:22969,38534:26151,38535:26522,38536:27598,38537:21737,38538:27097,38539:24149,38540:33180,38541:26517,38542:39850,38543:26622,38544:40018,38545:26717,38546:20134,38547:20451,38548:21448,38549:25273,38550:26411,38551:27819,38552:36804,38553:20397,38554:32365,38555:40639,38556:19975,38557:24930,38558:28288,38559:28459,38560:34067,38561:21619,38562:26410,38563:39749,38564:24051,38565:31637,38566:23724,38567:23494,38568:34588,38569:28234,38570:34001,38571:31252,38572:33032,38573:22937,38574:31885,38575:27665,38576:30496,38577:21209,38578:22818,38579:28961,38580:29279,38581:30683,38582:38695,38583:40289,38584:26891,38585:23167,38586:23064,38587:20901,38588:21517,38589:21629,38590:26126,38591:30431,38592:36855,38593:37528,38594:40180,38595:23018,38596:29277,38597:28357,38598:20813,38599:26825,38600:32191,38601:32236,38602:38754,38603:40634,38604:25720,38605:27169,38606:33538,38607:22916,38608:23391,38609:27611,38610:29467,38611:30450,38612:32178,38613:32791,38614:33945,38615:20786,38616:26408,38617:40665,38618:30446,38619:26466,38620:21247,38621:39173,38622:23588,38623:25147,38624:31870,38625:36016,38626:21839,38627:24758,38628:32011,38629:38272,38630:21249,38631:20063,38632:20918,38633:22812,38634:29242,38635:32822,38636:37326,38637:24357,38638:30690,38639:21380,38640:24441,38641:32004,38642:34220,38643:35379,38644:36493,38645:38742,38646:26611,38647:34222,38648:37971,38649:24841,38650:24840,38651:27833,38652:30290,38720:35565,38721:36664,38722:21807,38723:20305,38724:20778,38725:21191,38726:21451,38727:23461,38728:24189,38729:24736,38730:24962,38731:25558,38732:26377,38733:26586,38734:28263,38735:28044,38736:29494,38737:29495,38738:30001,38739:31056,38740:35029,38741:35480,38742:36938,38743:37009,38744:37109,38745:38596,38746:34701,38747:22805,38748:20104,38749:20313,38750:19982,38751:35465,38752:36671,38753:38928,38754:20653,38755:24188,38756:22934,38757:23481,38758:24248,38759:25562,38760:25594,38761:25793,38762:26332,38763:26954,38764:27096,38765:27915,38766:28342,38767:29076,38768:29992,38769:31407,38770:32650,38771:32768,38772:33865,38773:33993,38774:35201,38775:35617,38776:36362,38777:36965,38778:38525,38779:39178,38780:24958,38781:25233,38782:27442,38784:27779,38785:28020,38786:32716,38787:32764,38788:28096,38789:32645,38790:34746,38791:35064,38792:26469,38793:33713,38794:38972,38795:38647,38796:27931,38797:32097,38798:33853,38799:37226,38800:20081,38801:21365,38802:23888,38803:27396,38804:28651,38805:34253,38806:34349,38807:35239,38808:21033,38809:21519,38810:23653,38811:26446,38812:26792,38813:29702,38814:29827,38815:30178,38816:35023,38817:35041,38818:37324,38819:38626,38820:38520,38821:24459,38822:29575,38823:31435,38824:33870,38825:25504,38826:30053,38827:21129,38828:27969,38829:28316,38830:29705,38831:30041,38832:30827,38833:31890,38834:38534,38835:31452,38836:40845,38837:20406,38838:24942,38839:26053,38840:34396,38841:20102,38842:20142,38843:20698,38844:20001,38845:20940,38846:23534,38847:26009,38848:26753,38849:28092,38850:29471,38851:30274,38852:30637,38853:31260,38854:31975,38855:33391,38856:35538,38857:36988,38858:37327,38859:38517,38860:38936,38861:21147,38862:32209,38863:20523,38864:21400,38865:26519,38866:28107,38867:29136,38868:29747,38869:33256,38870:36650,38871:38563,38872:40023,38873:40607,38874:29792,38875:22593,38876:28057,38877:32047,38878:39006,38879:20196,38880:20278,38881:20363,38882:20919,38883:21169,38884:23994,38885:24604,38886:29618,38887:31036,38888:33491,38889:37428,38890:38583,38891:38646,38892:38666,38893:40599,38894:40802,38895:26278,38896:27508,38897:21015,38898:21155,38899:28872,38900:35010,38901:24265,38902:24651,38903:24976,38904:28451,38905:29001,38906:31806,38907:32244,38908:32879,38976:34030,38977:36899,38978:37676,38979:21570,38980:39791,38981:27347,38982:28809,38983:36034,38984:36335,38985:38706,38986:21172,38987:23105,38988:24266,38989:24324,38990:26391,38991:27004,38992:27028,38993:28010,38994:28431,38995:29282,38996:29436,38997:31725,38998:32769,38999:32894,39e3:34635,39001:37070,39002:20845,39003:40595,39004:31108,39005:32907,39006:37682,39007:35542,39008:20525,39009:21644,39010:35441,39011:27498,39012:36036,39013:33031,39014:24785,39015:26528,39016:40434,39017:20121,39018:20120,39019:39952,39020:35435,39021:34241,39022:34152,39023:26880,39024:28286,39025:30871,39026:33109,39071:24332,39072:19984,39073:19989,39074:20010,39075:20017,39076:20022,39077:20028,39078:20031,39079:20034,39080:20054,39081:20056,39082:20098,39083:20101,39084:35947,39085:20106,39086:33298,39087:24333,39088:20110,39089:20126,39090:20127,39091:20128,39092:20130,39093:20144,39094:20147,39095:20150,39096:20174,39097:20173,39098:20164,39099:20166,39100:20162,39101:20183,39102:20190,39103:20205,39104:20191,39105:20215,39106:20233,39107:20314,39108:20272,39109:20315,39110:20317,39111:20311,39112:20295,39113:20342,39114:20360,39115:20367,39116:20376,39117:20347,39118:20329,39119:20336,39120:20369,39121:20335,39122:20358,39123:20374,39124:20760,39125:20436,39126:20447,39127:20430,39128:20440,39129:20443,39130:20433,39131:20442,39132:20432,39133:20452,39134:20453,39135:20506,39136:20520,39137:20500,39138:20522,39139:20517,39140:20485,39141:20252,39142:20470,39143:20513,39144:20521,39145:20524,39146:20478,39147:20463,39148:20497,39149:20486,39150:20547,39151:20551,39152:26371,39153:20565,39154:20560,39155:20552,39156:20570,39157:20566,39158:20588,39159:20600,39160:20608,39161:20634,39162:20613,39163:20660,39164:20658,39232:20681,39233:20682,39234:20659,39235:20674,39236:20694,39237:20702,39238:20709,39239:20717,39240:20707,39241:20718,39242:20729,39243:20725,39244:20745,39245:20737,39246:20738,39247:20758,39248:20757,39249:20756,39250:20762,39251:20769,39252:20794,39253:20791,39254:20796,39255:20795,39256:20799,39257:20800,39258:20818,39259:20812,39260:20820,39261:20834,39262:31480,39263:20841,39264:20842,39265:20846,39266:20864,39267:20866,39268:22232,39269:20876,39270:20873,39271:20879,39272:20881,39273:20883,39274:20885,39275:20886,39276:20900,39277:20902,39278:20898,39279:20905,39280:20906,39281:20907,39282:20915,39283:20913,39284:20914,39285:20912,39286:20917,39287:20925,39288:20933,39289:20937,39290:20955,39291:20960,39292:34389,39293:20969,39294:20973,39296:20976,39297:20981,39298:20990,39299:20996,39300:21003,39301:21012,39302:21006,39303:21031,39304:21034,39305:21038,39306:21043,39307:21049,39308:21071,39309:21060,39310:21067,39311:21068,39312:21086,39313:21076,39314:21098,39315:21108,39316:21097,39317:21107,39318:21119,39319:21117,39320:21133,39321:21140,39322:21138,39323:21105,39324:21128,39325:21137,39326:36776,39327:36775,39328:21164,39329:21165,39330:21180,39331:21173,39332:21185,39333:21197,39334:21207,39335:21214,39336:21219,39337:21222,39338:39149,39339:21216,39340:21235,39341:21237,39342:21240,39343:21241,39344:21254,39345:21256,39346:30008,39347:21261,39348:21264,39349:21263,39350:21269,39351:21274,39352:21283,39353:21295,39354:21297,39355:21299,39356:21304,39357:21312,39358:21318,39359:21317,39360:19991,39361:21321,39362:21325,39363:20950,39364:21342,39365:21353,39366:21358,39367:22808,39368:21371,39369:21367,39370:21378,39371:21398,39372:21408,39373:21414,39374:21413,39375:21422,39376:21424,39377:21430,39378:21443,39379:31762,39380:38617,39381:21471,39382:26364,39383:29166,39384:21486,39385:21480,39386:21485,39387:21498,39388:21505,39389:21565,39390:21568,39391:21548,39392:21549,39393:21564,39394:21550,39395:21558,39396:21545,39397:21533,39398:21582,39399:21647,39400:21621,39401:21646,39402:21599,39403:21617,39404:21623,39405:21616,39406:21650,39407:21627,39408:21632,39409:21622,39410:21636,39411:21648,39412:21638,39413:21703,39414:21666,39415:21688,39416:21669,39417:21676,39418:21700,39419:21704,39420:21672,39488:21675,39489:21698,39490:21668,39491:21694,39492:21692,39493:21720,39494:21733,39495:21734,39496:21775,39497:21780,39498:21757,39499:21742,39500:21741,39501:21754,39502:21730,39503:21817,39504:21824,39505:21859,39506:21836,39507:21806,39508:21852,39509:21829,39510:21846,39511:21847,39512:21816,39513:21811,39514:21853,39515:21913,39516:21888,39517:21679,39518:21898,39519:21919,39520:21883,39521:21886,39522:21912,39523:21918,39524:21934,39525:21884,39526:21891,39527:21929,39528:21895,39529:21928,39530:21978,39531:21957,39532:21983,39533:21956,39534:21980,39535:21988,39536:21972,39537:22036,39538:22007,39539:22038,39540:22014,39541:22013,39542:22043,39543:22009,39544:22094,39545:22096,39546:29151,39547:22068,39548:22070,39549:22066,39550:22072,39552:22123,39553:22116,39554:22063,39555:22124,39556:22122,39557:22150,39558:22144,39559:22154,39560:22176,39561:22164,39562:22159,39563:22181,39564:22190,39565:22198,39566:22196,39567:22210,39568:22204,39569:22209,39570:22211,39571:22208,39572:22216,39573:22222,39574:22225,39575:22227,39576:22231,39577:22254,39578:22265,39579:22272,39580:22271,39581:22276,39582:22281,39583:22280,39584:22283,39585:22285,39586:22291,39587:22296,39588:22294,39589:21959,39590:22300,39591:22310,39592:22327,39593:22328,39594:22350,39595:22331,39596:22336,39597:22351,39598:22377,39599:22464,39600:22408,39601:22369,39602:22399,39603:22409,39604:22419,39605:22432,39606:22451,39607:22436,39608:22442,39609:22448,39610:22467,39611:22470,39612:22484,39613:22482,39614:22483,39615:22538,39616:22486,39617:22499,39618:22539,39619:22553,39620:22557,39621:22642,39622:22561,39623:22626,39624:22603,39625:22640,39626:27584,39627:22610,39628:22589,39629:22649,39630:22661,39631:22713,39632:22687,39633:22699,39634:22714,39635:22750,39636:22715,39637:22712,39638:22702,39639:22725,39640:22739,39641:22737,39642:22743,39643:22745,39644:22744,39645:22757,39646:22748,39647:22756,39648:22751,39649:22767,39650:22778,39651:22777,39652:22779,39653:22780,39654:22781,39655:22786,39656:22794,39657:22800,39658:22811,39659:26790,39660:22821,39661:22828,39662:22829,39663:22834,39664:22840,39665:22846,39666:31442,39667:22869,39668:22864,39669:22862,39670:22874,39671:22872,39672:22882,39673:22880,39674:22887,39675:22892,39676:22889,39744:22904,39745:22913,39746:22941,39747:20318,39748:20395,39749:22947,39750:22962,39751:22982,39752:23016,39753:23004,39754:22925,39755:23001,39756:23002,39757:23077,39758:23071,39759:23057,39760:23068,39761:23049,39762:23066,39763:23104,39764:23148,39765:23113,39766:23093,39767:23094,39768:23138,39769:23146,39770:23194,39771:23228,39772:23230,39773:23243,39774:23234,39775:23229,39776:23267,39777:23255,39778:23270,39779:23273,39780:23254,39781:23290,39782:23291,39783:23308,39784:23307,39785:23318,39786:23346,39787:23248,39788:23338,39789:23350,39790:23358,39791:23363,39792:23365,39793:23360,39794:23377,39795:23381,39796:23386,39797:23387,39798:23397,39799:23401,39800:23408,39801:23411,39802:23413,39803:23416,39804:25992,39805:23418,39806:23424,39808:23427,39809:23462,39810:23480,39811:23491,39812:23495,39813:23497,39814:23508,39815:23504,39816:23524,39817:23526,39818:23522,39819:23518,39820:23525,39821:23531,39822:23536,39823:23542,39824:23539,39825:23557,39826:23559,39827:23560,39828:23565,39829:23571,39830:23584,39831:23586,39832:23592,39833:23608,39834:23609,39835:23617,39836:23622,39837:23630,39838:23635,39839:23632,39840:23631,39841:23409,39842:23660,39843:23662,39844:20066,39845:23670,39846:23673,39847:23692,39848:23697,39849:23700,39850:22939,39851:23723,39852:23739,39853:23734,39854:23740,39855:23735,39856:23749,39857:23742,39858:23751,39859:23769,39860:23785,39861:23805,39862:23802,39863:23789,39864:23948,39865:23786,39866:23819,39867:23829,39868:23831,39869:23900,39870:23839,39871:23835,39872:23825,39873:23828,39874:23842,39875:23834,39876:23833,39877:23832,39878:23884,39879:23890,39880:23886,39881:23883,39882:23916,39883:23923,39884:23926,39885:23943,39886:23940,39887:23938,39888:23970,39889:23965,39890:23980,39891:23982,39892:23997,39893:23952,39894:23991,39895:23996,39896:24009,39897:24013,39898:24019,39899:24018,39900:24022,39901:24027,39902:24043,39903:24050,39904:24053,39905:24075,39906:24090,39907:24089,39908:24081,39909:24091,39910:24118,39911:24119,39912:24132,39913:24131,39914:24128,39915:24142,39916:24151,39917:24148,39918:24159,39919:24162,39920:24164,39921:24135,39922:24181,39923:24182,39924:24186,39925:40636,39926:24191,39927:24224,39928:24257,39929:24258,39930:24264,39931:24272,39932:24271,4e4:24278,40001:24291,40002:24285,40003:24282,40004:24283,40005:24290,40006:24289,40007:24296,40008:24297,40009:24300,40010:24305,40011:24307,40012:24304,40013:24308,40014:24312,40015:24318,40016:24323,40017:24329,40018:24413,40019:24412,40020:24331,40021:24337,40022:24342,40023:24361,40024:24365,40025:24376,40026:24385,40027:24392,40028:24396,40029:24398,40030:24367,40031:24401,40032:24406,40033:24407,40034:24409,40035:24417,40036:24429,40037:24435,40038:24439,40039:24451,40040:24450,40041:24447,40042:24458,40043:24456,40044:24465,40045:24455,40046:24478,40047:24473,40048:24472,40049:24480,40050:24488,40051:24493,40052:24508,40053:24534,40054:24571,40055:24548,40056:24568,40057:24561,40058:24541,40059:24755,40060:24575,40061:24609,40062:24672,40064:24601,40065:24592,40066:24617,40067:24590,40068:24625,40069:24603,40070:24597,40071:24619,40072:24614,40073:24591,40074:24634,40075:24666,40076:24641,40077:24682,40078:24695,40079:24671,40080:24650,40081:24646,40082:24653,40083:24675,40084:24643,40085:24676,40086:24642,40087:24684,40088:24683,40089:24665,40090:24705,40091:24717,40092:24807,40093:24707,40094:24730,40095:24708,40096:24731,40097:24726,40098:24727,40099:24722,40100:24743,40101:24715,40102:24801,40103:24760,40104:24800,40105:24787,40106:24756,40107:24560,40108:24765,40109:24774,40110:24757,40111:24792,40112:24909,40113:24853,40114:24838,40115:24822,40116:24823,40117:24832,40118:24820,40119:24826,40120:24835,40121:24865,40122:24827,40123:24817,40124:24845,40125:24846,40126:24903,40127:24894,40128:24872,40129:24871,40130:24906,40131:24895,40132:24892,40133:24876,40134:24884,40135:24893,40136:24898,40137:24900,40138:24947,40139:24951,40140:24920,40141:24921,40142:24922,40143:24939,40144:24948,40145:24943,40146:24933,40147:24945,40148:24927,40149:24925,40150:24915,40151:24949,40152:24985,40153:24982,40154:24967,40155:25004,40156:24980,40157:24986,40158:24970,40159:24977,40160:25003,40161:25006,40162:25036,40163:25034,40164:25033,40165:25079,40166:25032,40167:25027,40168:25030,40169:25018,40170:25035,40171:32633,40172:25037,40173:25062,40174:25059,40175:25078,40176:25082,40177:25076,40178:25087,40179:25085,40180:25084,40181:25086,40182:25088,40183:25096,40184:25097,40185:25101,40186:25100,40187:25108,40188:25115,40256:25118,40257:25121,40258:25130,40259:25134,40260:25136,40261:25138,40262:25139,40263:25153,40264:25166,40265:25182,40266:25187,40267:25179,40268:25184,40269:25192,40270:25212,40271:25218,40272:25225,40273:25214,40274:25234,40275:25235,40276:25238,40277:25300,40278:25219,40279:25236,40280:25303,40281:25297,40282:25275,40283:25295,40284:25343,40285:25286,40286:25812,40287:25288,40288:25308,40289:25292,40290:25290,40291:25282,40292:25287,40293:25243,40294:25289,40295:25356,40296:25326,40297:25329,40298:25383,40299:25346,40300:25352,40301:25327,40302:25333,40303:25424,40304:25406,40305:25421,40306:25628,40307:25423,40308:25494,40309:25486,40310:25472,40311:25515,40312:25462,40313:25507,40314:25487,40315:25481,40316:25503,40317:25525,40318:25451,40320:25449,40321:25534,40322:25577,40323:25536,40324:25542,40325:25571,40326:25545,40327:25554,40328:25590,40329:25540,40330:25622,40331:25652,40332:25606,40333:25619,40334:25638,40335:25654,40336:25885,40337:25623,40338:25640,40339:25615,40340:25703,40341:25711,40342:25718,40343:25678,40344:25898,40345:25749,40346:25747,40347:25765,40348:25769,40349:25736,40350:25788,40351:25818,40352:25810,40353:25797,40354:25799,40355:25787,40356:25816,40357:25794,40358:25841,40359:25831,40360:33289,40361:25824,40362:25825,40363:25260,40364:25827,40365:25839,40366:25900,40367:25846,40368:25844,40369:25842,40370:25850,40371:25856,40372:25853,40373:25880,40374:25884,40375:25861,40376:25892,40377:25891,40378:25899,40379:25908,40380:25909,40381:25911,40382:25910,40383:25912,40384:30027,40385:25928,40386:25942,40387:25941,40388:25933,40389:25944,40390:25950,40391:25949,40392:25970,40393:25976,40394:25986,40395:25987,40396:35722,40397:26011,40398:26015,40399:26027,40400:26039,40401:26051,40402:26054,40403:26049,40404:26052,40405:26060,40406:26066,40407:26075,40408:26073,40409:26080,40410:26081,40411:26097,40412:26482,40413:26122,40414:26115,40415:26107,40416:26483,40417:26165,40418:26166,40419:26164,40420:26140,40421:26191,40422:26180,40423:26185,40424:26177,40425:26206,40426:26205,40427:26212,40428:26215,40429:26216,40430:26207,40431:26210,40432:26224,40433:26243,40434:26248,40435:26254,40436:26249,40437:26244,40438:26264,40439:26269,40440:26305,40441:26297,40442:26313,40443:26302,40444:26300,40512:26308,40513:26296,40514:26326,40515:26330,40516:26336,40517:26175,40518:26342,40519:26345,40520:26352,40521:26357,40522:26359,40523:26383,40524:26390,40525:26398,40526:26406,40527:26407,40528:38712,40529:26414,40530:26431,40531:26422,40532:26433,40533:26424,40534:26423,40535:26438,40536:26462,40537:26464,40538:26457,40539:26467,40540:26468,40541:26505,40542:26480,40543:26537,40544:26492,40545:26474,40546:26508,40547:26507,40548:26534,40549:26529,40550:26501,40551:26551,40552:26607,40553:26548,40554:26604,40555:26547,40556:26601,40557:26552,40558:26596,40559:26590,40560:26589,40561:26594,40562:26606,40563:26553,40564:26574,40565:26566,40566:26599,40567:27292,40568:26654,40569:26694,40570:26665,40571:26688,40572:26701,40573:26674,40574:26702,40576:26803,40577:26667,40578:26713,40579:26723,40580:26743,40581:26751,40582:26783,40583:26767,40584:26797,40585:26772,40586:26781,40587:26779,40588:26755,40589:27310,40590:26809,40591:26740,40592:26805,40593:26784,40594:26810,40595:26895,40596:26765,40597:26750,40598:26881,40599:26826,40600:26888,40601:26840,40602:26914,40603:26918,40604:26849,40605:26892,40606:26829,40607:26836,40608:26855,40609:26837,40610:26934,40611:26898,40612:26884,40613:26839,40614:26851,40615:26917,40616:26873,40617:26848,40618:26863,40619:26920,40620:26922,40621:26906,40622:26915,40623:26913,40624:26822,40625:27001,40626:26999,40627:26972,40628:27e3,40629:26987,40630:26964,40631:27006,40632:26990,40633:26937,40634:26996,40635:26941,40636:26969,40637:26928,40638:26977,40639:26974,40640:26973,40641:27009,40642:26986,40643:27058,40644:27054,40645:27088,40646:27071,40647:27073,40648:27091,40649:27070,40650:27086,40651:23528,40652:27082,40653:27101,40654:27067,40655:27075,40656:27047,40657:27182,40658:27025,40659:27040,40660:27036,40661:27029,40662:27060,40663:27102,40664:27112,40665:27138,40666:27163,40667:27135,40668:27402,40669:27129,40670:27122,40671:27111,40672:27141,40673:27057,40674:27166,40675:27117,40676:27156,40677:27115,40678:27146,40679:27154,40680:27329,40681:27171,40682:27155,40683:27204,40684:27148,40685:27250,40686:27190,40687:27256,40688:27207,40689:27234,40690:27225,40691:27238,40692:27208,40693:27192,40694:27170,40695:27280,40696:27277,40697:27296,40698:27268,40699:27298,40700:27299,40768:27287,40769:34327,40770:27323,40771:27331,40772:27330,40773:27320,40774:27315,40775:27308,40776:27358,40777:27345,40778:27359,40779:27306,40780:27354,40781:27370,40782:27387,40783:27397,40784:34326,40785:27386,40786:27410,40787:27414,40788:39729,40789:27423,40790:27448,40791:27447,40792:30428,40793:27449,40794:39150,40795:27463,40796:27459,40797:27465,40798:27472,40799:27481,40800:27476,40801:27483,40802:27487,40803:27489,40804:27512,40805:27513,40806:27519,40807:27520,40808:27524,40809:27523,40810:27533,40811:27544,40812:27541,40813:27550,40814:27556,40815:27562,40816:27563,40817:27567,40818:27570,40819:27569,40820:27571,40821:27575,40822:27580,40823:27590,40824:27595,40825:27603,40826:27615,40827:27628,40828:27627,40829:27635,40830:27631,40832:40638,40833:27656,40834:27667,40835:27668,40836:27675,40837:27684,40838:27683,40839:27742,40840:27733,40841:27746,40842:27754,40843:27778,40844:27789,40845:27802,40846:27777,40847:27803,40848:27774,40849:27752,40850:27763,40851:27794,40852:27792,40853:27844,40854:27889,40855:27859,40856:27837,40857:27863,40858:27845,40859:27869,40860:27822,40861:27825,40862:27838,40863:27834,40864:27867,40865:27887,40866:27865,40867:27882,40868:27935,40869:34893,40870:27958,40871:27947,40872:27965,40873:27960,40874:27929,40875:27957,40876:27955,40877:27922,40878:27916,40879:28003,40880:28051,40881:28004,40882:27994,40883:28025,40884:27993,40885:28046,40886:28053,40887:28644,40888:28037,40889:28153,40890:28181,40891:28170,40892:28085,40893:28103,40894:28134,40895:28088,40896:28102,40897:28140,40898:28126,40899:28108,40900:28136,40901:28114,40902:28101,40903:28154,40904:28121,40905:28132,40906:28117,40907:28138,40908:28142,40909:28205,40910:28270,40911:28206,40912:28185,40913:28274,40914:28255,40915:28222,40916:28195,40917:28267,40918:28203,40919:28278,40920:28237,40921:28191,40922:28227,40923:28218,40924:28238,40925:28196,40926:28415,40927:28189,40928:28216,40929:28290,40930:28330,40931:28312,40932:28361,40933:28343,40934:28371,40935:28349,40936:28335,40937:28356,40938:28338,40939:28372,40940:28373,40941:28303,40942:28325,40943:28354,40944:28319,40945:28481,40946:28433,40947:28748,40948:28396,40949:28408,40950:28414,40951:28479,40952:28402,40953:28465,40954:28399,40955:28466,40956:28364,161:65377,162:65378,163:65379,164:65380,165:65381,166:65382,167:65383,168:65384,169:65385,170:65386,171:65387,172:65388,173:65389,174:65390,175:65391,176:65392,177:65393,178:65394,179:65395,180:65396,181:65397,182:65398,183:65399,184:65400,185:65401,186:65402,187:65403,188:65404,189:65405,190:65406,191:65407,192:65408,193:65409,194:65410,195:65411,196:65412,197:65413,198:65414,199:65415,200:65416,201:65417,202:65418,203:65419,204:65420,205:65421,206:65422,207:65423,208:65424,209:65425,210:65426,211:65427,212:65428,213:65429,214:65430,215:65431,216:65432,217:65433,218:65434,219:65435,220:65436,221:65437,222:65438,223:65439,57408:28478,57409:28435,57410:28407,57411:28550,57412:28538,57413:28536,57414:28545,57415:28544,57416:28527,57417:28507,57418:28659,57419:28525,57420:28546,57421:28540,57422:28504,57423:28558,57424:28561,57425:28610,57426:28518,57427:28595,57428:28579,57429:28577,57430:28580,57431:28601,57432:28614,57433:28586,57434:28639,57435:28629,57436:28652,57437:28628,57438:28632,57439:28657,57440:28654,57441:28635,57442:28681,57443:28683,57444:28666,57445:28689,57446:28673,57447:28687,57448:28670,57449:28699,57450:28698,57451:28532,57452:28701,57453:28696,57454:28703,57455:28720,57456:28734,57457:28722,57458:28753,57459:28771,57460:28825,57461:28818,57462:28847,57463:28913,57464:28844,57465:28856,57466:28851,57467:28846,57468:28895,57469:28875,57470:28893,57472:28889,57473:28937,57474:28925,57475:28956,57476:28953,57477:29029,57478:29013,57479:29064,57480:29030,57481:29026,57482:29004,57483:29014,57484:29036,57485:29071,57486:29179,57487:29060,57488:29077,57489:29096,57490:29100,57491:29143,57492:29113,57493:29118,57494:29138,57495:29129,57496:29140,57497:29134,57498:29152,57499:29164,57500:29159,57501:29173,57502:29180,57503:29177,57504:29183,57505:29197,57506:29200,57507:29211,57508:29224,57509:29229,57510:29228,57511:29232,57512:29234,57513:29243,57514:29244,57515:29247,57516:29248,57517:29254,57518:29259,57519:29272,57520:29300,57521:29310,57522:29314,57523:29313,57524:29319,57525:29330,57526:29334,57527:29346,57528:29351,57529:29369,57530:29362,57531:29379,57532:29382,57533:29380,57534:29390,57535:29394,57536:29410,57537:29408,57538:29409,57539:29433,57540:29431,57541:20495,57542:29463,57543:29450,57544:29468,57545:29462,57546:29469,57547:29492,57548:29487,57549:29481,57550:29477,57551:29502,57552:29518,57553:29519,57554:40664,57555:29527,57556:29546,57557:29544,57558:29552,57559:29560,57560:29557,57561:29563,57562:29562,57563:29640,57564:29619,57565:29646,57566:29627,57567:29632,57568:29669,57569:29678,57570:29662,57571:29858,57572:29701,57573:29807,57574:29733,57575:29688,57576:29746,57577:29754,57578:29781,57579:29759,57580:29791,57581:29785,57582:29761,57583:29788,57584:29801,57585:29808,57586:29795,57587:29802,57588:29814,57589:29822,57590:29835,57591:29854,57592:29863,57593:29898,57594:29903,57595:29908,57596:29681,57664:29920,57665:29923,57666:29927,57667:29929,57668:29934,57669:29938,57670:29936,57671:29937,57672:29944,57673:29943,57674:29956,57675:29955,57676:29957,57677:29964,57678:29966,57679:29965,57680:29973,57681:29971,57682:29982,57683:29990,57684:29996,57685:30012,57686:30020,57687:30029,57688:30026,57689:30025,57690:30043,57691:30022,57692:30042,57693:30057,57694:30052,57695:30055,57696:30059,57697:30061,57698:30072,57699:30070,57700:30086,57701:30087,57702:30068,57703:30090,57704:30089,57705:30082,57706:30100,57707:30106,57708:30109,57709:30117,57710:30115,57711:30146,57712:30131,57713:30147,57714:30133,57715:30141,57716:30136,57717:30140,57718:30129,57719:30157,57720:30154,57721:30162,57722:30169,57723:30179,57724:30174,57725:30206,57726:30207,57728:30204,57729:30209,57730:30192,57731:30202,57732:30194,57733:30195,57734:30219,57735:30221,57736:30217,57737:30239,57738:30247,57739:30240,57740:30241,57741:30242,57742:30244,57743:30260,57744:30256,57745:30267,57746:30279,57747:30280,57748:30278,57749:30300,57750:30296,57751:30305,57752:30306,57753:30312,57754:30313,57755:30314,57756:30311,57757:30316,57758:30320,57759:30322,57760:30326,57761:30328,57762:30332,57763:30336,57764:30339,57765:30344,57766:30347,57767:30350,57768:30358,57769:30355,57770:30361,57771:30362,57772:30384,57773:30388,57774:30392,57775:30393,57776:30394,57777:30402,57778:30413,57779:30422,57780:30418,57781:30430,57782:30433,57783:30437,57784:30439,57785:30442,57786:34351,57787:30459,57788:30472,57789:30471,57790:30468,57791:30505,57792:30500,57793:30494,57794:30501,57795:30502,57796:30491,57797:30519,57798:30520,57799:30535,57800:30554,57801:30568,57802:30571,57803:30555,57804:30565,57805:30591,57806:30590,57807:30585,57808:30606,57809:30603,57810:30609,57811:30624,57812:30622,57813:30640,57814:30646,57815:30649,57816:30655,57817:30652,57818:30653,57819:30651,57820:30663,57821:30669,57822:30679,57823:30682,57824:30684,57825:30691,57826:30702,57827:30716,57828:30732,57829:30738,57830:31014,57831:30752,57832:31018,57833:30789,57834:30862,57835:30836,57836:30854,57837:30844,57838:30874,57839:30860,57840:30883,57841:30901,57842:30890,57843:30895,57844:30929,57845:30918,57846:30923,57847:30932,57848:30910,57849:30908,57850:30917,57851:30922,57852:30956,57920:30951,57921:30938,57922:30973,57923:30964,57924:30983,57925:30994,57926:30993,57927:31001,57928:31020,57929:31019,57930:31040,57931:31072,57932:31063,57933:31071,57934:31066,57935:31061,57936:31059,57937:31098,57938:31103,57939:31114,57940:31133,57941:31143,57942:40779,57943:31146,57944:31150,57945:31155,57946:31161,57947:31162,57948:31177,57949:31189,57950:31207,57951:31212,57952:31201,57953:31203,57954:31240,57955:31245,57956:31256,57957:31257,57958:31264,57959:31263,57960:31104,57961:31281,57962:31291,57963:31294,57964:31287,57965:31299,57966:31319,57967:31305,57968:31329,57969:31330,57970:31337,57971:40861,57972:31344,57973:31353,57974:31357,57975:31368,57976:31383,57977:31381,57978:31384,57979:31382,57980:31401,57981:31432,57982:31408,57984:31414,57985:31429,57986:31428,57987:31423,57988:36995,57989:31431,57990:31434,57991:31437,57992:31439,57993:31445,57994:31443,57995:31449,57996:31450,57997:31453,57998:31457,57999:31458,58e3:31462,58001:31469,58002:31472,58003:31490,58004:31503,58005:31498,58006:31494,58007:31539,58008:31512,58009:31513,58010:31518,58011:31541,58012:31528,58013:31542,58014:31568,58015:31610,58016:31492,58017:31565,58018:31499,58019:31564,58020:31557,58021:31605,58022:31589,58023:31604,58024:31591,58025:31600,58026:31601,58027:31596,58028:31598,58029:31645,58030:31640,58031:31647,58032:31629,58033:31644,58034:31642,58035:31627,58036:31634,58037:31631,58038:31581,58039:31641,58040:31691,58041:31681,58042:31692,58043:31695,58044:31668,58045:31686,58046:31709,58047:31721,58048:31761,58049:31764,58050:31718,58051:31717,58052:31840,58053:31744,58054:31751,58055:31763,58056:31731,58057:31735,58058:31767,58059:31757,58060:31734,58061:31779,58062:31783,58063:31786,58064:31775,58065:31799,58066:31787,58067:31805,58068:31820,58069:31811,58070:31828,58071:31823,58072:31808,58073:31824,58074:31832,58075:31839,58076:31844,58077:31830,58078:31845,58079:31852,58080:31861,58081:31875,58082:31888,58083:31908,58084:31917,58085:31906,58086:31915,58087:31905,58088:31912,58089:31923,58090:31922,58091:31921,58092:31918,58093:31929,58094:31933,58095:31936,58096:31941,58097:31938,58098:31960,58099:31954,58100:31964,58101:31970,58102:39739,58103:31983,58104:31986,58105:31988,58106:31990,58107:31994,58108:32006,58176:32002,58177:32028,58178:32021,58179:32010,58180:32069,58181:32075,58182:32046,58183:32050,58184:32063,58185:32053,58186:32070,58187:32115,58188:32086,58189:32078,58190:32114,58191:32104,58192:32110,58193:32079,58194:32099,58195:32147,58196:32137,58197:32091,58198:32143,58199:32125,58200:32155,58201:32186,58202:32174,58203:32163,58204:32181,58205:32199,58206:32189,58207:32171,58208:32317,58209:32162,58210:32175,58211:32220,58212:32184,58213:32159,58214:32176,58215:32216,58216:32221,58217:32228,58218:32222,58219:32251,58220:32242,58221:32225,58222:32261,58223:32266,58224:32291,58225:32289,58226:32274,58227:32305,58228:32287,58229:32265,58230:32267,58231:32290,58232:32326,58233:32358,58234:32315,58235:32309,58236:32313,58237:32323,58238:32311,58240:32306,58241:32314,58242:32359,58243:32349,58244:32342,58245:32350,58246:32345,58247:32346,58248:32377,58249:32362,58250:32361,58251:32380,58252:32379,58253:32387,58254:32213,58255:32381,58256:36782,58257:32383,58258:32392,58259:32393,58260:32396,58261:32402,58262:32400,58263:32403,58264:32404,58265:32406,58266:32398,58267:32411,58268:32412,58269:32568,58270:32570,58271:32581,58272:32588,58273:32589,58274:32590,58275:32592,58276:32593,58277:32597,58278:32596,58279:32600,58280:32607,58281:32608,58282:32616,58283:32617,58284:32615,58285:32632,58286:32642,58287:32646,58288:32643,58289:32648,58290:32647,58291:32652,58292:32660,58293:32670,58294:32669,58295:32666,58296:32675,58297:32687,58298:32690,58299:32697,58300:32686,58301:32694,58302:32696,58303:35697,58304:32709,58305:32710,58306:32714,58307:32725,58308:32724,58309:32737,58310:32742,58311:32745,58312:32755,58313:32761,58314:39132,58315:32774,58316:32772,58317:32779,58318:32786,58319:32792,58320:32793,58321:32796,58322:32801,58323:32808,58324:32831,58325:32827,58326:32842,58327:32838,58328:32850,58329:32856,58330:32858,58331:32863,58332:32866,58333:32872,58334:32883,58335:32882,58336:32880,58337:32886,58338:32889,58339:32893,58340:32895,58341:32900,58342:32902,58343:32901,58344:32923,58345:32915,58346:32922,58347:32941,58348:20880,58349:32940,58350:32987,58351:32997,58352:32985,58353:32989,58354:32964,58355:32986,58356:32982,58357:33033,58358:33007,58359:33009,58360:33051,58361:33065,58362:33059,58363:33071,58364:33099,58432:38539,58433:33094,58434:33086,58435:33107,58436:33105,58437:33020,58438:33137,58439:33134,58440:33125,58441:33126,58442:33140,58443:33155,58444:33160,58445:33162,58446:33152,58447:33154,58448:33184,58449:33173,58450:33188,58451:33187,58452:33119,58453:33171,58454:33193,58455:33200,58456:33205,58457:33214,58458:33208,58459:33213,58460:33216,58461:33218,58462:33210,58463:33225,58464:33229,58465:33233,58466:33241,58467:33240,58468:33224,58469:33242,58470:33247,58471:33248,58472:33255,58473:33274,58474:33275,58475:33278,58476:33281,58477:33282,58478:33285,58479:33287,58480:33290,58481:33293,58482:33296,58483:33302,58484:33321,58485:33323,58486:33336,58487:33331,58488:33344,58489:33369,58490:33368,58491:33373,58492:33370,58493:33375,58494:33380,58496:33378,58497:33384,58498:33386,58499:33387,58500:33326,58501:33393,58502:33399,58503:33400,58504:33406,58505:33421,58506:33426,58507:33451,58508:33439,58509:33467,58510:33452,58511:33505,58512:33507,58513:33503,58514:33490,58515:33524,58516:33523,58517:33530,58518:33683,58519:33539,58520:33531,58521:33529,58522:33502,58523:33542,58524:33500,58525:33545,58526:33497,58527:33589,58528:33588,58529:33558,58530:33586,58531:33585,58532:33600,58533:33593,58534:33616,58535:33605,58536:33583,58537:33579,58538:33559,58539:33560,58540:33669,58541:33690,58542:33706,58543:33695,58544:33698,58545:33686,58546:33571,58547:33678,58548:33671,58549:33674,58550:33660,58551:33717,58552:33651,58553:33653,58554:33696,58555:33673,58556:33704,58557:33780,58558:33811,58559:33771,58560:33742,58561:33789,58562:33795,58563:33752,58564:33803,58565:33729,58566:33783,58567:33799,58568:33760,58569:33778,58570:33805,58571:33826,58572:33824,58573:33725,58574:33848,58575:34054,58576:33787,58577:33901,58578:33834,58579:33852,58580:34138,58581:33924,58582:33911,58583:33899,58584:33965,58585:33902,58586:33922,58587:33897,58588:33862,58589:33836,58590:33903,58591:33913,58592:33845,58593:33994,58594:33890,58595:33977,58596:33983,58597:33951,58598:34009,58599:33997,58600:33979,58601:34010,58602:34e3,58603:33985,58604:33990,58605:34006,58606:33953,58607:34081,58608:34047,58609:34036,58610:34071,58611:34072,58612:34092,58613:34079,58614:34069,58615:34068,58616:34044,58617:34112,58618:34147,58619:34136,58620:34120,58688:34113,58689:34306,58690:34123,58691:34133,58692:34176,58693:34212,58694:34184,58695:34193,58696:34186,58697:34216,58698:34157,58699:34196,58700:34203,58701:34282,58702:34183,58703:34204,58704:34167,58705:34174,58706:34192,58707:34249,58708:34234,58709:34255,58710:34233,58711:34256,58712:34261,58713:34269,58714:34277,58715:34268,58716:34297,58717:34314,58718:34323,58719:34315,58720:34302,58721:34298,58722:34310,58723:34338,58724:34330,58725:34352,58726:34367,58727:34381,58728:20053,58729:34388,58730:34399,58731:34407,58732:34417,58733:34451,58734:34467,58735:34473,58736:34474,58737:34443,58738:34444,58739:34486,58740:34479,58741:34500,58742:34502,58743:34480,58744:34505,58745:34851,58746:34475,58747:34516,58748:34526,58749:34537,58750:34540,58752:34527,58753:34523,58754:34543,58755:34578,58756:34566,58757:34568,58758:34560,58759:34563,58760:34555,58761:34577,58762:34569,58763:34573,58764:34553,58765:34570,58766:34612,58767:34623,58768:34615,58769:34619,58770:34597,58771:34601,58772:34586,58773:34656,58774:34655,58775:34680,58776:34636,58777:34638,58778:34676,58779:34647,58780:34664,58781:34670,58782:34649,58783:34643,58784:34659,58785:34666,58786:34821,58787:34722,58788:34719,58789:34690,58790:34735,58791:34763,58792:34749,58793:34752,58794:34768,58795:38614,58796:34731,58797:34756,58798:34739,58799:34759,58800:34758,58801:34747,58802:34799,58803:34802,58804:34784,58805:34831,58806:34829,58807:34814,58808:34806,58809:34807,58810:34830,58811:34770,58812:34833,58813:34838,58814:34837,58815:34850,58816:34849,58817:34865,58818:34870,58819:34873,58820:34855,58821:34875,58822:34884,58823:34882,58824:34898,58825:34905,58826:34910,58827:34914,58828:34923,58829:34945,58830:34942,58831:34974,58832:34933,58833:34941,58834:34997,58835:34930,58836:34946,58837:34967,58838:34962,58839:34990,58840:34969,58841:34978,58842:34957,58843:34980,58844:34992,58845:35007,58846:34993,58847:35011,58848:35012,58849:35028,58850:35032,58851:35033,58852:35037,58853:35065,58854:35074,58855:35068,58856:35060,58857:35048,58858:35058,58859:35076,58860:35084,58861:35082,58862:35091,58863:35139,58864:35102,58865:35109,58866:35114,58867:35115,58868:35137,58869:35140,58870:35131,58871:35126,58872:35128,58873:35148,58874:35101,58875:35168,58876:35166,58944:35174,58945:35172,58946:35181,58947:35178,58948:35183,58949:35188,58950:35191,58951:35198,58952:35203,58953:35208,58954:35210,58955:35219,58956:35224,58957:35233,58958:35241,58959:35238,58960:35244,58961:35247,58962:35250,58963:35258,58964:35261,58965:35263,58966:35264,58967:35290,58968:35292,58969:35293,58970:35303,58971:35316,58972:35320,58973:35331,58974:35350,58975:35344,58976:35340,58977:35355,58978:35357,58979:35365,58980:35382,58981:35393,58982:35419,58983:35410,58984:35398,58985:35400,58986:35452,58987:35437,58988:35436,58989:35426,58990:35461,58991:35458,58992:35460,58993:35496,58994:35489,58995:35473,58996:35493,58997:35494,58998:35482,58999:35491,59e3:35524,59001:35533,59002:35522,59003:35546,59004:35563,59005:35571,59006:35559,59008:35556,59009:35569,59010:35604,59011:35552,59012:35554,59013:35575,59014:35550,59015:35547,59016:35596,59017:35591,59018:35610,59019:35553,59020:35606,59021:35600,59022:35607,59023:35616,59024:35635,59025:38827,59026:35622,59027:35627,59028:35646,59029:35624,59030:35649,59031:35660,59032:35663,59033:35662,59034:35657,59035:35670,59036:35675,59037:35674,59038:35691,59039:35679,59040:35692,59041:35695,59042:35700,59043:35709,59044:35712,59045:35724,59046:35726,59047:35730,59048:35731,59049:35734,59050:35737,59051:35738,59052:35898,59053:35905,59054:35903,59055:35912,59056:35916,59057:35918,59058:35920,59059:35925,59060:35938,59061:35948,59062:35960,59063:35962,59064:35970,59065:35977,59066:35973,59067:35978,59068:35981,59069:35982,59070:35988,59071:35964,59072:35992,59073:25117,59074:36013,59075:36010,59076:36029,59077:36018,59078:36019,59079:36014,59080:36022,59081:36040,59082:36033,59083:36068,59084:36067,59085:36058,59086:36093,59087:36090,59088:36091,59089:36100,59090:36101,59091:36106,59092:36103,59093:36111,59094:36109,59095:36112,59096:40782,59097:36115,59098:36045,59099:36116,59100:36118,59101:36199,59102:36205,59103:36209,59104:36211,59105:36225,59106:36249,59107:36290,59108:36286,59109:36282,59110:36303,59111:36314,59112:36310,59113:36300,59114:36315,59115:36299,59116:36330,59117:36331,59118:36319,59119:36323,59120:36348,59121:36360,59122:36361,59123:36351,59124:36381,59125:36382,59126:36368,59127:36383,59128:36418,59129:36405,59130:36400,59131:36404,59132:36426,59200:36423,59201:36425,59202:36428,59203:36432,59204:36424,59205:36441,59206:36452,59207:36448,59208:36394,59209:36451,59210:36437,59211:36470,59212:36466,59213:36476,59214:36481,59215:36487,59216:36485,59217:36484,59218:36491,59219:36490,59220:36499,59221:36497,59222:36500,59223:36505,59224:36522,59225:36513,59226:36524,59227:36528,59228:36550,59229:36529,59230:36542,59231:36549,59232:36552,59233:36555,59234:36571,59235:36579,59236:36604,59237:36603,59238:36587,59239:36606,59240:36618,59241:36613,59242:36629,59243:36626,59244:36633,59245:36627,59246:36636,59247:36639,59248:36635,59249:36620,59250:36646,59251:36659,59252:36667,59253:36665,59254:36677,59255:36674,59256:36670,59257:36684,59258:36681,59259:36678,59260:36686,59261:36695,59262:36700,59264:36706,59265:36707,59266:36708,59267:36764,59268:36767,59269:36771,59270:36781,59271:36783,59272:36791,59273:36826,59274:36837,59275:36834,59276:36842,59277:36847,59278:36999,59279:36852,59280:36869,59281:36857,59282:36858,59283:36881,59284:36885,59285:36897,59286:36877,59287:36894,59288:36886,59289:36875,59290:36903,59291:36918,59292:36917,59293:36921,59294:36856,59295:36943,59296:36944,59297:36945,59298:36946,59299:36878,59300:36937,59301:36926,59302:36950,59303:36952,59304:36958,59305:36968,59306:36975,59307:36982,59308:38568,59309:36978,59310:36994,59311:36989,59312:36993,59313:36992,59314:37002,59315:37001,59316:37007,59317:37032,59318:37039,59319:37041,59320:37045,59321:37090,59322:37092,59323:25160,59324:37083,59325:37122,59326:37138,59327:37145,59328:37170,59329:37168,59330:37194,59331:37206,59332:37208,59333:37219,59334:37221,59335:37225,59336:37235,59337:37234,59338:37259,59339:37257,59340:37250,59341:37282,59342:37291,59343:37295,59344:37290,59345:37301,59346:37300,59347:37306,59348:37312,59349:37313,59350:37321,59351:37323,59352:37328,59353:37334,59354:37343,59355:37345,59356:37339,59357:37372,59358:37365,59359:37366,59360:37406,59361:37375,59362:37396,59363:37420,59364:37397,59365:37393,59366:37470,59367:37463,59368:37445,59369:37449,59370:37476,59371:37448,59372:37525,59373:37439,59374:37451,59375:37456,59376:37532,59377:37526,59378:37523,59379:37531,59380:37466,59381:37583,59382:37561,59383:37559,59384:37609,59385:37647,59386:37626,59387:37700,59388:37678,59456:37657,59457:37666,59458:37658,59459:37667,59460:37690,59461:37685,59462:37691,59463:37724,59464:37728,59465:37756,59466:37742,59467:37718,59468:37808,59469:37804,59470:37805,59471:37780,59472:37817,59473:37846,59474:37847,59475:37864,59476:37861,59477:37848,59478:37827,59479:37853,59480:37840,59481:37832,59482:37860,59483:37914,59484:37908,59485:37907,59486:37891,59487:37895,59488:37904,59489:37942,59490:37931,59491:37941,59492:37921,59493:37946,59494:37953,59495:37970,59496:37956,59497:37979,59498:37984,59499:37986,59500:37982,59501:37994,59502:37417,59503:38e3,59504:38005,59505:38007,59506:38013,59507:37978,59508:38012,59509:38014,59510:38017,59511:38015,59512:38274,59513:38279,59514:38282,59515:38292,59516:38294,59517:38296,59518:38297,59520:38304,59521:38312,59522:38311,59523:38317,59524:38332,59525:38331,59526:38329,59527:38334,59528:38346,59529:28662,59530:38339,59531:38349,59532:38348,59533:38357,59534:38356,59535:38358,59536:38364,59537:38369,59538:38373,59539:38370,59540:38433,59541:38440,59542:38446,59543:38447,59544:38466,59545:38476,59546:38479,59547:38475,59548:38519,59549:38492,59550:38494,59551:38493,59552:38495,59553:38502,59554:38514,59555:38508,59556:38541,59557:38552,59558:38549,59559:38551,59560:38570,59561:38567,59562:38577,59563:38578,59564:38576,59565:38580,59566:38582,59567:38584,59568:38585,59569:38606,59570:38603,59571:38601,59572:38605,59573:35149,59574:38620,59575:38669,59576:38613,59577:38649,59578:38660,59579:38662,59580:38664,59581:38675,59582:38670,59583:38673,59584:38671,59585:38678,59586:38681,59587:38692,59588:38698,59589:38704,59590:38713,59591:38717,59592:38718,59593:38724,59594:38726,59595:38728,59596:38722,59597:38729,59598:38748,59599:38752,59600:38756,59601:38758,59602:38760,59603:21202,59604:38763,59605:38769,59606:38777,59607:38789,59608:38780,59609:38785,59610:38778,59611:38790,59612:38795,59613:38799,59614:38800,59615:38812,59616:38824,59617:38822,59618:38819,59619:38835,59620:38836,59621:38851,59622:38854,59623:38856,59624:38859,59625:38876,59626:38893,59627:40783,59628:38898,59629:31455,59630:38902,59631:38901,59632:38927,59633:38924,59634:38968,59635:38948,59636:38945,59637:38967,59638:38973,59639:38982,59640:38991,59641:38987,59642:39019,59643:39023,59644:39024,59712:39025,59713:39028,59714:39027,59715:39082,59716:39087,59717:39089,59718:39094,59719:39108,59720:39107,59721:39110,59722:39145,59723:39147,59724:39171,59725:39177,59726:39186,59727:39188,59728:39192,59729:39201,59730:39197,59731:39198,59732:39204,59733:39200,59734:39212,59735:39214,59736:39229,59737:39230,59738:39234,59739:39241,59740:39237,59741:39248,59742:39243,59743:39249,59744:39250,59745:39244,59746:39253,59747:39319,59748:39320,59749:39333,59750:39341,59751:39342,59752:39356,59753:39391,59754:39387,59755:39389,59756:39384,59757:39377,59758:39405,59759:39406,59760:39409,59761:39410,59762:39419,59763:39416,59764:39425,59765:39439,59766:39429,59767:39394,59768:39449,59769:39467,59770:39479,59771:39493,59772:39490,59773:39488,59774:39491,59776:39486,59777:39509,59778:39501,59779:39515,59780:39511,59781:39519,59782:39522,59783:39525,59784:39524,59785:39529,59786:39531,59787:39530,59788:39597,59789:39600,59790:39612,59791:39616,59792:39631,59793:39633,59794:39635,59795:39636,59796:39646,59797:39647,59798:39650,59799:39651,59800:39654,59801:39663,59802:39659,59803:39662,59804:39668,59805:39665,59806:39671,59807:39675,59808:39686,59809:39704,59810:39706,59811:39711,59812:39714,59813:39715,59814:39717,59815:39719,59816:39720,59817:39721,59818:39722,59819:39726,59820:39727,59821:39730,59822:39748,59823:39747,59824:39759,59825:39757,59826:39758,59827:39761,59828:39768,59829:39796,59830:39827,59831:39811,59832:39825,59833:39830,59834:39831,59835:39839,59836:39840,59837:39848,59838:39860,59839:39872,59840:39882,59841:39865,59842:39878,59843:39887,59844:39889,59845:39890,59846:39907,59847:39906,59848:39908,59849:39892,59850:39905,59851:39994,59852:39922,59853:39921,59854:39920,59855:39957,59856:39956,59857:39945,59858:39955,59859:39948,59860:39942,59861:39944,59862:39954,59863:39946,59864:39940,59865:39982,59866:39963,59867:39973,59868:39972,59869:39969,59870:39984,59871:40007,59872:39986,59873:40006,59874:39998,59875:40026,59876:40032,59877:40039,59878:40054,59879:40056,59880:40167,59881:40172,59882:40176,59883:40201,59884:40200,59885:40171,59886:40195,59887:40198,59888:40234,59889:40230,59890:40367,59891:40227,59892:40223,59893:40260,59894:40213,59895:40210,59896:40257,59897:40255,59898:40254,59899:40262,59900:40264,59968:40285,59969:40286,59970:40292,59971:40273,59972:40272,59973:40281,59974:40306,59975:40329,59976:40327,59977:40363,59978:40303,59979:40314,59980:40346,59981:40356,59982:40361,59983:40370,59984:40388,59985:40385,59986:40379,59987:40376,59988:40378,59989:40390,59990:40399,59991:40386,59992:40409,59993:40403,59994:40440,59995:40422,59996:40429,59997:40431,59998:40445,59999:40474,6e4:40475,60001:40478,60002:40565,60003:40569,60004:40573,60005:40577,60006:40584,60007:40587,60008:40588,60009:40594,60010:40597,60011:40593,60012:40605,60013:40613,60014:40617,60015:40632,60016:40618,60017:40621,60018:38753,60019:40652,60020:40654,60021:40655,60022:40656,60023:40660,60024:40668,60025:40670,60026:40669,60027:40672,60028:40677,60029:40680,60030:40687,60032:40692,60033:40694,60034:40695,60035:40697,60036:40699,60037:40700,60038:40701,60039:40711,60040:40712,60041:30391,60042:40725,60043:40737,60044:40748,60045:40766,60046:40778,60047:40786,60048:40788,60049:40803,60050:40799,60051:40800,60052:40801,60053:40806,60054:40807,60055:40812,60056:40810,60057:40823,60058:40818,60059:40822,60060:40853,60061:40860,60062:40864,60063:22575,60064:27079,60065:36953,60066:29796,60067:20956,60068:29081}},function(G,y,g){"use strict";Object.defineProperty(y,"__esModule",{value:!0});var p=g(1),m=g(2);function l(E,r,a,F){var d;r.degree()=F/2;){var x=D,B=v;if(D=i,v=A,D.isZero())return null;i=x;for(var e=E.zero,C=D.getCoefficient(D.degree()),t=E.inverse(C);i.degree()>=D.degree()&&!i.isZero();){var n=i.degree()-D.degree(),k=E.multiply(i.getCoefficient(i.degree()),t);e=e.addOrSubtract(E.buildMonomial(n,k)),i=i.addOrSubtract(D.multiplyByMonomial(n,k))}if(A=e.multiplyPoly(v).addOrSubtract(B),i.degree()>=D.degree())return null}var u=A.getCoefficient(0);if(u===0)return null;var f=E.inverse(u);return[A.multiply(f),i.multiply(f)]}function s(E,r){var a=r.degree();if(a===1)return[r.getCoefficient(1)];for(var F=new Array(a),d=0,D=1;D=k&&u>=f?(e=[x,A,B],M=e[0],b=e[1],w=e[2]):f>=u&&f>=k?(C=[A,x,B],M=C[0],b=C[1],w=C[2]):(t=[A,B,x],M=t[0],b=t[1],w=t[2]),(w.x-b.x)*(M.y-b.y)-(w.y-b.y)*(M.x-b.x)<0&&(n=[w,M],M=n[0],w=n[1]),{bottomLeft:M,topLeft:b,topRight:w}}function E(A,x,B,e){var C=(c(a(A,B,e,5))/7+c(a(A,x,e,5))/7+c(a(B,A,e,5))/7+c(a(x,A,e,5))/7)/4;if(C<1)throw new Error("Invalid module size");var t=Math.round(s(A,x)/C),n=Math.round(s(A,B)/C),k=Math.floor((t+n)/2)+7;switch(k%4){case 0:k++;break;case 2:k--;break}return{dimension:k,moduleSize:C}}function r(A,x,B,e){var C=[{x:Math.floor(A.x),y:Math.floor(A.y)}],t=Math.abs(x.y-A.y)>Math.abs(x.x-A.x),n,k,u,f;t?(n=Math.floor(A.y),k=Math.floor(A.x),u=Math.floor(x.y),f=Math.floor(x.x)):(n=Math.floor(A.x),k=Math.floor(A.y),u=Math.floor(x.x),f=Math.floor(x.y));for(var M=Math.abs(u-n),b=Math.abs(f-k),w=Math.floor(-M/2),I=n0){if(O===f)break;O+=h,w-=M}}for(var z=[],L=0;L=U.bottom.startX&&Y<=U.bottom.endX||H>=U.bottom.startX&&Y<=U.bottom.endX||Y<=U.bottom.startX&&H>=U.bottom.endX&&L[2]/(U.bottom.endX-U.bottom.startX)m});Z.length>0?Z[0].bottom=Q:B.push({top:Q,bottom:Q})}if(x0){var $=X-L[4],J=$-L[3],Q={startX:J,y:P,endX:$},Z=C.filter(function(R){return J>=R.bottom.startX&&J<=R.bottom.endX||$>=R.bottom.startX&&J<=R.bottom.endX||J<=R.bottom.startX&&$>=R.bottom.endX&&L[2]/(R.bottom.endX-R.bottom.startX)m});Z.length>0?Z[0].bottom=Q:C.push({top:Q,bottom:Q})}}},j=-1;j<=A.width;j++)K(j);x.push.apply(x,B.filter(function(X){return X.bottom.y!==P&&X.bottom.y-X.top.y>=2})),B=B.filter(function(X){return X.bottom.y===P}),e.push.apply(e,C.filter(function(X){return X.bottom.y!==P})),C=C.filter(function(X){return X.bottom.y===P})},n=0;n<=A.height;n++)t(n);x.push.apply(x,B.filter(function(P){return P.bottom.y-P.top.y>=2})),e.push.apply(e,C);var k=x.filter(function(P){return P.bottom.y-P.top.y>=2}).map(function(P){var T=(P.top.startX+P.top.endX+P.bottom.startX+P.bottom.endX)/4,z=(P.top.y+P.bottom.y+1)/2;if(A.get(Math.round(T),Math.round(z))){var L=[P.top.endX-P.top.startX,P.bottom.endX-P.bottom.startX,P.bottom.y-P.top.y+1],K=c(L)/L.length,j=d({x:Math.round(T),y:Math.round(z)},[1,1,3,1,1],A);return{score:j,x:T,y:z,size:K}}}).filter(function(P){return!!P}).sort(function(P,T){return P.score-T.score}).map(function(P,T,z){if(T>p)return null;var L=z.filter(function(j,X){return T!==X}).map(function(j){return{x:j.x,y:j.y,score:j.score+Math.pow(j.size-P.size,2)/P.size,size:j.size}}).sort(function(j,X){return j.score-X.score});if(L.length<2)return null;var K=P.score+L[0].score+L[1].score;return{points:[P].concat(L.slice(0,2)),score:K}}).filter(function(P){return!!P}).sort(function(P,T){return P.score-T.score});if(k.length===0)return null;var u=o(k[0].points[0],k[0].points[1],k[0].points[2]),f=u.topRight,M=u.topLeft,b=u.bottomLeft,w=v(A,e,f,M,b),I=[];w&&I.push({alignmentPattern:{x:w.alignmentPattern.x,y:w.alignmentPattern.y},bottomLeft:{x:b.x,y:b.y},dimension:w.dimension,topLeft:{x:M.x,y:M.y},topRight:{x:f.x,y:f.y}});var h=D(A,f),N=D(A,M),S=D(A,b),O=v(A,e,h,N,S);return O&&I.push({alignmentPattern:{x:O.alignmentPattern.x,y:O.alignmentPattern.y},bottomLeft:{x:S.x,y:S.y},topLeft:{x:N.x,y:N.y},topRight:{x:h.x,y:h.y},dimension:O.dimension}),I.length===0?null:I}y.locate=i;function v(A,x,B,e,C){var t,n,k;try{t=E(e,B,C,A),n=t.dimension,k=t.moduleSize}catch{return null}var u={x:B.x-e.x+C.x,y:B.y-e.y+C.y},f=(s(e,C)+s(e,B))/2/k,M=1-3/f,b={x:e.x+M*(u.x-e.x),y:e.y+M*(u.y-e.y)},w=x.map(function(h){var N=(h.top.startX+h.top.endX+h.bottom.startX+h.bottom.endX)/4,S=(h.top.y+h.bottom.y+1)/2;if(A.get(Math.floor(N),Math.floor(S))){var O=[h.top.endX-h.top.startX,h.bottom.endX-h.bottom.startX,h.bottom.y-h.top.y+1],P=c(O)/O.length,T=d({x:Math.floor(N),y:Math.floor(S)},[1,1,1],A),z=T+s({x:N,y:S},b);return{x:N,y:S,score:z}}}).filter(function(h){return!!h}).sort(function(h,N){return h.score-N.score}),I=f>=15&&w.length?w[0]:b;return{alignmentPattern:I,dimension:n}}}]).default});
diff --git a/BeadQR/project.config.json b/BeadQR/project.config.json
deleted file mode 100644
index df30fa1c2487b304fdb0a1be0bf84f00ad5cba08..0000000000000000000000000000000000000000
--- a/BeadQR/project.config.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "description": "豆维 · 可扫码的拼豆",
- "appid": "wx17a895fdcb5de908",
- "compileType": "miniprogram",
- "libVersion": "3.17.1",
- "projectname": "豆维",
- "miniprogramRoot": "miniprogram/",
- "cloudfunctionRoot": "cloudfunctions/",
- "setting": {
- "es6": true,
- "enhance": true,
- "postcss": true,
- "minified": true,
- "urlCheck": false,
- "ignoreUploadUnusedFiles": true
- },
- "packOptions": {
- "ignore": []
- }
-}
diff --git a/BeadQR/project.private.config.json b/BeadQR/project.private.config.json
deleted file mode 100644
index 63c8bf65b255d79e5a650d4f5086a86def72ec20..0000000000000000000000000000000000000000
--- a/BeadQR/project.private.config.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "setting": {
- "compileHotReLoad": true,
- "urlCheck": false,
- "coverView": true,
- "lazyloadPlaceholderEnable": false,
- "skylineRenderEnable": false,
- "preloadBackgroundData": false,
- "autoAudits": false,
- "useApiHook": true,
- "useApiHostProcess": true,
- "showShadowRootInWxmlPanel": true,
- "useStaticServer": false,
- "useLanDebug": false,
- "showES6CompileOption": false,
- "checkInvalidKey": true,
- "ignoreDevUnusedFiles": true,
- "bigPackageSizeSupport": false,
- "useIsolateContext": true
- },
- "condition": {},
- "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
- "projectname": "BeadQR",
- "libVersion": "3.17.1"
-}
\ No newline at end of file
diff --git a/BeadQR/uploadCloudFunction.sh b/BeadQR/uploadCloudFunction.sh
deleted file mode 100644
index df311b39a9e52abb5444e47a84208134df1495b2..0000000000000000000000000000000000000000
--- a/BeadQR/uploadCloudFunction.sh
+++ /dev/null
@@ -1 +0,0 @@
-${installPath} cloud functions deploy --e ${envId} --n quickstartFunctions --r --project ${projectPath}
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..ed857a37d0de6a2e706a93734f00f6f9c6008fb9
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,28 @@
+# Surf Mystery Box 赠链追踪 — Hugging Face Spaces image
+# Stage 1: build the Vite frontend
+FROM oven/bun:1-slim AS web
+
+WORKDIR /web
+COPY frontend/package.json frontend/bun.lock ./
+RUN bun install
+
+COPY frontend/ ./
+# Served from the domain root, so assets use relative paths.
+ENV BASE_PATH=""
+RUN bun run build:client
+
+# Stage 2: backend + API + static files on one port
+FROM oven/bun:1-slim
+
+WORKDIR /app
+ENV NODE_ENV=production \
+ PORT=7860
+
+COPY package.json bun.lock ./
+RUN bun install --production
+
+COPY . .
+COPY --from=web /web/dist/client ./public
+
+EXPOSE 7860
+CMD ["bun", "server.js"]
diff --git a/README.md b/README.md
index 185db1017255a47eef50f0d7ffb65bd8e4f5c7a2..faa6ec8cc494d6888dbbd04231c7cde2e33e7de1 100644
--- a/README.md
+++ b/README.md
@@ -1,95 +1,39 @@
---
-title: 豆维 · 可扫码的拼豆 宣传片
-emoji: 🟡
-colorFrom: yellow
-colorTo: pink
-sdk: static
-app_file: index.html
+title: Surf Mystery Box Tracker
+emoji: 🎁
+colorFrom: purple
+colorTo: indigo
+sdk: docker
+app_port: 7860
pinned: false
---
-# 豆维 · 可扫码的拼豆 —— 宣传片工作室
+# Surf Mystery Box 赠链追踪
-在网页中播放宣传片,可选「和 AI / 豆包 AI / WorkBuddy 一起写」三个版本,
-浏览器内导出 MP4(横屏 B 站 1920×1080 / 竖屏抖音 1080×1920,24/30/60 fps),
-附横竖封面与抖音、B 站发布文案。
+自动收集 X / Telegram 上分享的 `asksurf.ai/mystery-box/g/` 赠链,并逐个检查是否还有名额。
-- `BeadQR/`:小程序源码
-- 根目录中文命名文件:原始素材
-- `media/`、`vo/`:宣传片用到的转码素材与旁白
-- `assets/`:网页播放器 / 渲染器 / 导出器(构建产物)
+## 功能
----
-
-## 第 3 轮修改 · 工作计划(先写计划,再动手;每完成一个大动作推送一次)
-
-### 0. 现状分析
-- Space 中只有 Vite 构建产物(`assets/App-*.js`),原始 TS 源码未入库。
-- 方案:把 `App-*.js` 用 prettier 展开为可读代码,在其上直接修改场景(Canvas 2D 渲染器)、
- 时间轴、旁白表、豆子绘制函数;修改后以新文件名发布并更新 `index-*.js` 的引用(避免 CDN 缓存旧文件)。
-- 关键结构:`of` = 场景表(hook → scan → title → problem → algo → step1 → step2 → palette → check →
- step3 → hands → iron → scan2 → peel → ai → end);`nf` = 旁白分句时间表;`mr/Rd` = 豆子精灵绘制;
- 各场景绘制函数通过 `switch(scene.id)` 分发。
-
-### 1. 开场「有没有一种可能」(00:00)
-- 问题:画面卡顿;画面上用了真实二维码。
-- 做法:
- - 去掉开场里逐帧生成/重绘的真实二维码与大量逐格绘制,改为**极简矢量图标**:
- - AI = 圆角方块 + 「AI」字样 + 小星光(sparkle)
- - 二维码 = 极简 QR 图标(三个定位角 + 少量点,不可扫描,仅示意)
- - 艺术二维码 = 定位角图标 + 渐变/花纹填充
- - 拼豆 = 三颗圆豆图标
- - 所有图标预渲染进离屏 canvas 缓存,每帧只做 drawImage + 变换,消除卡顿。
- - 动画:图标依次弹入(ease-out-back),“+ / =” 渐显,第二行「拼豆 + 二维码 = ?」。
-
-### 2. 豆维登场(原 00:19)
-- 去掉微信小程序码周围的豆子环。
-- 小程序码恢复为**原始的圆角方形**卡片(不再裁成圆形)。
-
-### 3. 调整顺序:想法 → 用 AI 实现 → 豆维登场
-- 新顺序:`hook(想法) → scan(扫码读出) → ai(和 AI 一起写) → title(豆维登场) → problem → … → peel → end`
-- 「顺便一提」不再适合放在前面,重新生成 AI / 豆包 AI / WorkBuddy 三个版本旁白:
- 「于是,我和 X 一起写代码,把这个想法变成了一个小程序。」并重新对齐字幕分句时间。
-- 同步修改:配乐能量曲线、转场、发布文案中的描述顺序。
-
-### 4. 第二步 · 选一张照片
-- 换成用户上传的照片(文件:`media/user_photo.jpg`);
-- 同时在网页上增加「替换照片」按钮,可直接选本地照片实时替换(导出视频也会使用它)。
-
-### 5. 豆子美化
-- 重写豆子精灵:圆柱短管造型(外圈 + 中心孔),
- - 径向渐变体积光、顶部柔和高光、内孔暗部 + 内壁反光、轻微环境光遮蔽与柔和投影;
- - 颜色按明度自适应(浅色豆不过曝,深色豆不发灰);
- - 精灵按颜色+尺寸缓存,保证性能。
+- **X**:每 15 分钟读取分享者的主页最新帖子(并解析短链确认是赠链);登录 X 后可实时搜索关键词
+- **Telegram**:用手机号登录 Telegram 账号后,可以读取**私有频道 / 私有群**里的赠链消息;未登录时读取公开频道
+- **名额检查**:每 5 分钟调用赠链接口复查剩余名额
+- **推送**:一旦发现有「还有名额」的赠链,立刻推送到企业微信机器人(每个赠链只推一次)
+- **界面**:收录列表、来源筛选、还有名额的赠链一键复制、倒计时
-### 6. 验证与发布
-- 本地起静态服务 + headless Chrome 截取每个改动场景的关键帧,检查画面和无报错;
-- 推送到 Ethscriptions/cut,线上页面再次检查。
+## 需要的配置
-### 进度
-- [x] 计划写入 README
-- [x] 1 开场重做(极简图标、去卡顿;图标与豆子精灵加载时预热)
-- [x] 2 豆维登场小程序码(去掉豆子环,恢复圆角方形卡片)
-- [x] 3 场景顺序 + 新旁白(想法 → 和 AI 一起写 → 豆维登场;三版本旁白重录)
-- [x] 4 照片替换(支持 `media/user_photo.jpg` 自动加载 + 页面「替换照片」按钮;已换成用户上传的照片 `media/user_photo.jpg`(原图存档于 `BeadQR/docs/source-photo.jpeg`))
-- [x] 5 豆子美化(果冻质感:左上受光体积、通透内孔、双层高光、柔和接触阴影;精灵 200px 缓存)
-- [x] 6 验证与发布
- - 用离线渲染器(node + Skia canvas)逐 2.5 秒渲染横屏、逐 4 秒渲染竖屏全片,16 个场景全部无报错;
- - 线上 `ethscriptions-cut.static.hf.space` 已更新到 `App-v3561c02df.js`,与本地文件逐字节一致;
- - 未在真实浏览器中测试「替换照片」按钮和完整 MP4 导出(沙箱缺少 Chrome 运行库)。
+| 名称 | 类型 | 说明 |
+| --- | --- | --- |
+| `SURF_API_KEY` | Secret | Surf 平台密钥(数据接口 + 数据库) |
+| `SURF_API_BASE_URL` | Variable | `https://api.asksurf.ai/gateway/v1` |
-### 如何换成你的照片
-1. 把照片命名为 `user_photo.jpg`,上传到 Space 的 `media/` 目录,页面会自动用它(居中裁成正方形);
-2. 或者在网页播放器工具栏点「替换照片」,直接选本地照片,预览和导出都会用这张照片。
+企业微信机器人地址、X Cookie、Telegram 登录都在页面「数据源设置」里配置,保存在数据库里。
-### 修复记录 · 页面报 “Failed to load dependencies”
-- 原因:上一版发布的 `App-*.js` 里,仍在引用已经改名删除的 `index-Pz9S9NhM.js`
- 和 `mediabunny-aac-encoder-Bj5AxWWW.js`。这两个文件返回 404,导致入口加载失败。
-- 修复:统一改为新文件名(`*-v3b174138.js`),并逐个检查 `assets/` 中所有相对引用都能找到对应文件。
- 用 Node 实际加载了 App 和 AAC 编码器两个模块,模块之间的导入导出都能正确对上。
-- 发布流程:以后每次发布前都先跑这个引用检查脚本,避免再次出现缺文件。
+## 本地运行
-### 更新 · 第二步照片已替换
-- 用户上传的像素小牛图:去掉外圈约 8px 的细灰边框,裁成正方形,缩放为 1200×1200,保存为 `media/user_photo.jpg`;
-- 页面加载时自动使用这张照片。「选一张照片」、照片融合成拼豆二维码、MARD 配色、扫码自检这几段画面,都改为基于这张照片生成;
-- 用离线渲染器检查了横屏、竖屏的第二步画面;线上文件可正常访问,允许跨域读取。
+```bash
+bun install
+cd frontend && bun install && bun run build:client && cd ..
+cp -r frontend/dist/client public
+PORT=7860 bun server.js
+```
diff --git a/assets/App-v3b174138.js b/assets/App-v3b174138.js
deleted file mode 100644
index 1bfc6eb66479e3002c8d1a5628a0557d4468c7a7..0000000000000000000000000000000000000000
--- a/assets/App-v3b174138.js
+++ /dev/null
@@ -1,34389 +0,0 @@
-const __vite__mapDeps = (
- i,
- m = __vite__mapDeps,
- d = m.f ||
- (m.f = [
- "./mediabunny-aac-encoder-v3b174138.js",
- "./index-v3b174138.js",
- "./index-B7FfWQ40.css",
- "./jsx-dev-runtime-Czb3f8pQ.js",
- "./index-BlGQAcOD.js",
- "./index-Br42UDbl.js",
- ]),
-) => i.map((i) => d[i]);
-var ad = Object.defineProperty;
-var od = (r, e, t) =>
- e in r
- ? ad(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t })
- : (r[e] = t);
-var Bn = (r, e, t) => od(r, typeof e != "symbol" ? e + "" : e, t);
-import { j as U } from "./jsx-dev-runtime-Czb3f8pQ.js";
-import { r as ye } from "./index-Br42UDbl.js";
-import { _ as cd } from "./index-v3b174138.js";
-/**
- * @license lucide-react v0.454.0 - ISC
- *
- * This source code is licensed under the ISC license.
- * See the LICENSE file in the root directory of this source tree.
- */ const ld = (r) => r.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(),
- rl = (...r) =>
- r
- .filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t)
- .join(" ")
- .trim();
-/**
- * @license lucide-react v0.454.0 - ISC
- *
- * This source code is licensed under the ISC license.
- * See the LICENSE file in the root directory of this source tree.
- */ var ud = {
- xmlns: "http://www.w3.org/2000/svg",
- width: 24,
- height: 24,
- viewBox: "0 0 24 24",
- fill: "none",
- stroke: "currentColor",
- strokeWidth: 2,
- strokeLinecap: "round",
- strokeLinejoin: "round",
-};
-/**
- * @license lucide-react v0.454.0 - ISC
- *
- * This source code is licensed under the ISC license.
- * See the LICENSE file in the root directory of this source tree.
- */ const dd = ye.forwardRef(
- (
- {
- color: r = "currentColor",
- size: e = 24,
- strokeWidth: t = 2,
- absoluteStrokeWidth: n,
- className: i = "",
- children: s,
- iconNode: a,
- ...o
- },
- c,
- ) =>
- ye.createElement(
- "svg",
- {
- ref: c,
- ...ud,
- width: e,
- height: e,
- stroke: r,
- strokeWidth: n ? (Number(t) * 24) / Number(e) : t,
- className: rl("lucide", i),
- ...o,
- },
- [
- ...a.map(([u, l]) => ye.createElement(u, l)),
- ...(Array.isArray(s) ? s : [s]),
- ],
- ),
-);
-/**
- * @license lucide-react v0.454.0 - ISC
- *
- * This source code is licensed under the ISC license.
- * See the LICENSE file in the root directory of this source tree.
- */ const Nt = (r, e) => {
- const t = ye.forwardRef(({ className: n, ...i }, s) =>
- ye.createElement(dd, {
- ref: s,
- iconNode: e,
- className: rl(`lucide-${ld(r)}`, n),
- ...i,
- }),
- );
- return ((t.displayName = `${r}`), t);
-};
-/**
- * @license lucide-react v0.454.0 - ISC
- *
- * This source code is licensed under the ISC license.
- * See the LICENSE file in the root directory of this source tree.
- */ const fd = Nt("Captions", [
- [
- "rect",
- {
- width: "18",
- height: "14",
- x: "3",
- y: "5",
- rx: "2",
- ry: "2",
- key: "12ruh7",
- },
- ],
- ["path", { d: "M7 15h4M15 15h2M7 11h2M13 11h4", key: "1ueiar" }],
-]);
-/**
- * @license lucide-react v0.454.0 - ISC
- *
- * This source code is licensed under the ISC license.
- * See the LICENSE file in the root directory of this source tree.
- */ const hd = Nt("Check", [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]]);
-/**
- * @license lucide-react v0.454.0 - ISC
- *
- * This source code is licensed under the ISC license.
- * See the LICENSE file in the root directory of this source tree.
- */ const md = Nt("Copy", [
- [
- "rect",
- {
- width: "14",
- height: "14",
- x: "8",
- y: "8",
- rx: "2",
- ry: "2",
- key: "17jyea",
- },
- ],
- [
- "path",
- {
- d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",
- key: "zix9uf",
- },
- ],
-]);
-/**
- * @license lucide-react v0.454.0 - ISC
- *
- * This source code is licensed under the ISC license.
- * See the LICENSE file in the root directory of this source tree.
- */ const nl = Nt("Download", [
- ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }],
- ["polyline", { points: "7 10 12 15 17 10", key: "2ggqvy" }],
- ["line", { x1: "12", x2: "12", y1: "15", y2: "3", key: "1vk2je" }],
-]);
-/**
- * @license lucide-react v0.454.0 - ISC
- *
- * This source code is licensed under the ISC license.
- * See the LICENSE file in the root directory of this source tree.
- */ const pd = Nt("Film", [
- [
- "rect",
- { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" },
- ],
- ["path", { d: "M7 3v18", key: "bbkbws" }],
- ["path", { d: "M3 7.5h4", key: "zfgn84" }],
- ["path", { d: "M3 12h18", key: "1i2n21" }],
- ["path", { d: "M3 16.5h4", key: "1230mu" }],
- ["path", { d: "M17 3v18", key: "in4fa5" }],
- ["path", { d: "M17 7.5h4", key: "myr1c1" }],
- ["path", { d: "M17 16.5h4", key: "go4c1d" }],
-]);
-/**
- * @license lucide-react v0.454.0 - ISC
- *
- * This source code is licensed under the ISC license.
- * See the LICENSE file in the root directory of this source tree.
- */ const ca = Nt("LoaderCircle", [
- ["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }],
-]);
-/**
- * @license lucide-react v0.454.0 - ISC
- *
- * This source code is licensed under the ISC license.
- * See the LICENSE file in the root directory of this source tree.
- */ const gd = Nt("Pause", [
- [
- "rect",
- { x: "14", y: "4", width: "4", height: "16", rx: "1", key: "zuxfzm" },
- ],
- [
- "rect",
- { x: "6", y: "4", width: "4", height: "16", rx: "1", key: "1okwgv" },
- ],
-]);
-/**
- * @license lucide-react v0.454.0 - ISC
- *
- * This source code is licensed under the ISC license.
- * See the LICENSE file in the root directory of this source tree.
- */ const yo = Nt("Play", [
- ["polygon", { points: "6 3 20 12 6 21 6 3", key: "1oa8hb" }],
-]);
-/**
- * @license lucide-react v0.454.0 - ISC
- *
- * This source code is licensed under the ISC license.
- * See the LICENSE file in the root directory of this source tree.
- */ const bd = Nt("RotateCcw", [
- [
- "path",
- { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8", key: "1357e3" },
- ],
- ["path", { d: "M3 3v5h5", key: "1xhq8a" }],
-]);
-/**
- * @license lucide-react v0.454.0 - ISC
- *
- * This source code is licensed under the ISC license.
- * See the LICENSE file in the root directory of this source tree.
- */ const wd = Nt("ShieldAlert", [
- [
- "path",
- {
- d: "M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",
- key: "oel41y",
- },
- ],
- ["path", { d: "M12 8v4", key: "1got3b" }],
- ["path", { d: "M12 16h.01", key: "1drbdi" }],
-]);
-/**
- * @license lucide-react v0.454.0 - ISC
- *
- * This source code is licensed under the ISC license.
- * See the LICENSE file in the root directory of this source tree.
- */ const yd = Nt("X", [
- ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
- ["path", { d: "m6 6 12 12", key: "d8bk6v" }],
- ]),
- Tn = function (r, e) {
- let i = r;
- const s = Vn[e];
- let a = null,
- o = 0,
- c = null;
- const u = [],
- l = {},
- d = function (w, x) {
- ((o = i * 4 + 17),
- (a = (function (k) {
- const S = new Array(k);
- for (let E = 0; E < k; E += 1) {
- S[E] = new Array(k);
- for (let B = 0; B < k; B += 1) S[E][B] = null;
- }
- return S;
- })(o)),
- f(0, 0),
- f(o - 7, 0),
- f(0, o - 7),
- m(),
- p(),
- g(w, x),
- i >= 7 && b(w),
- c == null && (c = _(i, s, u)),
- y(c, x));
- },
- f = function (w, x) {
- for (let k = -1; k <= 7; k += 1)
- if (!(w + k <= -1 || o <= w + k))
- for (let S = -1; S <= 7; S += 1)
- x + S <= -1 ||
- o <= x + S ||
- ((0 <= k && k <= 6 && (S == 0 || S == 6)) ||
- (0 <= S && S <= 6 && (k == 0 || k == 6)) ||
- (2 <= k && k <= 4 && 2 <= S && S <= 4)
- ? (a[w + k][x + S] = !0)
- : (a[w + k][x + S] = !1));
- },
- h = function () {
- let w = 0,
- x = 0;
- for (let k = 0; k < 8; k += 1) {
- d(!0, k);
- const S = kr.getLostPoint(l);
- (k == 0 || w > S) && ((w = S), (x = k));
- }
- return x;
- },
- p = function () {
- for (let w = 8; w < o - 8; w += 1)
- a[w][6] == null && (a[w][6] = w % 2 == 0);
- for (let w = 8; w < o - 8; w += 1)
- a[6][w] == null && (a[6][w] = w % 2 == 0);
- },
- m = function () {
- const w = kr.getPatternPosition(i);
- for (let x = 0; x < w.length; x += 1)
- for (let k = 0; k < w.length; k += 1) {
- const S = w[x],
- E = w[k];
- if (a[S][E] == null)
- for (let B = -2; B <= 2; B += 1)
- for (let R = -2; R <= 2; R += 1)
- B == -2 || B == 2 || R == -2 || R == 2 || (B == 0 && R == 0)
- ? (a[S + B][E + R] = !0)
- : (a[S + B][E + R] = !1);
- }
- },
- b = function (w) {
- const x = kr.getBCHTypeNumber(i);
- for (let k = 0; k < 18; k += 1) {
- const S = !w && ((x >> k) & 1) == 1;
- a[Math.floor(k / 3)][(k % 3) + o - 8 - 3] = S;
- }
- for (let k = 0; k < 18; k += 1) {
- const S = !w && ((x >> k) & 1) == 1;
- a[(k % 3) + o - 8 - 3][Math.floor(k / 3)] = S;
- }
- },
- g = function (w, x) {
- const k = (s << 3) | x,
- S = kr.getBCHTypeInfo(k);
- for (let E = 0; E < 15; E += 1) {
- const B = !w && ((S >> E) & 1) == 1;
- E < 6
- ? (a[E][8] = B)
- : E < 8
- ? (a[E + 1][8] = B)
- : (a[o - 15 + E][8] = B);
- }
- for (let E = 0; E < 15; E += 1) {
- const B = !w && ((S >> E) & 1) == 1;
- E < 8
- ? (a[8][o - E - 1] = B)
- : E < 9
- ? (a[8][15 - E - 1 + 1] = B)
- : (a[8][15 - E - 1] = B);
- }
- a[o - 8][8] = !w;
- },
- y = function (w, x) {
- let k = -1,
- S = o - 1,
- E = 7,
- B = 0;
- const R = kr.getMaskFunction(x);
- for (let M = o - 1; M > 0; M -= 2)
- for (M == 6 && (M -= 1); ;) {
- for (let z = 0; z < 2; z += 1)
- if (a[S][M - z] == null) {
- let q = !1;
- (B < w.length && (q = ((w[B] >>> E) & 1) == 1),
- R(S, M - z) && (q = !q),
- (a[S][M - z] = q),
- (E -= 1),
- E == -1 && ((B += 1), (E = 7)));
- }
- if (((S += k), S < 0 || o <= S)) {
- ((S -= k), (k = -k));
- break;
- }
- }
- },
- C = function (w, x) {
- let k = 0,
- S = 0,
- E = 0;
- const B = new Array(x.length),
- R = new Array(x.length);
- for (let j = 0; j < x.length; j += 1) {
- const se = x[j].dataCount,
- le = x[j].totalCount - se;
- ((S = Math.max(S, se)),
- (E = Math.max(E, le)),
- (B[j] = new Array(se)));
- for (let ie = 0; ie < B[j].length; ie += 1)
- B[j][ie] = 255 & w.getBuffer()[ie + k];
- k += se;
- const ue = kr.getErrorCorrectPolynomial(le),
- K = Yn(B[j], ue.getLength() - 1).mod(ue);
- R[j] = new Array(ue.getLength() - 1);
- for (let ie = 0; ie < R[j].length; ie += 1) {
- const Ie = ie + K.getLength() - R[j].length;
- R[j][ie] = Ie >= 0 ? K.getAt(Ie) : 0;
- }
- }
- let M = 0;
- for (let j = 0; j < x.length; j += 1) M += x[j].totalCount;
- const z = new Array(M);
- let q = 0;
- for (let j = 0; j < S; j += 1)
- for (let se = 0; se < x.length; se += 1)
- j < B[se].length && ((z[q] = B[se][j]), (q += 1));
- for (let j = 0; j < E; j += 1)
- for (let se = 0; se < x.length; se += 1)
- j < R[se].length && ((z[q] = R[se][j]), (q += 1));
- return z;
- },
- _ = function (w, x, k) {
- const S = ko.getRSBlocks(w, x),
- E = To();
- for (let R = 0; R < k.length; R += 1) {
- const M = k[R];
- (E.put(M.getMode(), 4),
- E.put(M.getLength(), kr.getLengthInBits(M.getMode(), w)),
- M.write(E));
- }
- let B = 0;
- for (let R = 0; R < S.length; R += 1) B += S[R].dataCount;
- if (E.getLengthInBits() > B * 8)
- throw (
- "code length overflow. (" + E.getLengthInBits() + ">" + B * 8 + ")"
- );
- for (
- E.getLengthInBits() + 4 <= B * 8 && E.put(0, 4);
- E.getLengthInBits() % 8 != 0;
- )
- E.putBit(!1);
- for (
- ;
- !(
- E.getLengthInBits() >= B * 8 ||
- (E.put(236, 8), E.getLengthInBits() >= B * 8)
- );
- )
- E.put(17, 8);
- return C(E, S);
- };
- ((l.addData = function (w, x) {
- x = x || "Byte";
- let k = null;
- switch (x) {
- case "Numeric":
- k = kd(w);
- break;
- case "Alphanumeric":
- k = Td(w);
- break;
- case "Byte":
- k = xd(w);
- break;
- case "Kanji":
- k = Sd(w);
- break;
- default:
- throw "mode:" + x;
- }
- (u.push(k), (c = null));
- }),
- (l.isDark = function (w, x) {
- if (w < 0 || o <= w || x < 0 || o <= x) throw w + "," + x;
- return a[w][x];
- }),
- (l.getModuleCount = function () {
- return o;
- }),
- (l.make = function () {
- if (i < 1) {
- let w = 1;
- for (; w < 40; w++) {
- const x = ko.getRSBlocks(w, s),
- k = To();
- for (let E = 0; E < u.length; E++) {
- const B = u[E];
- (k.put(B.getMode(), 4),
- k.put(B.getLength(), kr.getLengthInBits(B.getMode(), w)),
- B.write(k));
- }
- let S = 0;
- for (let E = 0; E < x.length; E++) S += x[E].dataCount;
- if (k.getLengthInBits() <= S * 8) break;
- }
- i = w;
- }
- d(!1, h());
- }),
- (l.createTableTag = function (w, x) {
- ((w = w || 2), (x = typeof x > "u" ? w * 4 : x));
- let k = "";
- ((k += ''),
- (k += ""));
- for (let S = 0; S < l.getModuleCount(); S += 1) {
- k += "";
- for (let E = 0; E < l.getModuleCount(); E += 1)
- ((k += ' | '));
- k += "
";
- }
- return ((k += ""), (k += "
"), k);
- }),
- (l.createSvgTag = function (w, x, k, S) {
- let E = {};
- (typeof arguments[0] == "object" &&
- ((E = arguments[0]),
- (w = E.cellSize),
- (x = E.margin),
- (k = E.alt),
- (S = E.title)),
- (w = w || 2),
- (x = typeof x > "u" ? w * 4 : x),
- (k = typeof k == "string" ? { text: k } : k || {}),
- (k.text = k.text || null),
- (k.id = k.text ? k.id || "qrcode-description" : null),
- (S = typeof S == "string" ? { text: S } : S || {}),
- (S.text = S.text || null),
- (S.id = S.text ? S.id || "qrcode-title" : null));
- const B = l.getModuleCount() * w + x * 2;
- let R,
- M,
- z,
- q,
- j = "",
- se;
- for (
- se = "l" + w + ",0 0," + w + " -" + w + ",0 0,-" + w + "z ",
- j += '"),
- j
- );
- }),
- (l.createDataURL = function (w, x) {
- ((w = w || 2), (x = typeof x > "u" ? w * 4 : x));
- const k = l.getModuleCount() * w + x * 2,
- S = x,
- E = k - x;
- return Ed(k, k, function (B, R) {
- if (S <= B && B < E && S <= R && R < E) {
- const M = Math.floor((B - S) / w),
- z = Math.floor((R - S) / w);
- return l.isDark(z, M) ? 0 : 1;
- } else return 1;
- });
- }),
- (l.createImgTag = function (w, x, k) {
- ((w = w || 2), (x = typeof x > "u" ? w * 4 : x));
- const S = l.getModuleCount() * w + x * 2;
- let E = "";
- return (
- (E += "
"),
- E
- );
- }));
- const v = function (w) {
- let x = "";
- for (let k = 0; k < w.length; k += 1) {
- const S = w.charAt(k);
- switch (S) {
- case "<":
- x += "<";
- break;
- case ">":
- x += ">";
- break;
- case "&":
- x += "&";
- break;
- case '"':
- x += """;
- break;
- default:
- x += S;
- break;
- }
- }
- return x;
- },
- I = function (w) {
- w = typeof w > "u" ? 2 : w;
- const k = l.getModuleCount() * 1 + w * 2,
- S = w,
- E = k - w;
- let B, R, M, z, q;
- const j = { "██": "█", "█ ": "▀", " █": "▄", " ": " " },
- se = { "██": "▀", "█ ": "▀", " █": " ", " ": " " };
- let le = "";
- for (B = 0; B < k; B += 2) {
- for (
- M = Math.floor((B - S) / 1), z = Math.floor((B + 1 - S) / 1), R = 0;
- R < k;
- R += 1
- )
- ((q = "█"),
- S <= R &&
- R < E &&
- S <= B &&
- B < E &&
- l.isDark(M, Math.floor((R - S) / 1)) &&
- (q = " "),
- S <= R &&
- R < E &&
- S <= B + 1 &&
- B + 1 < E &&
- l.isDark(z, Math.floor((R - S) / 1))
- ? (q += " ")
- : (q += "█"),
- (le += w < 1 && B + 1 >= E ? se[q] : j[q]));
- le += `
-`;
- }
- return k % 2 && w > 0
- ? le.substring(0, le.length - k - 1) + Array(k + 1).join("▀")
- : le.substring(0, le.length - 1);
- };
- return (
- (l.createASCII = function (w, x) {
- if (((w = w || 1), w < 2)) return I(x);
- ((w -= 1), (x = typeof x > "u" ? w * 2 : x));
- const k = l.getModuleCount() * w + x * 2,
- S = x,
- E = k - x;
- let B, R, M, z;
- const q = Array(w + 1).join("██"),
- j = Array(w + 1).join(" ");
- let se = "",
- le = "";
- for (B = 0; B < k; B += 1) {
- for (M = Math.floor((B - S) / w), le = "", R = 0; R < k; R += 1)
- ((z = 1),
- S <= R &&
- R < E &&
- S <= B &&
- B < E &&
- l.isDark(M, Math.floor((R - S) / w)) &&
- (z = 0),
- (le += z ? q : j));
- for (M = 0; M < w; M += 1)
- se +=
- le +
- `
-`;
- }
- return se.substring(0, se.length - 1);
- }),
- (l.renderTo2dContext = function (w, x) {
- x = x || 2;
- const k = l.getModuleCount();
- for (let S = 0; S < k; S++)
- for (let E = 0; E < k; E++)
- ((w.fillStyle = l.isDark(S, E) ? "black" : "white"),
- w.fillRect(E * x, S * x, x, x));
- }),
- l
- );
- };
-Tn.stringToBytes = function (r) {
- const e = [];
- for (let t = 0; t < r.length; t += 1) {
- const n = r.charCodeAt(t);
- e.push(n & 255);
- }
- return e;
-};
-Tn.createStringToBytes = function (r, e) {
- const t = (function () {
- const i = Cd(r),
- s = function () {
- const c = i.read();
- if (c == -1) throw "eof";
- return c;
- };
- let a = 0;
- const o = {};
- for (;;) {
- const c = i.read();
- if (c == -1) break;
- const u = s(),
- l = s(),
- d = s(),
- f = String.fromCharCode((c << 8) | u),
- h = (l << 8) | d;
- ((o[f] = h), (a += 1));
- }
- if (a != e) throw a + " != " + e;
- return o;
- })(),
- n = 63;
- return function (i) {
- const s = [];
- for (let a = 0; a < i.length; a += 1) {
- const o = i.charCodeAt(a);
- if (o < 128) s.push(o);
- else {
- const c = t[i.charAt(a)];
- typeof c == "number"
- ? (c & 255) == c
- ? s.push(c)
- : (s.push(c >>> 8), s.push(c & 255))
- : s.push(n);
- }
- }
- return s;
- };
-};
-const et = {
- MODE_NUMBER: 1,
- MODE_ALPHA_NUM: 2,
- MODE_8BIT_BYTE: 4,
- MODE_KANJI: 8,
- },
- Vn = { L: 1, M: 0, Q: 3, H: 2 },
- yr = {
- PATTERN000: 0,
- PATTERN001: 1,
- PATTERN010: 2,
- PATTERN011: 3,
- PATTERN100: 4,
- PATTERN101: 5,
- PATTERN110: 6,
- PATTERN111: 7,
- },
- kr = (function () {
- const r = [
- [],
- [6, 18],
- [6, 22],
- [6, 26],
- [6, 30],
- [6, 34],
- [6, 22, 38],
- [6, 24, 42],
- [6, 26, 46],
- [6, 28, 50],
- [6, 30, 54],
- [6, 32, 58],
- [6, 34, 62],
- [6, 26, 46, 66],
- [6, 26, 48, 70],
- [6, 26, 50, 74],
- [6, 30, 54, 78],
- [6, 30, 56, 82],
- [6, 30, 58, 86],
- [6, 34, 62, 90],
- [6, 28, 50, 72, 94],
- [6, 26, 50, 74, 98],
- [6, 30, 54, 78, 102],
- [6, 28, 54, 80, 106],
- [6, 32, 58, 84, 110],
- [6, 30, 58, 86, 114],
- [6, 34, 62, 90, 118],
- [6, 26, 50, 74, 98, 122],
- [6, 30, 54, 78, 102, 126],
- [6, 26, 52, 78, 104, 130],
- [6, 30, 56, 82, 108, 134],
- [6, 34, 60, 86, 112, 138],
- [6, 30, 58, 86, 114, 142],
- [6, 34, 62, 90, 118, 146],
- [6, 30, 54, 78, 102, 126, 150],
- [6, 24, 50, 76, 102, 128, 154],
- [6, 28, 54, 80, 106, 132, 158],
- [6, 32, 58, 84, 110, 136, 162],
- [6, 26, 54, 82, 110, 138, 166],
- [6, 30, 58, 86, 114, 142, 170],
- ],
- e = 1335,
- t = 7973,
- n = 21522,
- i = {},
- s = function (a) {
- let o = 0;
- for (; a != 0;) ((o += 1), (a >>>= 1));
- return o;
- };
- return (
- (i.getBCHTypeInfo = function (a) {
- let o = a << 10;
- for (; s(o) - s(e) >= 0;) o ^= e << (s(o) - s(e));
- return ((a << 10) | o) ^ n;
- }),
- (i.getBCHTypeNumber = function (a) {
- let o = a << 12;
- for (; s(o) - s(t) >= 0;) o ^= t << (s(o) - s(t));
- return (a << 12) | o;
- }),
- (i.getPatternPosition = function (a) {
- return r[a - 1];
- }),
- (i.getMaskFunction = function (a) {
- switch (a) {
- case yr.PATTERN000:
- return function (o, c) {
- return (o + c) % 2 == 0;
- };
- case yr.PATTERN001:
- return function (o, c) {
- return o % 2 == 0;
- };
- case yr.PATTERN010:
- return function (o, c) {
- return c % 3 == 0;
- };
- case yr.PATTERN011:
- return function (o, c) {
- return (o + c) % 3 == 0;
- };
- case yr.PATTERN100:
- return function (o, c) {
- return (Math.floor(o / 2) + Math.floor(c / 3)) % 2 == 0;
- };
- case yr.PATTERN101:
- return function (o, c) {
- return ((o * c) % 2) + ((o * c) % 3) == 0;
- };
- case yr.PATTERN110:
- return function (o, c) {
- return (((o * c) % 2) + ((o * c) % 3)) % 2 == 0;
- };
- case yr.PATTERN111:
- return function (o, c) {
- return (((o * c) % 3) + ((o + c) % 2)) % 2 == 0;
- };
- default:
- throw "bad maskPattern:" + a;
- }
- }),
- (i.getErrorCorrectPolynomial = function (a) {
- let o = Yn([1], 0);
- for (let c = 0; c < a; c += 1) o = o.multiply(Yn([1, Pr.gexp(c)], 0));
- return o;
- }),
- (i.getLengthInBits = function (a, o) {
- if (1 <= o && o < 10)
- switch (a) {
- case et.MODE_NUMBER:
- return 10;
- case et.MODE_ALPHA_NUM:
- return 9;
- case et.MODE_8BIT_BYTE:
- return 8;
- case et.MODE_KANJI:
- return 8;
- default:
- throw "mode:" + a;
- }
- else if (o < 27)
- switch (a) {
- case et.MODE_NUMBER:
- return 12;
- case et.MODE_ALPHA_NUM:
- return 11;
- case et.MODE_8BIT_BYTE:
- return 16;
- case et.MODE_KANJI:
- return 10;
- default:
- throw "mode:" + a;
- }
- else if (o < 41)
- switch (a) {
- case et.MODE_NUMBER:
- return 14;
- case et.MODE_ALPHA_NUM:
- return 13;
- case et.MODE_8BIT_BYTE:
- return 16;
- case et.MODE_KANJI:
- return 12;
- default:
- throw "mode:" + a;
- }
- else throw "type:" + o;
- }),
- (i.getLostPoint = function (a) {
- const o = a.getModuleCount();
- let c = 0;
- for (let d = 0; d < o; d += 1)
- for (let f = 0; f < o; f += 1) {
- let h = 0;
- const p = a.isDark(d, f);
- for (let m = -1; m <= 1; m += 1)
- if (!(d + m < 0 || o <= d + m))
- for (let b = -1; b <= 1; b += 1)
- f + b < 0 ||
- o <= f + b ||
- (m == 0 && b == 0) ||
- (p == a.isDark(d + m, f + b) && (h += 1));
- h > 5 && (c += 3 + h - 5);
- }
- for (let d = 0; d < o - 1; d += 1)
- for (let f = 0; f < o - 1; f += 1) {
- let h = 0;
- (a.isDark(d, f) && (h += 1),
- a.isDark(d + 1, f) && (h += 1),
- a.isDark(d, f + 1) && (h += 1),
- a.isDark(d + 1, f + 1) && (h += 1),
- (h == 0 || h == 4) && (c += 3));
- }
- for (let d = 0; d < o; d += 1)
- for (let f = 0; f < o - 6; f += 1)
- a.isDark(d, f) &&
- !a.isDark(d, f + 1) &&
- a.isDark(d, f + 2) &&
- a.isDark(d, f + 3) &&
- a.isDark(d, f + 4) &&
- !a.isDark(d, f + 5) &&
- a.isDark(d, f + 6) &&
- (c += 40);
- for (let d = 0; d < o; d += 1)
- for (let f = 0; f < o - 6; f += 1)
- a.isDark(f, d) &&
- !a.isDark(f + 1, d) &&
- a.isDark(f + 2, d) &&
- a.isDark(f + 3, d) &&
- a.isDark(f + 4, d) &&
- !a.isDark(f + 5, d) &&
- a.isDark(f + 6, d) &&
- (c += 40);
- let u = 0;
- for (let d = 0; d < o; d += 1)
- for (let f = 0; f < o; f += 1) a.isDark(f, d) && (u += 1);
- const l = Math.abs((100 * u) / o / o - 50) / 5;
- return ((c += l * 10), c);
- }),
- i
- );
- })(),
- Pr = (function () {
- const r = new Array(256),
- e = new Array(256);
- for (let n = 0; n < 8; n += 1) r[n] = 1 << n;
- for (let n = 8; n < 256; n += 1)
- r[n] = r[n - 4] ^ r[n - 5] ^ r[n - 6] ^ r[n - 8];
- for (let n = 0; n < 255; n += 1) e[r[n]] = n;
- const t = {};
- return (
- (t.glog = function (n) {
- if (n < 1) throw "glog(" + n + ")";
- return e[n];
- }),
- (t.gexp = function (n) {
- for (; n < 0;) n += 255;
- for (; n >= 256;) n -= 255;
- return r[n];
- }),
- t
- );
- })(),
- Yn = function (r, e) {
- if (typeof r.length > "u") throw r.length + "/" + e;
- const t = (function () {
- let i = 0;
- for (; i < r.length && r[i] == 0;) i += 1;
- const s = new Array(r.length - i + e);
- for (let a = 0; a < r.length - i; a += 1) s[a] = r[a + i];
- return s;
- })(),
- n = {};
- return (
- (n.getAt = function (i) {
- return t[i];
- }),
- (n.getLength = function () {
- return t.length;
- }),
- (n.multiply = function (i) {
- const s = new Array(n.getLength() + i.getLength() - 1);
- for (let a = 0; a < n.getLength(); a += 1)
- for (let o = 0; o < i.getLength(); o += 1)
- s[a + o] ^= Pr.gexp(Pr.glog(n.getAt(a)) + Pr.glog(i.getAt(o)));
- return Yn(s, 0);
- }),
- (n.mod = function (i) {
- if (n.getLength() - i.getLength() < 0) return n;
- const s = Pr.glog(n.getAt(0)) - Pr.glog(i.getAt(0)),
- a = new Array(n.getLength());
- for (let o = 0; o < n.getLength(); o += 1) a[o] = n.getAt(o);
- for (let o = 0; o < i.getLength(); o += 1)
- a[o] ^= Pr.gexp(Pr.glog(i.getAt(o)) + s);
- return Yn(a, 0).mod(i);
- }),
- n
- );
- },
- ko = (function () {
- const r = [
- [1, 26, 19],
- [1, 26, 16],
- [1, 26, 13],
- [1, 26, 9],
- [1, 44, 34],
- [1, 44, 28],
- [1, 44, 22],
- [1, 44, 16],
- [1, 70, 55],
- [1, 70, 44],
- [2, 35, 17],
- [2, 35, 13],
- [1, 100, 80],
- [2, 50, 32],
- [2, 50, 24],
- [4, 25, 9],
- [1, 134, 108],
- [2, 67, 43],
- [2, 33, 15, 2, 34, 16],
- [2, 33, 11, 2, 34, 12],
- [2, 86, 68],
- [4, 43, 27],
- [4, 43, 19],
- [4, 43, 15],
- [2, 98, 78],
- [4, 49, 31],
- [2, 32, 14, 4, 33, 15],
- [4, 39, 13, 1, 40, 14],
- [2, 121, 97],
- [2, 60, 38, 2, 61, 39],
- [4, 40, 18, 2, 41, 19],
- [4, 40, 14, 2, 41, 15],
- [2, 146, 116],
- [3, 58, 36, 2, 59, 37],
- [4, 36, 16, 4, 37, 17],
- [4, 36, 12, 4, 37, 13],
- [2, 86, 68, 2, 87, 69],
- [4, 69, 43, 1, 70, 44],
- [6, 43, 19, 2, 44, 20],
- [6, 43, 15, 2, 44, 16],
- [4, 101, 81],
- [1, 80, 50, 4, 81, 51],
- [4, 50, 22, 4, 51, 23],
- [3, 36, 12, 8, 37, 13],
- [2, 116, 92, 2, 117, 93],
- [6, 58, 36, 2, 59, 37],
- [4, 46, 20, 6, 47, 21],
- [7, 42, 14, 4, 43, 15],
- [4, 133, 107],
- [8, 59, 37, 1, 60, 38],
- [8, 44, 20, 4, 45, 21],
- [12, 33, 11, 4, 34, 12],
- [3, 145, 115, 1, 146, 116],
- [4, 64, 40, 5, 65, 41],
- [11, 36, 16, 5, 37, 17],
- [11, 36, 12, 5, 37, 13],
- [5, 109, 87, 1, 110, 88],
- [5, 65, 41, 5, 66, 42],
- [5, 54, 24, 7, 55, 25],
- [11, 36, 12, 7, 37, 13],
- [5, 122, 98, 1, 123, 99],
- [7, 73, 45, 3, 74, 46],
- [15, 43, 19, 2, 44, 20],
- [3, 45, 15, 13, 46, 16],
- [1, 135, 107, 5, 136, 108],
- [10, 74, 46, 1, 75, 47],
- [1, 50, 22, 15, 51, 23],
- [2, 42, 14, 17, 43, 15],
- [5, 150, 120, 1, 151, 121],
- [9, 69, 43, 4, 70, 44],
- [17, 50, 22, 1, 51, 23],
- [2, 42, 14, 19, 43, 15],
- [3, 141, 113, 4, 142, 114],
- [3, 70, 44, 11, 71, 45],
- [17, 47, 21, 4, 48, 22],
- [9, 39, 13, 16, 40, 14],
- [3, 135, 107, 5, 136, 108],
- [3, 67, 41, 13, 68, 42],
- [15, 54, 24, 5, 55, 25],
- [15, 43, 15, 10, 44, 16],
- [4, 144, 116, 4, 145, 117],
- [17, 68, 42],
- [17, 50, 22, 6, 51, 23],
- [19, 46, 16, 6, 47, 17],
- [2, 139, 111, 7, 140, 112],
- [17, 74, 46],
- [7, 54, 24, 16, 55, 25],
- [34, 37, 13],
- [4, 151, 121, 5, 152, 122],
- [4, 75, 47, 14, 76, 48],
- [11, 54, 24, 14, 55, 25],
- [16, 45, 15, 14, 46, 16],
- [6, 147, 117, 4, 148, 118],
- [6, 73, 45, 14, 74, 46],
- [11, 54, 24, 16, 55, 25],
- [30, 46, 16, 2, 47, 17],
- [8, 132, 106, 4, 133, 107],
- [8, 75, 47, 13, 76, 48],
- [7, 54, 24, 22, 55, 25],
- [22, 45, 15, 13, 46, 16],
- [10, 142, 114, 2, 143, 115],
- [19, 74, 46, 4, 75, 47],
- [28, 50, 22, 6, 51, 23],
- [33, 46, 16, 4, 47, 17],
- [8, 152, 122, 4, 153, 123],
- [22, 73, 45, 3, 74, 46],
- [8, 53, 23, 26, 54, 24],
- [12, 45, 15, 28, 46, 16],
- [3, 147, 117, 10, 148, 118],
- [3, 73, 45, 23, 74, 46],
- [4, 54, 24, 31, 55, 25],
- [11, 45, 15, 31, 46, 16],
- [7, 146, 116, 7, 147, 117],
- [21, 73, 45, 7, 74, 46],
- [1, 53, 23, 37, 54, 24],
- [19, 45, 15, 26, 46, 16],
- [5, 145, 115, 10, 146, 116],
- [19, 75, 47, 10, 76, 48],
- [15, 54, 24, 25, 55, 25],
- [23, 45, 15, 25, 46, 16],
- [13, 145, 115, 3, 146, 116],
- [2, 74, 46, 29, 75, 47],
- [42, 54, 24, 1, 55, 25],
- [23, 45, 15, 28, 46, 16],
- [17, 145, 115],
- [10, 74, 46, 23, 75, 47],
- [10, 54, 24, 35, 55, 25],
- [19, 45, 15, 35, 46, 16],
- [17, 145, 115, 1, 146, 116],
- [14, 74, 46, 21, 75, 47],
- [29, 54, 24, 19, 55, 25],
- [11, 45, 15, 46, 46, 16],
- [13, 145, 115, 6, 146, 116],
- [14, 74, 46, 23, 75, 47],
- [44, 54, 24, 7, 55, 25],
- [59, 46, 16, 1, 47, 17],
- [12, 151, 121, 7, 152, 122],
- [12, 75, 47, 26, 76, 48],
- [39, 54, 24, 14, 55, 25],
- [22, 45, 15, 41, 46, 16],
- [6, 151, 121, 14, 152, 122],
- [6, 75, 47, 34, 76, 48],
- [46, 54, 24, 10, 55, 25],
- [2, 45, 15, 64, 46, 16],
- [17, 152, 122, 4, 153, 123],
- [29, 74, 46, 14, 75, 47],
- [49, 54, 24, 10, 55, 25],
- [24, 45, 15, 46, 46, 16],
- [4, 152, 122, 18, 153, 123],
- [13, 74, 46, 32, 75, 47],
- [48, 54, 24, 14, 55, 25],
- [42, 45, 15, 32, 46, 16],
- [20, 147, 117, 4, 148, 118],
- [40, 75, 47, 7, 76, 48],
- [43, 54, 24, 22, 55, 25],
- [10, 45, 15, 67, 46, 16],
- [19, 148, 118, 6, 149, 119],
- [18, 75, 47, 31, 76, 48],
- [34, 54, 24, 34, 55, 25],
- [20, 45, 15, 61, 46, 16],
- ],
- e = function (i, s) {
- const a = {};
- return ((a.totalCount = i), (a.dataCount = s), a);
- },
- t = {},
- n = function (i, s) {
- switch (s) {
- case Vn.L:
- return r[(i - 1) * 4 + 0];
- case Vn.M:
- return r[(i - 1) * 4 + 1];
- case Vn.Q:
- return r[(i - 1) * 4 + 2];
- case Vn.H:
- return r[(i - 1) * 4 + 3];
- default:
- return;
- }
- };
- return (
- (t.getRSBlocks = function (i, s) {
- const a = n(i, s);
- if (typeof a > "u")
- throw "bad rs block @ typeNumber:" + i + "/errorCorrectionLevel:" + s;
- const o = a.length / 3,
- c = [];
- for (let u = 0; u < o; u += 1) {
- const l = a[u * 3 + 0],
- d = a[u * 3 + 1],
- f = a[u * 3 + 2];
- for (let h = 0; h < l; h += 1) c.push(e(d, f));
- }
- return c;
- }),
- t
- );
- })(),
- To = function () {
- const r = [];
- let e = 0;
- const t = {};
- return (
- (t.getBuffer = function () {
- return r;
- }),
- (t.getAt = function (n) {
- const i = Math.floor(n / 8);
- return ((r[i] >>> (7 - (n % 8))) & 1) == 1;
- }),
- (t.put = function (n, i) {
- for (let s = 0; s < i; s += 1) t.putBit(((n >>> (i - s - 1)) & 1) == 1);
- }),
- (t.getLengthInBits = function () {
- return e;
- }),
- (t.putBit = function (n) {
- const i = Math.floor(e / 8);
- (r.length <= i && r.push(0), n && (r[i] |= 128 >>> (e % 8)), (e += 1));
- }),
- t
- );
- },
- kd = function (r) {
- const e = et.MODE_NUMBER,
- t = r,
- n = {};
- ((n.getMode = function () {
- return e;
- }),
- (n.getLength = function (a) {
- return t.length;
- }),
- (n.write = function (a) {
- const o = t;
- let c = 0;
- for (; c + 2 < o.length;)
- (a.put(i(o.substring(c, c + 3)), 10), (c += 3));
- c < o.length &&
- (o.length - c == 1
- ? a.put(i(o.substring(c, c + 1)), 4)
- : o.length - c == 2 && a.put(i(o.substring(c, c + 2)), 7));
- }));
- const i = function (a) {
- let o = 0;
- for (let c = 0; c < a.length; c += 1) o = o * 10 + s(a.charAt(c));
- return o;
- },
- s = function (a) {
- if ("0" <= a && a <= "9") return a.charCodeAt(0) - 48;
- throw "illegal char :" + a;
- };
- return n;
- },
- Td = function (r) {
- const e = et.MODE_ALPHA_NUM,
- t = r,
- n = {};
- ((n.getMode = function () {
- return e;
- }),
- (n.getLength = function (s) {
- return t.length;
- }),
- (n.write = function (s) {
- const a = t;
- let o = 0;
- for (; o + 1 < a.length;)
- (s.put(i(a.charAt(o)) * 45 + i(a.charAt(o + 1)), 11), (o += 2));
- o < a.length && s.put(i(a.charAt(o)), 6);
- }));
- const i = function (s) {
- if ("0" <= s && s <= "9") return s.charCodeAt(0) - 48;
- if ("A" <= s && s <= "Z") return s.charCodeAt(0) - 65 + 10;
- switch (s) {
- case " ":
- return 36;
- case "$":
- return 37;
- case "%":
- return 38;
- case "*":
- return 39;
- case "+":
- return 40;
- case "-":
- return 41;
- case ".":
- return 42;
- case "/":
- return 43;
- case ":":
- return 44;
- default:
- throw "illegal char :" + s;
- }
- };
- return n;
- },
- xd = function (r) {
- const e = et.MODE_8BIT_BYTE,
- t = Tn.stringToBytes(r),
- n = {};
- return (
- (n.getMode = function () {
- return e;
- }),
- (n.getLength = function (i) {
- return t.length;
- }),
- (n.write = function (i) {
- for (let s = 0; s < t.length; s += 1) i.put(t[s], 8);
- }),
- n
- );
- },
- Sd = function (r) {
- const e = et.MODE_KANJI,
- t = Tn.stringToBytes;
- (function (s, a) {
- const o = t(s);
- if (o.length != 2 || ((o[0] << 8) | o[1]) != a)
- throw "sjis not supported.";
- })("友", 38726);
- const n = t(r),
- i = {};
- return (
- (i.getMode = function () {
- return e;
- }),
- (i.getLength = function (s) {
- return ~~(n.length / 2);
- }),
- (i.write = function (s) {
- const a = n;
- let o = 0;
- for (; o + 1 < a.length;) {
- let c = ((255 & a[o]) << 8) | (255 & a[o + 1]);
- if (33088 <= c && c <= 40956) c -= 33088;
- else if (57408 <= c && c <= 60351) c -= 49472;
- else throw "illegal char at " + (o + 1) + "/" + c;
- ((c = ((c >>> 8) & 255) * 192 + (c & 255)), s.put(c, 13), (o += 2));
- }
- if (o < a.length) throw "illegal char at " + (o + 1);
- }),
- i
- );
- },
- il = function () {
- const r = [],
- e = {};
- return (
- (e.writeByte = function (t) {
- r.push(t & 255);
- }),
- (e.writeShort = function (t) {
- (e.writeByte(t), e.writeByte(t >>> 8));
- }),
- (e.writeBytes = function (t, n, i) {
- ((n = n || 0), (i = i || t.length));
- for (let s = 0; s < i; s += 1) e.writeByte(t[s + n]);
- }),
- (e.writeString = function (t) {
- for (let n = 0; n < t.length; n += 1) e.writeByte(t.charCodeAt(n));
- }),
- (e.toByteArray = function () {
- return r;
- }),
- (e.toString = function () {
- let t = "";
- t += "[";
- for (let n = 0; n < r.length; n += 1)
- (n > 0 && (t += ","), (t += r[n]));
- return ((t += "]"), t);
- }),
- e
- );
- },
- Pd = function () {
- let r = 0,
- e = 0,
- t = 0,
- n = "";
- const i = {},
- s = function (o) {
- n += String.fromCharCode(a(o & 63));
- },
- a = function (o) {
- if (o < 0) throw "n:" + o;
- if (o < 26) return 65 + o;
- if (o < 52) return 97 + (o - 26);
- if (o < 62) return 48 + (o - 52);
- if (o == 62) return 43;
- if (o == 63) return 47;
- throw "n:" + o;
- };
- return (
- (i.writeByte = function (o) {
- for (r = (r << 8) | (o & 255), e += 8, t += 1; e >= 6;)
- (s(r >>> (e - 6)), (e -= 6));
- }),
- (i.flush = function () {
- if ((e > 0 && (s(r << (6 - e)), (r = 0), (e = 0)), t % 3 != 0)) {
- const o = 3 - (t % 3);
- for (let c = 0; c < o; c += 1) n += "=";
- }
- }),
- (i.toString = function () {
- return n;
- }),
- i
- );
- },
- Cd = function (r) {
- const e = r;
- let t = 0,
- n = 0,
- i = 0;
- const s = {};
- s.read = function () {
- for (; i < 8;) {
- if (t >= e.length) {
- if (i == 0) return -1;
- throw "unexpected end of file./" + i;
- }
- const c = e.charAt(t);
- if (((t += 1), c == "=")) return ((i = 0), -1);
- if (c.match(/^\s$/)) continue;
- ((n = (n << 6) | a(c.charCodeAt(0))), (i += 6));
- }
- const o = (n >>> (i - 8)) & 255;
- return ((i -= 8), o);
- };
- const a = function (o) {
- if (65 <= o && o <= 90) return o - 65;
- if (97 <= o && o <= 122) return o - 97 + 26;
- if (48 <= o && o <= 57) return o - 48 + 52;
- if (o == 43) return 62;
- if (o == 47) return 63;
- throw "c:" + o;
- };
- return s;
- },
- vd = function (r, e) {
- const t = r,
- n = e,
- i = new Array(r * e),
- s = {};
- ((s.setPixel = function (u, l, d) {
- i[l * t + u] = d;
- }),
- (s.write = function (u) {
- (u.writeString("GIF87a"),
- u.writeShort(t),
- u.writeShort(n),
- u.writeByte(128),
- u.writeByte(0),
- u.writeByte(0),
- u.writeByte(0),
- u.writeByte(0),
- u.writeByte(0),
- u.writeByte(255),
- u.writeByte(255),
- u.writeByte(255),
- u.writeString(","),
- u.writeShort(0),
- u.writeShort(0),
- u.writeShort(t),
- u.writeShort(n),
- u.writeByte(0));
- const l = 2,
- d = o(l);
- u.writeByte(l);
- let f = 0;
- for (; d.length - f > 255;)
- (u.writeByte(255), u.writeBytes(d, f, 255), (f += 255));
- (u.writeByte(d.length - f),
- u.writeBytes(d, f, d.length - f),
- u.writeByte(0),
- u.writeString(";"));
- }));
- const a = function (u) {
- const l = u;
- let d = 0,
- f = 0;
- const h = {};
- return (
- (h.write = function (p, m) {
- if (p >>> m) throw "length over";
- for (; d + m >= 8;)
- (l.writeByte(255 & ((p << d) | f)),
- (m -= 8 - d),
- (p >>>= 8 - d),
- (f = 0),
- (d = 0));
- ((f = (p << d) | f), (d = d + m));
- }),
- (h.flush = function () {
- d > 0 && l.writeByte(f);
- }),
- h
- );
- },
- o = function (u) {
- const l = 1 << u,
- d = (1 << u) + 1;
- let f = u + 1;
- const h = c();
- for (let y = 0; y < l; y += 1) h.add(String.fromCharCode(y));
- (h.add(String.fromCharCode(l)), h.add(String.fromCharCode(d)));
- const p = il(),
- m = a(p);
- m.write(l, f);
- let b = 0,
- g = String.fromCharCode(i[b]);
- for (b += 1; b < i.length;) {
- const y = String.fromCharCode(i[b]);
- ((b += 1),
- h.contains(g + y)
- ? (g = g + y)
- : (m.write(h.indexOf(g), f),
- h.size() < 4095 &&
- (h.size() == 1 << f && (f += 1), h.add(g + y)),
- (g = y)));
- }
- return (
- m.write(h.indexOf(g), f),
- m.write(d, f),
- m.flush(),
- p.toByteArray()
- );
- },
- c = function () {
- const u = {};
- let l = 0;
- const d = {};
- return (
- (d.add = function (f) {
- if (d.contains(f)) throw "dup key:" + f;
- ((u[f] = l), (l += 1));
- }),
- (d.size = function () {
- return l;
- }),
- (d.indexOf = function (f) {
- return u[f];
- }),
- (d.contains = function (f) {
- return typeof u[f] < "u";
- }),
- d
- );
- };
- return s;
- },
- Ed = function (r, e, t) {
- const n = vd(r, e);
- for (let o = 0; o < e; o += 1)
- for (let c = 0; c < r; c += 1) n.setPixel(c, o, t(c, o));
- const i = il();
- n.write(i);
- const s = Pd(),
- a = i.toByteArray();
- for (let o = 0; o < a.length; o += 1) s.writeByte(a[o]);
- return (s.flush(), "data:image/gif;base64," + s);
- };
-Tn.stringToBytes;
-const Id = [
- ["A1", "#f9f0cd"],
- ["A2", "#fbfbd4"],
- ["A3", "#fafc9f"],
- ["A4", "#ffe953"],
- ["A5", "#f4d738"],
- ["A6", "#fdad49"],
- ["A7", "#ff7c2f"],
- ["A8", "#eaca49"],
- ["A9", "#ff995a"],
- ["A10", "#ff9d55"],
- ["A11", "#ffdd99"],
- ["A12", "#fcb58f"],
- ["A13", "#ffbb59"],
- ["A14", "#ff6d40"],
- ["A15", "#fdff44"],
- ["A16", "#fef9ae"],
- ["A17", "#ffe36e"],
- ["A18", "#fecf98"],
- ["A19", "#fd7b72"],
- ["A20", "#efcd67"],
- ["A21", "#ffe395"],
- ["A22", "#fff3a4"],
- ["A23", "#f3d5bf"],
- ["A24", "#fbf8c9"],
- ["A25", "#ffd67d"],
- ["A26", "#ffbb27"],
- ["B1", "#e6ee32"],
- ["B2", "#5be419"],
- ["B3", "#7cee9d"],
- ["B4", "#1ef942"],
- ["B5", "#00bd35"],
- ["B6", "#5ae8ba"],
- ["B7", "#03ac88"],
- ["B8", "#029d26"],
- ["B9", "#26523a"],
- ["B10", "#95d3c2"],
- ["B11", "#5d722a"],
- ["B12", "#156f40"],
- ["B13", "#d9f794"],
- ["B14", "#ade945"],
- ["B15", "#2e5132"],
- ["B16", "#c6ed9c"],
- ["B17", "#9bb13a"],
- ["B18", "#e6ee49"],
- ["B19", "#25b88c"],
- ["B20", "#c2f0cc"],
- ["B21", "#146a6b"],
- ["B22", "#0b3c43"],
- ["B23", "#303921"],
- ["B24", "#eefca5"],
- ["B25", "#4e846d"],
- ["B26", "#8c7a36"],
- ["B27", "#d1dcc1"],
- ["B28", "#9ee5b9"],
- ["B29", "#c5e254"],
- ["B30", "#ecfbd0"],
- ["B31", "#c4e6b5"],
- ["B32", "#9bab5a"],
- ["C1", "#e8ffe7"],
- ["C2", "#bcf9f6"],
- ["C3", "#a0e2fb"],
- ["C4", "#42ccff"],
- ["C5", "#01aceb"],
- ["C6", "#50a9f0"],
- ["C7", "#0188d3"],
- ["C8", "#1054c0"],
- ["C9", "#314bca"],
- ["C10", "#3ebce2"],
- ["C11", "#03b9b9"],
- ["C12", "#1c334d"],
- ["C13", "#cde8ff"],
- ["C14", "#d5fdff"],
- ["C15", "#23c4c6"],
- ["C16", "#1757a8"],
- ["C17", "#50d3ec"],
- ["C18", "#1c3344"],
- ["C19", "#1787a2"],
- ["C20", "#0082be"],
- ["C21", "#beddff"],
- ["C22", "#67b4be"],
- ["C23", "#c2dceb"],
- ["C24", "#7dc4ff"],
- ["C25", "#a9e5e5"],
- ["C26", "#2f99b3"],
- ["C27", "#ebf5fc"],
- ["C28", "#bbcfed"],
- ["C29", "#4b5ba3"],
- ["D1", "#aeb4f2"],
- ["D2", "#858edd"],
- ["D3", "#3054af"],
- ["D4", "#182a84"],
- ["D5", "#b843c5"],
- ["D6", "#ac7bde"],
- ["D7", "#6e399a"],
- ["D8", "#e2d3ff"],
- ["D9", "#d5b9f8"],
- ["D10", "#361b50"],
- ["D11", "#b9bae1"],
- ["D12", "#de9ad4"],
- ["D13", "#b90295"],
- ["D14", "#8b279b"],
- ["D15", "#2f1f90"],
- ["D16", "#e2e1ee"],
- ["D17", "#c4d4f6"],
- ["D18", "#a45ec7"],
- ["D19", "#d8c3d7"],
- ["D20", "#9c32b2"],
- ["D21", "#9a009b"],
- ["D22", "#333995"],
- ["D23", "#eadafc"],
- ["D24", "#7786e5"],
- ["D25", "#484fc7"],
- ["D26", "#e9c3f6"],
- ["E1", "#fdd3cc"],
- ["E2", "#fecddf"],
- ["E3", "#ff97c3"],
- ["E4", "#e8649e"],
- ["E5", "#f551a2"],
- ["E6", "#ff346b"],
- ["E7", "#c63578"],
- ["E8", "#ffdbe9"],
- ["E9", "#e970cc"],
- ["E10", "#d33893"],
- ["E11", "#fcddd2"],
- ["E12", "#ffa1c5"],
- ["E13", "#b6006d"],
- ["E14", "#ffd1ba"],
- ["E15", "#f2cfd0"],
- ["E16", "#ffecde"],
- ["E17", "#ffe2ea"],
- ["E18", "#ffc9d6"],
- ["E19", "#ffd2e7"],
- ["E20", "#d8c7d1"],
- ["E21", "#bd9da1"],
- ["E22", "#cc78a7"],
- ["E23", "#937a8d"],
- ["E24", "#f6e4f9"],
- ["F1", "#fd957b"],
- ["F2", "#fc3d45"],
- ["F3", "#f74941"],
- ["F4", "#fc283c"],
- ["F5", "#d80127"],
- ["F6", "#b0443d"],
- ["F7", "#971937"],
- ["F8", "#bc0127"],
- ["F9", "#e2677a"],
- ["F10", "#a74d22"],
- ["F11", "#6f201f"],
- ["F12", "#fd4d6a"],
- ["F13", "#dd422f"],
- ["F14", "#ffa9ad"],
- ["F15", "#c80020"],
- ["F16", "#ffd9c8"],
- ["F17", "#f79b71"],
- ["F18", "#d37c46"],
- ["F19", "#c1444a"],
- ["F20", "#cd9391"],
- ["F21", "#f4b1b4"],
- ["F22", "#ffd0cb"],
- ["F23", "#f57e66"],
- ["F24", "#fcc1c4"],
- ["F25", "#e54b4f"],
- ["G1", "#ffe2ce"],
- ["G2", "#ffcaaa"],
- ["G3", "#f4c3a5"],
- ["G4", "#e1b383"],
- ["G5", "#ed9435"],
- ["G6", "#f59734"],
- ["G7", "#9d5b3e"],
- ["G8", "#592a21"],
- ["G9", "#e6b483"],
- ["G10", "#c88135"],
- ["G11", "#e0c593"],
- ["G12", "#ebbb83"],
- ["G13", "#b7714a"],
- ["G14", "#8d614c"],
- ["G15", "#fcf9e0"],
- ["G16", "#f2d9ba"],
- ["G17", "#56403c"],
- ["G18", "#ffe4cc"],
- ["G19", "#e1943a"],
- ["G20", "#a94023"],
- ["G21", "#cb8e77"],
- ["H1", "#e2e2e2"],
- ["H2", "#ffffff"],
- ["H3", "#b3b3b3"],
- ["H4", "#868686"],
- ["H5", "#474747"],
- ["H6", "#2c2c2c"],
- ["H7", "#000000"],
- ["H8", "#e7d6db"],
- ["H9", "#e4e7e3"],
- ["H10", "#eee9ea"],
- ["H11", "#cecdd5"],
- ["H12", "#fff5ed"],
- ["H13", "#f3e1c9"],
- ["H14", "#cfd7d3"],
- ["H15", "#98a6a8"],
- ["H16", "#3b2f23"],
- ["H17", "#f1eded"],
- ["H18", "#fffdf0"],
- ["H19", "#f6efe2"],
- ["H20", "#949fa3"],
- ["H21", "#f7f3e4"],
- ["H22", "#cacad5"],
- ["H23", "#9a9d94"],
- ["M1", "#bcc6b8"],
- ["M2", "#8aa385"],
- ["M3", "#697d80"],
- ["M4", "#dacebe"],
- ["M5", "#d0ccaa"],
- ["M6", "#b0a782"],
- ["M7", "#b4a497"],
- ["M8", "#b38281"],
- ["M9", "#a58767"],
- ["M10", "#c5b1bc"],
- ["M11", "#9f7494"],
- ["M12", "#644749"],
- ["M13", "#d19066"],
- ["M14", "#c77361"],
- ["M15", "#757d7b"],
- ],
- Ts = (r) => {
- const e = r / 255;
- return e <= 0.04045 ? e / 12.92 : Math.pow((e + 0.055) / 1.055, 2.4);
- };
-function sl(r, e, t) {
- const n = Ts(r),
- i = Ts(e),
- s = Ts(t),
- a = Math.cbrt(0.4122214708 * n + 0.5363325363 * i + 0.0514459929 * s),
- o = Math.cbrt(0.2119034982 * n + 0.6806995451 * i + 0.1073969566 * s),
- c = Math.cbrt(0.0883024619 * n + 0.2817188376 * i + 0.6299787005 * s);
- return [
- (0.2104542553 * a + 0.793617785 * o - 0.0040720468 * c) * 100,
- (1.9779984951 * a - 2.428592205 * o + 0.4505937099 * c) * 100,
- (0.0259040371 * a + 0.7827717662 * o - 0.808675766 * c) * 100,
- ];
-}
-function al(r) {
- const e = parseInt(r.slice(1), 16);
- return [(e >> 16) & 255, (e >> 8) & 255, e & 255];
-}
-const _d = (r, e, t) => (r * 0.299 + e * 0.587 + t * 0.114) / 255,
- la = Id.map(([r, e]) => {
- const [t, n, i] = al(e);
- return { id: r, hex: e, lab: sl(t, n, i), lum: _d(t, n, i) };
- }),
- Ln = la;
-function Ad(r, e, t, n) {
- const [i, s, a] = sl(r, e, t);
- let o = la[0],
- c = 1 / 0;
- for (const u of la) {
- if (!n(u.lum)) continue;
- const l = (u.lab[0] - i) ** 2 + (u.lab[1] - s) ** 2 + (u.lab[2] - a) ** 2;
- l < c && ((c = l), (o = u));
- }
- return o;
-}
-function Bd(r) {
- return Array.from(new TextEncoder().encode(r), (e) =>
- String.fromCharCode(e),
- ).join("");
-}
-function ol(r, e = "Q") {
- const t = Tn(0, e);
- (t.addData(Bd(r), "Byte"), t.make());
- const n = t.getModuleCount(),
- i = [];
- for (let s = 0; s < n; s++) {
- i.push([]);
- for (let a = 0; a < n; a++) i[s].push(t.isDark(s, a));
- }
- return i;
-}
-function cl(r, e, t) {
- const n = (i, s) => r >= i && r < i + 8 && e >= s && e < s + 8;
- return n(-1, -1) || n(-1, t - 7) || n(t - 7, -1);
-}
-function ll(r, e = 1) {
- const t = r.length,
- n = t + e * 2,
- i = [];
- for (let s = 0; s < n; s++)
- for (let a = 0; a < n; a++) {
- const o = s - e,
- c = a - e,
- u = o >= 0 && c >= 0 && o < t && c < t,
- l = u && r[o][c];
- i.push({
- dark: l,
- fn: u && cl(o, c, t),
- hex: l ? "#1c334d" : "#fbfbf6",
- id: l ? "C12" : "H2",
- });
- }
- return { n, cells: i };
-}
-function Fd(r, e, t, n, i = 1) {
- const s = r.length,
- a = s + i * 2,
- o = document.createElement("canvas");
- ((o.width = a), (o.height = a));
- const c = o.getContext("2d", { willReadFrequently: !0 });
- ((c.imageSmoothingEnabled = !0), (c.imageSmoothingQuality = "high"));
- const u = Math.min(t, n),
- l = document.createElement("canvas");
- ((l.width = a * 8), (l.height = a * 8));
- const d = l.getContext("2d");
- ((d.imageSmoothingQuality = "high"),
- d.drawImage(e, (t - u) / 2, (n - u) / 2, u, u, 0, 0, a * 8, a * 8),
- c.drawImage(l, 0, 0, a, a));
- const f = c.getImageData(0, 0, a, a).data,
- h = [];
- for (let p = 0; p < a; p++)
- for (let m = 0; m < a; m++) {
- const b = (p * a + m) * 4,
- g = p - i,
- y = m - i,
- C = g >= 0 && y >= 0 && g < s && y < s,
- _ = C && r[g][y],
- v = C && cl(g, y, s),
- I = v ? 0.28 : 0.36,
- w = v || !C ? 0.84 : 0.78,
- x = Ad(f[b], f[b + 1], f[b + 2], _ ? (k) => k <= I : (k) => k >= w);
- h.push({ dark: _, fn: v, hex: x.hex, id: x.id });
- }
- return { n: a, cells: h };
-}
-const xs = 200,
- ul = 0.78,
- xo = new Map(),
- Tr = (r, e, t) => r.map((n) => Math.round(n + (e - n) * t)),
- xt = (r, e = 1) => `rgba(${r[0]},${r[1]},${r[2]},${e})`;
-// 拼豆精灵(v3):果冻质感短圆管——左上受光、柔和体积、通透内孔、双层高光、柔和接触阴影
-function Rd(r) {
- let e = xo.get(r);
- if (e) return e;
- ((e = document.createElement("canvas")), (e.width = e.height = xs));
- const t = e.getContext("2d"),
- n = xs / 2,
- R = (xs * ul) / 2,
- H = R * 0.34,
- s = al(r),
- L = (0.299 * s[0] + 0.587 * s[1] + 0.114 * s[2]) / 255,
- hi = Tr(s, 255, 0.5 - L * 0.25),
- lo = Tr(s, 0, 0.16 + (1 - L) * 0.06),
- rimC = Tr(s, 0, 0.3),
- ring = () => {
- (t.beginPath(), t.arc(n, n, R, 0, Math.PI * 2), t.arc(n, n, H, 0, Math.PI * 2, !0));
- },
- disc = (x, y, rr) => {
- (t.beginPath(), t.arc(x, y, rr, 0, Math.PI * 2));
- };
- // 1. 接触阴影
- (t.save(),
- (t.filter = `blur(${R * 0.12}px)`),
- (t.fillStyle = "rgba(60,44,20,0.22)"),
- t.beginPath(),
- t.ellipse(n + R * 0.06, n + R * 0.12, R * 0.97, R * 0.93, 0, 0, Math.PI * 2),
- t.fill(),
- (t.filter = "none"),
- t.restore());
- // 2. 本体
- const g1 = t.createRadialGradient(n - R * 0.38, n - R * 0.42, R * 0.1, n + R * 0.05, n + R * 0.08, R * 1.05);
- (g1.addColorStop(0, xt(hi)), g1.addColorStop(0.5, xt(s)), g1.addColorStop(1, xt(lo)), (t.fillStyle = g1), ring(), t.fill("evenodd"));
- // 3. 圆管体积:环中线微亮、外缘轻压暗
- const g2 = t.createRadialGradient(n, n, H, n, n, R);
- (g2.addColorStop(0, xt(rimC, 0.28)),
- g2.addColorStop(0.22, xt(s, 0)),
- g2.addColorStop(0.55, "rgba(255,255,255,0.12)"),
- g2.addColorStop(0.85, xt(s, 0)),
- g2.addColorStop(1, xt(rimC, 0.3)),
- (t.fillStyle = g2),
- ring(),
- t.fill("evenodd"));
- // 4. 内孔:左上内壁背光、右下内壁受光,通透不发黑
- const g3 = t.createLinearGradient(n - H, n - H, n + H, n + H);
- (g3.addColorStop(0, xt(Tr(s, 0, 0.5))),
- g3.addColorStop(0.5, xt(Tr(s, 0, 0.3))),
- g3.addColorStop(1, xt(Tr(s, 255, 0.25))),
- (t.fillStyle = g3),
- disc(n, n, H),
- t.fill());
- const g4 = t.createRadialGradient(n - H * 0.2, n - H * 0.2, 0, n - H * 0.1, n - H * 0.1, H * 0.75);
- (g4.addColorStop(0, `rgba(20,14,8,${0.22 + (1 - L) * 0.08})`), g4.addColorStop(1, "rgba(20,14,8,0)"), (t.fillStyle = g4), disc(n, n, H), t.fill());
- // 5. 高光(裁剪在环内)
- (t.save(), ring(), t.clip("evenodd"));
- (t.filter = `blur(${R * 0.08}px)`),
- (t.strokeStyle = `rgba(255,255,255,${0.7 - L * 0.25})`),
- (t.lineWidth = R * 0.22),
- (t.lineCap = "round"),
- t.beginPath(),
- t.arc(n, n, (R + H) / 2 + R * 0.05, Math.PI * 1.05, Math.PI * 1.45),
- t.stroke();
- (t.filter = `blur(${R * 0.015}px)`),
- (t.fillStyle = "rgba(255,255,255,0.95)"),
- t.beginPath(),
- t.ellipse(n - R * 0.47, n - R * 0.47, R * 0.12, R * 0.06, -0.78, 0, Math.PI * 2),
- t.fill();
- (t.filter = `blur(${R * 0.06}px)`),
- (t.strokeStyle = `rgba(255,255,255,${0.2 + L * 0.12})`),
- (t.lineWidth = R * 0.08),
- t.beginPath(),
- t.arc(n, n, R * 0.88, Math.PI * 0.08, Math.PI * 0.45),
- t.stroke();
- ((t.filter = "none"), t.restore());
- // 6. 孔沿亮边 + 外轮廓
- ((t.lineWidth = R * 0.03),
- (t.strokeStyle = `rgba(255,255,255,${0.35 + L * 0.2})`),
- t.beginPath(),
- t.arc(n, n, H + R * 0.015, Math.PI * 0.05, Math.PI * 0.75),
- t.stroke(),
- (t.lineWidth = R * 0.025),
- (t.strokeStyle = xt(Tr(s, 0, 0.4), 0.45)),
- disc(n, n, R - R * 0.013),
- t.stroke());
- return (xo.set(r, e), e);
-}
-function mr(r, e, t, n, i, s = "bead") {
- if (n <= 0.5) return;
- if (s === "square" || n < 4) {
- ((r.fillStyle = i), r.fillRect(e - n / 2, t - n / 2, n, n));
- return;
- }
- const a = (n * 0.95) / ul;
- r.drawImage(Rd(i), e - a / 2, t - a / 2, a, a);
-}
-const Md = {
- dur: 11.26,
- text: "有没有一种可能?就像 AI 加上二维码,变成了艺术二维码;把拼豆和二维码加在一起,也能变成一幅可以扫码的作品。",
- chunks: [
- { t0: 0.099, t1: 1.337, text: "有没有一种可能" },
- { t0: 1.899, t1: 3.922, text: "就像 AI 加上二维码" },
- { t0: 4.167, t1: 5.502, text: "变成了艺术二维码" },
- { t0: 5.87, t1: 8.039, text: "把拼豆和二维码加在一起" },
- { t0: 8.26, t1: 10.699, text: "也能变成一幅可以扫码的作品" },
- ],
- },
- Nd = {
- dur: 3.05,
- text: "拼好之后,打开微信扫一扫。",
- chunks: [
- { t0: 0.099, t1: 0.957, text: "拼好之后" },
- { t0: 1.141, t1: 2.489, text: "打开微信扫一扫" },
- ],
- },
- Od = {
- dur: 3.19,
- text: "它会把藏在里面的话,读给你听。",
- chunks: [
- { t0: 0.099, t1: 1.631, text: "它会把藏在里面的话" },
- { t0: 1.839, t1: 2.624, text: "读给你听" },
- ],
- },
- Dd = {
- dur: 2.5,
- text: "豆维,可扫码的拼豆。",
- chunks: [
- { t0: 0.099, t1: 0.601, text: "豆维" },
- { t0: 0.798, t1: 1.925, text: "可扫码的拼豆" },
- ],
- },
- zd = {
- dur: 2.83,
- text: "普通的拼豆,只能用来看。",
- chunks: [
- { t0: 0.099, t1: 1.092, text: "普通的拼豆" },
- { t0: 1.3, t1: 2.28, text: "只能用来看" },
- ],
- },
- Wd = {
- dur: 6,
- text: "想拼出一个二维码?颜色差一点,格子错一格,就扫不出来。",
- chunks: [
- { t0: 0.099, t1: 1.557, text: "想拼出一个二维码" },
- { t0: 2.12, t1: 3.137, text: "颜色差一点" },
- { t0: 3.407, t1: 4.4, text: "格子错一格" },
- { t0: 4.583, t1: 5.453, text: "就扫不出来" },
- ],
- },
- Ud = {
- dur: 3.17,
- text: "豆维,把最难的部分交给算法。",
- chunks: [
- { t0: 0.099, t1: 0.577, text: "豆维" },
- { t0: 0.834, t1: 2.599, text: "把最难的部分交给算法" },
- ],
- },
- Hd = {
- dur: 5.47,
- text: "第一步,写下一句话。祝福、网址,或者一个名字。",
- chunks: [
- { t0: 0.099, t1: 0.675, text: "第一步" },
- { t0: 0.932, t1: 1.839, text: "写下一句话" },
- { t0: 2.402, t1: 3.689, text: "祝福、网址" },
- { t0: 3.934, t1: 4.902, text: "或者一个名字" },
- ],
- },
- Vd = {
- dur: 4.99,
- text: "第二步,选一张照片,二维码会悄悄融进画面里。",
- chunks: [
- { t0: 0.099, t1: 0.687, text: "第二步" },
- { t0: 0.969, t1: 1.962, text: "选一张照片" },
- { t0: 2.28, t1: 4.437, text: "二维码会悄悄融进画面里" },
- ],
- },
- Ld = {
- dur: 7.49,
- text: "配色引擎从 MARD 二百二十一种标准色里,为每一格挑出最像、又最好扫的颜色。",
- chunks: [
- { t0: 0.099, t1: 3.457, text: "配色引擎从 MARD 221种标准色里" },
- { t0: 3.776, t1: 6.913, text: "为每一格挑出最像、又最好扫的颜色" },
- ],
- },
- qd = {
- dur: 5.3,
- text: "生成之后,手机先替你扫一遍;扫不出来,一键优化。",
- chunks: [
- { t0: 0.099, t1: 0.969, text: "生成之后" },
- { t0: 1.19, t1: 2.66, text: "手机先替你扫一遍" },
- { t0: 2.991, t1: 3.69, text: "扫不出来" },
- { t0: 3.886, t1: 4.719, text: "一键优化" },
- ],
- },
- jd = {
- dur: 7.42,
- text: "第三步,导出图纸。每一格都标好色号,要准备多少颗豆,清单一目了然。",
- chunks: [
- { t0: 0.099, t1: 0.749, text: "第三步" },
- { t0: 0.957, t1: 1.815, text: "导出图纸" },
- { t0: 2.377, t1: 3.873, text: "每一格都标好色号" },
- { t0: 4.118, t1: 5.392, text: "要准备多少颗豆" },
- { t0: 5.601, t1: 6.85, text: "清单一目了然" },
- ],
- },
- $d = {
- dur: 2.45,
- text: "剩下的,交给双手。",
- chunks: [
- { t0: 0.099, t1: 0.785, text: "剩下的" },
- { t0: 1.03, t1: 1.888, text: "交给双手" },
- ],
- },
- Gd = {
- dur: 2.69,
- text: "一颗,一颗,再一颗。",
- chunks: [
- { t0: 0.099, t1: 0.577, text: "一颗" },
- { t0: 0.822, t1: 1.263, text: "一颗" },
- { t0: 1.533, t1: 2.133, text: "再一颗" },
- ],
- },
- Kd = {
- dur: 4.22,
- text: "放下最后一颗豆,盖上烫纸,慢慢熨平。",
- chunks: [
- { t0: 0.099, t1: 1.423, text: "放下最后一颗豆" },
- { t0: 1.631, t1: 2.501, text: "盖上烫纸" },
- { t0: 2.746, t1: 3.641, text: "慢慢熨平" },
- ],
- },
- Xd = {
- dur: 2.86,
- text: "还没揭开烫纸,先扫一下——",
- chunks: [
- { t0: 0.099, t1: 1.226, text: "还没揭开烫纸" },
- { t0: 1.484, t1: 2.28, text: "先扫一下" },
- ],
- },
- Qd = {
- dur: 1.87,
- text: "扫出来了!",
- chunks: [{ t0: 0.099, t1: 0.969, text: "扫出来了" }],
- },
- Yd = {
- dur: 3.89,
- text: "揭开它,一件会说话的礼物,就完成了。",
- chunks: [
- { t0: 0.099, t1: 0.724, text: "揭开它" },
- { t0: 0.981, t1: 2.378, text: "一件会说话的礼物" },
- { t0: 2.562, t1: 3.322, text: "就完成了" },
- ],
- },
- Zd = {
- dur: 5.3,
- text: "豆维,可扫码的拼豆。把想说的话,拼给重要的人。",
- chunks: [
- { t0: 0.099, t1: 0.601, text: "豆维" },
- { t0: 0.798, t1: 1.925, text: "可扫码的拼豆" },
- { t0: 2.475, t1: 3.444, text: "把想说的话" },
- { t0: 3.64, t1: 4.755, text: "拼给重要的人" },
- ],
- },
- Jd = {
- dur: 2.76,
- text: "微信扫码,现在就试试。",
- chunks: [
- { t0: 0.099, t1: 0.969, text: "微信扫码" },
- { t0: 1.239, t1: 2.195, text: "现在就试试" },
- ],
- },
- ef = {
- dur: 5.69,
- text: "为了实现这个想法,我和 AI 一起写代码,做出了一个小程序。",
- chunks: [
- { t0: 0.099, t1: 1.423, text: "为了实现这个想法" },
- { t0: 1.68, t1: 3.543, text: "我和 AI 一起写代码" },
- { t0: 3.763, t1: 5.136, text: "做出了一个小程序" },
- ],
- },
- tf = {
- dur: 6.12,
- text: "为了实现这个想法,我和豆包 AI 一起写代码,做出了一个小程序。",
- chunks: [
- { t0: 0.099, t1: 1.423, text: "为了实现这个想法" },
- { t0: 1.668, t1: 3.959, text: "我和豆包 AI 一起写代码" },
- { t0: 4.192, t1: 5.565, text: "做出了一个小程序" },
- ],
- },
- rf = {
- dur: 5.98,
- text: "为了实现这个想法,我和 WorkBuddy 一起写代码,做出了一个小程序。",
- chunks: [
- { t0: 0.099, t1: 1.423, text: "为了实现这个想法" },
- { t0: 1.68, t1: 3.824, text: "我和 WorkBuddy 一起写代码" },
- { t0: 4.033, t1: 5.418, text: "做出了一个小程序" },
- ],
- },
- nf = {
- l1: Md,
- l2: Nd,
- l3: Od,
- l4: Dd,
- l5: zd,
- l6: Wd,
- l7: Ud,
- l8: Hd,
- l9: Vd,
- l10: Ld,
- l11: qd,
- l12: jd,
- l13: $d,
- l14: Gd,
- l15: Kd,
- l16: Xd,
- l17: Qd,
- l18: Yd,
- l20: Zd,
- l21: Jd,
- l19_ai: ef,
- l19_doubao: tf,
- l19_wb: rf,
- },
- Ai = nf,
- cr = {
- ai: { label: "AI", vo: "l19_ai" },
- doubao: { label: "豆包 AI", vo: "l19_doubao" },
- workbuddy: { label: "WorkBuddy", vo: "l19_wb" },
- };
-let ns = "ai";
-const sf = () => ns,
- xi = () => cr[ns].label,
- So = (r) => (r === "l19" ? cr[ns].vo : r),
- af = {
- ...Ai,
- l19: {
- ...Ai.l19_ai,
- dur: Math.max(...Object.values(cr).map((r) => Ai[r.vo].dur)),
- },
- };
-let Po = 0;
-const Ce = (r, e) => {
- var t;
- return r.start + (((t = r.chunks[e]) == null ? void 0 : t.t0) ?? 0);
- },
- of = [
- {
- id: "hook",
- parts: [0.5, "l1", 0.3],
- trans: "black",
- energy: 1,
- clips: (r, e) => {
- const t = Ce(r.l1, 4) - 0.1;
- return (
- (Po = e - t),
- [
- {
- id: "show_finished",
- from: t,
- to: e,
- map: (n) => 0.2 + (n - t) * 0.85,
- },
- ]
- );
- },
- sfx: (r) => [
- { t: 0.05, type: "riser", gain: 0.3, p: 0.6 },
- { t: Ce(r.l1, 1), type: "pop", gain: 0.7, p: 1 },
- { t: Ce(r.l1, 1) + 0.45, type: "pop", gain: 0.7, p: 2 },
- { t: Ce(r.l1, 2), type: "sparkle", gain: 0.5 },
- { t: Ce(r.l1, 3), type: "pops", gain: 0.45, p: 0.5 },
- { t: Ce(r.l1, 3) + 0.6, type: "pop", gain: 0.7, p: 2 },
- { t: Ce(r.l1, 4) - 0.1, type: "whoosh", gain: 0.45 },
- ],
- },
- {
- id: "scan",
- parts: [0.1, "l2", 0.95, "l3", 0.4],
- trans: "cut",
- energy: 1,
- clips: (r, e) => {
- const t = r.l2.end - 0.15;
- return [
- {
- id: "show_finished",
- from: 0,
- to: t,
- map: (n) => 0.2 + (Po + n) * 0.85,
- },
- {
- id: "scan_final",
- from: t,
- to: e,
- map: (n) => Math.max(0, n - t) * 0.24,
- },
- ];
- },
- sfx: (r) => [
- { t: Ce(r.l2, 1), type: "beep", gain: 0.5 },
- { t: r.l2.end - 0.15, type: "whoosh", gain: 0.5 },
- { t: r.l2.end - 0.15 + 0.68, type: "ding", gain: 0.9 },
- { t: r.l2.end - 0.15 + 0.72, type: "sparkle", gain: 0.5 },
- ],
- },
- {
- id: "ai",
- parts: [0.35, "l19", 0.5],
- trans: "bead",
- energy: 2,
- clips: (r, e) => [
- { id: "ai_fast", from: 0, to: e, map: (t) => Math.min(7.9, t * 1.3) },
- ],
- sfx: () => [{ t: 0.1, type: "whoosh", gain: 0.4 }],
- },
- {
- id: "title",
- parts: [1, "l4", 1.1],
- trans: "bead",
- energy: 2,
- sfx: (r) => [
- { t: 0.1, type: "pops", gain: 0.5, p: 0.9 },
- { t: r.l4.start - 0.05, type: "impact", gain: 0.9 },
- { t: r.l4.start, type: "sparkle", gain: 0.4 },
- ],
- },
- {
- id: "problem",
- parts: [0.25, "l5", 0.35, "l6", 0.45],
- trans: "fade",
- energy: 0,
- clips: (r, e) => [
- {
- id: "show_normal",
- from: 0,
- to: r.l6.start,
- map: (t) => 1.5 + t * 0.9,
- },
- {
- id: "scan_fail",
- from: r.l6.start - 0.05,
- to: e,
- map: (t) => 0.4 + Math.max(0, t - r.l6.start) * 0.78,
- },
- ],
- sfx: (r, e) => [
- { t: r.l6.start - 0.05, type: "whoosh", gain: 0.4 },
- { t: r.l6.start + 0.4, type: "beep", gain: 0.35 },
- { t: Ce(r.l6, 1), type: "tick", gain: 0.5 },
- { t: Ce(r.l6, 2), type: "tick", gain: 0.5 },
- { t: Ce(r.l6, 3), type: "buzz", gain: 0.6 },
- { t: e - 0.25, type: "riser", gain: 0.35, p: 0.6 },
- ],
- },
- {
- id: "algo",
- parts: [0.25, "l7", 0.35],
- trans: "flash",
- energy: 2,
- clips: (r, e) => [
- { id: "app_demo", from: 0, to: e, map: (t) => 0.3 + t },
- ],
- sfx: () => [{ t: 0, type: "impact", gain: 0.6 }],
- },
- {
- id: "step1",
- parts: [0.2, "l8", 0.35],
- trans: "bead",
- energy: 2,
- sfx: (r) => {
- const e = [{ t: 0.05, type: "whoosh", gain: 0.4 }],
- t = Ce(r.l8, 1);
- for (let n = 0; n < Wi.length; n++)
- e.push({ t: t + n * ua, type: "type", gain: 0.45, p: n });
- return e;
- },
- },
- {
- id: "step2",
- parts: [0.2, "l9", 0.35],
- trans: "fade",
- energy: 2,
- sfx: (r) => [
- { t: Ce(r.l9, 1) - 0.1, type: "shutter", gain: 0.6 },
- { t: Ce(r.l9, 2), type: "pops", gain: 0.45, p: 1.6 },
- ],
- },
- {
- id: "palette",
- parts: [0.15, "l10", 0.35],
- trans: "fade",
- energy: 3,
- sfx: (r, e) => {
- const t = [];
- for (let n = 0.6; n < e - 0.3; n += 0.42)
- t.push({ t: n, type: "click", gain: 0.35, p: Math.round(n * 10) });
- return t;
- },
- },
- {
- id: "check",
- parts: [0.15, "l11", 0.4],
- trans: "fade",
- energy: 3,
- sfx: (r) => [
- { t: Ce(r.l11, 1), type: "beep", gain: 0.4 },
- { t: Ce(r.l11, 2), type: "buzz", gain: 0.35 },
- { t: Ce(r.l11, 3) + 0.1, type: "click", gain: 0.6, p: 3 },
- { t: Ce(r.l11, 3) + 0.55, type: "ding", gain: 0.7 },
- ],
- },
- {
- id: "step3",
- parts: [0.2, "l12", 0.45],
- trans: "bead",
- energy: 3,
- sfx: (r) => [
- { t: Ce(r.l12, 1), type: "paper", gain: 0.6 },
- { t: Ce(r.l12, 3), type: "paper", gain: 0.5 },
- ],
- },
- {
- id: "hands",
- parts: [0.3, "l13", 0.15, "l14", 0.35],
- trans: "flash",
- energy: 3,
- sfx: (r) => [
- { t: 0, type: "whoosh", gain: 0.35 },
- { t: Ce(r.l14, 0), type: "pop", gain: 0.8, p: 0 },
- { t: Ce(r.l14, 1), type: "pop", gain: 0.8, p: 1 },
- { t: Ce(r.l14, 2), type: "pop", gain: 0.9, p: 2 },
- ],
- },
- {
- id: "iron",
- parts: [0.15, "l15", 0.5],
- trans: "cut",
- energy: 2,
- clips: (r, e) => {
- const t = Ce(r.l15, 1) - 0.1,
- n = Ce(r.l15, 2) - 0.1;
- return [
- {
- id: "cover_paper",
- from: t,
- to: n,
- map: (i) => 2.5 + (i - t) * 1.6,
- },
- { id: "ironing", from: n, to: e, map: (i) => 1 + (i - n) * 1.7 },
- ];
- },
- sfx: (r) => [
- { t: Ce(r.l15, 0) + 0.5, type: "pop", gain: 0.9, p: 3 },
- { t: Ce(r.l15, 1) - 0.1, type: "paper", gain: 0.5 },
- { t: Ce(r.l15, 2) - 0.1, type: "steam", gain: 0.5 },
- ],
- },
- {
- id: "scan2",
- parts: [0.3, "l16", 0.45, "l17", 0.55],
- trans: "cut",
- energy: 0,
- clips: (r, e) => {
- const t = r.l16.end + 0.3;
- return [{ id: "scan_paper", from: 0, to: e, map: (n) => 5.26 - t + n }];
- },
- sfx: (r) => [
- { t: 0.35, type: "beep", gain: 0.4 },
- { t: r.l16.end + 0.3, type: "ding", gain: 1 },
- { t: r.l16.end + 0.32, type: "impact", gain: 0.7 },
- { t: r.l16.end + 0.35, type: "sparkle", gain: 0.6 },
- ],
- },
- {
- id: "peel",
- parts: [0.2, "l18", 0.6],
- trans: "cut",
- energy: 3,
- clips: () => [
- { id: "peel", from: 0, to: 2.9, map: (r) => 3.6 + r * 1.35 },
- ],
- sfx: () => [
- { t: 0.9, type: "paper", gain: 0.55 },
- { t: 2.9, type: "sparkle", gain: 0.4 },
- ],
- },
- {
- id: "end",
- parts: [0.45, "l20", 0.5, "l21", 2.6],
- trans: "bead",
- energy: 1,
- sfx: (r) => [
- { t: 0.1, type: "pops", gain: 0.4, p: 1 },
- { t: r.l20.start, type: "impact", gain: 0.55 },
- { t: r.l21.start, type: "ding", gain: 0.45 },
- ],
- },
- ],
- Wi = "生日快乐,愿你被世界温柔以待",
- ua = 0.11,
- cf = Wi;
-function lf() {
- const r = [];
- let e = 0;
- for (const t of of) {
- let n = 0;
- const i = {};
- for (const a of t.parts)
- if (typeof a == "number") n += a;
- else {
- const o = af[a];
- ((i[a] = { id: a, start: n, end: n + o.dur, chunks: o.chunks }),
- (n += o.dur));
- }
- const s = Math.round(n * 100) / 100;
- (r.push({
- id: t.id,
- start: e,
- dur: s,
- trans: t.trans ?? "cut",
- cues: i,
- clips: t.clips ? t.clips(i, s) : [],
- sfx: t.sfx ? t.sfx(i, s) : [],
- energy: t.energy,
- }),
- (e += s));
- }
- return { scenes: r, total: e };
-}
-const { scenes: qe, total: Le } = lf();
-function dl(r) {
- let e = 0;
- for (; e < qe.length - 1 && r >= qe[e + 1].start;) e++;
- return { scene: qe[e], index: e };
-}
-const Ui = 0.45;
-function Bi(r) {
- const { scene: e, index: t } = dl(r),
- n = [],
- i = r - e.start,
- s = (a, o) => {
- for (const c of a.clips)
- o >= c.from - 1e-4 &&
- o < c.to + (a === e ? 1e-4 : Ui) &&
- n.push({ id: c.id, time: Math.max(0, c.map(o)) });
- };
- if (
- (s(e, i), t > 0 && (e.trans === "fade" || e.trans === "bead") && i < Ui)
- ) {
- const a = qe[t - 1];
- s(a, a.dur + i);
- }
- return n;
-}
-function fl() {
- const r = [];
- for (const e of qe)
- for (const t of Object.values(e.cues)) {
- const n = t.chunks;
- let i = null;
- const s = () => {
- (i &&
- r.push({
- t0: e.start + t.start + i.t0 - 0.05,
- t1: e.start + t.start + i.t1 + 0.12,
- text: i.text,
- }),
- (i = null));
- };
- for (const a of n)
- i && i.text.length + a.text.length <= 13
- ? (i = { t0: i.t0, t1: a.t1, text: i.text + " " + a.text })
- : (s(), (i = { ...a }));
- s();
- }
- for (let e = 0; e < r.length - 1; e++)
- r[e].t1 = Math.min(r[e].t1, r[e + 1].t0);
- return r;
-}
-let hl = fl();
-function uf(r) {
- ns = r;
- for (const e of qe) e.cues.l19 && (e.cues.l19.chunks = Ai[cr[r].vo].chunks);
- hl = fl();
-}
-const df = qe.flatMap((r) => r.sfx.map((e) => ({ ...e, t: e.t + r.start }))),
- Ss = qe.flatMap((r) =>
- Object.values(r.cues).map((e) => ({
- id: e.id,
- t: r.start + e.start,
- dur: e.end - e.start,
- })),
- ),
- ml = "./",
- da = (r) => `${ml}media/${r}`,
- ff = (r) => `${ml}vo/${r}.mp3?v=3`,
- Co = [
- "show_finished",
- "scan_final",
- "show_normal",
- "scan_fail",
- "app_demo",
- "cover_paper",
- "ironing",
- "scan_paper",
- "peel",
- "ai_fast",
- ],
- vo = [
- "p_half1",
- "p_half2",
- "p_almost",
- "p_last",
- "p_done",
- "p_hold",
- "chart",
- "usage",
- "mpcode",
- "icon",
- "normal_frame",
- ],
- hf = { chart: "png", usage: "png", mpcode: "png", icon: "png" };
-function mf(r) {
- return new Promise((e, t) => {
- const n = new Image();
- ((n.crossOrigin = "anonymous"),
- (n.decoding = "async"),
- (n.onload = () => e(n)),
- (n.onerror = () => t(new Error("图片加载失败 " + r))),
- (n.src = r));
- });
-}
-function pf(r) {
- return new Promise((e) => {
- const t = document.createElement("video");
- ((t.muted = !0),
- (t.playsInline = !0),
- (t.preload = "auto"),
- (t.crossOrigin = "anonymous"));
- let n = !1;
- const i = () => {
- n || ((n = !0), e(t));
- };
- (t.addEventListener("loadeddata", i, { once: !0 }),
- t.addEventListener("error", i, { once: !0 }),
- setTimeout(i, 15e3),
- (t.src = r),
- t.load());
- });
-}
-async function gf(r) {
- const e = Co.length + vo.length;
- let t = 0;
- const n = () => (r == null ? void 0 : r(++t / e)),
- i = {},
- s = {};
- await Promise.all([
- ...vo.map(async (f) => {
- ((i[f] = await mf(da(`${f}.${hf[f] ?? "jpg"}`))), n());
- }),
- ...Co.map(async (f) => {
- ((s[f] = await pf(da(`${f}.mp4`))), n());
- }),
- ]);
- const up = await mf(da("user_photo.jpg?v=3")).catch(() => null);
- const a = ol(cf, "Q"),
- o = ll(a),
- c = i.p_done;
- let u = document.createElement("canvas");
- ((u.width = u.height = 800),
- u.getContext("2d").drawImage(c, 200, 300, 800, 800, 0, 0, 800, 800));
- let l = Fd(a, u, 800, 800),
- d = {
- n: l.n,
- cells: l.cells.map((f, h) =>
- f.dark && !f.fn && (h * 7919) % 5 < 2 ? { ...f, hex: "#8c7a96" } : f,
- ),
- };
- if (up) {
- const A0 = { qr: a, photo: u, fused: l, weak: d };
- (bwSetPhoto(A0, up), (u = A0.photo), (l = A0.fused), (d = A0.weak));
- }
- // 预热:提前生成豆子精灵与开场图标,避免首次出现时逐帧生成造成卡顿
- for (const f of new Set([...ct, ...l.cells.map((h) => h.hex), ...d.cells.map((h) => h.hex), "#ffbb27", "#fbfbf6", "#1c334d"])) Rd(f);
- for (const f of ["ai", "qr", "art", "ask"]) (hkIcon(f, 230), hkIcon(f, 190));
- return { images: i, videos: s, qr: a, plain: o, fused: l, weak: d, photo: u };
-}
-// 「第二步 · 选一张照片」:用用户照片替换,并重新生成照片融合的拼豆二维码
-function bwSetPhoto(A, img) {
- const w = img.naturalWidth || img.width,
- h = img.naturalHeight || img.height,
- m = Math.min(w, h),
- u = document.createElement("canvas");
- ((u.width = u.height = 800),
- u.getContext("2d").drawImage(img, (w - m) / 2, (h - m) / 2, m, m, 0, 0, 800, 800));
- const l = Fd(A.qr, u, 800, 800);
- ((A.photo = u),
- (A.fused = l),
- (A.weak = {
- n: l.n,
- cells: l.cells.map((f, k) => (f.dark && !f.fn && (k * 7919) % 5 < 2 ? { ...f, hex: "#8c7a96" } : f)),
- }));
- for (const f of new Set(l.cells.map((k) => k.hex))) Rd(f);
- return A;
-}
-const Ps = new Map();
-async function bf(r, e) {
- const t = {};
- return (
- await Promise.all(
- r.map(async (n) => {
- let i = Ps.get(n);
- (i ||
- ((i = fetch(ff(n))
- .then((s) => s.arrayBuffer())
- .then((s) => e.decodeAudioData(s))),
- Ps.set(n, i),
- i.catch(() => Ps.delete(n))),
- (t[n] = await i));
- }),
- ),
- t
- );
-}
-const ar = 48e3,
- wf = 96,
- Pt = 60 / wf,
- pl = [
- { root: 41, tones: [53, 57, 60, 64] },
- { root: 45, tones: [52, 57, 60, 64] },
- { root: 38, tones: [53, 57, 60, 62] },
- { root: 46, tones: [53, 57, 58, 62] },
- ],
- on = (r) => 440 * Math.pow(2, (r - 69) / 12);
-function Da(r) {
- let e = r >>> 0;
- return () => ((e = (e * 1664525 + 1013904223) >>> 0), e / 4294967296);
-}
-function gl(r) {
- let e = qe[0];
- for (const t of qe) r >= t.start && (e = t);
- if (e.id === "scan2") {
- const t = e.cues.l16;
- if (t && r - e.start >= t.end + 0.3) return 3;
- }
- return e.id === "end" ? (r - e.start > e.dur - 3 ? 0 : 1) : e.energy;
-}
-function Zn(r, e, t, n, i, s) {
- (e.gain.setValueAtTime(1e-4, t),
- e.gain.linearRampToValueAtTime(i, t + n),
- e.gain.exponentialRampToValueAtTime(1e-4, t + n + s));
-}
-function yf(r) {
- const e = ar * 2,
- t = r.createBuffer(1, e, ar),
- n = t.getChannelData(0),
- i = Da(7);
- for (let s = 0; s < e; s++) n[s] = i() * 2 - 1;
- return t;
-}
-function mt(r, e, t, n, i, s, a, o = 0.005, c = 0) {
- const u = r.createOscillator();
- ((u.type = e), u.frequency.setValueAtTime(t, n), (u.detune.value = c));
- const l = r.createGain();
- return (
- Zn(r, l, n, o, a, i),
- u.connect(l).connect(s),
- u.start(n),
- u.stop(n + o + i + 0.05),
- u
- );
-}
-function St(r, e, t, n, i, s, a, o, c = 1, u = 0.002) {
- const l = r.createBufferSource();
- l.buffer = e;
- const d = r.createBiquadFilter();
- ((d.type = a), d.frequency.setValueAtTime(o, t), (d.Q.value = c));
- const f = r.createGain();
- return (
- Zn(r, f, t, u, s, n),
- l.connect(d).connect(f).connect(i),
- l.start(t, (t * 0.37) % 1.5),
- l.stop(t + u + n + 0.05),
- { f: d, g: f }
- );
-}
-function kf(r, e, t, n, i) {
- const s = Le,
- a = r.createBiquadFilter();
- ((a.type = "lowpass"), (a.Q.value = 0.6));
- const o = r.createGain();
- ((o.gain.value = 0.09), a.connect(o).connect(e));
- const c = Pt * 8;
- let u = !1;
- for (let f = 0, h = 0; f < s + c; f += c, h++) {
- if (f < t || f >= n) continue;
- u = !0;
- const p = f - t,
- m = pl[h % 4];
- for (const b of m.tones)
- for (const g of [-7, 7]) {
- const y = r.createOscillator();
- ((y.type = "sawtooth"),
- (y.frequency.value = on(b)),
- (y.detune.value = g));
- const C = r.createGain();
- (C.gain.setValueAtTime(1e-4, p),
- C.gain.linearRampToValueAtTime(0.16, p + 0.9),
- C.gain.setValueAtTime(0.16, p + c - 0.3),
- C.gain.linearRampToValueAtTime(1e-4, p + c + 0.6),
- y.connect(C).connect(a),
- y.start(p),
- y.stop(p + c + 0.7));
- }
- }
- if (!u) {
- a.disconnect();
- return;
- }
- const l = (f) => [500, 1100, 1700, 2400][gl(Math.max(0, f))],
- d = Math.floor(t / Pt);
- a.frequency.setValueAtTime(l((d - 1) * Pt), 0);
- for (let f = d; f * Pt < t + i; f++) {
- const h = f * Pt;
- if (h > s) break;
- const p = h + Pt - t;
- p > 0 && a.frequency.linearRampToValueAtTime(l(h), p);
- }
-}
-function Tf(r, e, t, n, i) {
- const s = Da(42),
- a = Le,
- o = r.createGain();
- ((o.gain.value = 0.32), o.connect(e));
- const c = r.createGain();
- ((c.gain.value = 0.2), c.connect(e));
- const u = r.createGain();
- ((u.gain.value = 0.42), u.connect(e));
- const l = r.createDelay(1);
- l.delayTime.value = Pt * 0.75;
- const d = r.createGain();
- d.gain.value = 0.28;
- const f = r.createGain();
- ((f.gain.value = 0.35),
- c.connect(l),
- l.connect(d).connect(l),
- l.connect(f).connect(e));
- const h = Math.ceil(a / (Pt / 4));
- for (let p = 0; p < h; p++) {
- const m = (p * Pt) / 4;
- if (m > a - 0.2) break;
- const b = gl(m),
- g = Math.floor(p / 16),
- y = pl[Math.floor(g / 2) % 4],
- C = p % 4,
- _ = Math.floor(p / 4) % 4,
- v = b >= 3 && p % 16 === 0 && s() > 0.3,
- I = v ? y.tones[(s() * 4) | 0] + 24 : 0;
- if (m < n || m >= i) continue;
- const w = m - n;
- if (b >= 1 && C % 2 === 0) {
- const x = [0, 2, 1, 3, 2, 1, 3, 0][((p / 2) % 8) | 0],
- k = y.tones[x] + 12 + (b >= 3 && (p / 2) % 8 === 7 ? 12 : 0),
- S = b === 1 ? 0.55 : 0.85;
- (mt(r, "sine", on(k), w, 0.32, c, 0.5 * S),
- mt(r, "sine", on(k) * 4, w, 0.06, c, 0.12 * S));
- }
- if (b >= 2 && C === 0 && (_ === 0 || _ === 2 || (b >= 3 && _ === 3))) {
- const x = on(y.root + (_ === 3 ? 7 : 0));
- (mt(r, "triangle", x, w, Pt * 1.2, o, 0.9, 0.01),
- mt(r, "sine", x / 2, w, Pt * 1.2, o, 0.6, 0.01));
- }
- if (b >= 2 && C === 0 && (_ % 2 === 0 || b >= 3)) {
- const x = r.createOscillator();
- ((x.type = "sine"),
- x.frequency.setValueAtTime(150, w),
- x.frequency.exponentialRampToValueAtTime(42, w + 0.14));
- const k = r.createGain();
- (Zn(r, k, w, 0.002, 1, 0.32),
- x.connect(k).connect(u),
- x.start(w),
- x.stop(w + 0.4));
- }
- (b >= 2 &&
- C === 0 &&
- _ % 2 === 1 &&
- (St(r, t, w, 0.16, u, 0.55, "bandpass", 1800, 0.8),
- St(r, t, w + 0.012, 0.12, u, 0.3, "bandpass", 1200, 1)),
- b >= 2 &&
- (b >= 3 || C === 2) &&
- St(r, t, w, 0.035, u, C === 2 ? 0.2 : 0.09, "highpass", 8e3, 0.7),
- v && mt(r, "sine", on(I), w + Pt * 0.5, 0.9, c, 0.18));
- }
-}
-function bl(r, e, t, n, i, s = 0.6, a = 0) {
- const o = r.createGain();
- switch (((o.gain.value = s), o.connect(e), i)) {
- case "whoosh": {
- const { f: c } = St(r, t, n, 0.55, o, 0.7, "bandpass", 300, 1.4, 0.18);
- (c.frequency.exponentialRampToValueAtTime(3200, n + 0.25),
- c.frequency.exponentialRampToValueAtTime(500, n + 0.6));
- break;
- }
- case "pop": {
- const c = r.createOscillator();
- c.type = "sine";
- const u = 700 + a * 140;
- (c.frequency.setValueAtTime(u, n),
- c.frequency.exponentialRampToValueAtTime(u * 0.45, n + 0.07));
- const l = r.createGain();
- (Zn(r, l, n, 0.002, 0.9, 0.1),
- c.connect(l).connect(o),
- c.start(n),
- c.stop(n + 0.15),
- St(r, t, n, 0.02, o, 0.4, "highpass", 3e3));
- break;
- }
- case "pops": {
- const c = Da(Math.round(n * 1e3)),
- u = Math.round(14 * a);
- for (let l = 0; l < u; l++)
- bl(r, o, t, n + c() * a, "pop", 0.25 + c() * 0.3, c() * 4);
- break;
- }
- case "type": {
- (St(r, t, n, 0.03, o, 0.6, "highpass", 2500),
- mt(r, "square", 1600 + (a % 3) * 120, n, 0.015, o, 0.05));
- break;
- }
- case "beep":
- mt(r, "sine", 1480, n, 0.09, o, 0.5);
- break;
- case "click":
- mt(r, "sine", 2e3 + (a % 5) * 150, n, 0.04, o, 0.45);
- break;
- case "tick":
- mt(r, "triangle", 820, n, 0.06, o, 0.6);
- break;
- case "ding": {
- for (const [c, u, l] of [
- [1318.5, 0.5, 1.4],
- [1975.5, 0.3, 1.1],
- [2637, 0.15, 0.7],
- [659.3, 0.2, 1.2],
- ])
- mt(r, "sine", c, n, l, o, u);
- break;
- }
- case "sparkle": {
- [84, 88, 91, 96, 100].forEach((u, l) =>
- mt(r, "sine", on(u), n + l * 0.045, 0.35, o, 0.18),
- );
- break;
- }
- case "impact": {
- const c = r.createOscillator();
- ((c.type = "sine"),
- c.frequency.setValueAtTime(90, n),
- c.frequency.exponentialRampToValueAtTime(32, n + 0.7));
- const u = r.createGain();
- (Zn(r, u, n, 0.004, 1, 0.9),
- c.connect(u).connect(o),
- c.start(n),
- c.stop(n + 1),
- St(r, t, n, 0.5, o, 0.35, "lowpass", 1800),
- St(r, t, n, 1.2, o, 0.08, "highpass", 6e3));
- break;
- }
- case "buzz": {
- const c = r.createBiquadFilter();
- ((c.type = "lowpass"),
- (c.frequency.value = 1e3),
- c.connect(o),
- mt(r, "square", 110, n, 0.32, c, 0.35, 0.005),
- mt(r, "square", 116.5, n, 0.32, c, 0.35, 0.005));
- break;
- }
- case "shutter": {
- (St(r, t, n, 0.035, o, 0.8, "bandpass", 2500, 0.8),
- St(r, t, n + 0.07, 0.05, o, 0.6, "bandpass", 1800, 0.8));
- break;
- }
- case "paper": {
- const { f: c } = St(r, t, n, 0.4, o, 0.5, "bandpass", 1200, 0.9, 0.08);
- c.frequency.linearRampToValueAtTime(2600, n + 0.4);
- break;
- }
- case "steam":
- St(r, t, n, 1.6, o, 0.35, "highpass", 3500, 0.5, 0.3);
- break;
- case "riser": {
- const c = a || 1,
- u = r.createBufferSource();
- u.buffer = t;
- const l = r.createBiquadFilter();
- ((l.type = "bandpass"),
- (l.Q.value = 2),
- l.frequency.setValueAtTime(400, n),
- l.frequency.exponentialRampToValueAtTime(5e3, n + c));
- const d = r.createGain();
- (d.gain.setValueAtTime(1e-4, n),
- d.gain.exponentialRampToValueAtTime(0.6, n + c),
- d.gain.linearRampToValueAtTime(1e-4, n + c + 0.08),
- u.connect(l).connect(d).connect(o),
- u.start(n),
- u.stop(n + c + 0.1));
- break;
- }
- }
-}
-const Cs = new Map();
-let Eo = null;
-const Si = 4,
- Io = 7;
-async function xf(r) {
- const e = new Float32Array(r),
- t = new Float32Array(r),
- n = [];
- for (let a = 0; a < Le; a += Si) n.push(a);
- const i = async (a) => {
- const o = a + Si,
- c = Math.ceil((Si + Io) * ar),
- u = new OfflineAudioContext(2, c, ar);
- u.destination.channelInterpretation = "discrete";
- const l = yf(u),
- d = u.createChannelMerger(2);
- d.connect(u.destination);
- const f = u.createGain();
- ((f.channelCount = 1),
- (f.channelCountMode = "explicit"),
- f.connect(d, 0, 0));
- const h = u.createGain();
- ((h.channelCount = 1),
- (h.channelCountMode = "explicit"),
- h.connect(d, 0, 1),
- Tf(u, f, l, a, o),
- kf(u, f, a, o, Si + Io));
- for (const y of df)
- y.t >= a && y.t < o && bl(u, h, l, y.t - a, y.type, y.gain, y.p);
- const p = await u.startRendering(),
- m = p.getChannelData(0),
- b = p.getChannelData(1),
- g = Math.round(a * ar);
- for (let y = 0; y < c && g + y < r; y++)
- ((e[g + y] += m[y]), (t[g + y] += b[y]));
- },
- s = [...n];
- return (
- await Promise.all(
- [0, 1, 2].map(async () => {
- for (; s.length;) await i(s.shift());
- }),
- ),
- [e, t]
- );
-}
-function fa() {
- const r = sf(),
- e = Cs.get(r);
- if (e) return e;
- const t = (async () => {
- const n = Math.ceil((Le + 0.3) * ar),
- i = new OfflineAudioContext(2, n, ar),
- s = [...new Set(Ss.map((x) => So(x.id)))],
- [a, [o, c]] = await Promise.all([bf(s, i), Eo ?? (Eo = xf(n))]),
- u = i.createDynamicsCompressor();
- ((u.threshold.value = -14),
- (u.ratio.value = 3),
- (u.attack.value = 0.005),
- (u.release.value = 0.2));
- const l = i.createGain();
- ((l.gain.value = 0.95), u.connect(l).connect(i.destination));
- const d = i.createGain(),
- f = i.createGain();
- ((d.gain.value = 0.62),
- d.connect(f).connect(u),
- f.gain.setValueAtTime(1, 0));
- const h = [];
- for (const x of Ss.slice().sort((k, S) => k.t - S.t)) {
- const k = [x.t - 0.12, x.t + x.dur + 0.1],
- S = h[h.length - 1];
- S && k[0] <= S[1] + 0.35 ? (S[1] = Math.max(S[1], k[1])) : h.push(k);
- }
- for (const [x, k] of h)
- (f.gain.setValueAtTime(1, Math.max(0, x - 0.15)),
- f.gain.linearRampToValueAtTime(0.42, x + 0.05),
- f.gain.setValueAtTime(0.42, k),
- f.gain.linearRampToValueAtTime(1, k + 0.4));
- const p = i.createGain();
- (p.gain.setValueAtTime(1, Math.max(0, Le - 2.2)),
- p.gain.linearRampToValueAtTime(1e-4, Le + 0.2));
- const m = i.createGain();
- m.connect(p).connect(d);
- const b = i.createBuffer(1, n, ar);
- b.copyToChannel(o, 0);
- const g = i.createBufferSource();
- ((g.buffer = b), g.connect(m), g.start(0));
- const y = i.createGain();
- ((y.gain.value = 0.75), y.connect(u));
- const C = i.createBuffer(1, n, ar);
- C.copyToChannel(c, 0);
- const _ = i.createBufferSource();
- ((_.buffer = C), _.connect(y), _.start(0));
- const v = i.createGain();
- v.gain.value = 1.15;
- const I = i.createBiquadFilter();
- ((I.type = "highpass"), (I.frequency.value = 90));
- const w = i.createBiquadFilter();
- ((w.type = "peaking"),
- (w.frequency.value = 3200),
- (w.gain.value = 2.5),
- v.connect(I).connect(w).connect(u));
- for (const x of Ss) {
- const k = a[So(x.id)];
- if (!k) continue;
- const S = i.createBufferSource();
- ((S.buffer = k), S.connect(v), S.start(x.t));
- }
- return i.startRendering();
- })();
- return (
- Cs.set(r, t),
- t.catch(() => {
- (Cs.delete(r), (Eo = null));
- }),
- t
- );
-}
-function is(r) {
- return r === "landscape"
- ? { W: 1920, H: 1080, P: !1, safe: { t: 60, b: 80, l: 90, r: 90 } }
- : { W: 1080, H: 1920, P: !0, safe: { t: 210, b: 440, l: 60, r: 150 } };
-}
-const wl =
- '"Noto Sans SC","PingFang SC","Hiragino Sans GB","Microsoft YaHei","Source Han Sans SC",sans-serif',
- Sf = '"JetBrains Mono","SF Mono",Menlo,Consolas,monospace',
- X = {
- paper: "#f4f1ea",
- ink: "#16201f",
- teal: "#0f766e",
- green: "#07c160",
- red: "#e5484d",
- orange: "#f59e0b",
- sub: "#5b6461",
- },
- ct = [
- "#146a6b",
- "#ffbb27",
- "#fd7b72",
- "#0188d3",
- "#5ae8ba",
- "#f4d738",
- "#1c334d",
- "#fecf98",
- "#ff7c2f",
- "#03ac88",
- ],
- Be = (r, e = 0, t = 1) => Math.max(e, Math.min(t, r)),
- V = (r, e, t) => Be((r - e) / (t - e)),
- fe = (r) => 1 - Math.pow(1 - Be(r), 3),
- tr = (r) => (
- (r = Be(r)),
- r < 0.5 ? 4 * r * r * r : 1 - Math.pow(-2 * r + 2, 3) / 2
- ),
- lt = (r) => {
- r = Be(r);
- const e = 1.70158;
- return 1 + (e + 1) * Math.pow(r - 1, 3) + e * Math.pow(r - 1, 2);
- },
- pt = (r, e, t) => r + (e - r) * t,
- Ye = (r) => {
- const e = Math.sin(r * 127.1 + 311.7) * 43758.5453;
- return e - Math.floor(e);
- };
-function Jn(r, e = 900, t = wl) {
- return `${e} ${r}px ${t}`;
-}
-function be(r, e, t, n, i) {
- (r.save(),
- (r.font = Jn(i.size, i.weight ?? 900, i.font)),
- (r.textAlign = i.align ?? "left"),
- (r.textBaseline = "alphabetic"),
- (r.globalAlpha *= i.alpha ?? 1),
- i.spacing && (r.letterSpacing = `${i.spacing}px`),
- i.shadow &&
- ((r.shadowColor = "rgba(0,0,0,0.45)"),
- (r.shadowBlur = i.shadow),
- (r.shadowOffsetY = i.shadow / 4)),
- i.stroke &&
- ((r.lineWidth = i.strokeW ?? 8),
- (r.strokeStyle = i.stroke),
- (r.lineJoin = "round"),
- r.strokeText(e, t, n)),
- (r.fillStyle = i.color ?? "#fff"),
- r.fillText(e, t, n),
- r.restore());
-}
-function We(r, e, t, n, i, s) {
- if (i <= 0) return;
- (r.save(), (r.font = Jn(s.size, s.weight ?? 900, s.font)));
- const a = [...e],
- o = a.map((d) => r.measureText(d).width),
- c = o.reduce((d, f) => d + f, 0);
- let u = s.align === "center" ? t - c / 2 : s.align === "right" ? t - c : t;
- const l = a.length;
- (a.forEach((d, f) => {
- const h = fe(Be(i * (l * 0.35 + 1.2) - f * 0.35, 0, 1));
- (h > 0 &&
- be(r, d, u, n + (1 - h) * s.size * 0.45, {
- ...s,
- align: "left",
- alpha: (s.alpha ?? 1) * h,
- }),
- (u += o[f]));
- }),
- r.restore());
-}
-function Fr(r, e, t, n = 900) {
- (r.save(), (r.font = Jn(t, n)));
- const i = r.measureText(e).width;
- return (r.restore(), i);
-}
-function Ue(r, e, t, n, i) {
- const s = i.size ?? 30,
- a = s * 0.7,
- o = i.dot ? s * 0.9 : 0,
- c = Fr(r, e, s, i.weight ?? 700) + a * 2 + o,
- u = s * 1.75,
- l = i.align === "center" ? t - c / 2 : i.align === "right" ? t - c : t;
- return (
- r.save(),
- (r.globalAlpha *= i.alpha ?? 1),
- (r.fillStyle = i.bg ?? X.teal),
- r.beginPath(),
- r.roundRect(l, n - u / 2, c, u, u / 2),
- r.fill(),
- i.dot &&
- ((r.fillStyle = i.dot),
- r.beginPath(),
- r.arc(l + a + s * 0.25, n, s * 0.22, 0, Math.PI * 2),
- r.fill()),
- be(r, e, l + a + o, n + s * 0.36, {
- size: s,
- weight: i.weight ?? 700,
- color: i.color ?? "#fff",
- }),
- r.restore(),
- c
- );
-}
-function Qr(r, e, t, n, i, s, a, o, c = 1, u = 0.5, l = 0.5) {
- if (!t || !n) return;
- const d = Math.max(a / t, o / n) * c,
- f = t * d,
- h = n * d;
- (r.save(),
- r.beginPath(),
- r.rect(i, s, a, o),
- r.clip(),
- r.drawImage(e, i + (a - f) * u, s + (o - h) * l, f, h),
- r.restore());
-}
-let xr = null;
-function gn(r, e, t, n = 0.5, i = 1.15) {
- if (((r.fillStyle = "#0b0d0c"), r.fillRect(0, 0, e.W, e.H), t)) {
- xr || (xr = document.createElement("canvas"));
- const s = Math.round(e.W / 36),
- a = Math.round(e.H / 36);
- (xr.width !== s || xr.height !== a) && ((xr.width = s), (xr.height = a));
- const o = xr.getContext("2d");
- ((o.imageSmoothingQuality = "high"),
- Qr(o, t.img, t.w, t.h, 0, 0, s, a, i),
- r.save(),
- (r.imageSmoothingEnabled = !0),
- (r.imageSmoothingQuality = "high"),
- r.drawImage(xr, 0, 0, e.W, e.H),
- r.restore());
- }
- ((r.fillStyle = `rgba(8,10,10,${n})`), r.fillRect(0, 0, e.W, e.H));
-}
-function za(r, e, t, n, i, s, a = {}) {
- const o = a.r ?? 28;
- (r.save(),
- (r.globalAlpha *= a.alpha ?? 1),
- a.shadow !== !1 &&
- ((r.shadowColor = "rgba(0,0,0,0.45)"),
- (r.shadowBlur = 50),
- (r.shadowOffsetY = 18),
- (r.fillStyle = "#111"),
- r.beginPath(),
- r.roundRect(t, n, i, s, o),
- r.fill(),
- (r.shadowColor = "transparent")),
- r.beginPath(),
- r.roundRect(t, n, i, s, o),
- r.clip(),
- (r.fillStyle = "#1a1d1c"),
- r.fillRect(t, n, i, s),
- e &&
- Qr(r, e.img, e.w, e.h, t, n, i, s, a.zoom ?? 1, a.fx ?? 0.5, a.fy ?? 0.5),
- r.restore(),
- a.border &&
- (r.save(),
- (r.strokeStyle = a.border),
- (r.lineWidth = 3),
- r.beginPath(),
- r.roundRect(t, n, i, s, o),
- r.stroke(),
- r.restore()));
-}
-function di(r, e, t, n, i, s = {}) {
- const a = s.aspect ?? (e ? e.w / e.h : 0.4614),
- o = i * 0.016,
- c = i - o * 2,
- u = c * a,
- l = u + o * 2;
- return (
- r.save(),
- (r.globalAlpha *= s.alpha ?? 1),
- r.translate(t, n),
- s.rot && r.rotate(s.rot),
- (r.shadowColor = "rgba(0,0,0,0.5)"),
- (r.shadowBlur = 60),
- (r.shadowOffsetY = 24),
- (r.fillStyle = "#0a0a0a"),
- r.beginPath(),
- r.roundRect(-l / 2, -i / 2, l, i, i * 0.075),
- r.fill(),
- (r.shadowColor = "transparent"),
- (r.strokeStyle = "#3a3d3c"),
- (r.lineWidth = 3),
- r.beginPath(),
- r.roundRect(-l / 2 + 1.5, -i / 2 + 1.5, l - 3, i - 3, i * 0.075),
- r.stroke(),
- r.beginPath(),
- r.roundRect(-u / 2, -c / 2, u, c, i * 0.062),
- r.clip(),
- (r.fillStyle = "#f6f5f1"),
- r.fillRect(-u / 2, -c / 2, u, c),
- e && r.drawImage(e.img, -u / 2, -c / 2, u, c),
- r.restore(),
- { w: l, h: i, sx: t - u / 2, sy: n - c / 2, sw: u, sh: c }
- );
-}
-const _o = new Map();
-function Gt(r, e, t = X.paper) {
- const n = `${e.W}x${e.H}:${t}`;
- let i = _o.get(n);
- if (!i) {
- ((i = document.createElement("canvas")), (i.width = e.W), (i.height = e.H));
- const s = i.getContext("2d");
- ((s.fillStyle = t), s.fillRect(0, 0, e.W, e.H));
- const a = s.createRadialGradient(
- e.W / 2,
- e.H * 0.45,
- 0,
- e.W / 2,
- e.H / 2,
- Math.max(e.W, e.H) * 0.75,
- );
- (a.addColorStop(0, "rgba(255,255,255,0.55)"),
- a.addColorStop(1, "rgba(120,100,70,0.12)"),
- (s.fillStyle = a),
- s.fillRect(0, 0, e.W, e.H));
- const o = 36;
- s.fillStyle = "rgba(60,50,30,0.075)";
- for (let c = o / 2; c < e.H; c += o)
- for (let u = o / 2; u < e.W; u += o)
- (s.beginPath(), s.arc(u, c, 3.2, 0, Math.PI * 2), s.fill());
- _o.set(n, i);
- }
- r.drawImage(i, 0, 0);
-}
-function Pf(r, e, t = 0.45) {
- const n = r.createRadialGradient(
- e.W / 2,
- e.H / 2,
- Math.min(e.W, e.H) * 0.35,
- e.W / 2,
- e.H / 2,
- Math.max(e.W, e.H) * 0.75,
- );
- (n.addColorStop(0, "rgba(0,0,0,0)"),
- n.addColorStop(1, `rgba(0,0,0,${t})`),
- (r.fillStyle = n),
- r.fillRect(0, 0, e.W, e.H));
-}
-function yl(r, e, t = 0.55, n = 0.55) {
- let i = r.createLinearGradient(0, 0, 0, e.H * 0.4);
- (i.addColorStop(0, `rgba(0,0,0,${t})`),
- i.addColorStop(1, "rgba(0,0,0,0)"),
- (r.fillStyle = i),
- r.fillRect(0, 0, e.W, e.H * 0.4),
- (i = r.createLinearGradient(0, e.H * 0.55, 0, e.H)),
- i.addColorStop(0, "rgba(0,0,0,0)"),
- i.addColorStop(1, `rgba(0,0,0,${n})`),
- (r.fillStyle = i),
- r.fillRect(0, e.H * 0.55, e.W, e.H * 0.45));
-}
-function ss(r, e, t, n, i, s = {}) {
- const a = i / e.n;
- s.board !== !1 &&
- (r.save(),
- (r.shadowColor = "rgba(40,30,10,0.25)"),
- (r.shadowBlur = 40),
- (r.shadowOffsetY = 14),
- (r.fillStyle = "#fbfaf6"),
- r.beginPath(),
- r.roundRect(t - a * 0.8, n - a * 0.8, i + a * 1.6, i + a * 1.6, a * 1.2),
- r.fill(),
- r.restore());
- for (let o = 0; o < e.n; o++)
- for (let c = 0; c < e.n; c++) {
- const u = o * e.n + c,
- l = s.k ? s.k(o, c, u) : 1;
- l <= 0.01 ||
- mr(
- r,
- t + (c + 0.5) * a,
- n + (o + 0.5) * a,
- a * l,
- s.hex ? s.hex(u) : e.cells[u].hex,
- );
- }
-}
-function as(r, e, t, n, i, s, a = 1) {
- if (a <= 0) return;
- (r.save(), (r.globalAlpha *= a));
- const o = Math.min(n, i) * 0.12;
- ((r.strokeStyle = X.green), (r.lineWidth = 8), (r.lineCap = "round"));
- const c = [
- [e, t, 1, 1],
- [e + n, t, -1, 1],
- [e, t + i, 1, -1],
- [e + n, t + i, -1, -1],
- ];
- for (const [h, p, m, b] of c)
- (r.beginPath(),
- r.moveTo(h, p + b * o),
- r.lineTo(h, p),
- r.lineTo(h + m * o, p),
- r.stroke());
- const u = (s * 0.55) % 1,
- l = t + i * 0.06 + u * i * 0.88,
- d = r.createLinearGradient(0, l - i * 0.18, 0, l);
- (d.addColorStop(0, "rgba(7,193,96,0)"),
- d.addColorStop(1, "rgba(7,193,96,0.35)"),
- (r.fillStyle = d),
- r.fillRect(e + n * 0.06, l - i * 0.18, n * 0.88, i * 0.18));
- const f = r.createLinearGradient(e, 0, e + n, 0);
- (f.addColorStop(0, "rgba(7,193,96,0)"),
- f.addColorStop(0.5, "rgba(120,255,180,1)"),
- f.addColorStop(1, "rgba(7,193,96,0)"),
- (r.fillStyle = f),
- r.fillRect(e + n * 0.04, l - 3, n * 0.92, 6),
- r.restore());
-}
-function Wa(r, e, t, n, i = 1) {
- if (n <= 0 || n >= 1.6) return;
- r.save();
- for (let o = 0; o < 3; o++) {
- const c = Be(n - o * 0.12);
- c <= 0 ||
- ((r.globalAlpha = (1 - c) * 0.8),
- (r.strokeStyle = X.green),
- (r.lineWidth = 10 * i * (1 - c) + 2),
- r.beginPath(),
- r.arc(e, t, (80 + c * 260) * i, 0, Math.PI * 2),
- r.stroke());
- }
- const s = Be(1.6 - n),
- a = lt(V(n, 0, 0.35)) * i;
- ((r.globalAlpha = Be(s)),
- (r.fillStyle = X.green),
- r.beginPath(),
- r.arc(e, t, 78 * a, 0, Math.PI * 2),
- r.fill(),
- (r.strokeStyle = "#fff"),
- (r.lineWidth = 14 * a),
- (r.lineCap = "round"),
- (r.lineJoin = "round"),
- r.beginPath(),
- r.moveTo(e - 34 * a, t + 2 * a),
- r.lineTo(e - 8 * a, t + 28 * a),
- r.lineTo(e + 38 * a, t - 26 * a),
- r.stroke(),
- r.restore());
-}
-function Cf(r, e, t, n, i = 40, s = 600, a = 1) {
- if (!(n <= 0 || n > 1.4))
- for (let o = 0; o < i; o++) {
- const c = Ye(o + a) * Math.PI * 2,
- u = 0.35 + Ye(o * 3 + a) * 0.65,
- l = fe(n),
- d = e + Math.cos(c) * s * u * l,
- f = t + Math.sin(c) * s * u * l + n * n * 320,
- h = 22 + Ye(o * 7 + a) * 22;
- (r.save(),
- (r.globalAlpha = Be(1.3 - n)),
- mr(r, d, f, h, ct[o % ct.length]),
- r.restore());
- }
-}
-function ha(r, e, t, n, i, s, a = 420) {
- if (s <= 0) return;
- const o = 0.32,
- c = Be(s / o),
- u = t - a * (1 - c * c),
- l = Math.max(0, s - o),
- d = l > 0 ? Math.sin(l * 30) * Math.exp(-l * 9) * 0.18 : 0;
- (r.save(),
- (r.globalAlpha = 0.35 * c),
- (r.fillStyle = "#000"),
- r.beginPath(),
- r.ellipse(
- e + n * 0.06,
- t + n * 0.42,
- n * 0.5 * (0.5 + c * 0.5),
- n * 0.14,
- 0,
- 0,
- Math.PI * 2,
- ),
- r.fill(),
- r.restore(),
- r.save(),
- (r.globalAlpha *= Be(s / 0.08)),
- r.translate(e, u),
- r.scale(1 + d, 1 - d),
- mr(r, 0, 0, n, i),
- r.restore(),
- l > 0 &&
- l < 0.5 &&
- (r.save(),
- (r.globalAlpha = (1 - l / 0.5) * 0.8),
- (r.strokeStyle = "#fff"),
- (r.lineWidth = 5),
- r.beginPath(),
- r.arc(e, t, n * (0.6 + l * 1.6), 0, Math.PI * 2),
- r.stroke(),
- r.restore()));
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ function T(r) {
- if (!r) throw new Error("Assertion failed.");
-}
-const ma = Math.PI / 180,
- vf = 180 / Math.PI,
- Gn = (r) => {
- const e = ((r % 360) + 360) % 360;
- if (e === 0 || e === 90 || e === 180 || e === 270) return e;
- throw new Error(`Invalid rotation ${r}.`);
- },
- ei = [1, 0, 0, 0, 1, 0, 0, 0, 1],
- kl = (r, e, t) => {
- const [n, i, , s, a] = r,
- o = Math.abs(n) * e + Math.abs(s) * t,
- c = Math.abs(i) * e + Math.abs(a) * t;
- return ti(ti(Ao(-e / 2, -t / 2), r), Ao(o / 2, c / 2));
- },
- Pi = (r) => {
- const [e, t] = r,
- n = Math.atan2(t, Tl(r) ? -e : e);
- return Gn(ga(n * vf, 90));
- },
- Tl = (r) => {
- const [e, t, , n, i] = r;
- return e * i - t * n < 0;
- },
- xl = (r) => {
- const e = r * ma,
- t = Math.round(Math.cos(e)),
- n = Math.round(Math.sin(e));
- return [t, n, 0, -n, t, 0, 0, 0, 1];
- },
- Ao = (r, e) => [1, 0, 0, 0, 1, 0, r, e, 1],
- Sl = (r, e) => [r, 0, 0, 0, e, 0, 0, 0, 1],
- ti = (r, e) => {
- const t = new Array(9);
- for (let n = 0; n < 3; n++)
- for (let i = 0; i < 3; i++)
- t[3 * n + i] =
- r[3 * n] * e[i] + r[3 * n + 1] * e[3 + i] + r[3 * n + 2] * e[6 + i];
- return t;
- },
- Ef = (r, e, t, n) => ({ rotation: Gn(r + (e ? -t : t)), flip: e !== n }),
- Ae = (r) => r && r[r.length - 1],
- lr = (r) => r >= 0 && r < 2 ** 32,
- If = (r) => r >= -2147483648 && r < 2 ** 31,
- G = (r) => {
- let e = 0;
- for (; r.readBits(1) === 0 && e < 32;) e++;
- if (e >= 32) throw new Error("Invalid exponential-Golomb code.");
- return (1 << e) - 1 + r.readBits(e);
- },
- Yr = (r, e) => {
- const t = e + 1,
- n = Math.floor(Math.log2(t));
- (r.writeBits(n, 0), r.writeBits(1, 1), r.writeBits(n, t - 2 ** n));
- },
- or = (r) => {
- const e = G(r);
- return (e & 1) === 0 ? -(e >> 1) : (e + 1) >> 1;
- },
- Ze = (r) =>
- r.constructor === Uint8Array
- ? r
- : ArrayBuffer.isView(r)
- ? new Uint8Array(r.buffer, r.byteOffset, r.byteLength)
- : new Uint8Array(r),
- ge = (r) =>
- r.constructor === DataView
- ? r
- : ArrayBuffer.isView(r)
- ? new DataView(r.buffer, r.byteOffset, r.byteLength)
- : new DataView(r),
- _f =
- typeof globalThis.TextEncoder < "u"
- ? globalThis.TextEncoder
- : class {
- constructor() {
- this.encoding = "utf-8";
- }
- encode(e = "") {
- const t = new Uint8Array(3 * e.length);
- let n = 0;
- for (let i = 0; i < e.length; i++) {
- let s = e.charCodeAt(i);
- if (s < 128) t[n++] = s;
- else if (s < 2048)
- ((t[n++] = 192 | (s >> 6)), (t[n++] = 128 | (s & 63)));
- else if (s < 55296 || s > 57343)
- ((t[n++] = 224 | (s >> 12)),
- (t[n++] = 128 | ((s >> 6) & 63)),
- (t[n++] = 128 | (s & 63)));
- else {
- const a = i + 1 < e.length ? e.charCodeAt(i + 1) : 0;
- s < 56320 && a >= 56320 && a <= 57343
- ? ((s = 65536 + ((s - 55296) << 10) + (a - 56320)),
- i++,
- (t[n++] = 240 | (s >> 18)),
- (t[n++] = 128 | ((s >> 12) & 63)),
- (t[n++] = 128 | ((s >> 6) & 63)),
- (t[n++] = 128 | (s & 63)))
- : ((t[n++] = 239), (t[n++] = 191), (t[n++] = 189));
- }
- }
- return t.slice(0, n);
- }
- },
- Kn =
- typeof globalThis.TextDecoder < "u"
- ? globalThis.TextDecoder
- : class {
- constructor(e = "utf-8") {
- const t = e.trim().toLowerCase();
- if (t === "utf-8" || t === "utf8" || t === "unicode-1-1-utf-8")
- this.encoding = "utf-8";
- else if (t === "utf-16le" || t === "utf-16")
- this.encoding = "utf-16le";
- else if (t === "utf-16be") this.encoding = "utf-16be";
- else
- throw new RangeError(
- `The encoding label provided ('${e}') is invalid.`,
- );
- }
- decode(e) {
- const t = e ? Ze(e) : new Uint8Array(0),
- n = [];
- if (this.encoding === "utf-8") {
- let s =
- t.length >= 3 && t[0] === 239 && t[1] === 187 && t[2] === 191
- ? 3
- : 0;
- for (; s < t.length;) {
- const a = t[s];
- if (a < 128) {
- (n.push(a), s++);
- continue;
- }
- let o, c;
- if (a >= 194 && a < 224) ((o = 1), (c = a & 31));
- else if (a >= 224 && a < 240) ((o = 2), (c = a & 15));
- else if (a >= 240 && a < 245) ((o = 3), (c = a & 7));
- else {
- (n.push(65533), s++);
- continue;
- }
- let u = a === 224 ? 160 : a === 240 ? 144 : 128,
- l = a === 237 ? 159 : a === 244 ? 143 : 191,
- d = 1;
- for (; d <= o; d++) {
- const f = s + d < t.length ? t[s + d] : 0;
- if (f < u || f > l) break;
- ((c = (c << 6) | (f & 63)), (u = 128), (l = 191));
- }
- ((s += d),
- d <= o
- ? n.push(65533)
- : c >= 65536
- ? ((c -= 65536),
- n.push(55296 | (c >> 10), 56320 | (c & 1023)))
- : n.push(c));
- }
- } else {
- const s = this.encoding === "utf-16le",
- a = s ? 255 : 254,
- o = s ? 254 : 255;
- let c = t.length >= 2 && t[0] === a && t[1] === o ? 2 : 0;
- for (; c + 1 < t.length;) {
- const u = s ? t[c] | (t[c + 1] << 8) : (t[c] << 8) | t[c + 1];
- if (((c += 2), u >= 55296 && u <= 56319)) {
- const l =
- c + 1 < t.length
- ? s
- ? t[c] | (t[c + 1] << 8)
- : (t[c] << 8) | t[c + 1]
- : -1;
- l >= 56320 && l <= 57343
- ? (n.push(u, l), (c += 2))
- : n.push(65533);
- } else u >= 56320 && u <= 57343 ? n.push(65533) : n.push(u);
- }
- c < t.length && n.push(65533);
- }
- let i = "";
- for (let s = 0; s < n.length; s += 8192)
- i += String.fromCharCode(...n.slice(s, s + 8192));
- return i;
- }
- },
- ot = new Kn(),
- jt = new _f(),
- Ua = (r) => Object.fromEntries(Object.entries(r).map(([e, t]) => [t, e])),
- xn = { bt709: 1, bt470bg: 5, smpte170m: 6, bt2020: 9, smpte432: 12 },
- rr = Ua(xn),
- Sn = {
- bt709: 1,
- smpte170m: 6,
- linear: 8,
- "iec61966-2-1": 13,
- pq: 16,
- hlg: 18,
- },
- nr = Ua(Sn),
- Pn = { rgb: 0, bt709: 1, bt470bg: 5, smpte170m: 6, "bt2020-ncl": 9 },
- ir = Ua(Pn),
- Ha = (r) =>
- !!r &&
- !!r.primaries &&
- !!r.transfer &&
- !!r.matrix &&
- r.fullRange !== void 0,
- Af = (r) =>
- !r ||
- (r.primaries == null &&
- r.transfer == null &&
- r.matrix == null &&
- r.fullRange == null),
- Pl = {
- primaries: void 0,
- transfer: void 0,
- matrix: void 0,
- fullRange: void 0,
- },
- os = (r) =>
- r instanceof ArrayBuffer ||
- (typeof SharedArrayBuffer < "u" && r instanceof SharedArrayBuffer) ||
- ArrayBuffer.isView(r);
-class Cn {
- constructor() {
- ((this.currentPromise = Promise.resolve()), (this.pending = 0));
- }
- async acquire() {
- let e;
- const t = new Promise((i) => {
- let s = !1;
- e = () => {
- s || (i(), this.pending--, (s = !0));
- };
- }),
- n = this.currentPromise;
- return ((this.currentPromise = t), this.pending++, await n, e);
- }
-}
-const Bf = /^[0-9a-fA-F]+$/,
- ri = (r) => [...r].map((e) => e.toString(16).padStart(2, "0")).join(""),
- Ff = (r) => {
- T(r.length % 2 === 0);
- const e = new Uint8Array(r.length / 2);
- for (let t = 0; t < r.length; t += 2)
- e[t / 2] = parseInt(r.slice(t, t + 2), 16);
- return e;
- },
- Bo = (r) => (
- (r = ((r >> 1) & 1431655765) | ((r & 1431655765) << 1)),
- (r = ((r >> 2) & 858993459) | ((r & 858993459) << 2)),
- (r = ((r >> 4) & 252645135) | ((r & 252645135) << 4)),
- (r = ((r >> 8) & 16711935) | ((r & 16711935) << 8)),
- (r = ((r >> 16) & 65535) | ((r & 65535) << 16)),
- r >>> 0
- ),
- fi = (r, e, t) => {
- let n = 0,
- i = r.length - 1,
- s = -1;
- for (; n <= i;) {
- const a = (n + i) >> 1,
- o = t(r[a]);
- o === e ? ((s = a), (i = a - 1)) : o < e ? (n = a + 1) : (i = a - 1);
- }
- return s;
- },
- ke = (r, e, t) => {
- let n = 0,
- i = r.length - 1,
- s = -1;
- for (; n <= i;) {
- const a = (n + (i - n + 1) / 2) | 0;
- t(r[a]) <= e ? ((s = a), (n = a + 1)) : (i = a - 1);
- }
- return s;
- },
- Fo = (r, e, t) => {
- const n = ke(r, t(e), t);
- r.splice(n + 1, 0, e);
- },
- Ke = () => {
- let r, e;
- return {
- promise: new Promise((n, i) => {
- ((r = n), (e = i));
- }),
- resolve: r,
- reject: e,
- };
- },
- pa = (r, e) => {
- const t = r.indexOf(e);
- t !== -1 && r.splice(t, 1);
- },
- Cl = (r, e) => {
- for (let t = r.length - 1; t >= 0; t--) if (e(r[t])) return r[t];
- },
- Va = (r, e) => {
- for (let t = r.length - 1; t >= 0; t--) if (e(r[t])) return t;
- return -1;
- },
- Rf = async function* (r) {
- Symbol.iterator in r
- ? yield* r[Symbol.iterator]()
- : yield* r[Symbol.asyncIterator]();
- },
- Mf = (r) => {
- if (!(Symbol.iterator in r) && !(Symbol.asyncIterator in r))
- throw new TypeError("Argument must be an iterable or async iterable.");
- },
- pr = (r) => {
- throw new Error(`Unexpected value: ${r}`);
- },
- vl = (r, e, t) => {
- const n = r.getUint8(e),
- i = r.getUint8(e + 1),
- s = r.getUint8(e + 2);
- return (n << 16) | (i << 8) | s;
- },
- La = (r, e, t, n) => {
- ((t = t >>> 0),
- (t = t & 16777215),
- n
- ? (r.setUint8(e, t & 255),
- r.setUint8(e + 1, (t >>> 8) & 255),
- r.setUint8(e + 2, (t >>> 16) & 255))
- : (r.setUint8(e, (t >>> 16) & 255),
- r.setUint8(e + 1, (t >>> 8) & 255),
- r.setUint8(e + 2, t & 255)));
- },
- Nf = (r, e, t, n) => {
- ((t = De(t, -8388608, 8388607)),
- t < 0 && (t = (t + 16777216) & 16777215),
- La(r, e, t, n));
- },
- Ro = (r, e) => ({
- async next() {
- const t = await r.next();
- return t.done
- ? { value: void 0, done: !0 }
- : { value: e(t.value), done: !1 };
- },
- return() {
- return r.return();
- },
- throw(t) {
- return r.throw(t);
- },
- [Symbol.asyncIterator]() {
- return this;
- },
- }),
- De = (r, e, t) => Math.max(e, Math.min(t, r)),
- Of = (r, e, t) => r + (e - r) * t,
- nt = "und",
- ni = (r) => {
- const e = Math.round(r);
- return Math.abs(r / e - 1) < 10 * Number.EPSILON ? e : r;
- },
- ga = (r, e) => Math.round(r / e) * e,
- Hi = (r, e) => Math.round(r * e) / e,
- vs = (r, e) => Math.floor(r / e) * e,
- Mo = (r, e) => Math.floor(r * e) / e,
- Df = (r) => {
- let e = 0;
- for (; r;) (e++, (r >>= 1));
- return e;
- },
- ba = (r) => {
- let e = 0;
- for (; r !== 0;) ((r &= r - 1), e++);
- return e;
- },
- zf = /^[a-z]{3}$/,
- qa = (r) => zf.test(r),
- _r = 1e6 * (1 + Number.EPSILON),
- No = (r, e) => {
- const t = { ...r, ...e };
- if (r.headers || e.headers) {
- const n = r.headers ? wa(r.headers) : {},
- i = e.headers ? wa(e.headers) : {},
- s = { ...n };
- (Object.entries(i).forEach(([a, o]) => {
- const c = Object.keys(s).find(
- (u) => u.toLowerCase() === a.toLowerCase(),
- );
- (c && delete s[c], (s[a] = o));
- }),
- (t.headers = s));
- }
- return t;
- },
- wa = (r) => {
- if (r instanceof Headers) {
- const e = {};
- return (
- r.forEach((t, n) => {
- e[n] = t;
- }),
- e
- );
- }
- if (Array.isArray(r)) {
- const e = {};
- return (
- r.forEach(([t, n]) => {
- e[t] = n;
- }),
- e
- );
- }
- return r;
- },
- Oo = async (r, e, t, n, i) => {
- let s = 0;
- for (;;)
- try {
- return await r(e, t);
- } catch (a) {
- if (i()) throw a;
- s++;
- const o = n(s, a, e);
- if (o === null) throw a;
- if (
- (te._error("Retrying failed fetch. Error:", a),
- !Number.isFinite(o) || o < 0)
- )
- throw new TypeError(
- "Retry delay must be a non-negative finite number.",
- );
- if ((o > 0 && (await si(1e3 * o)), i())) throw a;
- }
- },
- Wf = (r, e) => {
- const t = r < 0 ? -1 : 1;
- r = Math.abs(r);
- let n = 0,
- i = 1,
- s = 1,
- a = 0,
- o = r;
- for (;;) {
- const c = Math.floor(o),
- u = c * s + n,
- l = c * a + i;
- if (l > e) return { num: t * s, den: a };
- if (((n = s), (i = a), (s = u), (a = l), (o = 1 / (o - c)), !isFinite(o)))
- break;
- }
- return { num: t * s, den: a };
- };
-class ja {
- constructor() {
- this.currentPromise = Promise.resolve();
- }
- call(e) {
- return (this.currentPromise = this.currentPromise.then(e));
- }
-}
-let Es = null;
-const Fi = () => {
- var r;
- return Es !== null
- ? Es
- : (Es = !!(
- typeof navigator < "u" &&
- (((r = navigator.vendor) != null && r.match(/apple/i)) ||
- (/AppleWebKit/.test(navigator.userAgent) &&
- !/Chrome/.test(navigator.userAgent)) ||
- /\b(iPad|iPhone|iPod)\b/.test(navigator.userAgent))
- ));
-};
-let Is = null;
-const Vi = () => {
- var r;
- return Is !== null
- ? Is
- : (Is =
- typeof navigator < "u" &&
- ((r = navigator.userAgent) == null ? void 0 : r.includes("Firefox")));
-};
-let _s = null;
-const ya = () => {
- var r;
- return _s !== null
- ? _s
- : (_s = !!(
- typeof navigator < "u" &&
- (((r = navigator.vendor) != null && r.includes("Google Inc")) ||
- /Chrome/.test(navigator.userAgent))
- ));
- },
- $a = (r) =>
- typeof globalThis.isSecureContext < "u" && !globalThis.isSecureContext
- ? `${r} is not available in this environment; this may be because this page is running in an insecure context. Try serving your page over HTTPS or use localhost.`
- : `${r} is not available in this environment.`,
- Uf = (r) =>
- r instanceof DOMException &&
- r.name === "QuotaExceededError" &&
- /reclaimed/i.test(r.message),
- Hf = (async () => {})().constructor,
- O = (r) =>
- r instanceof Hf || r instanceof Promise
- ? !0
- : typeof (r == null ? void 0 : r.then) == "function",
- en = (r, e) => (r !== -1 ? r : e),
- ka = (r, e, t, n) => r <= n && t <= e,
- El = function* (r) {
- for (const e in r) {
- const t = r[e];
- t !== void 0 && (yield { key: e, value: t });
- }
- },
- Il = (r) => {
- const e = atob(r),
- t = new Uint8Array(e.length);
- for (let n = 0; n < e.length; n++) t[n] = e.charCodeAt(n);
- return t;
- },
- Vf = (r, e) => {
- if (r.length !== e.length) return !1;
- for (let t = 0; t < r.length; t++) if (r[t] !== e[t]) return !1;
- return !0;
- },
- Ga = () => {
- Symbol.dispose ?? (Symbol.dispose = Symbol("Symbol.dispose"));
- },
- hi = (r) => typeof r == "number" && !Number.isNaN(r),
- Er = (r, e) => {
- if (e.includes("://")) return e;
- if (r.includes("://")) {
- const o = r.indexOf("?");
- o !== -1 && (r = r.slice(0, o));
- }
- let t;
- if (e.startsWith("/")) {
- const o = r.indexOf("://");
- if (o === -1) t = e;
- else {
- const c = r.indexOf("/", o + 3);
- c === -1 ? (t = r + e) : (t = r.slice(0, c) + e);
- }
- } else {
- const o = r.lastIndexOf("/");
- o === -1 ? (t = e) : (t = r.slice(0, o + 1) + e);
- }
- let n = "";
- const i = t.indexOf("://");
- if (i !== -1) {
- const o = t.indexOf("/", i + 3);
- o !== -1 && ((n = t.slice(0, o)), (t = t.slice(o)));
- }
- const s = t.split("/"),
- a = [];
- for (const o of s) o === ".." ? a.pop() : o !== "." && a.push(o);
- return n + a.join("/");
- },
- Lf = (r, e) => {
- const t = r.indexOf("?");
- if (t === -1) return null;
- const n = r.indexOf("#", t),
- i = r.slice(t + 1, n === -1 ? void 0 : n);
- for (const s of i.split("&")) {
- const a = s.indexOf("="),
- o = a === -1 ? s : s.slice(0, a);
- if (decodeURIComponent(o) !== e) continue;
- const c = a === -1 ? "" : s.slice(a + 1);
- return decodeURIComponent(c);
- }
- return null;
- },
- qn = (r, e) => {
- let t = 0;
- for (let n = 0; n < r.length; n++) e(r[n]) && t++;
- return t;
- },
- Ka = (r, e) => {
- let t = -1,
- n = 1 / 0;
- for (let i = 0; i < r.length; i++) {
- const s = e(r[i]);
- s < n && ((n = s), (t = i));
- }
- return t;
- },
- ii = (r) => {
- (T(Number.isInteger(r.num)), T(Number.isInteger(r.den)), T(r.den !== 0));
- let e = Math.abs(r.num),
- t = Math.abs(r.den);
- for (; t !== 0;) {
- const i = e % t;
- ((e = t), (t = i));
- }
- const n = e || 1;
- return { num: r.num / n, den: r.den / n };
- },
- As = (r, e) => {
- if (typeof r != "object" || !r)
- throw new TypeError(`${e} must be an object.`);
- if (!Number.isInteger(r.left) || r.left < 0)
- throw new TypeError(`${e}.left must be a non-negative integer.`);
- if (!Number.isInteger(r.top) || r.top < 0)
- throw new TypeError(`${e}.top must be a non-negative integer.`);
- if (!Number.isInteger(r.width) || r.width < 0)
- throw new TypeError(`${e}.width must be a non-negative integer.`);
- if (!Number.isInteger(r.height) || r.height < 0)
- throw new TypeError(`${e}.height must be a non-negative integer.`);
- },
- si = (r) => new Promise((e) => setTimeout(e, r)),
- Do = (r) => (Array.isArray(r) ? r : [r]);
-class mi {
- constructor() {
- this._listeners = new Map();
- }
- on(e, t, n) {
- this._listeners.has(e) || this._listeners.set(e, new Set());
- const i = { fn: t, once: (n == null ? void 0 : n.once) ?? !1 };
- return (
- this._listeners.get(e).add(i),
- () => {
- var s;
- (s = this._listeners.get(e)) == null || s.delete(i);
- }
- );
- }
- _emit(...e) {
- const [t, n] = e,
- i = this._listeners.get(t);
- if (i)
- for (const s of i) {
- try {
- s.fn(n);
- } catch (a) {
- console.error(a);
- }
- s.once && i.delete(s);
- }
- }
-}
-const qf = (r) =>
- r !== null &&
- typeof r == "object" &&
- Object.getPrototypeOf(r) === Object.prototype &&
- Object.values(r).every((e) => typeof e == "string");
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ var Ut;
-(function (r) {
- ((r[(r.Silent = 0)] = "Silent"),
- (r[(r.Errors = 1)] = "Errors"),
- (r[(r.Warnings = 2)] = "Warnings"),
- (r[(r.Info = 3)] = "Info"));
-})(Ut || (Ut = {}));
-class te {
- constructor() {}
- static get level() {
- return te._level;
- }
- static set level(e) {
- if (
- e !== Ut.Silent &&
- e !== Ut.Errors &&
- e !== Ut.Warnings &&
- e !== Ut.Info
- )
- throw new TypeError(
- "Invalid log level. Use one of the values of the LogLevel enum.",
- );
- te._level = e;
- }
- static get _emitter() {
- return te._emitterInstance ?? (te._emitterInstance = new mi());
- }
- static on(e, t, n) {
- return te._emitter.on(e, t, n);
- }
- static _error(...e) {
- (te._emitter._emit("error", e),
- te._level >= Ut.Errors && console.error(...e));
- }
- static _warn(...e) {
- (te._emitter._emit("warn", e),
- te._level >= Ut.Warnings && console.warn(...e));
- }
- static _info(...e) {
- (te._emitter._emit("info", e), te._level >= Ut.Info && console.info(...e));
- }
-}
-te._level = Ut.Info;
-te._emitterInstance = null;
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class fn {
- constructor(e, t) {
- if (((this.data = e), (this.mimeType = t), !(e instanceof Uint8Array)))
- throw new TypeError("data must be a Uint8Array.");
- if (typeof t != "string") throw new TypeError("mimeType must be a string.");
- }
-}
-class _l {
- constructor(e, t, n, i) {
- if (
- ((this.data = e),
- (this.mimeType = t),
- (this.name = n),
- (this.description = i),
- !(e instanceof Uint8Array))
- )
- throw new TypeError("data must be a Uint8Array.");
- if (t !== void 0 && typeof t != "string")
- throw new TypeError("mimeType, when provided, must be a string.");
- if (n !== void 0 && typeof n != "string")
- throw new TypeError("name, when provided, must be a string.");
- if (i !== void 0 && typeof i != "string")
- throw new TypeError("description, when provided, must be a string.");
- }
-}
-const jf = (r) => {
- if (!r || typeof r != "object")
- throw new TypeError("tags must be an object.");
- if (r.title !== void 0 && typeof r.title != "string")
- throw new TypeError("tags.title, when provided, must be a string.");
- if (r.description !== void 0 && typeof r.description != "string")
- throw new TypeError("tags.description, when provided, must be a string.");
- if (r.artist !== void 0 && typeof r.artist != "string")
- throw new TypeError("tags.artist, when provided, must be a string.");
- if (r.album !== void 0 && typeof r.album != "string")
- throw new TypeError("tags.album, when provided, must be a string.");
- if (r.albumArtist !== void 0 && typeof r.albumArtist != "string")
- throw new TypeError("tags.albumArtist, when provided, must be a string.");
- if (
- r.trackNumber !== void 0 &&
- (!Number.isInteger(r.trackNumber) || r.trackNumber <= 0)
- )
- throw new TypeError(
- "tags.trackNumber, when provided, must be a positive integer.",
- );
- if (
- r.tracksTotal !== void 0 &&
- (!Number.isInteger(r.tracksTotal) || r.tracksTotal <= 0)
- )
- throw new TypeError(
- "tags.tracksTotal, when provided, must be a positive integer.",
- );
- if (
- r.discNumber !== void 0 &&
- (!Number.isInteger(r.discNumber) || r.discNumber <= 0)
- )
- throw new TypeError(
- "tags.discNumber, when provided, must be a positive integer.",
- );
- if (
- r.discsTotal !== void 0 &&
- (!Number.isInteger(r.discsTotal) || r.discsTotal <= 0)
- )
- throw new TypeError(
- "tags.discsTotal, when provided, must be a positive integer.",
- );
- if (r.genre !== void 0 && typeof r.genre != "string")
- throw new TypeError("tags.genre, when provided, must be a string.");
- if (
- r.date !== void 0 &&
- (!(r.date instanceof Date) || Number.isNaN(r.date.getTime()))
- )
- throw new TypeError("tags.date, when provided, must be a valid Date.");
- if (
- r.beatsPerMinute !== void 0 &&
- (!Number.isInteger(r.beatsPerMinute) || r.beatsPerMinute <= 0)
- )
- throw new TypeError(
- "tags.beatsPerMinute, when provided, must be a positive integer.",
- );
- if (r.lyrics !== void 0 && typeof r.lyrics != "string")
- throw new TypeError("tags.lyrics, when provided, must be a string.");
- if (r.images !== void 0) {
- if (!Array.isArray(r.images))
- throw new TypeError("tags.images, when provided, must be an array.");
- for (const e of r.images) {
- if (!e || typeof e != "object")
- throw new TypeError("Each image in tags.images must be an object.");
- if (!(e.data instanceof Uint8Array))
- throw new TypeError("Each image.data must be a Uint8Array.");
- if (typeof e.mimeType != "string")
- throw new TypeError("Each image.mimeType must be a string.");
- if (!["coverFront", "coverBack", "unknown"].includes(e.kind))
- throw new TypeError(
- "Each image.kind must be 'coverFront', 'coverBack', or 'unknown'.",
- );
- }
- }
- if (r.comment !== void 0 && typeof r.comment != "string")
- throw new TypeError("tags.comment, when provided, must be a string.");
- if (r.raw !== void 0) {
- if (!r.raw || typeof r.raw != "object")
- throw new TypeError("tags.raw, when provided, must be an object.");
- for (const e of Object.values(r.raw))
- if (
- e !== null &&
- typeof e != "string" &&
- !(Array.isArray(e) && e.every((t) => typeof t == "string")) &&
- !(e instanceof Uint8Array) &&
- !(e instanceof fn) &&
- !(e instanceof _l) &&
- !qf(e)
- )
- throw new TypeError(
- "Each value in tags.raw must be a string, string array, Uint8Array, RichImageData, AttachedFile, Record, or null.",
- );
- }
- },
- gr = {
- default: !0,
- primary: !0,
- forced: !1,
- original: !1,
- commentary: !1,
- hearingImpaired: !1,
- visuallyImpaired: !1,
- },
- $f = (r) => {
- if (!r || typeof r != "object")
- throw new TypeError("disposition must be an object.");
- if (r.default !== void 0 && typeof r.default != "boolean")
- throw new TypeError("disposition.default must be a boolean.");
- if (r.primary !== void 0 && typeof r.primary != "boolean")
- throw new TypeError("disposition.primary must be a boolean.");
- if (r.forced !== void 0 && typeof r.forced != "boolean")
- throw new TypeError("disposition.forced must be a boolean.");
- if (r.original !== void 0 && typeof r.original != "boolean")
- throw new TypeError("disposition.original must be a boolean.");
- if (r.commentary !== void 0 && typeof r.commentary != "boolean")
- throw new TypeError("disposition.commentary must be a boolean.");
- if (r.hearingImpaired !== void 0 && typeof r.hearingImpaired != "boolean")
- throw new TypeError("disposition.hearingImpaired must be a boolean.");
- if (r.visuallyImpaired !== void 0 && typeof r.visuallyImpaired != "boolean")
- throw new TypeError("disposition.visuallyImpaired must be a boolean.");
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class pe {
- constructor(e) {
- ((this.bytes = e), (this.pos = 0));
- }
- seekToByte(e) {
- this.pos = 8 * e;
- }
- readBit() {
- const e = Math.floor(this.pos / 8),
- t = this.bytes[e] ?? 0,
- n = 7 - (this.pos & 7),
- i = (t & (1 << n)) >> n;
- return (this.pos++, i);
- }
- readBits(e) {
- if (e === 1) return this.readBit();
- let t = 0;
- for (let n = 0; n < e; n++) ((t <<= 1), (t |= this.readBit()));
- return t;
- }
- writeBits(e, t) {
- const n = this.pos + e;
- for (let i = this.pos; i < n; i++) {
- const s = Math.floor(i / 8);
- let a = this.bytes[s];
- const o = 7 - (i & 7);
- ((a &= ~(1 << o)),
- (a |= ((t & (1 << (n - i - 1))) >> (n - i - 1)) << o),
- (this.bytes[s] = a));
- }
- this.pos = n;
- }
- copyBits(e, t) {
- let n = 0;
- for (n; n < e - 7; n += 8) this.writeBits(8, t.readBits(8));
- const i = e - n;
- i > 0 && this.writeBits(i, t.readBits(i));
- }
- readAlignedByte() {
- if (this.pos % 8 !== 0) throw new Error("Bitstream is not byte-aligned.");
- const e = this.pos / 8,
- t = this.bytes[e] ?? 0;
- return ((this.pos += 8), t);
- }
- skipBits(e) {
- this.pos += e;
- }
- getBitsLeft() {
- return this.bytes.length * 8 - this.pos;
- }
- clone() {
- const e = new pe(this.bytes);
- return ((e.pos = this.pos), e);
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const Kr = [
- 96e3, 88200, 64e3, 48e3, 44100, 32e3, 24e3, 22050, 16e3, 12e3, 11025, 8e3,
- 7350,
- ],
- pi = [-1, 1, 2, 3, 4, 5, 6, 8],
- Xa = (r) => {
- if (!r || r.byteLength < 2)
- throw new TypeError("AAC description must be at least 2 bytes long.");
- const e = new pe(r),
- t = Bs(e),
- { frequencyIndex: n, sampleRate: i } = Fs(e),
- s = e.readBits(4);
- let a = null;
- s >= 1 && s <= 7 && (a = pi[s]);
- let o = t,
- c = !1,
- u = i;
- if (t === 5 || t === 29)
- ((c = t === 29),
- (u = Fs(e).sampleRate),
- (o = Bs(e)),
- o === 22 && e.skipBits(4));
- else
- for (; e.getBitsLeft() > 15;) {
- const l = e.pos;
- if (e.readBits(11) !== 695) {
- e.pos = l + 1;
- continue;
- }
- Bs(e) === 5 &&
- e.readBits(1) &&
- ((u = Fs(e).sampleRate),
- e.getBitsLeft() > 11 &&
- e.readBits(11) === 1352 &&
- (c = !!e.readBits(1)));
- break;
- }
- return (
- a !== null && a > 1 && (c = !1),
- {
- objectType: t,
- coreObjectType: o,
- frequencyIndex: n,
- channelConfiguration: s,
- outputSampleRate: u,
- outputNumberOfChannels: c && a === 1 ? 2 : a,
- }
- );
- },
- Bs = (r) => {
- const e = r.readBits(5);
- return e === 31 ? 32 + r.readBits(6) : e;
- },
- Fs = (r) => {
- const e = r.readBits(4);
- return e === 15
- ? { frequencyIndex: e, sampleRate: r.readBits(24) }
- : { frequencyIndex: e, sampleRate: e < Kr.length ? Kr[e] : null };
- },
- Al = (r) => {
- const e = r.objectType === 5 || r.objectType === 29,
- t = r.objectType === 29,
- n = e ? r.outputSampleRate / 2 : r.outputSampleRate,
- i = t ? 1 : r.outputNumberOfChannels,
- s = pi.indexOf(i);
- if (s === -1)
- throw new TypeError(
- `Unsupported number of channels: ${r.outputNumberOfChannels}`,
- );
- let a = 16;
- (r.objectType >= 32 && (a += 6),
- Ta(n) === 15 && (a += 24),
- e && ((a += 9), Ta(r.outputSampleRate) === 15 && (a += 24)));
- const o = Math.ceil(a / 8),
- c = new Uint8Array(o),
- u = new pe(c);
- return (
- zo(u, r.objectType),
- Wo(u, n),
- u.writeBits(4, s),
- e && (Wo(u, r.outputSampleRate), zo(u, 2)),
- u.writeBits(3, 0),
- c
- );
- },
- zo = (r, e) => {
- e < 32 ? r.writeBits(5, e) : (r.writeBits(5, 31), r.writeBits(6, e - 32));
- },
- Wo = (r, e) => {
- const t = Ta(e);
- (r.writeBits(4, t), t === 15 && r.writeBits(24, e));
- },
- Ta = (r) => {
- const e = Kr.indexOf(r);
- return e === -1 ? 15 : e;
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const cs = [48e3, 44100, 32e3],
- Bl = [24e3, 22050, 16e3];
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const Gf = "1.61.3",
- Rs = `Mediabunny v${Gf}`;
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ var Xe;
-(function (r) {
- ((r[(r.NON_IDR_SLICE = 1)] = "NON_IDR_SLICE"),
- (r[(r.SLICE_DPA = 2)] = "SLICE_DPA"),
- (r[(r.SLICE_DPB = 3)] = "SLICE_DPB"),
- (r[(r.SLICE_DPC = 4)] = "SLICE_DPC"),
- (r[(r.IDR = 5)] = "IDR"),
- (r[(r.SEI = 6)] = "SEI"),
- (r[(r.SPS = 7)] = "SPS"),
- (r[(r.PPS = 8)] = "PPS"),
- (r[(r.AUD = 9)] = "AUD"),
- (r[(r.SPS_EXT = 13)] = "SPS_EXT"));
-})(Xe || (Xe = {}));
-var ze;
-(function (r) {
- ((r[(r.RASL_N = 8)] = "RASL_N"),
- (r[(r.RASL_R = 9)] = "RASL_R"),
- (r[(r.BLA_W_LP = 16)] = "BLA_W_LP"),
- (r[(r.RSV_IRAP_VCL23 = 23)] = "RSV_IRAP_VCL23"),
- (r[(r.VPS_NUT = 32)] = "VPS_NUT"),
- (r[(r.SPS_NUT = 33)] = "SPS_NUT"),
- (r[(r.PPS_NUT = 34)] = "PPS_NUT"),
- (r[(r.AUD_NUT = 35)] = "AUD_NUT"),
- (r[(r.PREFIX_SEI_NUT = 39)] = "PREFIX_SEI_NUT"),
- (r[(r.SUFFIX_SEI_NUT = 40)] = "SUFFIX_SEI_NUT"));
-})(ze || (ze = {}));
-const gi = function* (r) {
- let e = 0,
- t = -1;
- for (; e < r.length - 2;) {
- const n = r.indexOf(0, e);
- if (n === -1 || n >= r.length - 2) break;
- e = n;
- let i = 0;
- if (
- (e + 3 < r.length && r[e + 1] === 0 && r[e + 2] === 0 && r[e + 3] === 1
- ? (i = 4)
- : r[e + 1] === 0 && r[e + 2] === 1 && (i = 3),
- i === 0)
- ) {
- e++;
- continue;
- }
- (t !== -1 && e > t && (yield { offset: t, length: e - t }),
- (t = e + i),
- (e = t));
- }
- t !== -1 && t < r.length && (yield { offset: t, length: r.length - t });
- },
- Fl = function* (r, e) {
- let t = 0;
- const n = new DataView(r.buffer, r.byteOffset, r.byteLength);
- for (; t + e <= r.length;) {
- let i;
- (e === 1
- ? (i = n.getUint8(t))
- : e === 2
- ? (i = n.getUint16(t, !1))
- : e === 3
- ? (i = vl(n, t))
- : (T(e === 4), (i = n.getUint32(t, !1))),
- (t += e),
- yield { offset: t, length: i },
- (t += i));
- }
- },
- Rl = (r, e) => {
- if (e.description) {
- const i = (Ze(e.description)[4] & 3) + 1;
- return Fl(r, i);
- } else return gi(r);
- },
- ai = (r) => r & 31,
- ls = (r) => {
- const e = [],
- t = r.length;
- for (let n = 0; n < t; n++)
- n + 2 < t && r[n] === 0 && r[n + 1] === 0 && r[n + 2] === 3
- ? (e.push(0, 0), (n += 2))
- : e.push(r[n]);
- return new Uint8Array(e);
- },
- Kf = (r) => {
- const e = [];
- let t = 0;
- for (const n of r)
- (t === 2 && n <= 3 && (e.push(3), (t = 0)),
- e.push(n),
- (t = n === 0 ? t + 1 : 0));
- return new Uint8Array(e);
- },
- Ms = new Uint8Array([0, 0, 0, 1]),
- Ml = (r) => {
- const e = r.reduce((i, s) => i + Ms.byteLength + s.byteLength, 0),
- t = new Uint8Array(e);
- let n = 0;
- for (const i of r)
- (t.set(Ms, n), (n += Ms.byteLength), t.set(i, n), (n += i.byteLength));
- return t;
- },
- Qa = (r, e) => {
- const t = r.reduce((s, a) => s + e + a.byteLength, 0),
- n = new Uint8Array(t);
- let i = 0;
- for (const s of r) {
- const a = new DataView(n.buffer, n.byteOffset, n.byteLength);
- switch (e) {
- case 1:
- a.setUint8(i, s.byteLength);
- break;
- case 2:
- a.setUint16(i, s.byteLength, !1);
- break;
- case 3:
- La(a, i, s.byteLength, !1);
- break;
- case 4:
- a.setUint32(i, s.byteLength, !1);
- break;
- }
- ((i += e), n.set(s, i), (i += s.byteLength));
- }
- return n;
- },
- Xf = (r, e) => {
- if (e.description) {
- const i = (Ze(e.description)[4] & 3) + 1;
- return Qa(r, i);
- } else return Ml(r);
- },
- bi = (r) => {
- try {
- const e = [],
- t = [],
- n = [];
- for (const o of gi(r)) {
- const c = r.subarray(o.offset, o.offset + o.length),
- u = ai(c[0]);
- u === Xe.SPS
- ? e.push(c)
- : u === Xe.PPS
- ? t.push(c)
- : u === Xe.SPS_EXT && n.push(c);
- }
- if (e.length === 0 || t.length === 0) return null;
- const i = e[0],
- s = bn(i);
- T(s !== null);
- const a =
- s.profileIdc === 100 ||
- s.profileIdc === 110 ||
- s.profileIdc === 122 ||
- s.profileIdc === 144;
- return {
- configurationVersion: 1,
- avcProfileIndication: s.profileIdc,
- profileCompatibility: s.constraintFlags,
- avcLevelIndication: s.levelIdc,
- lengthSizeMinusOne: 3,
- sequenceParameterSets: e,
- pictureParameterSets: t,
- chromaFormat: a ? s.chromaFormatIdc : null,
- bitDepthLumaMinus8: a ? s.bitDepthLumaMinus8 : null,
- bitDepthChromaMinus8: a ? s.bitDepthChromaMinus8 : null,
- sequenceParameterSetExt: a ? n : null,
- };
- } catch (e) {
- return (
- te._error("Error building AVC Decoder Configuration Record:", e),
- null
- );
- }
- },
- Nl = (r) => {
- const e = [];
- (e.push(r.configurationVersion),
- e.push(r.avcProfileIndication),
- e.push(r.profileCompatibility),
- e.push(r.avcLevelIndication),
- e.push(252 | (r.lengthSizeMinusOne & 3)),
- e.push(224 | (r.sequenceParameterSets.length & 31)));
- for (const t of r.sequenceParameterSets) {
- const n = t.byteLength;
- (e.push(n >> 8), e.push(n & 255));
- for (let i = 0; i < n; i++) e.push(t[i]);
- }
- e.push(r.pictureParameterSets.length);
- for (const t of r.pictureParameterSets) {
- const n = t.byteLength;
- (e.push(n >> 8), e.push(n & 255));
- for (let i = 0; i < n; i++) e.push(t[i]);
- }
- if (
- (r.avcProfileIndication === 100 ||
- r.avcProfileIndication === 110 ||
- r.avcProfileIndication === 122 ||
- r.avcProfileIndication === 144) &&
- r.chromaFormat !== null
- ) {
- (T(r.bitDepthLumaMinus8 !== null),
- T(r.bitDepthChromaMinus8 !== null),
- T(r.sequenceParameterSetExt !== null),
- e.push(252 | (r.chromaFormat & 3)),
- e.push(248 | (r.bitDepthLumaMinus8 & 7)),
- e.push(248 | (r.bitDepthChromaMinus8 & 7)),
- e.push(r.sequenceParameterSetExt.length));
- for (const t of r.sequenceParameterSetExt) {
- const n = t.byteLength;
- (e.push(n >> 8), e.push(n & 255));
- for (let i = 0; i < n; i++) e.push(t[i]);
- }
- }
- return new Uint8Array(e);
- },
- Ya = (r) => {
- try {
- const e = ge(r);
- let t = 0;
- const n = e.getUint8(t++),
- i = e.getUint8(t++),
- s = e.getUint8(t++),
- a = e.getUint8(t++),
- o = e.getUint8(t++) & 3,
- c = e.getUint8(t++) & 31,
- u = [];
- for (let h = 0; h < c; h++) {
- const p = e.getUint16(t, !1);
- ((t += 2), u.push(r.subarray(t, t + p)), (t += p));
- }
- const l = e.getUint8(t++),
- d = [];
- for (let h = 0; h < l; h++) {
- const p = e.getUint16(t, !1);
- ((t += 2), d.push(r.subarray(t, t + p)), (t += p));
- }
- const f = {
- configurationVersion: n,
- avcProfileIndication: i,
- profileCompatibility: s,
- avcLevelIndication: a,
- lengthSizeMinusOne: o,
- sequenceParameterSets: u,
- pictureParameterSets: d,
- chromaFormat: null,
- bitDepthLumaMinus8: null,
- bitDepthChromaMinus8: null,
- sequenceParameterSetExt: null,
- };
- if (
- (i === 100 || i === 110 || i === 122 || i === 144) &&
- t + 4 <= r.length
- ) {
- const h = e.getUint8(t++) & 3,
- p = e.getUint8(t++) & 7,
- m = e.getUint8(t++) & 7,
- b = e.getUint8(t++);
- ((f.chromaFormat = h),
- (f.bitDepthLumaMinus8 = p),
- (f.bitDepthChromaMinus8 = m));
- const g = [];
- for (let y = 0; y < b; y++) {
- const C = e.getUint16(t, !1);
- ((t += 2), g.push(r.subarray(t, t + C)), (t += C));
- }
- f.sequenceParameterSetExt = g;
- }
- return f;
- } catch (e) {
- return (
- te._error("Error deserializing AVC Decoder Configuration Record:", e),
- null
- );
- }
- },
- Ol = {
- 1: { num: 1, den: 1 },
- 2: { num: 12, den: 11 },
- 3: { num: 10, den: 11 },
- 4: { num: 16, den: 11 },
- 5: { num: 40, den: 33 },
- 6: { num: 24, den: 11 },
- 7: { num: 20, den: 11 },
- 8: { num: 32, den: 11 },
- 9: { num: 80, den: 33 },
- 10: { num: 18, den: 11 },
- 11: { num: 15, den: 11 },
- 12: { num: 64, den: 33 },
- 13: { num: 160, den: 99 },
- 14: { num: 4, den: 3 },
- 15: { num: 3, den: 2 },
- 16: { num: 2, den: 1 },
- },
- bn = (r) => {
- try {
- const e = ls(r),
- t = new pe(e);
- if ((t.skipBits(1), t.skipBits(2), t.readBits(5) !== 7)) return null;
- const i = t.readAlignedByte(),
- s = t.readAlignedByte(),
- a = t.readAlignedByte();
- G(t);
- let o = 1,
- c = 0,
- u = 0,
- l = 0;
- if (
- (i === 100 ||
- i === 110 ||
- i === 122 ||
- i === 244 ||
- i === 44 ||
- i === 83 ||
- i === 86 ||
- i === 118 ||
- i === 128) &&
- ((o = G(t)),
- o === 3 && (l = t.readBits(1)),
- (c = G(t)),
- (u = G(t)),
- t.skipBits(1),
- t.readBits(1))
- ) {
- for (let q = 0; q < (o !== 3 ? 8 : 12); q++)
- if (t.readBits(1)) {
- const se = q < 6 ? 16 : 64;
- let le = 8,
- ue = 8;
- for (let $e = 0; $e < se; $e++) {
- if (ue !== 0) {
- const K = or(t);
- ue = (le + K + 256) % 256;
- }
- le = ue === 0 ? le : ue;
- }
- }
- }
- G(t);
- const d = G(t);
- if (d === 0) G(t);
- else if (d === 1) {
- (t.skipBits(1), or(t), or(t));
- const z = G(t);
- for (let q = 0; q < z; q++) or(t);
- }
- (G(t), t.skipBits(1));
- const f = G(t),
- h = G(t),
- p = 16 * (f + 1),
- m = 16 * (h + 1);
- let b = p,
- g = m;
- const y = t.readBits(1);
- if ((y || t.skipBits(1), t.skipBits(1), t.readBits(1))) {
- const z = G(t),
- q = G(t),
- j = G(t),
- se = G(t);
- let le, ue;
- if ((l === 0 ? o : 0) === 0) ((le = 1), (ue = 2 - y));
- else {
- const K = o === 3 ? 1 : 2,
- ie = o === 1 ? 2 : 1;
- ((le = K), (ue = ie * (2 - y)));
- }
- ((b -= le * (z + q)), (g -= ue * (j + se)));
- }
- let _ = 2,
- v = 2,
- I = 2,
- w = 0,
- x = { num: 1, den: 1 },
- k = null,
- S = null,
- E = null,
- B = null;
- const R = t.pos;
- if (t.readBits(1)) {
- if (t.readBits(1)) {
- const K = t.readBits(8);
- if (K === 255) x = { num: t.readBits(16), den: t.readBits(16) };
- else {
- const ie = Ol[K];
- ie && (x = ie);
- }
- }
- (t.readBits(1) && t.skipBits(1),
- t.readBits(1) &&
- (t.skipBits(3),
- (w = t.readBits(1)),
- t.readBits(1) &&
- ((_ = t.readBits(8)), (v = t.readBits(8)), (I = t.readBits(8)))),
- t.readBits(1) && (G(t), G(t)),
- t.readBits(1) && (t.skipBits(32), t.skipBits(32), t.skipBits(1)));
- const ue = t.readBits(1);
- ue && Uo(t);
- const $e = t.readBits(1);
- ($e && Uo(t),
- (ue || $e) && t.skipBits(1),
- t.skipBits(1),
- (E = t.pos),
- (B = t.readBits(1)),
- B && (t.skipBits(1), G(t), G(t), G(t), G(t), (k = G(t)), (S = G(t))));
- }
- if (k === null) {
- T(S === null);
- const z = s & 16;
- if (
- (i === 44 ||
- i === 86 ||
- i === 100 ||
- i === 110 ||
- i === 122 ||
- i === 244) &&
- z
- )
- ((k = 0), (S = 0));
- else {
- const q = f + 1,
- j = h + 1,
- se = (2 - y) * j,
- le = ji.find(($e) => $e.level >= a) ?? Ae(ji),
- ue = Math.min(Math.floor(le.maxDpbMbs / (q * se)), 16);
- ((k = ue), (S = ue));
- }
- }
- return (
- T(S !== null),
- {
- emulationUnpreventedBytes: e,
- profileIdc: i,
- constraintFlags: s,
- levelIdc: a,
- frameMbsOnlyFlag: y,
- chromaFormatIdc: o,
- bitDepthLumaMinus8: c,
- bitDepthChromaMinus8: u,
- codedWidth: p,
- codedHeight: m,
- displayWidth: b,
- displayHeight: g,
- pixelAspectRatio: x,
- colourPrimaries: _,
- matrixCoefficients: I,
- transferCharacteristics: v,
- fullRangeFlag: w,
- numReorderFrames: k,
- maxDecFrameBuffering: S,
- vuiParametersFlagBitOffset: R,
- bitstreamRestrictionFlagBitOffset: E,
- bitstreamRestrictionFlag: B,
- }
- );
- } catch (e) {
- return (te._error("Error parsing AVC SPS:", e), null);
- }
- },
- Uo = (r) => {
- const e = G(r);
- (r.skipBits(4), r.skipBits(4));
- for (let t = 0; t <= e; t++) (G(r), G(r), r.skipBits(1));
- (r.skipBits(5), r.skipBits(5), r.skipBits(5), r.skipBits(5));
- },
- Ho = (r) => {
- T(r.bitstreamRestrictionFlag !== 1);
- const e = new Uint8Array(r.emulationUnpreventedBytes.byteLength + 64),
- t = new pe(r.emulationUnpreventedBytes),
- n = new pe(e);
- (r.bitstreamRestrictionFlag === null
- ? (n.copyBits(r.vuiParametersFlagBitOffset, t),
- n.writeBits(1, 1),
- n.writeBits(1, 0),
- n.writeBits(1, 0),
- n.writeBits(1, 0),
- n.writeBits(1, 0),
- n.writeBits(1, 0),
- n.writeBits(1, 0),
- n.writeBits(1, 0),
- n.writeBits(1, 0))
- : (T(r.bitstreamRestrictionFlagBitOffset !== null),
- n.copyBits(r.bitstreamRestrictionFlagBitOffset, t)),
- n.writeBits(1, 1),
- n.writeBits(1, 1),
- Yr(n, 2),
- Yr(n, 1),
- Yr(n, 16),
- Yr(n, 16),
- Yr(n, r.numReorderFrames),
- Yr(n, r.maxDecFrameBuffering),
- n.writeBits(1, 1),
- n.writeBits((8 - (n.pos % 8)) % 8, 0));
- const i = n.pos / 8;
- return (T(Number.isInteger(i)), Kf(e.subarray(0, i)));
- },
- Qf = (r, e) => {
- if (e.description) {
- const i = (Ze(e.description)[21] & 3) + 1;
- return Qa(r, i);
- } else return Ml(r);
- },
- Li = (r, e) => {
- if (e.description) {
- const i = (Ze(e.description)[21] & 3) + 1;
- return Fl(r, i);
- } else return gi(r);
- },
- wn = (r) => (r >> 1) & 63,
- us = (r) => {
- try {
- const e = new pe(ls(r));
- (e.skipBits(16), e.readBits(4));
- const t = e.readBits(3),
- n = e.readBits(1),
- {
- general_profile_space: i,
- general_tier_flag: s,
- general_profile_idc: a,
- general_profile_compatibility_flags: o,
- general_constraint_indicator_flags: c,
- general_level_idc: u,
- } = Yf(e, t);
- G(e);
- const l = G(e);
- let d = 0;
- l === 3 && (d = e.readBits(1));
- const f = G(e),
- h = G(e);
- let p = f,
- m = h;
- if (e.readBits(1)) {
- const B = G(e),
- R = G(e),
- M = G(e),
- z = G(e);
- let q = 1,
- j = 1;
- const se = d === 0 ? l : 0;
- (se === 1 ? ((q = 2), (j = 2)) : se === 2 && ((q = 2), (j = 1)),
- (p -= (B + R) * q),
- (m -= (M + z) * j));
- }
- const b = G(e),
- g = G(e);
- G(e);
- const C = e.readBits(1) ? 0 : t;
- let _ = 0;
- for (let B = C; B <= t; B++) (G(e), (_ = G(e)), G(e));
- (G(e),
- G(e),
- G(e),
- G(e),
- G(e),
- G(e),
- e.readBits(1) && e.readBits(1) && Zf(e),
- e.skipBits(1),
- e.skipBits(1),
- e.readBits(1) &&
- (e.skipBits(4), e.skipBits(4), G(e), G(e), e.skipBits(1)));
- const v = G(e);
- if ((Jf(e, v), e.readBits(1))) {
- const B = G(e);
- for (let R = 0; R < B; R++) (G(e), e.skipBits(1));
- }
- (e.skipBits(1), e.skipBits(1));
- let I = 2,
- w = 2,
- x = 2,
- k = 0,
- S = 0,
- E = { num: 1, den: 1 };
- if (e.readBits(1)) {
- const B = th(e, t);
- ((E = B.pixelAspectRatio),
- (I = B.colourPrimaries),
- (w = B.transferCharacteristics),
- (x = B.matrixCoefficients),
- (k = B.fullRangeFlag),
- (S = B.minSpatialSegmentationIdc));
- }
- return {
- displayWidth: p,
- displayHeight: m,
- pixelAspectRatio: E,
- colourPrimaries: I,
- transferCharacteristics: w,
- matrixCoefficients: x,
- fullRangeFlag: k,
- maxDecFrameBuffering: _ + 1,
- spsMaxSubLayersMinus1: t,
- spsTemporalIdNestingFlag: n,
- generalProfileSpace: i,
- generalTierFlag: s,
- generalProfileIdc: a,
- generalProfileCompatibilityFlags: o,
- generalConstraintIndicatorFlags: c,
- generalLevelIdc: u,
- chromaFormatIdc: l,
- bitDepthLumaMinus8: b,
- bitDepthChromaMinus8: g,
- minSpatialSegmentationIdc: S,
- };
- } catch (e) {
- return (te._error("Error parsing HEVC SPS:", e), null);
- }
- },
- wi = (r) => {
- try {
- const e = [],
- t = [],
- n = [],
- i = [];
- for (const u of gi(r)) {
- const l = r.subarray(u.offset, u.offset + u.length),
- d = wn(l[0]);
- d === ze.VPS_NUT
- ? e.push(l)
- : d === ze.SPS_NUT
- ? t.push(l)
- : d === ze.PPS_NUT
- ? n.push(l)
- : (d === ze.PREFIX_SEI_NUT || d === ze.SUFFIX_SEI_NUT) &&
- i.push(l);
- }
- if (t.length === 0 || n.length === 0) return null;
- const s = us(t[0]);
- if (!s) return null;
- let a = 0;
- if (n.length > 0) {
- const u = n[0],
- l = new pe(ls(u));
- (l.skipBits(16),
- G(l),
- G(l),
- l.skipBits(1),
- l.skipBits(1),
- l.skipBits(3),
- l.skipBits(1),
- l.skipBits(1),
- G(l),
- G(l),
- or(l),
- l.skipBits(1),
- l.skipBits(1),
- l.readBits(1) && G(l),
- or(l),
- or(l),
- l.skipBits(1),
- l.skipBits(1),
- l.skipBits(1),
- l.skipBits(1));
- const d = l.readBits(1),
- f = l.readBits(1);
- !d && !f ? (a = 0) : d && !f ? (a = 2) : !d && f ? (a = 3) : (a = 0);
- }
- const o = [
- ...(e.length
- ? [{ arrayCompleteness: 1, nalUnitType: ze.VPS_NUT, nalUnits: e }]
- : []),
- ...(t.length
- ? [{ arrayCompleteness: 1, nalUnitType: ze.SPS_NUT, nalUnits: t }]
- : []),
- ...(n.length
- ? [{ arrayCompleteness: 1, nalUnitType: ze.PPS_NUT, nalUnits: n }]
- : []),
- ...(i.length
- ? [{ arrayCompleteness: 1, nalUnitType: wn(i[0][0]), nalUnits: i }]
- : []),
- ];
- return {
- configurationVersion: 1,
- generalProfileSpace: s.generalProfileSpace,
- generalTierFlag: s.generalTierFlag,
- generalProfileIdc: s.generalProfileIdc,
- generalProfileCompatibilityFlags: s.generalProfileCompatibilityFlags,
- generalConstraintIndicatorFlags: s.generalConstraintIndicatorFlags,
- generalLevelIdc: s.generalLevelIdc,
- minSpatialSegmentationIdc: s.minSpatialSegmentationIdc,
- parallelismType: a,
- chromaFormatIdc: s.chromaFormatIdc,
- bitDepthLumaMinus8: s.bitDepthLumaMinus8,
- bitDepthChromaMinus8: s.bitDepthChromaMinus8,
- avgFrameRate: 0,
- constantFrameRate: 0,
- numTemporalLayers: s.spsMaxSubLayersMinus1 + 1,
- temporalIdNested: s.spsTemporalIdNestingFlag,
- lengthSizeMinusOne: 3,
- arrays: o,
- };
- } catch (e) {
- return (
- te._error("Error building HEVC Decoder Configuration Record:", e),
- null
- );
- }
- },
- Yf = (r, e) => {
- const t = r.readBits(2),
- n = r.readBits(1),
- i = r.readBits(5);
- let s = 0;
- for (let l = 0; l < 32; l++) s = (s << 1) | r.readBits(1);
- const a = new Uint8Array(6);
- for (let l = 0; l < 6; l++) a[l] = r.readBits(8);
- const o = r.readBits(8),
- c = [],
- u = [];
- for (let l = 0; l < e; l++) (c.push(r.readBits(1)), u.push(r.readBits(1)));
- if (e > 0) for (let l = e; l < 8; l++) r.skipBits(2);
- for (let l = 0; l < e; l++) (c[l] && r.skipBits(88), u[l] && r.skipBits(8));
- return {
- general_profile_space: t,
- general_tier_flag: n,
- general_profile_idc: i,
- general_profile_compatibility_flags: s,
- general_constraint_indicator_flags: a,
- general_level_idc: o,
- };
- },
- Zf = (r) => {
- for (let e = 0; e < 4; e++)
- for (let t = 0; t < (e === 3 ? 2 : 6); t++)
- if (!r.readBits(1)) G(r);
- else {
- const i = Math.min(64, 1 << (4 + (e << 1)));
- e > 1 && or(r);
- for (let s = 0; s < i; s++) or(r);
- }
- },
- Jf = (r, e) => {
- const t = [];
- for (let n = 0; n < e; n++) t[n] = eh(r, n, e, t);
- },
- eh = (r, e, t, n) => {
- let i = 0,
- s = 0,
- a = 0;
- if ((e !== 0 && (s = r.readBits(1)), s)) {
- if (e === t) {
- const c = G(r);
- a = e - (c + 1);
- } else a = e - 1;
- (r.readBits(1), G(r));
- const o = n[a] ?? 0;
- for (let c = 0; c <= o; c++) r.readBits(1) || r.readBits(1);
- i = n[a];
- } else {
- const o = G(r),
- c = G(r);
- for (let u = 0; u < o; u++) (G(r), r.readBits(1));
- for (let u = 0; u < c; u++) (G(r), r.readBits(1));
- i = o + c;
- }
- return i;
- },
- th = (r, e) => {
- let t = 2,
- n = 2,
- i = 2,
- s = 0,
- a = 0,
- o = { num: 1, den: 1 };
- if (r.readBits(1)) {
- const c = r.readBits(8);
- if (c === 255) o = { num: r.readBits(16), den: r.readBits(16) };
- else {
- const u = Ol[c];
- u && (o = u);
- }
- }
- return (
- r.readBits(1) && r.readBits(1),
- r.readBits(1) &&
- (r.readBits(3),
- (s = r.readBits(1)),
- r.readBits(1) &&
- ((t = r.readBits(8)), (n = r.readBits(8)), (i = r.readBits(8)))),
- r.readBits(1) && (G(r), G(r)),
- r.readBits(1),
- r.readBits(1),
- r.readBits(1),
- r.readBits(1) && (G(r), G(r), G(r), G(r)),
- r.readBits(1) &&
- (r.readBits(32),
- r.readBits(32),
- r.readBits(1) && G(r),
- r.readBits(1) && rh(r, !0, e)),
- r.readBits(1) &&
- (r.readBits(1),
- r.readBits(1),
- r.readBits(1),
- (a = G(r)),
- G(r),
- G(r),
- G(r),
- G(r)),
- {
- pixelAspectRatio: o,
- colourPrimaries: t,
- transferCharacteristics: n,
- matrixCoefficients: i,
- fullRangeFlag: s,
- minSpatialSegmentationIdc: a,
- }
- );
- },
- rh = (r, e, t) => {
- let n = !1,
- i = !1,
- s = !1;
- ((n = r.readBits(1) === 1),
- (i = r.readBits(1) === 1),
- (n || i) &&
- ((s = r.readBits(1) === 1),
- s && (r.readBits(8), r.readBits(5), r.readBits(1), r.readBits(5)),
- r.readBits(4),
- r.readBits(4),
- s && r.readBits(4),
- r.readBits(5),
- r.readBits(5),
- r.readBits(5)));
- for (let a = 0; a <= t; a++) {
- const o = r.readBits(1) === 1;
- let c = !0;
- o || (c = r.readBits(1) === 1);
- let u = !1;
- c ? G(r) : (u = r.readBits(1) === 1);
- let l = 1;
- (u || (l = G(r) + 1), n && Vo(r, l, s), i && Vo(r, l, s));
- }
- },
- Vo = (r, e, t) => {
- for (let n = 0; n < e; n++) (G(r), G(r), t && (G(r), G(r)), r.readBits(1));
- },
- nh = (r) => {
- const e = [];
- (e.push(r.configurationVersion),
- e.push(
- ((r.generalProfileSpace & 3) << 6) |
- ((r.generalTierFlag & 1) << 5) |
- (r.generalProfileIdc & 31),
- ),
- e.push((r.generalProfileCompatibilityFlags >>> 24) & 255),
- e.push((r.generalProfileCompatibilityFlags >>> 16) & 255),
- e.push((r.generalProfileCompatibilityFlags >>> 8) & 255),
- e.push(r.generalProfileCompatibilityFlags & 255),
- e.push(...r.generalConstraintIndicatorFlags),
- e.push(r.generalLevelIdc & 255),
- e.push(240 | ((r.minSpatialSegmentationIdc >> 8) & 15)),
- e.push(r.minSpatialSegmentationIdc & 255),
- e.push(252 | (r.parallelismType & 3)),
- e.push(252 | (r.chromaFormatIdc & 3)),
- e.push(248 | (r.bitDepthLumaMinus8 & 7)),
- e.push(248 | (r.bitDepthChromaMinus8 & 7)),
- e.push((r.avgFrameRate >> 8) & 255),
- e.push(r.avgFrameRate & 255),
- e.push(
- ((r.constantFrameRate & 3) << 6) |
- ((r.numTemporalLayers & 7) << 3) |
- ((r.temporalIdNested & 1) << 2) |
- (r.lengthSizeMinusOne & 3),
- ),
- e.push(r.arrays.length & 255));
- for (const t of r.arrays) {
- (e.push(((t.arrayCompleteness & 1) << 7) | 0 | (t.nalUnitType & 63)),
- e.push((t.nalUnits.length >> 8) & 255),
- e.push(t.nalUnits.length & 255));
- for (const n of t.nalUnits) {
- (e.push((n.length >> 8) & 255), e.push(n.length & 255));
- for (let i = 0; i < n.length; i++) e.push(n[i]);
- }
- }
- return new Uint8Array(e);
- },
- Dl = (r) => {
- try {
- const e = ge(r);
- let t = 0;
- const n = e.getUint8(t++),
- i = e.getUint8(t++),
- s = (i >> 6) & 3,
- a = (i >> 5) & 1,
- o = i & 31,
- c = e.getUint32(t, !1);
- t += 4;
- const u = r.subarray(t, t + 6);
- t += 6;
- const l = e.getUint8(t++),
- d = ((e.getUint8(t++) & 15) << 8) | e.getUint8(t++),
- f = e.getUint8(t++) & 3,
- h = e.getUint8(t++) & 3,
- p = e.getUint8(t++) & 7,
- m = e.getUint8(t++) & 7,
- b = e.getUint16(t, !1);
- t += 2;
- const g = e.getUint8(t++),
- y = (g >> 6) & 3,
- C = (g >> 3) & 7,
- _ = (g >> 2) & 1,
- v = g & 3,
- I = e.getUint8(t++),
- w = [];
- for (let x = 0; x < I; x++) {
- const k = e.getUint8(t++),
- S = (k >> 7) & 1,
- E = k & 63,
- B = e.getUint16(t, !1);
- t += 2;
- const R = [];
- for (let M = 0; M < B; M++) {
- const z = e.getUint16(t, !1);
- ((t += 2), R.push(r.subarray(t, t + z)), (t += z));
- }
- w.push({ arrayCompleteness: S, nalUnitType: E, nalUnits: R });
- }
- return {
- configurationVersion: n,
- generalProfileSpace: s,
- generalTierFlag: a,
- generalProfileIdc: o,
- generalProfileCompatibilityFlags: c,
- generalConstraintIndicatorFlags: u,
- generalLevelIdc: l,
- minSpatialSegmentationIdc: d,
- parallelismType: f,
- chromaFormatIdc: h,
- bitDepthLumaMinus8: p,
- bitDepthChromaMinus8: m,
- avgFrameRate: b,
- constantFrameRate: y,
- numTemporalLayers: C,
- temporalIdNested: _,
- lengthSizeMinusOne: v,
- arrays: w,
- };
- } catch (e) {
- return (
- te._error("Error deserializing HEVC Decoder Configuration Record:", e),
- null
- );
- }
- };
-var Je;
-(function (r) {
- ((r[(r.audAllowed = 0)] = "audAllowed"),
- (r[(r.beforeFirstVcl = 1)] = "beforeFirstVcl"),
- (r[(r.afterFirstVcl = 2)] = "afterFirstVcl"),
- (r[(r.eoBitstreamAllowed = 3)] = "eoBitstreamAllowed"),
- (r[(r.noMoreDataAllowed = 4)] = "noMoreDataAllowed"));
-})(Je || (Je = {}));
-const ih = (r, e) => {
- const t = new Set();
- let n = Je.audAllowed;
- for (const s of Li(r, e)) {
- if (n === Je.noMoreDataAllowed) {
- t.add(s.offset);
- continue;
- }
- const a = wn(r[s.offset]);
- if (n === Je.eoBitstreamAllowed && a !== 37) {
- t.add(s.offset);
- continue;
- }
- let o = !1;
- (a === 35
- ? n > Je.audAllowed
- ? (o = !0)
- : (n = Je.beforeFirstVcl)
- : a <= 31
- ? n > Je.afterFirstVcl
- ? (o = !0)
- : (n = Je.afterFirstVcl)
- : a === 36
- ? n !== Je.afterFirstVcl
- ? (o = !0)
- : (n = Je.eoBitstreamAllowed)
- : a === 37
- ? n < Je.afterFirstVcl
- ? (o = !0)
- : (n = Je.noMoreDataAllowed)
- : a === 32 ||
- a === 33 ||
- a === 34 ||
- a === 39 ||
- (a >= 41 && a <= 44) ||
- (a >= 48 && a <= 55)
- ? n > Je.beforeFirstVcl
- ? (o = !0)
- : (n = Je.beforeFirstVcl)
- : (a === 38 ||
- a === 40 ||
- (a >= 45 && a <= 47) ||
- (a >= 56 && a <= 63)) &&
- n < Je.afterFirstVcl &&
- (o = !0),
- o && t.add(s.offset));
- }
- if (t.size === 0) return null;
- const i = [];
- for (const s of Li(r, e))
- t.has(s.offset) || i.push(r.subarray(s.offset, s.offset + s.length));
- return Qf(i, e);
- },
- sh = {
- 1: {
- colourPrimaries: 5,
- transferCharacteristics: 6,
- matrixCoefficients: 5,
- },
- 2: {
- colourPrimaries: 1,
- transferCharacteristics: 1,
- matrixCoefficients: 1,
- },
- 3: {
- colourPrimaries: 6,
- transferCharacteristics: 6,
- matrixCoefficients: 6,
- },
- 4: {
- colourPrimaries: 7,
- transferCharacteristics: 7,
- matrixCoefficients: 7,
- },
- 5: {
- colourPrimaries: 9,
- transferCharacteristics: 14,
- matrixCoefficients: 9,
- },
- 7: {
- colourPrimaries: 1,
- transferCharacteristics: 13,
- matrixCoefficients: 0,
- },
- },
- Za = (r) => {
- const e = new pe(r);
- if (e.readBits(2) !== 2) return null;
- const n = e.readBits(1),
- s = (e.readBits(1) << 1) + n;
- if (
- (s === 3 && e.skipBits(1),
- e.readBits(1) === 1 ||
- e.readBits(1) !== 0 ||
- (e.skipBits(2), e.readBits(24) !== 4817730))
- )
- return null;
- let u = 8;
- s >= 2 && (u = e.readBits(1) ? 12 : 10);
- const l = e.readBits(3);
- let d = 0,
- f = 0;
- if (l !== 7)
- if (((f = e.readBits(1)), s === 1 || s === 3)) {
- const x = e.readBits(1),
- k = e.readBits(1);
- ((d = !x && !k ? 3 : x && !k ? 2 : 1), e.skipBits(1));
- } else d = 1;
- else ((d = 3), (f = 1));
- const h = e.readBits(16),
- p = e.readBits(16),
- m = h + 1,
- b = p + 1,
- g = m * b;
- let y = Ae(Ar).level;
- for (const w of Ar)
- if (g <= w.maxPictureSize) {
- y = w.level;
- break;
- }
- const C = sh[l],
- _ = (C == null ? void 0 : C.colourPrimaries) ?? 2,
- v = (C == null ? void 0 : C.transferCharacteristics) ?? 2,
- I = (C == null ? void 0 : C.matrixCoefficients) ?? 2;
- return {
- profile: s,
- level: y,
- bitDepth: u,
- chromaSubsampling: d,
- videoFullRangeFlag: f,
- colourPrimaries: _,
- transferCharacteristics: v,
- matrixCoefficients: I,
- };
- },
- ah = (r) =>
- r.colourPrimaries !== 2 ||
- r.transferCharacteristics !== 2 ||
- r.matrixCoefficients !== 2,
- zl = function* (r) {
- const e = new pe(r),
- t = () => {
- let n = 0;
- for (let i = 0; i < 8; i++) {
- const s = e.readAlignedByte();
- if (((n += (s & 127) * 2 ** (i * 7)), !(s & 128))) break;
- if (i === 7 && s & 128) return null;
- }
- return n > 2 ** 32 - 1 ? null : n;
- };
- for (; e.getBitsLeft() >= 8;) {
- e.skipBits(1);
- const n = e.readBits(4),
- i = e.readBits(1),
- s = e.readBits(1);
- (e.skipBits(1), i && e.skipBits(8));
- let a;
- if (s) {
- const o = t();
- if (o === null) return;
- a = o;
- } else a = Math.floor(e.getBitsLeft() / 8);
- (T(e.pos % 8 === 0),
- yield { type: n, data: r.subarray(e.pos / 8, e.pos / 8 + a) },
- e.skipBits(a * 8));
- }
- },
- ds = (r) => {
- for (const { type: e, data: t } of zl(r)) {
- if (e !== 1) continue;
- const n = new pe(t),
- i = n.readBits(3);
- n.readBits(1);
- const s = n.readBits(1);
- let a = 0,
- o = 0,
- c = 0;
- if (s) a = n.readBits(5);
- else {
- const k = n.readBits(1);
- let S = 0;
- if (k) {
- if ((n.skipBits(32), n.skipBits(32), n.readBits(1))) {
- let M = 0;
- for (; M < 32 && !n.readBits(1);) M++;
- M < 32 && n.skipBits(M);
- }
- ((S = n.readBits(1)),
- S &&
- ((c = n.readBits(5)),
- n.skipBits(32),
- n.skipBits(5),
- n.skipBits(5)));
- }
- const E = n.readBits(1),
- B = n.readBits(5);
- for (let R = 0; R <= B; R++) {
- n.skipBits(12);
- const M = n.readBits(5);
- if ((R === 0 && (a = M), M > 7)) {
- const z = n.readBits(1);
- R === 0 && (o = z);
- }
- if (S && n.readBits(1)) {
- const q = c + 1;
- (n.skipBits(q), n.skipBits(q), n.skipBits(1));
- }
- E && n.readBits(1) && n.skipBits(4);
- }
- }
- const u = n.readBits(4),
- l = n.readBits(4),
- d = u + 1;
- n.skipBits(d);
- const f = l + 1;
- n.skipBits(f);
- let h = 0;
- if (
- (s ? (h = 0) : (h = n.readBits(1)),
- h && (n.skipBits(4), n.skipBits(3)),
- n.skipBits(1),
- n.skipBits(1),
- n.skipBits(1),
- !s)
- ) {
- (n.skipBits(1), n.skipBits(1), n.skipBits(1), n.skipBits(1));
- const k = n.readBits(1);
- k && (n.skipBits(1), n.skipBits(1));
- const S = n.readBits(1);
- let E = 0;
- (S ? (E = 2) : (E = n.readBits(1)),
- E > 0 && (n.readBits(1) || n.skipBits(1)),
- k && n.skipBits(3));
- }
- (n.skipBits(1), n.skipBits(1), n.skipBits(1));
- const p = n.readBits(1);
- let m = 8;
- i === 2 && p ? (m = n.readBits(1) ? 12 : 10) : i <= 2 && (m = p ? 10 : 8);
- let b = 0;
- i !== 1 && (b = n.readBits(1));
- let g = 2,
- y = 2,
- C = 2;
- n.readBits(1) &&
- ((g = n.readBits(8)), (y = n.readBits(8)), (C = n.readBits(8)));
- let v = 0,
- I = 1,
- w = 1,
- x = 0;
- return (
- b
- ? (v = n.readBits(1))
- : g === 1 && y === 13 && C === 0
- ? ((v = 1), (I = 0), (w = 0))
- : ((v = n.readBits(1)),
- i === 0
- ? ((I = 1), (w = 1))
- : i === 1
- ? ((I = 0), (w = 0))
- : m === 12
- ? ((I = n.readBits(1)), (w = I ? n.readBits(1) : 0))
- : ((I = 1), (w = 0)),
- I && w && (x = n.readBits(2))),
- {
- profile: i,
- level: a,
- tier: o,
- bitDepth: m,
- monochrome: b,
- chromaSubsamplingX: I,
- chromaSubsamplingY: w,
- chromaSamplePosition: x,
- videoFullRangeFlag: v,
- colourPrimaries: g,
- transferCharacteristics: y,
- matrixCoefficients: C,
- }
- );
- }
- return null;
- },
- Wl = (r) =>
- r.colourPrimaries !== 2 ||
- r.transferCharacteristics !== 2 ||
- r.matrixCoefficients !== 2,
- Ul = (r) => {
- if (r.length < 36) return null;
- const t = ge(r);
- return t.getUint32(4) !== 1768124518 || t.getUint16(8) < 28
- ? null
- : {
- fullRange: !1,
- colourPrimaries: t.getUint8(22),
- transferCharacteristics: t.getUint8(23),
- matrixCoefficients: t.getUint8(24),
- };
- },
- Hl = (r) => {
- const e = ge(r),
- t = e.getUint8(9),
- n = e.getUint16(10, !0),
- i = e.getUint32(12, !0),
- s = e.getInt16(16, !0),
- a = e.getUint8(18);
- let o = null;
- return (
- a && (o = r.subarray(19, 21 + t)),
- {
- outputChannelCount: t,
- preSkip: n,
- inputSampleRate: i,
- outputGain: s,
- channelMappingFamily: a,
- channelMappingTable: o,
- }
- );
- },
- oh = [
- 480, 960, 1920, 2880, 480, 960, 1920, 2880, 480, 960, 1920, 2880, 480, 960,
- 480, 960, 120, 240, 480, 960, 120, 240, 480, 960, 120, 240, 480, 960, 120,
- 240, 480, 960,
- ],
- ch = (r) => {
- const e = r[0] >> 3,
- t = r[0] & 3;
- let n;
- return (
- t === 0 ? (n = 1) : t === 1 || t === 2 ? (n = 2) : (n = r[1] & 63),
- { durationInSamples: oh[e] * n }
- );
- },
- lh = (r) => {
- if (r.length < 7) throw new Error("Setup header is too short.");
- if (r[0] !== 5) throw new Error("Wrong packet type in Setup header.");
- if (String.fromCharCode(...r.slice(1, 7)) !== "vorbis")
- throw new Error("Invalid packet signature in Setup header.");
- const t = r.length,
- n = new Uint8Array(t);
- for (let d = 0; d < t; d++) n[d] = r[t - 1 - d];
- const i = new pe(n);
- let s = 0;
- for (; i.getBitsLeft() > 97;)
- if (i.readBits(1) === 1) {
- s = i.pos;
- break;
- }
- if (s === 0)
- throw new Error("Invalid Setup header: framing bit not found.");
- let a = 0,
- o = !1,
- c = 0;
- for (; i.getBitsLeft() >= 97;) {
- const d = i.pos,
- f = i.readBits(8),
- h = i.readBits(16),
- p = i.readBits(16);
- if (f > 63 || h !== 0 || p !== 0) {
- i.pos = d;
- break;
- }
- if ((i.skipBits(1), a++, a > 64)) break;
- i.clone().readBits(6) + 1 === a && ((o = !0), (c = a));
- }
- if (!o) throw new Error("Invalid Setup header: mode header not found.");
- if (c > 63) throw new Error(`Unsupported mode count: ${c}.`);
- const u = c;
- ((i.pos = 0), i.skipBits(s));
- const l = Array(u).fill(0);
- for (let d = u - 1; d >= 0; d--) (i.skipBits(40), (l[d] = i.readBits(1)));
- return { modeBlockflags: l };
- },
- fs = (r, e, t) => {
- switch (r) {
- case "avc": {
- for (const n of Rl(t, e)) {
- const i = t[n.offset],
- s = ai(i);
- if (s >= Xe.NON_IDR_SLICE && s <= Xe.SLICE_DPC) return "delta";
- if (s === Xe.IDR) return "key";
- if (s === Xe.SEI && !ya()) {
- const a = t.subarray(n.offset, n.offset + n.length),
- o = ls(a);
- let c = 1;
- do {
- let u = 0;
- for (;;) {
- const f = o[c++];
- if (f === void 0 || ((u += f), f < 255)) break;
- }
- let l = 0;
- for (;;) {
- const f = o[c++];
- if (f === void 0 || ((l += f), f < 255)) break;
- }
- if (u === 6) {
- const f = new pe(o);
- f.pos = 8 * c;
- const h = G(f),
- p = f.readBits(1);
- if (h === 0 && p === 1) return "key";
- }
- c += l;
- } while (c < o.length - 1);
- }
- }
- return "delta";
- }
- case "hevc": {
- for (const n of Li(t, e)) {
- const i = wn(t[n.offset]);
- if (i < ze.BLA_W_LP) return "delta";
- if (i <= ze.RSV_IRAP_VCL23) return "key";
- }
- return "delta";
- }
- case "vp8":
- return (t[0] & 1) === 0 ? "key" : "delta";
- case "vp9": {
- const n = new pe(t);
- if (n.readBits(2) !== 2) return null;
- const i = n.readBits(1);
- return (
- (n.readBits(1) << 1) + i === 3 && n.skipBits(1),
- n.readBits(1) ? null : n.readBits(1) === 0 ? "key" : "delta"
- );
- }
- case "av1": {
- let n = !1;
- for (const { type: i, data: s } of zl(t))
- if (i === 1) {
- const a = new pe(s);
- (a.skipBits(4), (n = !!a.readBits(1)));
- } else if (i === 3 || i === 6 || i === 7) {
- if (n) return "key";
- const a = new pe(s);
- return a.readBits(1) ? null : a.readBits(2) === 0 ? "key" : "delta";
- }
- return null;
- }
- case "prores":
- return "key";
- default:
- (pr(r), T(!1));
- }
- };
-var hn;
-(function (r) {
- ((r[(r.STREAMINFO = 0)] = "STREAMINFO"),
- (r[(r.VORBIS_COMMENT = 4)] = "VORBIS_COMMENT"),
- (r[(r.PICTURE = 6)] = "PICTURE"));
-})(hn || (hn = {}));
-const xa = (r, e) => {
- var o, c;
- const t = ge(r);
- let n = 0;
- const i = t.getUint32(n, !0);
- n += 4;
- const s = ot.decode(r.subarray(n, n + i));
- ((n += i),
- i > 0 && (e.raw ?? (e.raw = {}), (o = e.raw).vendor ?? (o.vendor = s)));
- const a = t.getUint32(n, !0);
- n += 4;
- for (let u = 0; u < a; u++) {
- const l = t.getUint32(n, !0);
- n += 4;
- const d = ot.decode(r.subarray(n, n + l));
- n += l;
- const f = d.indexOf("=");
- if (f === -1) continue;
- const h = d.slice(0, f).toUpperCase(),
- p = d.slice(f + 1);
- switch (
- (e.raw ?? (e.raw = {}),
- Array.isArray(e.raw[h])
- ? (e.raw[h] = [...e.raw[h], p])
- : typeof e.raw[h] == "string"
- ? (e.raw[h] = [e.raw[h], p])
- : ((c = e.raw)[h] ?? (c[h] = p)),
- h)
- ) {
- case "TITLE":
- e.title ?? (e.title = p);
- break;
- case "DESCRIPTION":
- e.description ?? (e.description = p);
- break;
- case "ARTIST":
- e.artist ?? (e.artist = p);
- break;
- case "ALBUM":
- e.album ?? (e.album = p);
- break;
- case "ALBUMARTIST":
- e.albumArtist ?? (e.albumArtist = p);
- break;
- case "COMMENT":
- e.comment ?? (e.comment = p);
- break;
- case "LYRICS":
- e.lyrics ?? (e.lyrics = p);
- break;
- case "TRACKNUMBER":
- {
- const m = p.split("/"),
- b = Number.parseInt(m[0], 10),
- g = m[1] && Number.parseInt(m[1], 10);
- (Number.isInteger(b) &&
- b > 0 &&
- (e.trackNumber ?? (e.trackNumber = b)),
- g &&
- Number.isInteger(g) &&
- g > 0 &&
- (e.tracksTotal ?? (e.tracksTotal = g)));
- }
- break;
- case "TRACKTOTAL":
- {
- const m = Number.parseInt(p, 10);
- Number.isInteger(m) &&
- m > 0 &&
- (e.tracksTotal ?? (e.tracksTotal = m));
- }
- break;
- case "DISCNUMBER":
- {
- const m = p.split("/"),
- b = Number.parseInt(m[0], 10),
- g = m[1] && Number.parseInt(m[1], 10);
- (Number.isInteger(b) &&
- b > 0 &&
- (e.discNumber ?? (e.discNumber = b)),
- g &&
- Number.isInteger(g) &&
- g > 0 &&
- (e.discsTotal ?? (e.discsTotal = g)));
- }
- break;
- case "DISCTOTAL":
- {
- const m = Number.parseInt(p, 10);
- Number.isInteger(m) &&
- m > 0 &&
- (e.discsTotal ?? (e.discsTotal = m));
- }
- break;
- case "DATE":
- {
- const m = new Date(p);
- Number.isNaN(m.getTime()) || (e.date ?? (e.date = m));
- }
- break;
- case "BPM":
- {
- const m = Number.parseInt(p, 10);
- Number.isInteger(m) &&
- m > 0 &&
- (e.beatsPerMinute ?? (e.beatsPerMinute = m));
- }
- break;
- case "GENRE":
- e.genre ?? (e.genre = p);
- break;
- case "METADATA_BLOCK_PICTURE":
- {
- const m = Il(p),
- b = ge(m),
- g = b.getUint32(0, !1),
- y = b.getUint32(4, !1),
- C = String.fromCharCode(...m.subarray(8, 8 + y)),
- _ = b.getUint32(8 + y, !1),
- v = ot.decode(m.subarray(12 + y, 12 + y + _)),
- I = b.getUint32(y + _ + 28),
- w = m.subarray(y + _ + 32, y + _ + 32 + I);
- (e.images ?? (e.images = []),
- e.images.push({
- data: w,
- mimeType: C,
- kind:
- g === 3 ? "coverFront" : g === 4 ? "coverBack" : "unknown",
- name: void 0,
- description: v || void 0,
- }));
- }
- break;
- }
- }
- },
- Ja = [2, 1, 2, 3, 3, 4, 4, 5],
- Vl = (r) => {
- if (r.length < 7 || r[0] !== 11 || r[1] !== 119) return null;
- const e = new pe(r);
- (e.skipBits(16), e.skipBits(16));
- const t = e.readBits(2);
- if (t === 3) return null;
- const n = e.readBits(6),
- i = e.readBits(5);
- if (i > 8) return null;
- const s = e.readBits(3),
- a = e.readBits(3);
- ((a & 1) !== 0 && a !== 1 && e.skipBits(2),
- (a & 4) !== 0 && e.skipBits(2),
- a === 2 && e.skipBits(2));
- const o = e.readBits(1),
- c = Math.floor(n / 2);
- return { fscod: t, bsid: i, bsmod: s, acmod: a, lfeon: o, bitRateCode: c };
- },
- uh = [
- 128,
- 138,
- 192,
- 128,
- 140,
- 192,
- 160,
- 174,
- 240,
- 160,
- 176,
- 240,
- 192,
- 208,
- 288,
- 192,
- 210,
- 288,
- 224,
- 242,
- 336,
- 224,
- 244,
- 336,
- 256,
- 278,
- 384,
- 256,
- 280,
- 384,
- 320,
- 348,
- 480,
- 320,
- 350,
- 480,
- 384,
- 416,
- 288 * 2,
- 384,
- 418,
- 288 * 2,
- 448,
- 486,
- 336 * 2,
- 448,
- 488,
- 336 * 2,
- 256 * 2,
- 278 * 2,
- 384 * 2,
- 256 * 2,
- 279 * 2,
- 384 * 2,
- 320 * 2,
- 348 * 2,
- 480 * 2,
- 320 * 2,
- 349 * 2,
- 480 * 2,
- 384 * 2,
- 417 * 2,
- 576 * 2,
- 384 * 2,
- 418 * 2,
- 576 * 2,
- 448 * 2,
- 487 * 2,
- 672 * 2,
- 448 * 2,
- 488 * 2,
- 672 * 2,
- 512 * 2,
- 557 * 2,
- 768 * 2,
- 512 * 2,
- 558 * 2,
- 768 * 2,
- 640 * 2,
- 696 * 2,
- 960 * 2,
- 640 * 2,
- 697 * 2,
- 960 * 2,
- 768 * 2,
- 835 * 2,
- 1152 * 2,
- 768 * 2,
- 836 * 2,
- 1152 * 2,
- 896 * 2,
- 975 * 2,
- 1344 * 2,
- 896 * 2,
- 976 * 2,
- 1344 * 2,
- 1024 * 2,
- 1114 * 2,
- 1536 * 2,
- 1024 * 2,
- 1115 * 2,
- 1536 * 2,
- 1152 * 2,
- 1253 * 2,
- 1728 * 2,
- 1152 * 2,
- 1254 * 2,
- 1728 * 2,
- 1280 * 2,
- 1393 * 2,
- 1920 * 2,
- 1280 * 2,
- 1394 * 2,
- 1920 * 2,
- ],
- dh = 1536,
- Ll = [1, 2, 3, 6],
- ql = (r) => {
- if (r.length < 6 || r[0] !== 11 || r[1] !== 119) return null;
- const e = new pe(r);
- e.skipBits(16);
- const t = e.readBits(2);
- if ((e.skipBits(3), t !== 0 && t !== 2)) return null;
- const n = e.readBits(11),
- i = e.readBits(2);
- let s = 0,
- a;
- i === 3 ? ((s = e.readBits(2)), (a = 3)) : (a = e.readBits(2));
- const o = e.readBits(3),
- c = e.readBits(1),
- u = e.readBits(5);
- if (u < 11 || u > 16) return null;
- const l = Ll[a];
- let d;
- return (
- i < 3 ? (d = cs[i] / 1e3) : (d = Bl[s] / 1e3),
- {
- dataRate: Math.round(((n + 1) * d) / (l * 16)),
- substreams: [
- {
- fscod: i,
- fscod2: s,
- bsid: u,
- bsmod: 0,
- acmod: o,
- lfeon: c,
- numDepSub: 0,
- chanLoc: 0,
- },
- ],
- }
- );
- },
- fh = (r) => {
- if (r.length < 2) return null;
- const e = new pe(r),
- t = e.readBits(13),
- n = e.readBits(3),
- i = [];
- for (let s = 0; s <= n && !(Math.ceil(e.pos / 8) + 3 > r.length); s++) {
- const a = e.readBits(2),
- o = e.readBits(5);
- (e.skipBits(1), e.skipBits(1));
- const c = e.readBits(3),
- u = e.readBits(3),
- l = e.readBits(1);
- e.skipBits(3);
- const d = e.readBits(4);
- let f = 0;
- (d > 0 ? (f = e.readBits(9)) : e.skipBits(1),
- i.push({
- fscod: a,
- fscod2: null,
- bsid: o,
- bsmod: c,
- acmod: u,
- lfeon: l,
- numDepSub: d,
- chanLoc: f,
- }));
- }
- return i.length === 0 ? null : { dataRate: t, substreams: i };
- },
- jl = (r) => {
- const e = r.substreams[0];
- return (
- T(e),
- e.fscod < 3
- ? cs[e.fscod]
- : e.fscod2 !== null && e.fscod2 < 3
- ? Bl[e.fscod2]
- : null
- );
- },
- $l = (r) => {
- const e = r.substreams[0];
- T(e);
- let t = Ja[e.acmod] + e.lfeon;
- if (e.numDepSub > 0) {
- const n = [2, 2, 1, 1, 2, 2, 2, 1, 1];
- for (let i = 0; i < 9; i++) e.chanLoc & (1 << (8 - i)) && (t += n[i]);
- }
- return t;
- },
- hh = 1683496997,
- Ri = 18,
- Sa = 10,
- mh = 4096,
- Lo = 32,
- eo = 20,
- ph = 8,
- gh = [
- 0, 8e3, 16e3, 32e3, 0, 0, 11025, 22050, 44100, 0, 0, 12e3, 24e3, 48e3, 96e3,
- 192e3,
- ],
- bh = [
- 32e3, 56e3, 64e3, 96e3, 112e3, 128e3, 192e3, 224e3, 256e3, 32e4, 384e3,
- 448e3, 512e3, 576e3, 64e4, 768e3, 96e4, 1024e3, 1152e3, 128e4, 1344e3,
- 1408e3, 1411200, 1472e3, 1536e3, 192e4, 2048e3, 3072e3, 384e4, 0, 0, 0,
- ],
- wh = [16, 16, 20, 20, 0, 24, 24, 0],
- qi = [1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8],
- yh = [1, 2, 2, 2, 2, 3, 18, 19, 6, 7, 518, 323, 83, 519, 582, 535],
- kh = 8,
- Th = 44646,
- xh = [32e3, 44100, 48e3, 0],
- Sh = [
- 8e3, 16e3, 32e3, 64e3, 128e3, 22050, 44100, 88200, 176400, 352800, 12e3,
- 24e3, 48e3, 96e3, 192e3, 384e3,
- ],
- Gl = [512, 1024, 2048, 4096],
- to = (r) => {
- const e = Xl(r),
- t = ge(r);
- let n = e ? Math.ceil(e.frameSize / 4) * 4 : 0,
- i = null;
- for (; n + 4 <= r.length && t.getUint32(n) === hh;) {
- const a = Mi(r.subarray(n));
- if (!a) break;
- (i ?? (i = a), (n += a.frameSize));
- }
- if (e)
- return {
- frameSize: i ? n : e.frameSize,
- sampleRate: e.sampleRate,
- numberOfChannels: e.numberOfChannels,
- sampleCount: e.sampleCount,
- channelLayout: e.channelLayout,
- pcmResolution: e.pcmResolution,
- bitRate: e.bitRate,
- core: e,
- hasExtensions: i !== null,
- };
- if (!(i != null && i.asset)) return null;
- const { asset: s } = i;
- return {
- frameSize: n,
- sampleRate: s.sampleRate,
- numberOfChannels: s.numberOfChannels,
- sampleCount: s.sampleCount,
- channelLayout: s.channelLayout,
- pcmResolution: s.pcmResolution,
- bitRate: 0,
- core: null,
- hasExtensions: !0,
- };
- },
- Kl = (r) => {
- const e = to(r);
- return e != null && e.core ? (e.hasExtensions ? "dtsh" : "dtsc") : null;
- },
- Xl = (r) => {
- if (
- r.length < Ri ||
- r[0] !== 127 ||
- r[1] !== 254 ||
- r[2] !== 128 ||
- r[3] !== 1
- )
- return null;
- const e = new pe(r);
- if ((e.skipBits(32), e.skipBits(1), e.readBits(5) !== Lo - 1)) return null;
- const t = e.readBits(1),
- n = e.readBits(7) + 1;
- if (n % ph !== 0) return null;
- const i = e.readBits(14) + 1;
- if (i < 96) return null;
- const s = e.readBits(6);
- if (s >= qi.length) return null;
- const a = gh[e.readBits(4)];
- if (a === 0) return null;
- const o = bh[e.readBits(5)];
- if (e.readBits(1) !== 0) return null;
- (e.skipBits(4), e.skipBits(5));
- const c = e.readBits(2);
- if (c === 3) return null;
- (e.skipBits(1), t && e.skipBits(16), e.skipBits(7));
- const u = wh[e.readBits(3)];
- if (u === 0) return null;
- const l = c !== 0;
- return {
- frameSize: i,
- sampleRate: a,
- numberOfChannels: qi[s] + (l ? 1 : 0),
- sampleCount: n * Lo,
- channelLayout: yh[s] | (l ? kh : 0),
- amode: s,
- lfePresent: l,
- bitRate: o,
- pcmResolution: u,
- };
- },
- Mi = (r) => {
- if (
- r.length < Sa ||
- r[0] !== 100 ||
- r[1] !== 88 ||
- r[2] !== 32 ||
- r[3] !== 37
- )
- return null;
- const e = new pe(r);
- (e.skipBits(32), e.skipBits(8));
- const t = e.readBits(2),
- n = e.readBits(1),
- i = 8 + 4 * n,
- s = 16 + 4 * n;
- e.skipBits(i);
- const a = e.readBits(s) + 1,
- o = { frameSize: a, asset: null };
- if (!e.readBits(1)) return o;
- const c = xh[e.readBits(2)],
- u = 512 * (e.readBits(3) + 1);
- e.readBits(1) && e.skipBits(36);
- const l = e.readBits(3) + 1,
- d = e.readBits(3) + 1,
- f = [];
- for (let g = 0; g < l; g++) f.push(e.readBits(t + 1));
- for (const g of f) e.skipBits(8 * ba(g));
- if (e.readBits(1)) {
- e.skipBits(2);
- const g = (e.readBits(2) + 1) << 2,
- y = e.readBits(2) + 1;
- e.skipBits(y * g);
- }
- for (let g = 0; g < d; g++) e.skipBits(s);
- (e.skipBits(9),
- e.skipBits(3),
- e.readBits(1) && e.skipBits(4),
- e.readBits(1) && e.skipBits(24),
- e.readBits(1) && e.skipBits(8 * (e.readBits(10) + 1)));
- const h = e.readBits(5) + 1,
- p = Sh[e.readBits(4)],
- m = e.readBits(8) + 1;
- let b = 0;
- if (
- e.readBits(1) &&
- (m > 2 && e.skipBits(1), m > 6 && e.skipBits(1), e.readBits(1))
- ) {
- const g = (e.readBits(2) + 1) << 2;
- b = e.readBits(g);
- }
- return c === 0 || e.getBitsLeft() < 0
- ? o
- : {
- frameSize: a,
- asset: {
- sampleRate: p,
- numberOfChannels: m,
- sampleCount: Math.round((u * p) / c),
- channelLayout: b,
- pcmResolution: h,
- },
- };
- },
- Ph = (r) => {
- if (r.length < eo) return null;
- const e = ge(r),
- t = e.getUint32(0);
- if (t === 0) return null;
- const n = new pe(r);
- n.seekToByte(13);
- const i = n.readBits(2);
- n.skipBits(5);
- const s = n.readBits(1),
- a = n.readBits(6);
- (n.skipBits(14), n.skipBits(1), n.skipBits(3));
- const o = n.readBits(16);
- let c = null;
- return (
- o !== 0 ? (c = vh(o)) : a < qi.length && (c = qi[a] + s),
- {
- sampleRate: t,
- maxBitrate: e.getUint32(4),
- avgBitrate: e.getUint32(8),
- pcmSampleDepth: r[12],
- sampleCount: Gl[i],
- channelLayout: o,
- numberOfChannels: c,
- }
- );
- },
- Ch = (r) => {
- var s, a;
- const e = new Uint8Array(eo),
- t = ge(e);
- (t.setUint32(0, r.sampleRate),
- t.setUint32(4, r.bitRate),
- t.setUint32(8, r.bitRate),
- (e[12] = r.pcmResolution));
- const n = r.core && !r.hasExtensions ? 1 : 0,
- i = new pe(e);
- return (
- i.seekToByte(13),
- i.writeBits(2, Math.max(Gl.indexOf(r.sampleCount), 0)),
- i.writeBits(5, n),
- i.writeBits(1, (s = r.core) != null && s.lfePresent ? 1 : 0),
- i.writeBits(6, ((a = r.core) == null ? void 0 : a.amode) ?? 0),
- i.writeBits(14, r.core ? r.core.frameSize - 1 : 0),
- i.writeBits(1, 0),
- i.writeBits(3, 0),
- i.writeBits(16, r.channelLayout),
- i.writeBits(1, 0),
- i.writeBits(1, 0),
- i.writeBits(1, 0),
- i.writeBits(5, 0),
- e
- );
- },
- vh = (r) => ba(r) + ba(r & Th);
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const Rt = ["avc", "hevc", "vp9", "av1", "vp8", "prores"],
- ut = [
- "pcm-s16",
- "pcm-s16be",
- "pcm-s24",
- "pcm-s24be",
- "pcm-s32",
- "pcm-s32be",
- "pcm-f32",
- "pcm-f32be",
- "pcm-f64",
- "pcm-f64be",
- "pcm-u8",
- "pcm-s8",
- "ulaw",
- "alaw",
- ],
- ro = ["aac", "opus", "mp3", "vorbis", "flac", "ac3", "eac3", "dts"],
- fr = [...ro, ...ut],
- oi = ["webvtt"],
- ji = [
- { maxMacroblocks: 99, maxBitrate: 64e3, maxDpbMbs: 396, level: 10 },
- { maxMacroblocks: 396, maxBitrate: 192e3, maxDpbMbs: 900, level: 11 },
- { maxMacroblocks: 396, maxBitrate: 384e3, maxDpbMbs: 2376, level: 12 },
- { maxMacroblocks: 396, maxBitrate: 768e3, maxDpbMbs: 2376, level: 13 },
- { maxMacroblocks: 396, maxBitrate: 2e6, maxDpbMbs: 2376, level: 20 },
- { maxMacroblocks: 792, maxBitrate: 4e6, maxDpbMbs: 4752, level: 21 },
- { maxMacroblocks: 1620, maxBitrate: 4e6, maxDpbMbs: 8100, level: 22 },
- { maxMacroblocks: 1620, maxBitrate: 1e7, maxDpbMbs: 8100, level: 30 },
- { maxMacroblocks: 3600, maxBitrate: 14e6, maxDpbMbs: 18e3, level: 31 },
- { maxMacroblocks: 5120, maxBitrate: 2e7, maxDpbMbs: 20480, level: 32 },
- { maxMacroblocks: 8192, maxBitrate: 2e7, maxDpbMbs: 32768, level: 40 },
- { maxMacroblocks: 8192, maxBitrate: 5e7, maxDpbMbs: 32768, level: 41 },
- { maxMacroblocks: 8704, maxBitrate: 5e7, maxDpbMbs: 34816, level: 42 },
- { maxMacroblocks: 22080, maxBitrate: 135e6, maxDpbMbs: 110400, level: 50 },
- { maxMacroblocks: 36864, maxBitrate: 24e7, maxDpbMbs: 184320, level: 51 },
- { maxMacroblocks: 36864, maxBitrate: 24e7, maxDpbMbs: 184320, level: 52 },
- { maxMacroblocks: 139264, maxBitrate: 24e7, maxDpbMbs: 696320, level: 60 },
- { maxMacroblocks: 139264, maxBitrate: 48e7, maxDpbMbs: 696320, level: 61 },
- { maxMacroblocks: 139264, maxBitrate: 8e8, maxDpbMbs: 696320, level: 62 },
- ],
- qo = [
- { maxPictureSize: 36864, maxBitrate: 128e3, tier: "L", level: 30 },
- { maxPictureSize: 122880, maxBitrate: 15e5, tier: "L", level: 60 },
- { maxPictureSize: 245760, maxBitrate: 3e6, tier: "L", level: 63 },
- { maxPictureSize: 552960, maxBitrate: 6e6, tier: "L", level: 90 },
- { maxPictureSize: 983040, maxBitrate: 1e7, tier: "L", level: 93 },
- { maxPictureSize: 2228224, maxBitrate: 12e6, tier: "L", level: 120 },
- { maxPictureSize: 2228224, maxBitrate: 3e7, tier: "H", level: 120 },
- { maxPictureSize: 2228224, maxBitrate: 2e7, tier: "L", level: 123 },
- { maxPictureSize: 2228224, maxBitrate: 5e7, tier: "H", level: 123 },
- { maxPictureSize: 8912896, maxBitrate: 25e6, tier: "L", level: 150 },
- { maxPictureSize: 8912896, maxBitrate: 1e8, tier: "H", level: 150 },
- { maxPictureSize: 8912896, maxBitrate: 4e7, tier: "L", level: 153 },
- { maxPictureSize: 8912896, maxBitrate: 16e7, tier: "H", level: 153 },
- { maxPictureSize: 8912896, maxBitrate: 6e7, tier: "L", level: 156 },
- { maxPictureSize: 8912896, maxBitrate: 24e7, tier: "H", level: 156 },
- { maxPictureSize: 35651584, maxBitrate: 6e7, tier: "L", level: 180 },
- { maxPictureSize: 35651584, maxBitrate: 24e7, tier: "H", level: 180 },
- { maxPictureSize: 35651584, maxBitrate: 12e7, tier: "L", level: 183 },
- { maxPictureSize: 35651584, maxBitrate: 48e7, tier: "H", level: 183 },
- { maxPictureSize: 35651584, maxBitrate: 24e7, tier: "L", level: 186 },
- { maxPictureSize: 35651584, maxBitrate: 8e8, tier: "H", level: 186 },
- ],
- Ar = [
- { maxPictureSize: 36864, maxBitrate: 2e5, level: 10 },
- { maxPictureSize: 73728, maxBitrate: 8e5, level: 11 },
- { maxPictureSize: 122880, maxBitrate: 18e5, level: 20 },
- { maxPictureSize: 245760, maxBitrate: 36e5, level: 21 },
- { maxPictureSize: 552960, maxBitrate: 72e5, level: 30 },
- { maxPictureSize: 983040, maxBitrate: 12e6, level: 31 },
- { maxPictureSize: 2228224, maxBitrate: 18e6, level: 40 },
- { maxPictureSize: 2228224, maxBitrate: 3e7, level: 41 },
- { maxPictureSize: 8912896, maxBitrate: 6e7, level: 50 },
- { maxPictureSize: 8912896, maxBitrate: 12e7, level: 51 },
- { maxPictureSize: 8912896, maxBitrate: 18e7, level: 52 },
- { maxPictureSize: 35651584, maxBitrate: 18e7, level: 60 },
- { maxPictureSize: 35651584, maxBitrate: 24e7, level: 61 },
- { maxPictureSize: 35651584, maxBitrate: 48e7, level: 62 },
- ],
- jo = [
- { maxPictureSize: 147456, maxBitrate: 15e5, tier: "M", level: 0 },
- { maxPictureSize: 278784, maxBitrate: 3e6, tier: "M", level: 1 },
- { maxPictureSize: 665856, maxBitrate: 6e6, tier: "M", level: 4 },
- { maxPictureSize: 1065024, maxBitrate: 1e7, tier: "M", level: 5 },
- { maxPictureSize: 2359296, maxBitrate: 12e6, tier: "M", level: 8 },
- { maxPictureSize: 2359296, maxBitrate: 3e7, tier: "H", level: 8 },
- { maxPictureSize: 2359296, maxBitrate: 2e7, tier: "M", level: 9 },
- { maxPictureSize: 2359296, maxBitrate: 5e7, tier: "H", level: 9 },
- { maxPictureSize: 8912896, maxBitrate: 3e7, tier: "M", level: 12 },
- { maxPictureSize: 8912896, maxBitrate: 1e8, tier: "H", level: 12 },
- { maxPictureSize: 8912896, maxBitrate: 4e7, tier: "M", level: 13 },
- { maxPictureSize: 8912896, maxBitrate: 16e7, tier: "H", level: 13 },
- { maxPictureSize: 8912896, maxBitrate: 6e7, tier: "M", level: 14 },
- { maxPictureSize: 8912896, maxBitrate: 24e7, tier: "H", level: 14 },
- { maxPictureSize: 35651584, maxBitrate: 6e7, tier: "M", level: 15 },
- { maxPictureSize: 35651584, maxBitrate: 24e7, tier: "H", level: 15 },
- { maxPictureSize: 35651584, maxBitrate: 6e7, tier: "M", level: 16 },
- { maxPictureSize: 35651584, maxBitrate: 24e7, tier: "H", level: 16 },
- { maxPictureSize: 35651584, maxBitrate: 1e8, tier: "M", level: 17 },
- { maxPictureSize: 35651584, maxBitrate: 48e7, tier: "H", level: 17 },
- { maxPictureSize: 35651584, maxBitrate: 16e7, tier: "M", level: 18 },
- { maxPictureSize: 35651584, maxBitrate: 8e8, tier: "H", level: 18 },
- { maxPictureSize: 35651584, maxBitrate: 16e7, tier: "M", level: 19 },
- { maxPictureSize: 35651584, maxBitrate: 8e8, tier: "H", level: 19 },
- ],
- $o = ".01.01.01.01.00",
- Go = ".0.110.01.01.01.0",
- qr = ["ap4x", "ap4h", "apch", "apcn", "apcs", "apco"],
- $i = ["dtsc", "dtsh", "dtsl", "dtse"],
- Eh = [
- { fourCc: "apco", bitrate: 45e6, alpha: !1 },
- { fourCc: "apcs", bitrate: 102e6, alpha: !1 },
- { fourCc: "apcn", bitrate: 147e6, alpha: !1 },
- { fourCc: "apch", bitrate: 22e7, alpha: !1 },
- { fourCc: "ap4h", bitrate: 33e7, alpha: !0 },
- { fourCc: "ap4x", bitrate: 5e8, alpha: !0 },
- ],
- Ih = (r, e, t, n, i) => {
- if (r === "avc") {
- const a = Math.ceil(e / 16) * Math.ceil(t / 16),
- o =
- ji.find((f) => a <= f.maxMacroblocks && n <= f.maxBitrate) ?? Ae(ji),
- c = o ? o.level : 0,
- u = "64".padStart(2, "0"),
- l = "00",
- d = c.toString(16).padStart(2, "0");
- return `avc1.${u}${l}${d}`;
- } else if (r === "hevc") {
- const c = e * t,
- u =
- qo.find((d) => c <= d.maxPictureSize && n <= d.maxBitrate) ?? Ae(qo);
- return `hev1.1.6.${u.tier}${u.level}.B0`;
- } else {
- if (r === "vp8") return "vp8";
- if (r === "vp9") {
- const a = e * t;
- return `vp09.00.${(Ar.find((u) => a <= u.maxPictureSize && n <= u.maxBitrate) ?? Ae(Ar)).level.toString().padStart(2, "0")}.08`;
- } else if (r === "av1") {
- const a = e * t,
- o =
- jo.find((l) => a <= l.maxPictureSize && n <= l.maxBitrate) ??
- Ae(jo);
- return `av01.0.${o.level.toString().padStart(2, "0")}${o.tier}.08`;
- } else if (r === "prores") {
- const a = Math.pow((e * t) / 2073600, 0.95),
- o = Eh.filter((l) => l.alpha === i);
- let c = o[0].fourCc,
- u = 1 / 0;
- for (const { fourCc: l, bitrate: d } of o) {
- const f = Math.abs(d * a - n);
- f < u && ((u = f), (c = l));
- }
- return c;
- } else pr(r);
- }
- throw new TypeError(`Unhandled codec '${String(r)}'.`);
- },
- _h = (r) => {
- const e = r.split("."),
- i = (1 << 7) + 1,
- s = Number(e[1]),
- a = e[2],
- o = Number(a.slice(0, -1)),
- c = (s << 5) + o,
- u = a.slice(-1) === "H" ? 1 : 0,
- l = Number(e[3]),
- d = l === 8 ? 0 : 1,
- f = l === 12 ? 1 : 0,
- h = e[4] ? Number(e[4]) : 0,
- p = e[5] ? Number(e[5][0]) : 1,
- m = e[5] ? Number(e[5][1]) : 1,
- b = e[5] ? Number(e[5][2]) : 0,
- g = (u << 7) + (d << 6) + (f << 5) + (h << 4) + (p << 3) + (m << 2) + b;
- return [i, c, g, 0];
- },
- hs = (r) => {
- const {
- codec: e,
- codecDescription: t,
- colorSpace: n,
- avcCodecInfo: i,
- hevcCodecInfo: s,
- vp9CodecInfo: a,
- av1CodecInfo: o,
- proresFormat: c,
- } = r;
- if (e === "avc") {
- if ((T(r.avcType !== null), i)) {
- const u = new Uint8Array([
- i.avcProfileIndication,
- i.profileCompatibility,
- i.avcLevelIndication,
- ]);
- return `avc${r.avcType}.${ri(u)}`;
- }
- if (!t || t.byteLength < 4)
- throw new TypeError(
- "AVC decoder description is not provided or is not at least 4 bytes long.",
- );
- return `avc${r.avcType}.${ri(t.subarray(1, 4))}`;
- } else if (e === "hevc") {
- let u, l, d, f, h, p;
- if (s)
- ((u = s.generalProfileSpace),
- (l = s.generalProfileIdc),
- (d = Bo(s.generalProfileCompatibilityFlags)),
- (f = s.generalTierFlag),
- (h = s.generalLevelIdc),
- (p = [...s.generalConstraintIndicatorFlags]));
- else {
- if (!t || t.byteLength < 23)
- throw new TypeError(
- "HEVC decoder description is not provided or is not at least 23 bytes long.",
- );
- const b = ge(t),
- g = b.getUint8(1);
- ((u = (g >> 6) & 3),
- (l = g & 31),
- (d = Bo(b.getUint32(2))),
- (f = (g >> 5) & 1),
- (h = b.getUint8(12)),
- (p = []));
- for (let y = 0; y < 6; y++) p.push(b.getUint8(6 + y));
- }
- let m = "hev1.";
- for (
- m += ["", "A", "B", "C"][u] + l,
- m += ".",
- m += d.toString(16).toUpperCase(),
- m += ".",
- m += f === 0 ? "L" : "H",
- m += h;
- p.length > 0 && p[p.length - 1] === 0;
- )
- p.pop();
- return (
- p.length > 0 &&
- ((m += "."),
- (m += p.map((b) => b.toString(16).toUpperCase()).join("."))),
- m
- );
- } else {
- if (e === "vp8") return "vp8";
- if (e === "vp9") {
- if (!a) {
- const y = r.width * r.height;
- let C = Ae(Ar).level;
- for (const _ of Ar)
- if (y <= _.maxPictureSize) {
- C = _.level;
- break;
- }
- return `vp09.00.${C.toString().padStart(2, "0")}.08`;
- }
- const u = a.profile.toString().padStart(2, "0"),
- l = a.level.toString().padStart(2, "0"),
- d = a.bitDepth.toString().padStart(2, "0"),
- f = a.chromaSubsampling.toString().padStart(2, "0"),
- h = a.colourPrimaries.toString().padStart(2, "0"),
- p = a.transferCharacteristics.toString().padStart(2, "0"),
- m = a.matrixCoefficients.toString().padStart(2, "0"),
- b = a.videoFullRangeFlag.toString().padStart(2, "0");
- let g = `vp09.${u}.${l}.${d}.${f}`;
- return (
- (g += `.${h}.${p}.${m}.${b}`),
- g.endsWith($o) && (g = g.slice(0, -$o.length)),
- g
- );
- } else if (e === "av1") {
- if (!o) {
- const _ = r.width * r.height;
- let v = Ae(Ar).level;
- for (const I of Ar)
- if (_ <= I.maxPictureSize) {
- v = I.level;
- break;
- }
- return `av01.0.${v.toString().padStart(2, "0")}M.08`;
- }
- const u = o.profile,
- l = o.level.toString().padStart(2, "0"),
- d = o.tier ? "H" : "M",
- f = o.bitDepth.toString().padStart(2, "0"),
- h = o.monochrome ? "1" : "0",
- p =
- 100 * o.chromaSubsamplingX +
- 10 * o.chromaSubsamplingY +
- 1 *
- (o.chromaSubsamplingX && o.chromaSubsamplingY
- ? o.chromaSamplePosition
- : 0);
- let m, b, g, y;
- Wl(o)
- ? ((m = o.colourPrimaries),
- (b = o.transferCharacteristics),
- (g = o.matrixCoefficients),
- (y = o.videoFullRangeFlag))
- : ((m = n != null && n.primaries ? xn[n.primaries] : 1),
- (b = n != null && n.transfer ? Sn[n.transfer] : 1),
- (g = n != null && n.matrix ? Pn[n.matrix] : 1),
- (y = n != null && n.fullRange ? 1 : 0));
- let C = `av01.${u}.${l}${d}.${f}`;
- return (
- (C += `.${h}.${p.toString().padStart(3, "0")}`),
- (C += `.${m.toString().padStart(2, "0")}`),
- (C += `.${b.toString().padStart(2, "0")}`),
- (C += `.${g.toString().padStart(2, "0")}`),
- (C += `.${y}`),
- C.endsWith(Go) && (C = C.slice(0, -Go.length)),
- C
- );
- } else {
- if (e === "prores") return c ?? "apch";
- e !== null && pr(e);
- }
- }
- throw new TypeError(`Unhandled codec '${e}'.`);
- },
- Ql = (r) => {
- var e, t, n, i, s, a;
- switch (r.codec) {
- case "avc":
- {
- let o =
- (e = r.avcCodecInfo) == null ? void 0 : e.sequenceParameterSets[0];
- if (
- (!o &&
- r.codecDescription &&
- (o =
- (t = Ya(r.codecDescription)) == null
- ? void 0
- : t.sequenceParameterSets[0]),
- o)
- ) {
- const c = bn(o);
- if (c)
- return {
- primaries: rr[c.colourPrimaries],
- transfer: nr[c.transferCharacteristics],
- matrix: ir[c.matrixCoefficients],
- fullRange: !!c.fullRangeFlag,
- };
- }
- }
- break;
- case "hevc":
- {
- let o =
- (i =
- (n = r.hevcCodecInfo) == null
- ? void 0
- : n.arrays.find((c) => c.nalUnitType === ze.SPS_NUT)) == null
- ? void 0
- : i.nalUnits[0];
- if (
- (!o &&
- r.codecDescription &&
- (o =
- (a =
- (s = Dl(r.codecDescription)) == null
- ? void 0
- : s.arrays.find((c) => c.nalUnitType === ze.SPS_NUT)) ==
- null
- ? void 0
- : a.nalUnits[0]),
- o)
- ) {
- const c = us(o);
- if (c)
- return {
- primaries: rr[c.colourPrimaries],
- transfer: nr[c.transferCharacteristics],
- matrix: ir[c.matrixCoefficients],
- fullRange: !!c.fullRangeFlag,
- };
- }
- }
- break;
- case "vp8":
- break;
- case "vp9":
- if (r.vp9CodecInfo)
- return {
- primaries: rr[r.vp9CodecInfo.colourPrimaries],
- transfer: nr[r.vp9CodecInfo.transferCharacteristics],
- matrix: ir[r.vp9CodecInfo.matrixCoefficients],
- fullRange: !!r.vp9CodecInfo.videoFullRangeFlag,
- };
- break;
- case "av1":
- if (r.av1CodecInfo)
- return {
- primaries: rr[r.av1CodecInfo.colourPrimaries],
- transfer: nr[r.av1CodecInfo.transferCharacteristics],
- matrix: ir[r.av1CodecInfo.matrixCoefficients],
- fullRange: !!r.av1CodecInfo.videoFullRangeFlag,
- };
- break;
- case "prores":
- if (r.proresCodecInfo)
- return {
- primaries: rr[r.proresCodecInfo.colourPrimaries],
- transfer: nr[r.proresCodecInfo.transferCharacteristics],
- matrix: ir[r.proresCodecInfo.matrixCoefficients],
- fullRange: r.proresCodecInfo.fullRange,
- };
- break;
- }
- return {
- primaries: void 0,
- transfer: void 0,
- matrix: void 0,
- fullRange: void 0,
- };
- },
- Ah = (r, e, t) => {
- if (r === "aac")
- return e >= 2 && t <= 24e3
- ? "mp4a.40.29"
- : t <= 24e3
- ? "mp4a.40.5"
- : "mp4a.40.2";
- if (r === "mp3") return "mp3";
- if (r === "opus") return "opus";
- if (r === "vorbis") return "vorbis";
- if (r === "flac") return "flac";
- if (r === "ac3") return "ac-3";
- if (r === "eac3") return "ec-3";
- if (r === "dts") return "dtsc";
- if (ut.includes(r)) return r;
- throw new TypeError(`Unhandled codec '${r}'.`);
- },
- no = (r) => {
- const { codec: e, codecDescription: t, aacCodecInfo: n, dtsFormat: i } = r;
- if (e === "aac") {
- if (!n) throw new TypeError("AAC codec info must be provided.");
- if (n.isMpeg2) return "mp4a.67";
- {
- let s;
- return (
- n.objectType !== null ? (s = n.objectType) : (s = Xa(t).objectType),
- `mp4a.40.${s}`
- );
- }
- } else {
- if (e === "mp3") return "mp3";
- if (e === "opus") return "opus";
- if (e === "vorbis") return "vorbis";
- if (e === "flac") return "flac";
- if (e === "ac3") return "ac-3";
- if (e === "eac3") return "ec-3";
- if (e === "dts") return i ?? "dtsc";
- if (e && ut.includes(e)) return e;
- }
- throw new TypeError(`Unhandled codec '${e}'.`);
- },
- ms = 48e3,
- Yl = /^pcm-([usf])(\d+)(be)?$/,
- Rr = (r) => {
- if ((T(ut.includes(r)), r === "ulaw"))
- return {
- dataType: "ulaw",
- sampleSize: 1,
- littleEndian: !0,
- silentValue: 255,
- };
- if (r === "alaw")
- return {
- dataType: "alaw",
- sampleSize: 1,
- littleEndian: !0,
- silentValue: 213,
- };
- const e = Yl.exec(r);
- T(e);
- let t;
- e[1] === "u"
- ? (t = "unsigned")
- : e[1] === "s"
- ? (t = "signed")
- : (t = "float");
- const n = Number(e[2]) / 8,
- i = e[3] !== "be",
- s = r === "pcm-u8" ? 2 ** 7 : 0;
- return { dataType: t, sampleSize: n, littleEndian: i, silentValue: s };
- },
- ur = (r) =>
- r.startsWith("avc1") || r.startsWith("avc3")
- ? "avc"
- : r.startsWith("hev1") || r.startsWith("hvc1")
- ? "hevc"
- : r === "vp8"
- ? "vp8"
- : r.startsWith("vp09")
- ? "vp9"
- : r.startsWith("av01")
- ? "av1"
- : qr.includes(r)
- ? "prores"
- : r === "mp3" ||
- r === "mp4a.69" ||
- r === "mp4a.6B" ||
- r === "mp4a.6b" ||
- r === "mp4a.40.34"
- ? "mp3"
- : r.startsWith("mp4a.40.") || r === "mp4a.67"
- ? "aac"
- : r === "opus" || r === "Opus"
- ? "opus"
- : r === "vorbis"
- ? "vorbis"
- : r === "flac"
- ? "flac"
- : r === "ac-3" || r === "ac3"
- ? "ac3"
- : r === "ec-3" || r === "eac3"
- ? "eac3"
- : $i.includes(r)
- ? "dts"
- : r === "ulaw"
- ? "ulaw"
- : r === "alaw"
- ? "alaw"
- : Yl.test(r)
- ? r
- : r === "webvtt"
- ? "webvtt"
- : null,
- Bh = (r) =>
- r === "avc"
- ? { avc: { format: "avc" } }
- : r === "hevc"
- ? { hevc: { format: "hevc" } }
- : {},
- Fh = (r) =>
- r === "aac"
- ? { aac: { format: "aac" } }
- : r === "opus"
- ? { opus: { format: "opus" } }
- : {},
- Rh = ["avc1", "avc3", "hev1", "hvc1", "vp8", "vp09", "av01", ...qr],
- Mh = /^(avc1|avc3)\.[0-9a-fA-F]{6}$/,
- Nh =
- /^(hev1|hvc1)\.(?:[ABC]?\d+)\.[0-9a-fA-F]{1,8}\.[LH]\d+(?:\.[0-9a-fA-F]{1,2}){0,6}$/,
- Oh = /^vp09(?:\.\d{2}){3}(?:(?:\.\d{2}){5})?$/,
- Dh = /^av01\.\d\.\d{2}[MH]\.\d{2}(?:\.\d\.\d{3}\.\d{2}\.\d{2}\.\d{2}\.\d)?$/,
- Zl = (r, e) => {
- if (!r) throw new TypeError("Video chunk metadata must be provided.");
- if (typeof r != "object")
- throw new TypeError("Video chunk metadata must be an object.");
- if (!r.decoderConfig)
- throw new TypeError(
- "Video chunk metadata must include a decoder configuration.",
- );
- if (typeof r.decoderConfig != "object")
- throw new TypeError(
- "Video chunk metadata decoder configuration must be an object.",
- );
- if (typeof r.decoderConfig.codec != "string")
- throw new TypeError(
- "Video chunk metadata decoder configuration must specify a codec string.",
- );
- if (!Rh.some((t) => r.decoderConfig.codec.startsWith(t)))
- throw new TypeError(
- "Video chunk metadata decoder configuration codec string must be a valid video codec string as specified in the Mediabunny Codec Registry.",
- );
- if (
- !Number.isInteger(r.decoderConfig.codedWidth) ||
- r.decoderConfig.codedWidth <= 0
- )
- throw new TypeError(
- "Video chunk metadata decoder configuration must specify a valid codedWidth (positive integer).",
- );
- if (
- !Number.isInteger(r.decoderConfig.codedHeight) ||
- r.decoderConfig.codedHeight <= 0
- )
- throw new TypeError(
- "Video chunk metadata decoder configuration must specify a valid codedHeight (positive integer).",
- );
- if (
- r.decoderConfig.displayAspectWidth !== void 0 &&
- (!Number.isInteger(r.decoderConfig.displayAspectWidth) ||
- r.decoderConfig.displayAspectWidth <= 0)
- )
- throw new TypeError(
- "Video chunk metadata decoder configuration displayAspectWidth, when defined, must be a positive integer.",
- );
- if (
- r.decoderConfig.displayAspectHeight !== void 0 &&
- (!Number.isInteger(r.decoderConfig.displayAspectHeight) ||
- r.decoderConfig.displayAspectHeight <= 0)
- )
- throw new TypeError(
- "Video chunk metadata decoder configuration displayAspectHeight, when defined, must be a positive integer.",
- );
- if (
- (r.decoderConfig.displayAspectWidth !== void 0) !=
- (r.decoderConfig.displayAspectHeight !== void 0)
- )
- throw new TypeError(
- "Video chunk metadata decoder configuration must specify both displayAspectWidth and displayAspectHeight, or neither.",
- );
- if (
- r.decoderConfig.description !== void 0 &&
- !os(r.decoderConfig.description)
- )
- throw new TypeError(
- "Video chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view.",
- );
- if (r.decoderConfig.colorSpace !== void 0) {
- const { colorSpace: t } = r.decoderConfig;
- if (typeof t != "object")
- throw new TypeError(
- "Video chunk metadata decoder configuration colorSpace, when provided, must be an object.",
- );
- const n = Object.keys(xn);
- if (t.primaries != null && !n.includes(t.primaries))
- throw new TypeError(
- `Video chunk metadata decoder configuration colorSpace primaries, when defined, must be one of ${n.join(", ")}.`,
- );
- const i = Object.keys(Sn);
- if (t.transfer != null && !i.includes(t.transfer))
- throw new TypeError(
- `Video chunk metadata decoder configuration colorSpace transfer, when defined, must be one of ${i.join(", ")}.`,
- );
- const s = Object.keys(Pn);
- if (t.matrix != null && !s.includes(t.matrix))
- throw new TypeError(
- `Video chunk metadata decoder configuration colorSpace matrix, when defined, must be one of ${s.join(", ")}.`,
- );
- if (t.fullRange != null && typeof t.fullRange != "boolean")
- throw new TypeError(
- "Video chunk metadata decoder configuration colorSpace fullRange, when defined, must be a boolean.",
- );
- }
- if (
- r.decoderConfig.codec.startsWith("avc1") ||
- r.decoderConfig.codec.startsWith("avc3")
- ) {
- if (!Mh.test(r.decoderConfig.codec))
- throw new TypeError(
- "Video chunk metadata decoder configuration codec string for AVC must be a valid AVC codec string as specified in Section 3.4 of RFC 6381.",
- );
- } else if (
- r.decoderConfig.codec.startsWith("hev1") ||
- r.decoderConfig.codec.startsWith("hvc1")
- ) {
- if (!Nh.test(r.decoderConfig.codec))
- throw new TypeError(
- "Video chunk metadata decoder configuration codec string for HEVC must be a valid HEVC codec string as specified in Section E.3 of ISO 14496-15.",
- );
- } else if (r.decoderConfig.codec.startsWith("vp8")) {
- if (r.decoderConfig.codec !== "vp8")
- throw new TypeError(
- 'Video chunk metadata decoder configuration codec string for VP8 must be "vp8".',
- );
- } else if (r.decoderConfig.codec.startsWith("vp09")) {
- if (!Oh.test(r.decoderConfig.codec))
- throw new TypeError(
- 'Video chunk metadata decoder configuration codec string for VP9 must be a valid VP9 codec string as specified in Section "Codecs Parameter String" of https://www.webmproject.org/vp9/mp4/.',
- );
- } else if (r.decoderConfig.codec.startsWith("av01")) {
- if (!Dh.test(r.decoderConfig.codec))
- throw new TypeError(
- 'Video chunk metadata decoder configuration codec string for AV1 must be a valid AV1 codec string as specified in Section "Codecs Parameter String" of https://aomediacodec.github.io/av1-isobmff/.',
- );
- } else if (
- qr.some((t) => r.decoderConfig.codec.startsWith(t)) &&
- !qr.some((t) => r.decoderConfig.codec === t)
- )
- throw new TypeError(
- `Video chunk metadata decoder configuration codec string for ProRes must be one of the valid ProRes four-character codes: ${qr.join(", ")}.`,
- );
- if (e !== null && ur(r.decoderConfig.codec) !== e)
- throw new TypeError(
- `Video chunk metadata decoder configuration codec string '${r.decoderConfig.codec}' does not fit to the track codec '${e}'.`,
- );
- },
- zh = [
- "mp4a",
- "mp3",
- "opus",
- "vorbis",
- "flac",
- "ulaw",
- "alaw",
- "pcm",
- "ac-3",
- "ec-3",
- "dts",
- ],
- Jl = (r, e) => {
- if (!r) throw new TypeError("Audio chunk metadata must be provided.");
- if (typeof r != "object")
- throw new TypeError("Audio chunk metadata must be an object.");
- if (!r.decoderConfig)
- throw new TypeError(
- "Audio chunk metadata must include a decoder configuration.",
- );
- if (typeof r.decoderConfig != "object")
- throw new TypeError(
- "Audio chunk metadata decoder configuration must be an object.",
- );
- if (typeof r.decoderConfig.codec != "string")
- throw new TypeError(
- "Audio chunk metadata decoder configuration must specify a codec string.",
- );
- if (!zh.some((t) => r.decoderConfig.codec.startsWith(t)))
- throw new TypeError(
- "Audio chunk metadata decoder configuration codec string must be a valid audio codec string as specified in the Mediabunny Codec Registry.",
- );
- if (
- !Number.isInteger(r.decoderConfig.sampleRate) ||
- r.decoderConfig.sampleRate <= 0
- )
- throw new TypeError(
- "Audio chunk metadata decoder configuration must specify a valid sampleRate (positive integer).",
- );
- if (
- !Number.isInteger(r.decoderConfig.numberOfChannels) ||
- r.decoderConfig.numberOfChannels <= 0
- )
- throw new TypeError(
- "Audio chunk metadata decoder configuration must specify a valid numberOfChannels (positive integer).",
- );
- if (
- r.decoderConfig.description !== void 0 &&
- !os(r.decoderConfig.description)
- )
- throw new TypeError(
- "Audio chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view.",
- );
- if (
- r.decoderConfig.codec.startsWith("mp4a") &&
- r.decoderConfig.codec !== "mp4a.69" &&
- r.decoderConfig.codec !== "mp4a.6B" &&
- r.decoderConfig.codec !== "mp4a.6b"
- ) {
- if (
- ![
- "mp4a.40.2",
- "mp4a.40.02",
- "mp4a.40.5",
- "mp4a.40.05",
- "mp4a.40.29",
- "mp4a.67",
- ].includes(r.decoderConfig.codec)
- )
- throw new TypeError(
- "Audio chunk metadata decoder configuration codec string for AAC must be a valid AAC codec string as specified in https://www.w3.org/TR/webcodecs-aac-codec-registration/.",
- );
- } else if (
- r.decoderConfig.codec.startsWith("mp3") ||
- r.decoderConfig.codec.startsWith("mp4a")
- ) {
- if (
- r.decoderConfig.codec !== "mp3" &&
- r.decoderConfig.codec !== "mp4a.69" &&
- r.decoderConfig.codec !== "mp4a.6B" &&
- r.decoderConfig.codec !== "mp4a.6b"
- )
- throw new TypeError(
- 'Audio chunk metadata decoder configuration codec string for MP3 must be "mp3", "mp4a.69" or "mp4a.6B".',
- );
- } else if (r.decoderConfig.codec.startsWith("opus")) {
- if (r.decoderConfig.codec !== "opus")
- throw new TypeError(
- 'Audio chunk metadata decoder configuration codec string for Opus must be "opus".',
- );
- if (
- r.decoderConfig.description &&
- r.decoderConfig.description.byteLength < 18
- )
- throw new TypeError(
- "Audio chunk metadata decoder configuration description, when specified, is expected to be an Identification Header as specified in Section 5.1 of RFC 7845.",
- );
- } else if (r.decoderConfig.codec.startsWith("vorbis")) {
- if (r.decoderConfig.codec !== "vorbis")
- throw new TypeError(
- 'Audio chunk metadata decoder configuration codec string for Vorbis must be "vorbis".',
- );
- if (!r.decoderConfig.description)
- throw new TypeError(
- "Audio chunk metadata decoder configuration for Vorbis must include a description, which is expected to adhere to the format described in https://www.w3.org/TR/webcodecs-vorbis-codec-registration/.",
- );
- } else if (r.decoderConfig.codec.startsWith("flac")) {
- if (r.decoderConfig.codec !== "flac")
- throw new TypeError(
- 'Audio chunk metadata decoder configuration codec string for FLAC must be "flac".',
- );
- if (
- !r.decoderConfig.description ||
- r.decoderConfig.description.byteLength < 42
- )
- throw new TypeError(
- "Audio chunk metadata decoder configuration for FLAC must include a description, which is expected to adhere to the format described in https://www.w3.org/TR/webcodecs-flac-codec-registration/.",
- );
- } else if (
- r.decoderConfig.codec.startsWith("ac-3") ||
- r.decoderConfig.codec.startsWith("ac3")
- ) {
- if (r.decoderConfig.codec !== "ac-3")
- throw new TypeError(
- 'Audio chunk metadata decoder configuration codec string for AC-3 must be "ac-3".',
- );
- } else if (
- r.decoderConfig.codec.startsWith("ec-3") ||
- r.decoderConfig.codec.startsWith("eac3")
- ) {
- if (r.decoderConfig.codec !== "ec-3")
- throw new TypeError(
- 'Audio chunk metadata decoder configuration codec string for EC-3 must be "ec-3".',
- );
- } else if (r.decoderConfig.codec.startsWith("dts")) {
- if (!$i.includes(r.decoderConfig.codec))
- throw new TypeError(
- `Audio chunk metadata decoder configuration codec string for DTS must be one of the following four-character codes: ${$i.join(", ")}.`,
- );
- } else if (
- (r.decoderConfig.codec.startsWith("pcm") ||
- r.decoderConfig.codec.startsWith("ulaw") ||
- r.decoderConfig.codec.startsWith("alaw")) &&
- !ut.includes(r.decoderConfig.codec)
- )
- throw new TypeError(
- `Audio chunk metadata decoder configuration codec string for PCM must be one of the supported PCM codecs (${ut.join(", ")}).`,
- );
- if (e !== null && ur(r.decoderConfig.codec) !== e)
- throw new TypeError(
- `Audio chunk metadata decoder configuration codec string '${r.decoderConfig.codec}' does not fit to the track codec '${e}'.`,
- );
- },
- Wh = (r) => {
- if (!r) throw new TypeError("Subtitle metadata must be provided.");
- if (typeof r != "object")
- throw new TypeError("Subtitle metadata must be an object.");
- if (!r.config)
- throw new TypeError("Subtitle metadata must include a config object.");
- if (typeof r.config != "object")
- throw new TypeError("Subtitle metadata config must be an object.");
- if (typeof r.config.description != "string")
- throw new TypeError(
- "Subtitle metadata config description must be a string.",
- );
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const jr = 4,
- Uh = [44100, 48e3, 32e3],
- Hh = [
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 32, 40,
- 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1, -1, 32, 48, 56,
- 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1, -1, 32, 64, 96, 128,
- 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, 16, 24, 32, 40, 48, 56,
- 64, 80, 96, 112, 128, 144, 160, -1, -1, 8, 16, 24, 32, 40, 48, 56, 64, 80,
- 96, 112, 128, 144, 160, -1, -1, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160,
- 176, 192, 224, 256, -1,
- ],
- eu = 1483304551,
- tu = 1231971951,
- Vh = (r, e, t, n, i) =>
- e === 0
- ? 0
- : e === 1
- ? Math.floor((144 * t) / (n << r)) + i
- : e === 2
- ? Math.floor((144 * t) / n) + i
- : (Math.floor((12 * t) / n) + i) * 4,
- Lh = (r, e, t, n) =>
- e === 0
- ? 0
- : e === 1
- ? (144 * t) / (n << r)
- : e === 2
- ? (144 * t) / n
- : ((12 * t) / n) * 4,
- ru = (r, e) => (r === 3 ? (e === 3 ? 21 : 36) : e === 3 ? 13 : 21),
- io = (r, e) => {
- const t = r >>> 24,
- n = (r >>> 16) & 255,
- i = (r >>> 8) & 255,
- s = r & 255;
- if (t !== 255 && n !== 255 && i !== 255 && s !== 255)
- return { header: null, bytesAdvanced: 4 };
- if (t !== 255) return { header: null, bytesAdvanced: 1 };
- if ((n & 224) !== 224) return { header: null, bytesAdvanced: 1 };
- let a = 0,
- o = 0;
- n & 16 ? (a = n & 8 ? 0 : 1) : ((a = 1), (o = 1));
- const c = (n >> 3) & 3,
- u = (n >> 1) & 3,
- l = (i >> 4) & 15,
- d = ((i >> 2) & 3) % 3,
- f = (i >> 1) & 1,
- h = (s >> 6) & 3,
- p = (s >> 4) & 3,
- m = (s >> 3) & 1,
- b = (s >> 2) & 1,
- g = s & 3,
- y = Hh[a * 16 * 4 + u * 16 + l];
- if (y === -1) return { header: null, bytesAdvanced: 1 };
- const C = y * 1e3,
- _ = Uh[d] >> (a + o),
- v = Vh(a, u, C, _, f);
- if (e !== null && e < v) return { header: null, bytesAdvanced: 1 };
- let I;
- return (
- c === 3
- ? (I = u === 3 ? 384 : 1152)
- : u === 3
- ? (I = 384)
- : u === 2
- ? (I = 1152)
- : (I = 576),
- {
- header: {
- totalSize: v,
- mpegVersionId: c,
- lowSamplingFrequency: a,
- layer: u,
- bitrate: C,
- frequencyIndex: d,
- sampleRate: _,
- channel: h,
- modeExtension: p,
- copyright: m,
- original: b,
- emphasis: g,
- audioSamplesInFrame: I,
- },
- bytesAdvanced: 1,
- }
- );
- },
- Pa = (r) => {
- let e = 2130706432,
- t = 0;
- for (; e !== 0;) ((t >>= 1), (t |= r & e), (e >>= 8));
- return t;
- };
-var Gi;
-(function (r) {
- ((r[(r.FrameCount = 1)] = "FrameCount"),
- (r[(r.FileSize = 2)] = "FileSize"),
- (r[(r.Toc = 4)] = "Toc"));
-})(Gi || (Gi = {}));
-const ci = (r) => (r === 3 ? 1 : 2);
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class br {
- constructor(e) {
- this.input = e;
- }
- dispose() {}
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const Tt = new Uint8Array(0);
-class Ee {
- constructor(e, t, n, i, s = -1, a, o) {
- if (
- ((this.data = e),
- (this.type = t),
- (this.timestamp = n),
- (this.duration = i),
- (this.sequenceNumber = s),
- e === Tt && a === void 0)
- )
- throw new Error(
- "Internal error: byteLength must be explicitly provided when constructing metadata-only packets.",
- );
- if ((a === void 0 && (a = e.byteLength), !(e instanceof Uint8Array)))
- throw new TypeError("data must be a Uint8Array.");
- if (t !== "key" && t !== "delta")
- throw new TypeError('type must be either "key" or "delta".');
- if (!Number.isFinite(n)) throw new TypeError("timestamp must be a number.");
- if (!Number.isFinite(i) || i < 0)
- throw new TypeError("duration must be a non-negative number.");
- if (!Number.isFinite(s))
- throw new TypeError("sequenceNumber must be a number.");
- if (!Number.isInteger(a) || a < 0)
- throw new TypeError("byteLength must be a non-negative integer.");
- if (o !== void 0 && (typeof o != "object" || !o))
- throw new TypeError("sideData, when provided, must be an object.");
- if (
- (o == null ? void 0 : o.alpha) !== void 0 &&
- !(o.alpha instanceof Uint8Array)
- )
- throw new TypeError(
- "sideData.alpha, when provided, must be a Uint8Array.",
- );
- if (
- (o == null ? void 0 : o.alphaByteLength) !== void 0 &&
- (!Number.isInteger(o.alphaByteLength) || o.alphaByteLength < 0)
- )
- throw new TypeError(
- "sideData.alphaByteLength, when provided, must be a non-negative integer.",
- );
- ((this.byteLength = a),
- (this.sideData = o ?? {}),
- this.sideData.alpha &&
- this.sideData.alphaByteLength === void 0 &&
- (this.sideData.alphaByteLength = this.sideData.alpha.byteLength));
- }
- get isMetadataOnly() {
- return this.data === Tt;
- }
- get microsecondTimestamp() {
- return Math.trunc(_r * this.timestamp);
- }
- get microsecondDuration() {
- return Math.trunc(_r * this.duration);
- }
- toEncodedVideoChunk() {
- if (this.isMetadataOnly)
- throw new TypeError(
- "Metadata-only packets cannot be converted to a video chunk.",
- );
- if (typeof EncodedVideoChunk > "u")
- throw new Error(
- "EncodedVideoChunk is not available in this environment.",
- );
- return new EncodedVideoChunk({
- data: this.data,
- type: this.type,
- timestamp: this.microsecondTimestamp,
- duration: this.microsecondDuration,
- });
- }
- alphaToEncodedVideoChunk(e = this.type) {
- if (!this.sideData.alpha)
- throw new TypeError("This packet does not contain alpha side data.");
- if (this.isMetadataOnly)
- throw new TypeError(
- "Metadata-only packets cannot be converted to a video chunk.",
- );
- if (typeof EncodedVideoChunk > "u")
- throw new Error(
- "EncodedVideoChunk is not available in this environment.",
- );
- return new EncodedVideoChunk({
- data: this.sideData.alpha,
- type: e,
- timestamp: this.microsecondTimestamp,
- duration: this.microsecondDuration,
- });
- }
- toEncodedAudioChunk() {
- if (this.isMetadataOnly)
- throw new TypeError(
- "Metadata-only packets cannot be converted to an audio chunk.",
- );
- if (typeof EncodedAudioChunk > "u")
- throw new Error(
- "EncodedAudioChunk is not available in this environment.",
- );
- return new EncodedAudioChunk({
- data: this.data,
- type: this.type,
- timestamp: this.microsecondTimestamp,
- duration: this.microsecondDuration,
- });
- }
- static fromEncodedChunk(e, t) {
- if (!(e instanceof EncodedVideoChunk || e instanceof EncodedAudioChunk))
- throw new TypeError(
- "chunk must be an EncodedVideoChunk or EncodedAudioChunk.",
- );
- const n = new Uint8Array(e.byteLength);
- return (
- e.copyTo(n),
- new Ee(
- n,
- e.type,
- e.timestamp / 1e6,
- (e.duration ?? 0) / 1e6,
- void 0,
- void 0,
- t,
- )
- );
- }
- clone(e) {
- if (e !== void 0 && (typeof e != "object" || e === null))
- throw new TypeError("options, when provided, must be an object.");
- if (
- (e == null ? void 0 : e.data) !== void 0 &&
- !(e.data instanceof Uint8Array)
- )
- throw new TypeError("options.data, when provided, must be a Uint8Array.");
- if (
- (e == null ? void 0 : e.type) !== void 0 &&
- e.type !== "key" &&
- e.type !== "delta"
- )
- throw new TypeError(
- 'options.type, when provided, must be either "key" or "delta".',
- );
- if (
- (e == null ? void 0 : e.timestamp) !== void 0 &&
- !Number.isFinite(e.timestamp)
- )
- throw new TypeError(
- "options.timestamp, when provided, must be a number.",
- );
- if (
- (e == null ? void 0 : e.duration) !== void 0 &&
- !Number.isFinite(e.duration)
- )
- throw new TypeError("options.duration, when provided, must be a number.");
- if (
- (e == null ? void 0 : e.sequenceNumber) !== void 0 &&
- !Number.isFinite(e.sequenceNumber)
- )
- throw new TypeError(
- "options.sequenceNumber, when provided, must be a number.",
- );
- if (
- (e == null ? void 0 : e.sideData) !== void 0 &&
- (typeof e.sideData != "object" || e.sideData === null)
- )
- throw new TypeError(
- "options.sideData, when provided, must be an object.",
- );
- return new Ee(
- (e == null ? void 0 : e.data) ?? this.data,
- (e == null ? void 0 : e.type) ?? this.type,
- (e == null ? void 0 : e.timestamp) ?? this.timestamp,
- (e == null ? void 0 : e.duration) ?? this.duration,
- (e == null ? void 0 : e.sequenceNumber) ?? this.sequenceNumber,
- this.byteLength,
- (e == null ? void 0 : e.sideData) ?? this.sideData,
- );
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const nu = (r) => {
- let t =
- (r.hasVideo ? "video/" : r.hasAudio ? "audio/" : "application/") +
- (r.isQuickTime ? "quicktime" : "mp4");
- if (r.codecStrings.length > 0) {
- const n = [...new Set(r.codecStrings)];
- t += `; codecs="${n.join(", ")}"`;
- }
- return t;
- },
- iu = (r) => {
- const e = ge(r);
- let t = 0;
- const n = e.getUint8(t);
- ((t += 1), (t += 3));
- const i = ri(r.subarray(t, t + 16));
- t += 16;
- let s = null;
- if (n > 0) {
- const o = e.getUint32(t);
- if (((t += 4), o > 0)) {
- s = [];
- for (let c = 0; c < o; c++)
- (s.push(ri(r.subarray(t, t + 16))), (t += 16));
- }
- }
- const a = e.getUint32(t);
- return ((t += 4), { systemId: i, keyIds: s, data: r.slice(t, t + a) });
- },
- su = (r, e) => r.systemId === e.systemId && Vf(r.data, e.data);
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const sr = 8,
- Hr = 16,
- Cr = (r) => {
- let e = L(r);
- const t = Ne(r, 4);
- let n = 8;
- e === 1 && ((e = ft(r)), (n = 16));
- const s = e - n;
- return s < 0
- ? null
- : { name: t, totalSize: e, headerSize: n, contentSize: s };
- },
- Dr = (r) => Vr(r) / 65536,
- Ns = (r) => Vr(r) / 1073741824,
- Os = (r) => {
- let e = 0;
- for (let t = 0; t < 4; t++) {
- e <<= 7;
- const n = Y(r);
- if (((e |= n & 127), (n & 128) === 0)) break;
- }
- return e;
- },
- Dt = (r) => {
- let e = Ve(r);
- return (
- r.skip(2),
- (e = Math.min(e, r.remainingLength)),
- ot.decode(Z(r, e))
- );
- },
- qh = (r) => {
- const e = Cr(r);
- if (!e || e.name !== "data" || r.remainingLength < 8) return null;
- const t = L(r);
- r.skip(4);
- const n = Z(r, e.contentSize - 8);
- switch (t) {
- case 1:
- return ot.decode(n);
- case 2:
- return new Kn("utf-16be").decode(n);
- case 13:
- return new fn(n, "image/jpeg");
- case 14:
- return new fn(n, "image/png");
- case 27:
- return new fn(n, "image/bmp");
- default:
- return n;
- }
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const Ht = 16,
- Qt = new Uint32Array(256),
- tn = new Uint32Array(256),
- rn = new Uint32Array(256),
- nn = new Uint32Array(256),
- sn = new Uint32Array(256),
- Qe = new Uint32Array(256),
- au = new Uint32Array(10);
-let ou = !1;
-const jh = () => {
- const r = new Uint8Array(256),
- e = new Uint8Array(256),
- t = new Uint8Array(256);
- for (let s = 0, a = 1; s < 256; s++)
- ((t[s] = a), (e[a] = s), (a = a ^ (a << 1) ^ (a & 128 ? 283 : 0)));
- const n = (s, a) => (s && a ? t[(e[s] + e[a]) % 255] : 0);
- r[0] = 99;
- for (let s = 1; s < 256; s++) {
- const a = t[255 - e[s]];
- let o = a ^ (a << 1) ^ (a << 2) ^ (a << 3) ^ (a << 4);
- ((o = (o >>> 8) ^ (o & 255) ^ 99), (r[s] = o));
- }
- for (let s = 0; s < 256; s++) {
- const a = r[s],
- o = r.indexOf(s);
- ((Qt[s] = (a << 24) | (a << 16) | (a << 8) | a),
- (Qe[s] = (o << 24) | (o << 16) | (o << 8) | o));
- const c = n(o, 14),
- u = n(o, 9),
- l = n(o, 13),
- d = n(o, 11),
- f = (c << 24) | (u << 16) | (l << 8) | d;
- ((tn[s] = f),
- (rn[s] = (f >>> 8) | (f << 24)),
- (nn[s] = (f >>> 16) | (f << 16)),
- (sn[s] = (f >>> 24) | (f << 8)));
- }
- let i = 1;
- for (let s = 0; s < 10; s++)
- ((au[s] = i << 24), (i = (i << 1) ^ (i & 128 ? 283 : 0)));
- ou = !0;
-};
-class cu {
- constructor() {
- ((this.roundkey = new Uint32Array(44)),
- (this.iv = new Uint32Array(Ht / Uint32Array.BYTES_PER_ELEMENT)),
- (this.in = new Uint8Array(Ht)),
- (this.out = new Uint8Array(Ht)),
- (this.inView = new DataView(this.in.buffer)),
- (this.outView = new DataView(this.out.buffer)));
- }
- init({ key: e, iv: t }) {
- (T(e.byteLength === 16), T(t.byteLength === 16), ou || jh());
- const n = new DataView(e.buffer, e.byteOffset, e.byteLength),
- i = new DataView(t.buffer, t.byteOffset, t.byteLength);
- ((this.roundkey[0] = n.getUint32(0, !1)),
- (this.roundkey[1] = n.getUint32(4, !1)),
- (this.roundkey[2] = n.getUint32(8, !1)),
- (this.roundkey[3] = n.getUint32(12, !1)),
- (this.iv[0] = i.getUint32(0, !1)),
- (this.iv[1] = i.getUint32(4, !1)),
- (this.iv[2] = i.getUint32(8, !1)),
- (this.iv[3] = i.getUint32(12, !1)));
- for (let s = 4; s < 44; s += 4) {
- const a = this.roundkey[s - 1];
- ((this.roundkey[s] =
- this.roundkey[s - 4] ^
- (Qt[(a >>> 16) & 255] & 4278190080) ^
- (Qt[(a >>> 8) & 255] & 16711680) ^
- (Qt[(a >>> 0) & 255] & 65280) ^
- (Qt[(a >>> 24) & 255] & 255) ^
- au[s / 4 - 1]),
- (this.roundkey[s + 1] = this.roundkey[s - 3] ^ this.roundkey[s]),
- (this.roundkey[s + 2] = this.roundkey[s - 2] ^ this.roundkey[s + 1]),
- (this.roundkey[s + 3] = this.roundkey[s - 1] ^ this.roundkey[s + 2]));
- }
- for (let s = 0, a = 40; s < a; s += 4, a -= 4)
- for (let o = 0; o < 4; o++) {
- const c = this.roundkey[s + o];
- ((this.roundkey[s + o] = this.roundkey[a + o]),
- (this.roundkey[a + o] = c));
- }
- for (let s = 4; s < 40; s += 4)
- for (let a = 0; a < 4; a++) {
- const o = this.roundkey[s + a];
- this.roundkey[s + a] =
- tn[Qt[(o >>> 24) & 255] & 255] ^
- rn[Qt[(o >>> 16) & 255] & 255] ^
- nn[Qt[(o >>> 8) & 255] & 255] ^
- sn[Qt[(o >>> 0) & 255] & 255];
- }
- }
- decrypt() {
- let e = this.inView.getUint32(0, !1) ^ this.roundkey[0],
- t = this.inView.getUint32(4, !1) ^ this.roundkey[1],
- n = this.inView.getUint32(8, !1) ^ this.roundkey[2],
- i = this.inView.getUint32(12, !1) ^ this.roundkey[3];
- const s = this.inView.getUint32(0, !1),
- a = this.inView.getUint32(4, !1),
- o = this.inView.getUint32(8, !1),
- c = this.inView.getUint32(12, !1);
- let u, l, d, f;
- for (let g = 1; g < 10; g++) {
- const y = g * 4;
- ((u =
- tn[e >>> 24] ^
- rn[(i >>> 16) & 255] ^
- nn[(n >>> 8) & 255] ^
- sn[t & 255] ^
- this.roundkey[y]),
- (l =
- tn[t >>> 24] ^
- rn[(e >>> 16) & 255] ^
- nn[(i >>> 8) & 255] ^
- sn[n & 255] ^
- this.roundkey[y + 1]),
- (d =
- tn[n >>> 24] ^
- rn[(t >>> 16) & 255] ^
- nn[(e >>> 8) & 255] ^
- sn[i & 255] ^
- this.roundkey[y + 2]),
- (f =
- tn[i >>> 24] ^
- rn[(n >>> 16) & 255] ^
- nn[(t >>> 8) & 255] ^
- sn[e & 255] ^
- this.roundkey[y + 3]),
- (e = u),
- (t = l),
- (n = d),
- (i = f));
- }
- const h =
- (Qe[(e >>> 24) & 255] & 4278190080) ^
- (Qe[(i >>> 16) & 255] & 16711680) ^
- (Qe[(n >>> 8) & 255] & 65280) ^
- (Qe[(t >>> 0) & 255] & 255) ^
- this.roundkey[40],
- p =
- (Qe[(t >>> 24) & 255] & 4278190080) ^
- (Qe[(e >>> 16) & 255] & 16711680) ^
- (Qe[(i >>> 8) & 255] & 65280) ^
- (Qe[(n >>> 0) & 255] & 255) ^
- this.roundkey[41],
- m =
- (Qe[(n >>> 24) & 255] & 4278190080) ^
- (Qe[(t >>> 16) & 255] & 16711680) ^
- (Qe[(e >>> 8) & 255] & 65280) ^
- (Qe[(i >>> 0) & 255] & 255) ^
- this.roundkey[42],
- b =
- (Qe[(i >>> 24) & 255] & 4278190080) ^
- (Qe[(n >>> 16) & 255] & 16711680) ^
- (Qe[(t >>> 8) & 255] & 65280) ^
- (Qe[(e >>> 0) & 255] & 255) ^
- this.roundkey[43];
- (this.outView.setUint32(0, h ^ this.iv[0], !1),
- this.outView.setUint32(4, p ^ this.iv[1], !1),
- this.outView.setUint32(8, m ^ this.iv[2], !1),
- this.outView.setUint32(12, b ^ this.iv[3], !1),
- (this.iv[0] = s),
- (this.iv[1] = a),
- (this.iv[2] = o),
- (this.iv[3] = c));
- }
-}
-const $h = (r, e, t) => {
- let n = !1,
- i = 0;
- const s = 2 ** 16,
- a = 16,
- o = new cu();
- return new ReadableStream({
- pull: async (c) => {
- n || (o.init(await e()), (n = !0));
- const u = s + a;
- let l = r.requestSliceRange(i, 0, u);
- if ((O(l) && (l = await l), !l || l.length === 0))
- throw new Error("Invalid ciphertext.");
- const d = l.length;
- if (d % 16 !== 0) throw new Error("Invalid ciphertext.");
- const f = d === u ? d - a : d,
- h = Z(l, f),
- p = new Uint8Array(f);
- for (let m = 0; m < f; m += 16)
- (o.in.set(h.subarray(m, m + 16)), o.decrypt(), p.set(o.out, m));
- if (f < d) (c.enqueue(p), (i += f));
- else {
- const m = p[f - 1];
- if (m === 0 || m > 16)
- throw new Error(
- "Invalid PKCS#7 padding. Incorrect key or corrupted data.",
- );
- const b = p.subarray(0, f - m);
- (c.enqueue(b), c.close(), t());
- }
- },
- cancel: () => {
- t();
- },
- });
-};
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class so extends br {
- constructor(e) {
- (super(e),
- (this.moovSlice = null),
- (this.currentTrack = null),
- (this.tracks = []),
- (this.metadataPromise = null),
- (this.movieTimescale = -1),
- (this.movieDurationInTimescale = -1),
- (this.movieMatrix = ei),
- (this.isQuickTime = !1),
- (this.metadataTags = {}),
- (this.currentMetadataKeys = null),
- (this.isFragmented = !1),
- (this.fragmentTrackDefaults = []),
- (this.psshBoxes = []),
- (this.currentFragment = null),
- (this.lastReadFragment = null),
- (this.decryptionKeyCache = new Map()),
- (this.reader = e._reader));
- }
- async getTrackBackings() {
- return (await this.readMetadata(), this.tracks.map((e) => e.trackBacking));
- }
- async getMimeType() {
- await this.readMetadata();
- const e = await this.getTrackBackings(),
- t = await Promise.all(
- e.map((n) =>
- n
- .getDecoderConfig()
- .then((i) => (i == null ? void 0 : i.codec) ?? null),
- ),
- );
- return nu({
- isQuickTime: this.isQuickTime,
- hasVideo: this.tracks.some((n) => {
- var i;
- return ((i = n.info) == null ? void 0 : i.type) === "video";
- }),
- hasAudio: this.tracks.some((n) => {
- var i;
- return ((i = n.info) == null ? void 0 : i.type) === "audio";
- }),
- codecStrings: t.filter(Boolean),
- });
- }
- async getMetadataTags() {
- return (await this.readMetadata(), this.metadataTags);
- }
- readMetadata() {
- return (
- this.metadataPromise ??
- (this.metadataPromise = (async () => {
- let e = 0,
- t = !1,
- n = !1;
- for (;;) {
- let i = this.reader.requestSliceRange(e, sr, Hr);
- if ((O(i) && (i = await i), !i)) break;
- const s = e,
- a = Cr(i);
- if (!a) break;
- if (a.name === "ftyp" || a.name === "styp") {
- const o = Ne(i, 4);
- this.isQuickTime = o === "qt ";
- } else if (a.name === "moov") {
- let o = this.reader.requestSlice(i.filePos, a.contentSize);
- if ((O(o) && (o = await o), !o)) break;
- ((this.moovSlice = o), this.readContiguousBoxes(this.moovSlice));
- for (const c of this.tracks) {
- const u =
- c.editListPreviousSegmentDurations / this.movieTimescale;
- c.editListOffset -= Math.round(u * c.timescale);
- }
- ((t =
- this.isFragmented &&
- this.reader.fileSize !== null &&
- this.reader.fileSize > s + a.totalSize),
- (n = !0));
- break;
- } else if (a.name === "moof") {
- if (!this.input._initInput)
- throw new Error(
- '"moof" box encountered with no "moov" box present; this file is likely a Segment as described in ISO/IEC 14496-12 Section 8.16. A separate init file that contains a "moov" box is required to read this file, please provide it using InputOptions.initInput.',
- );
- (await this.copyMetadataFromInitInput(this.input._initInput),
- (t = !1),
- (n = !0));
- break;
- }
- e = s + a.totalSize;
- }
- if (
- (!n &&
- this.input._initInput &&
- (await this.copyMetadataFromInitInput(this.input._initInput)),
- t)
- ) {
- T(this.reader.fileSize !== null);
- let i = this.reader.requestSlice(this.reader.fileSize - 4, 4);
- (O(i) && (i = await i), T(i));
- const s = L(i),
- a = this.reader.fileSize - s;
- if (a >= 0 && a <= this.reader.fileSize - Hr) {
- let o = this.reader.requestSliceRange(a, sr, Hr);
- if ((O(o) && (o = await o), o)) {
- const c = Cr(o);
- if (c && c.name === "mfra") {
- let u = this.reader.requestSlice(o.filePos, c.contentSize);
- (O(u) && (u = await u), u && this.readContiguousBoxes(u));
- }
- }
- }
- }
- })())
- );
- }
- async copyMetadataFromInitInput(e) {
- const t = await e._getDemuxer();
- if (t.constructor !== so)
- throw new Error("Init input must match the input's format.");
- (await t.readMetadata(),
- (this.movieTimescale = t.movieTimescale),
- (this.movieDurationInTimescale = t.movieDurationInTimescale),
- (this.movieMatrix = t.movieMatrix),
- (this.metadataTags = t.metadataTags),
- (this.isFragmented = !0),
- (this.fragmentTrackDefaults = t.fragmentTrackDefaults),
- (this.psshBoxes = t.psshBoxes));
- for (const n of t.tracks) {
- const i = {
- id: n.id,
- demuxer: this,
- trackBacking: null,
- disposition: n.disposition,
- timescale: n.timescale,
- durationInMediaTimescale: n.durationInMediaTimescale,
- durationInMovieTimescale: n.durationInMovieTimescale,
- matrix: n.matrix,
- internalCodecId: n.internalCodecId,
- name: n.name,
- languageCode: n.languageCode,
- sampleTableByteOffset: null,
- sampleTable: null,
- fragmentLookupTable: [],
- currentFragmentState: null,
- fragmentPositionCache: [],
- editListPreviousSegmentDurations: n.editListPreviousSegmentDurations,
- editListOffset: n.editListOffset,
- encryptionInfo: n.encryptionInfo,
- encryptionAuxInfo: null,
- frmaCodecString: null,
- maxBitrate: n.maxBitrate,
- avgBitrate: n.avgBitrate,
- info: n.info,
- };
- if (n.trackBacking) {
- if ((T(i.info), i.info.type === "video" && i.info.width !== -1)) {
- const s = i;
- ((i.trackBacking = new Ko(s)), this.tracks.push(i));
- } else if (i.info.type === "audio" && i.info.numberOfChannels !== -1) {
- const s = i;
- ((i.trackBacking = new Xo(s)), this.tracks.push(i));
- }
- }
- }
- }
- getSampleTableForTrack(e) {
- var s, a;
- if (e.sampleTable) return e.sampleTable;
- const t = {
- sampleTimingEntries: [],
- sampleCompositionTimeOffsets: [],
- sampleSizes: [],
- keySampleIndices: null,
- chunkOffsets: [],
- sampleToChunk: [],
- presentationTimestamps: null,
- presentationTimestampIndexMap: null,
- };
- if (((e.sampleTable = t), e.sampleTableByteOffset === null)) return t;
- T(this.moovSlice);
- const n = this.moovSlice.slice(e.sampleTableByteOffset);
- if (
- ((this.currentTrack = e),
- this.traverseBox(n),
- (this.currentTrack = null),
- ((s = e.info) == null ? void 0 : s.type) === "audio" &&
- e.info.codec &&
- ut.includes(e.info.codec) &&
- t.sampleCompositionTimeOffsets.length === 0)
- ) {
- T(((a = e.info) == null ? void 0 : a.type) === "audio");
- const o = Rr(e.info.codec),
- c = [],
- u = [];
- for (let l = 0; l < t.sampleToChunk.length; l++) {
- const d = t.sampleToChunk[l],
- f = t.sampleToChunk[l + 1],
- h =
- (f ? f.startChunkIndex : t.chunkOffsets.length) - d.startChunkIndex;
- for (let p = 0; p < h; p++) {
- const m = d.startSampleIndex + p * d.samplesPerChunk,
- b = m + d.samplesPerChunk,
- g = ke(t.sampleTimingEntries, m, (S) => S.startIndex),
- y = t.sampleTimingEntries[g],
- C = ke(t.sampleTimingEntries, b, (S) => S.startIndex),
- _ = t.sampleTimingEntries[C],
- v = y.startDecodeTimestamp + (m - y.startIndex) * y.delta,
- w = _.startDecodeTimestamp + (b - _.startIndex) * _.delta - v,
- x = Ae(c);
- x && x.delta === w
- ? x.count++
- : c.push({
- startIndex: d.startChunkIndex + p,
- startDecodeTimestamp: v,
- count: 1,
- delta: w,
- });
- const k = d.samplesPerChunk * o.sampleSize * e.info.numberOfChannels;
- u.push(k);
- }
- ((d.startSampleIndex = d.startChunkIndex), (d.samplesPerChunk = 1));
- }
- ((t.sampleTimingEntries = c), (t.sampleSizes = u));
- }
- if (t.sampleCompositionTimeOffsets.length > 0) {
- t.presentationTimestamps = [];
- for (const o of t.sampleTimingEntries)
- for (let c = 0; c < o.count; c++)
- t.presentationTimestamps.push({
- presentationTimestamp: o.startDecodeTimestamp + c * o.delta,
- sampleIndex: o.startIndex + c,
- });
- for (const o of t.sampleCompositionTimeOffsets)
- for (let c = 0; c < o.count; c++) {
- const u = o.startIndex + c,
- l = t.presentationTimestamps[u];
- l && (l.presentationTimestamp += o.offset);
- }
- (t.presentationTimestamps.sort(
- (o, c) => o.presentationTimestamp - c.presentationTimestamp,
- ),
- (t.presentationTimestampIndexMap = Array(
- t.presentationTimestamps.length,
- ).fill(-1)));
- for (let o = 0; o < t.presentationTimestamps.length; o++)
- t.presentationTimestampIndexMap[
- t.presentationTimestamps[o].sampleIndex
- ] = o;
- }
- return t;
- }
- async readFragment(e) {
- var a;
- if (((a = this.lastReadFragment) == null ? void 0 : a.moofOffset) === e)
- return this.lastReadFragment;
- let t = this.reader.requestSliceRange(e, sr, Hr);
- (O(t) && (t = await t), T(t));
- const n = Cr(t);
- T((n == null ? void 0 : n.name) === "moof");
- let i = this.reader.requestSlice(e, n.totalSize);
- (O(i) && (i = await i), T(i), this.traverseBox(i));
- const s = this.lastReadFragment;
- T(s && s.moofOffset === e);
- for (const [, o] of s.trackData) {
- const c = o.track,
- { fragmentPositionCache: u } = c;
- if (!o.startTimestampIsFinal) {
- const d = c.fragmentLookupTable.find(
- (f) => f.moofOffset === s.moofOffset,
- );
- if (d) Ds(o, d.timestamp);
- else {
- const f = ke(u, s.moofOffset - 1, (h) => h.moofOffset);
- if (f !== -1) {
- const h = u[f];
- Ds(o, h.endTimestamp);
- }
- }
- o.startTimestampIsFinal = !0;
- }
- const l = ke(u, o.startTimestamp, (d) => d.startTimestamp);
- if (
- ((l === -1 || u[l].moofOffset !== s.moofOffset) &&
- u.splice(l + 1, 0, {
- moofOffset: s.moofOffset,
- startTimestamp: o.startTimestamp,
- endTimestamp: o.endTimestamp,
- }),
- o.encryptionAuxInfo && c.encryptionInfo)
- ) {
- const d = await uu(this.reader, c.encryptionInfo, o.encryptionAuxInfo);
- for (let f = 0; f < Math.min(o.samples.length, d.length); f++) {
- const h = d[f];
- o.samples[f].encryption = h;
- }
- }
- }
- return s;
- }
- readContiguousBoxes(e) {
- const t = e.filePos;
- for (; e.filePos - t <= e.length - sr && this.traverseBox(e););
- }
- *iterateContiguousBoxes(e) {
- const t = e.filePos;
- for (; e.filePos - t <= e.length - sr;) {
- const n = e.filePos,
- i = Cr(e);
- if (!i) break;
- (yield { boxInfo: i, slice: e }, (e.filePos = n + i.totalSize));
- }
- }
- traverseBox(e) {
- var a,
- o,
- c,
- u,
- l,
- d,
- f,
- h,
- p,
- m,
- b,
- g,
- y,
- C,
- _,
- v,
- I,
- w,
- x,
- k,
- S,
- E,
- B,
- R,
- M,
- z,
- q,
- j,
- se,
- le,
- ue,
- $e,
- K,
- ie,
- Ie,
- Ge,
- Fe,
- je,
- He,
- we,
- Oe,
- st,
- _t,
- At,
- Ot,
- wr,
- En,
- In,
- _n,
- An;
- const t = e.filePos,
- n = Cr(e);
- if (!n) return !1;
- const i = e.filePos,
- s = t + n.totalSize;
- switch (n.name) {
- case "mdia":
- case "minf":
- case "dinf":
- case "mfra":
- case "edts":
- case "sinf":
- case "schi":
- this.readContiguousBoxes(e.slice(i, n.contentSize));
- break;
- case "mvhd":
- {
- const P = Y(e);
- (e.skip(3),
- P === 1
- ? (e.skip(16),
- (this.movieTimescale = L(e)),
- (this.movieDurationInTimescale = ft(e)))
- : (e.skip(8),
- (this.movieTimescale = L(e)),
- (this.movieDurationInTimescale = L(e))),
- e.skip(16),
- (this.movieMatrix = Qo(e)));
- }
- break;
- case "trak":
- {
- const P = {
- id: -1,
- demuxer: this,
- trackBacking: null,
- disposition: { ...gr, primary: !1 },
- info: null,
- timescale: -1,
- durationInMovieTimescale: -1,
- durationInMediaTimescale: -1,
- matrix: ei,
- internalCodecId: null,
- name: null,
- languageCode: nt,
- sampleTableByteOffset: -1,
- sampleTable: null,
- fragmentLookupTable: [],
- currentFragmentState: null,
- fragmentPositionCache: [],
- editListPreviousSegmentDurations: 0,
- editListOffset: 0,
- encryptionInfo: null,
- encryptionAuxInfo: null,
- frmaCodecString: null,
- maxBitrate: null,
- avgBitrate: null,
- };
- if (
- ((this.currentTrack = P),
- this.readContiguousBoxes(e.slice(i, n.contentSize)),
- P.id !== -1 && P.timescale !== -1 && P.info !== null)
- ) {
- if (P.info.type === "video" && P.info.width !== -1) {
- const A = P;
- ((P.trackBacking = new Ko(A)), this.tracks.push(P));
- } else if (
- P.info.type === "audio" &&
- P.info.numberOfChannels !== -1
- ) {
- const A = P;
- ((P.trackBacking = new Xo(A)), this.tracks.push(P));
- }
- }
- this.currentTrack = null;
- }
- break;
- case "tkhd":
- {
- const P = this.currentTrack;
- if (!P) break;
- const A = Y(e),
- D = !!(Zt(e) & 1);
- if (((P.disposition.default = D), A === 0))
- (e.skip(8),
- (P.id = L(e)),
- e.skip(4),
- (P.durationInMovieTimescale = L(e)));
- else if (A === 1)
- (e.skip(16),
- (P.id = L(e)),
- e.skip(4),
- (P.durationInMovieTimescale = ft(e)));
- else throw new Error(`Incorrect track header version ${A}.`);
- e.skip(16);
- const $ = Qo(e);
- P.matrix = ti($, this.movieMatrix);
- }
- break;
- case "elst":
- {
- const P = this.currentTrack;
- if (!P) break;
- const A = Y(e);
- e.skip(3);
- let F = !1,
- D = 0;
- const $ = L(e);
- for (let W = 0; W < $; W++) {
- const Q = A === 1 ? ft(e) : L(e),
- re = A === 1 ? Jp(e) : Vr(e),
- oe = Dr(e);
- if (F) {
- te._warn(
- "Unsupported edit list: multiple edits are not currently supported. Only using first edit.",
- );
- break;
- }
- if (re === -1) {
- D += Q;
- continue;
- }
- if (oe !== 1) {
- te._warn("Unsupported edit list entry: media rate must be 1.");
- break;
- }
- ((P.editListPreviousSegmentDurations = D),
- (P.editListOffset = re),
- (F = !0));
- }
- }
- break;
- case "mdhd":
- {
- const P = this.currentTrack;
- if (!P) break;
- const A = Y(e);
- (e.skip(3),
- A === 0
- ? (e.skip(8),
- (P.timescale = L(e)),
- (P.durationInMediaTimescale = L(e)))
- : A === 1 &&
- (e.skip(16),
- (P.timescale = L(e)),
- (P.durationInMediaTimescale = ft(e))));
- let F = Ve(e);
- if (F > 0) {
- P.languageCode = "";
- for (let D = 0; D < 3; D++)
- ((P.languageCode =
- String.fromCharCode(96 + (F & 31)) + P.languageCode),
- (F >>= 5));
- qa(P.languageCode) || (P.languageCode = nt);
- }
- }
- break;
- case "hdlr":
- {
- const P = this.currentTrack;
- if (!P) break;
- e.skip(8);
- const A = Ne(e, 4);
- A === "vide"
- ? (P.info = {
- type: "video",
- width: -1,
- height: -1,
- squarePixelWidth: -1,
- squarePixelHeight: -1,
- codec: null,
- codecDescription: null,
- colorSpace: { ...Pl },
- avcType: null,
- avcCodecInfo: null,
- hevcCodecInfo: null,
- vp9CodecInfo: null,
- av1CodecInfo: null,
- proresCodecInfo: null,
- proresFormat: null,
- })
- : A === "soun" &&
- (P.info = {
- type: "audio",
- numberOfChannels: -1,
- sampleRate: -1,
- codec: null,
- codecDescription: null,
- aacCodecInfo: null,
- dtsFormat: null,
- pcmLittleEndian: !1,
- pcmSampleSize: null,
- });
- }
- break;
- case "stbl":
- {
- const P = this.currentTrack;
- if (!P) break;
- ((P.sampleTableByteOffset = t),
- this.readContiguousBoxes(e.slice(i, n.contentSize)));
- }
- break;
- case "stsd":
- {
- const P = this.currentTrack;
- if (!P || P.info === null || P.sampleTable) break;
- const A = Y(e);
- e.skip(3);
- const F = L(e);
- for (let D = 0; D < F; D++) {
- const $ = e.filePos,
- W = Cr(e);
- if (!W) break;
- P.internalCodecId = W.name;
- const Q = W.name.toLowerCase();
- if (P.info.type === "video") {
- (e.skip(24),
- (P.info.width = Ve(e)),
- (P.info.height = Ve(e)),
- (P.info.squarePixelWidth = P.info.width),
- (P.info.squarePixelHeight = P.info.height),
- e.skip(50),
- (P.frmaCodecString = null),
- this.readContiguousBoxes(
- e.slice(e.filePos, $ + W.totalSize - e.filePos),
- ));
- const re = Q === "encv" ? P.frmaCodecString : Q;
- ((P.frmaCodecString = null),
- re === "avc1" || re === "avc3"
- ? ((P.info.codec = "avc"),
- (P.info.avcType = re === "avc1" ? 1 : 3))
- : re === "hvc1" || re === "hev1"
- ? (P.info.codec = "hevc")
- : re === "vp08"
- ? (P.info.codec = "vp8")
- : re === "vp09"
- ? (P.info.codec = "vp9")
- : re === "av01"
- ? (P.info.codec = "av1")
- : qr.includes(Q)
- ? ((P.info.codec = "prores"),
- (P.info.proresFormat = Q))
- : re === null
- ? te._warn(
- "Unknown encrypted video codec due to missing frma box.",
- )
- : te._warn(
- `Unsupported video codec (sample entry type '${W.name}').`,
- ));
- } else {
- e.skip(8);
- const re = Ve(e);
- e.skip(6);
- let oe = Ve(e),
- ce = Ve(e);
- e.skip(4);
- let Se = L(e) / 65536,
- xe = null;
- (A === 0 &&
- re > 0 &&
- (re === 1
- ? (e.skip(4), (ce = 8 * L(e)), e.skip(8))
- : re === 2 &&
- (e.skip(4),
- (Se = Lu(e)),
- (oe = L(e)),
- e.skip(4),
- (ce = L(e)),
- (xe = L(e)),
- e.skip(8))),
- (P.info.numberOfChannels = oe),
- (P.info.sampleRate = Se),
- (P.frmaCodecString = null),
- this.readContiguousBoxes(
- e.slice(e.filePos, $ + W.totalSize - e.filePos),
- ));
- const ae = Q === "enca" ? P.frmaCodecString : Q;
- if (((P.frmaCodecString = null), ae !== "mp4a"))
- if (ae === "opus")
- ((P.info.codec = "opus"), (P.info.sampleRate = ms));
- else if (ae === "flac") P.info.codec = "flac";
- else if (ae === "ulaw") P.info.codec = "ulaw";
- else if (ae === "alaw") P.info.codec = "alaw";
- else if (ae === "ac-3") P.info.codec = "ac3";
- else if (ae === "ec-3") P.info.codec = "eac3";
- else if ($i.includes(ae))
- ((P.info.codec = "dts"), (P.info.dtsFormat = ae));
- else if (ae === "twos")
- ce === 8
- ? (P.info.codec = "pcm-s8")
- : ce === 16
- ? (P.info.codec = P.info.pcmLittleEndian
- ? "pcm-s16"
- : "pcm-s16be")
- : (te._warn(
- `Unsupported sample size ${ce} for codec 'twos'.`,
- ),
- (P.info.codec = null));
- else if (ae === "sowt")
- ce === 8
- ? (P.info.codec = "pcm-s8")
- : ce === 16
- ? (P.info.codec = "pcm-s16")
- : (te._warn(
- `Unsupported sample size ${ce} for codec 'sowt'.`,
- ),
- (P.info.codec = null));
- else if (ae === "raw ") P.info.codec = "pcm-u8";
- else if (ae === "in24")
- P.info.codec = P.info.pcmLittleEndian
- ? "pcm-s24"
- : "pcm-s24be";
- else if (ae === "in32")
- P.info.codec = P.info.pcmLittleEndian
- ? "pcm-s32"
- : "pcm-s32be";
- else if (ae === "fl32")
- P.info.codec = P.info.pcmLittleEndian
- ? "pcm-f32"
- : "pcm-f32be";
- else if (ae === "fl64")
- P.info.codec = P.info.pcmLittleEndian
- ? "pcm-f64"
- : "pcm-f64be";
- else if (ae === "ipcm") {
- const me = P.info.pcmSampleSize;
- P.info.pcmLittleEndian
- ? me === 16
- ? (P.info.codec = "pcm-s16")
- : me === 24
- ? (P.info.codec = "pcm-s24")
- : me === 32
- ? (P.info.codec = "pcm-s32")
- : (te._warn(`Invalid ipcm sample size ${me}.`),
- (P.info.codec = null))
- : me === 16
- ? (P.info.codec = "pcm-s16be")
- : me === 24
- ? (P.info.codec = "pcm-s24be")
- : me === 32
- ? (P.info.codec = "pcm-s32be")
- : (te._warn(`Invalid ipcm sample size ${me}.`),
- (P.info.codec = null));
- } else if (ae === "fpcm") {
- const me = P.info.pcmSampleSize;
- P.info.pcmLittleEndian
- ? me === 32
- ? (P.info.codec = "pcm-f32")
- : me === 64
- ? (P.info.codec = "pcm-f64")
- : (te._warn(`Invalid fpcm sample size ${me}.`),
- (P.info.codec = null))
- : me === 32
- ? (P.info.codec = "pcm-f32be")
- : me === 64
- ? (P.info.codec = "pcm-f64be")
- : (te._warn(`Invalid fpcm sample size ${me}.`),
- (P.info.codec = null));
- } else if (ae === "lpcm" && xe !== null) {
- const me = (ce + 7) >> 3,
- Re = !!(xe & 1),
- Xt = !!(xe & 2),
- Ti = xe & 4 ? -1 : 0;
- (ce > 0 &&
- ce <= 64 &&
- (Re
- ? ce === 32 &&
- (P.info.codec = Xt ? "pcm-f32be" : "pcm-f32")
- : Ti & (1 << (me - 1))
- ? me === 1
- ? (P.info.codec = "pcm-s8")
- : me === 2
- ? (P.info.codec = Xt ? "pcm-s16be" : "pcm-s16")
- : me === 3
- ? (P.info.codec = Xt ? "pcm-s24be" : "pcm-s24")
- : me === 4 &&
- (P.info.codec = Xt ? "pcm-s32be" : "pcm-s32")
- : me === 1 && (P.info.codec = "pcm-u8")),
- P.info.codec === null &&
- te._warn("Unsupported PCM format."));
- } else
- ae === null
- ? te._warn(
- "Unknown encrypted audio codec due to missing frma box.",
- )
- : te._warn(
- `Unsupported audio codec (sample entry type '${W.name}').`,
- );
- }
- e.filePos = $ + W.totalSize;
- }
- }
- break;
- case "frma":
- {
- const P = this.currentTrack;
- if (!P) break;
- const F = Ne(e, 4).toLowerCase();
- P.frmaCodecString = F;
- }
- break;
- case "schm":
- {
- const P = this.currentTrack;
- if (!P) break;
- e.skip(4);
- const A = Ne(e, 4);
- A === "cenc" || A === "cens" || A === "cbcs"
- ? (P.encryptionInfo = {
- scheme: A,
- defaultKid: null,
- defaultIsProtected: null,
- defaultPerSampleIvSize: null,
- defaultConstantIv: null,
- defaultCryptByteBlock: null,
- defaultSkipByteBlock: null,
- })
- : te._warn(`Unsupported encryption scheme '${A}'.`);
- }
- break;
- case "tenc":
- {
- const P = this.currentTrack;
- if (!P || !P.encryptionInfo) break;
- const A = Y(e);
- (e.skip(3), e.skip(1));
- const F = Y(e);
- if (
- (A > 0
- ? ((P.encryptionInfo.defaultCryptByteBlock = F >> 4),
- (P.encryptionInfo.defaultSkipByteBlock = F & 15))
- : ((P.encryptionInfo.defaultCryptByteBlock = 0),
- (P.encryptionInfo.defaultSkipByteBlock = 0)),
- (P.encryptionInfo.defaultIsProtected = Y(e) !== 0),
- (P.encryptionInfo.defaultPerSampleIvSize = Y(e)),
- (P.encryptionInfo.defaultKid = ri(Z(e, 16))),
- P.encryptionInfo.defaultIsProtected &&
- P.encryptionInfo.defaultPerSampleIvSize === 0)
- ) {
- const D = Y(e),
- $ = new Uint8Array(16);
- ($.set(Z(e, D), 0), (P.encryptionInfo.defaultConstantIv = $));
- }
- }
- break;
- case "avcC":
- {
- const P = this.currentTrack;
- if (!P || (T(P.info), n.contentSize === 0)) break;
- P.info.codecDescription = Z(e, n.contentSize);
- const A =
- (a = Ya(P.info.codecDescription)) == null
- ? void 0
- : a.sequenceParameterSets[0],
- F = A && bn(A);
- F && Yo(P, F.pixelAspectRatio);
- }
- break;
- case "hvcC":
- {
- const P = this.currentTrack;
- if (!P || (T(P.info), n.contentSize === 0)) break;
- P.info.codecDescription = Z(e, n.contentSize);
- const A =
- (c =
- (o = Dl(P.info.codecDescription)) == null
- ? void 0
- : o.arrays.find((D) => D.nalUnitType === ze.SPS_NUT)) == null
- ? void 0
- : c.nalUnits[0],
- F = A && us(A);
- F && Yo(P, F.pixelAspectRatio);
- }
- break;
- case "vpcC":
- {
- const P = this.currentTrack;
- if (!P) break;
- (T(((u = P.info) == null ? void 0 : u.type) === "video"), e.skip(4));
- const A = Y(e),
- F = Y(e),
- D = Y(e),
- $ = D >> 4,
- W = (D >> 1) & 7,
- Q = D & 1,
- re = Y(e),
- oe = Y(e),
- ce = Y(e);
- P.info.vp9CodecInfo = {
- profile: A,
- level: F,
- bitDepth: $,
- chromaSubsampling: W,
- videoFullRangeFlag: Q,
- colourPrimaries: re,
- transferCharacteristics: oe,
- matrixCoefficients: ce,
- };
- }
- break;
- case "av1C":
- {
- const P = this.currentTrack;
- if (!P) break;
- (T(((l = P.info) == null ? void 0 : l.type) === "video"), e.skip(1));
- const A = Y(e),
- F = A >> 5,
- D = A & 31,
- $ = Y(e),
- W = $ >> 7,
- Q = ($ >> 6) & 1,
- re = ($ >> 5) & 1,
- oe = ($ >> 4) & 1,
- ce = ($ >> 3) & 1,
- Se = ($ >> 2) & 1,
- xe = $ & 3,
- ae = F === 2 && Q ? (re ? 12 : 10) : Q ? 10 : 8;
- e.skip(1);
- const me = Z(e, n.contentSize - 4),
- Re = ds(me);
- P.info.av1CodecInfo = {
- profile: F,
- level: D,
- tier: W,
- bitDepth: ae,
- monochrome: oe,
- chromaSubsamplingX: ce,
- chromaSubsamplingY: Se,
- chromaSamplePosition: xe,
- videoFullRangeFlag:
- (Re == null ? void 0 : Re.videoFullRangeFlag) ?? 0,
- colourPrimaries: (Re == null ? void 0 : Re.colourPrimaries) ?? 2,
- transferCharacteristics:
- (Re == null ? void 0 : Re.transferCharacteristics) ?? 2,
- matrixCoefficients:
- (Re == null ? void 0 : Re.matrixCoefficients) ?? 2,
- };
- }
- break;
- case "colr":
- {
- const P = this.currentTrack;
- if (!P) break;
- T(((d = P.info) == null ? void 0 : d.type) === "video");
- const A = Ne(e, 4);
- if (A !== "nclx" && A !== "nclc") break;
- const F = Ve(e),
- D = Ve(e),
- $ = Ve(e);
- let W;
- (A === "nclx" && (W = !!(Y(e) & 128)),
- (P.info.colorSpace = {
- primaries: rr[F],
- transfer: nr[D],
- matrix: ir[$],
- fullRange: W,
- }));
- }
- break;
- case "pasp":
- {
- const P = this.currentTrack;
- if (!P) break;
- T(((f = P.info) == null ? void 0 : f.type) === "video");
- const A = L(e),
- F = L(e);
- A > 0 &&
- F > 0 &&
- ((P.info.squarePixelWidth = P.info.width),
- (P.info.squarePixelHeight = P.info.height),
- A > F
- ? (P.info.squarePixelWidth = Math.round((P.info.width * A) / F))
- : (P.info.squarePixelHeight = Math.round(
- (P.info.height * F) / A,
- )));
- }
- break;
- case "btrt":
- {
- const P = this.currentTrack;
- if (!P) break;
- e.skip(4);
- const A = L(e),
- F = L(e);
- ((P.maxBitrate = A > 0 ? A : null),
- (P.avgBitrate = F > 0 ? F : null));
- }
- break;
- case "wave":
- this.readContiguousBoxes(e.slice(i, n.contentSize));
- break;
- case "esds":
- {
- const P = this.currentTrack;
- if (!P || ((h = P.info) == null ? void 0 : h.type) !== "audio") break;
- e.skip(4);
- const A = Y(e);
- (T(A === 3), Os(e), e.skip(2));
- const F = Y(e),
- D = (F & 128) !== 0,
- $ = (F & 64) !== 0,
- W = (F & 32) !== 0;
- if ((D && e.skip(2), $)) {
- const Se = Y(e);
- e.skip(Se);
- }
- W && e.skip(2);
- const Q = Y(e);
- T(Q === 4);
- const re = Os(e),
- oe = e.filePos,
- ce = Y(e);
- if (
- (ce === 64 || ce === 103
- ? ((P.info.codec = "aac"),
- (P.info.aacCodecInfo = {
- isMpeg2: ce === 103,
- objectType: null,
- }))
- : ce === 105 || ce === 107
- ? (P.info.codec = "mp3")
- : ce === 221
- ? (P.info.codec = "vorbis")
- : ce === 169
- ? (P.info.codec = "dts")
- : te._warn(
- `Unsupported audio codec (objectTypeIndication ${ce}) - discarding track.`,
- ),
- e.skip(12),
- re > e.filePos - oe)
- ) {
- const Se = Y(e);
- T(Se === 5);
- const xe = Os(e);
- if (
- ((P.info.codecDescription = Z(e, xe)), P.info.codec === "aac")
- ) {
- const ae = Xa(P.info.codecDescription);
- (ae.outputNumberOfChannels !== null &&
- (P.info.numberOfChannels = ae.outputNumberOfChannels),
- ae.outputSampleRate !== null &&
- (P.info.sampleRate = ae.outputSampleRate));
- }
- }
- }
- break;
- case "enda":
- {
- const P = this.currentTrack;
- if (!P) break;
- (T(((p = P.info) == null ? void 0 : p.type) === "audio"),
- (P.info.pcmLittleEndian = !!(Ve(e) & 255)));
- }
- break;
- case "pcmC":
- {
- const P = this.currentTrack;
- if (!P) break;
- (T(((m = P.info) == null ? void 0 : m.type) === "audio"), e.skip(4));
- const A = Y(e);
- ((P.info.pcmLittleEndian = !!(A & 1)), (P.info.pcmSampleSize = Y(e)));
- }
- break;
- case "dOps":
- {
- const P = this.currentTrack;
- if (!P) break;
- (T(((b = P.info) == null ? void 0 : b.type) === "audio"), e.skip(1));
- const A = Y(e),
- F = Ve(e),
- D = L(e),
- $ = Na(e),
- W = Y(e);
- let Q;
- W !== 0 ? (Q = Z(e, 2 + A)) : (Q = new Uint8Array(0));
- const re = new Uint8Array(19 + Q.byteLength),
- oe = new DataView(re.buffer);
- (oe.setUint32(0, 1332770163, !1),
- oe.setUint32(4, 1214603620, !1),
- oe.setUint8(8, 1),
- oe.setUint8(9, A),
- oe.setUint16(10, F, !0),
- oe.setUint32(12, D, !0),
- oe.setInt16(16, $, !0),
- oe.setUint8(18, W),
- re.set(Q, 19),
- (P.info.codecDescription = re),
- (P.info.numberOfChannels = A));
- }
- break;
- case "dfLa":
- {
- const P = this.currentTrack;
- if (!P) break;
- (T(((g = P.info) == null ? void 0 : g.type) === "audio"), e.skip(4));
- const A = 127,
- F = 128,
- D = e.filePos;
- for (; e.filePos < s;) {
- const oe = Y(e),
- ce = Zt(e);
- if ((oe & A) === hn.STREAMINFO) {
- e.skip(10);
- const xe = L(e),
- ae = xe >>> 12,
- me = ((xe >> 9) & 7) + 1;
- ((P.info.sampleRate = ae),
- (P.info.numberOfChannels = me),
- e.skip(20));
- } else e.skip(ce);
- if (oe & F) break;
- }
- const $ = e.filePos;
- e.filePos = D;
- const W = Z(e, $ - D),
- Q = new Uint8Array(4 + W.byteLength);
- (new DataView(Q.buffer).setUint32(0, 1716281667, !1),
- Q.set(W, 4),
- (P.info.codecDescription = Q));
- }
- break;
- case "dac3":
- {
- const P = this.currentTrack;
- if (!P) break;
- T(((y = P.info) == null ? void 0 : y.type) === "audio");
- const A = Z(e, 3),
- F = new pe(A),
- D = F.readBits(2);
- F.skipBits(8);
- const $ = F.readBits(3),
- W = F.readBits(1);
- (D < 3 && (P.info.sampleRate = cs[D]),
- (P.info.numberOfChannels = Ja[$] + W));
- }
- break;
- case "dec3":
- {
- const P = this.currentTrack;
- if (!P) break;
- T(((C = P.info) == null ? void 0 : C.type) === "audio");
- const A = Z(e, n.contentSize),
- F = fh(A);
- if (!F) {
- te._warn("Invalid dec3 box contents, ignoring.");
- break;
- }
- const D = jl(F);
- (D !== null && (P.info.sampleRate = D),
- (P.info.numberOfChannels = $l(F)));
- }
- break;
- case "ddts":
- {
- const P = this.currentTrack;
- if (!P) break;
- T(((_ = P.info) == null ? void 0 : _.type) === "audio");
- const A = Z(e, Math.min(n.contentSize, eo)),
- F = Ph(A);
- if (!F) {
- te._warn("Invalid ddts box contents, ignoring.");
- break;
- }
- ((P.info.sampleRate = F.sampleRate),
- F.numberOfChannels !== null &&
- (P.info.numberOfChannels = F.numberOfChannels));
- }
- break;
- case "stts":
- {
- const P = this.currentTrack;
- if (!P || !P.sampleTable) break;
- e.skip(4);
- const A = L(e);
- let F = 0,
- D = 0;
- for (let $ = 0; $ < A; $++) {
- const W = L(e),
- Q = L(e);
- (P.sampleTable.sampleTimingEntries.push({
- startIndex: F,
- startDecodeTimestamp: D,
- count: W,
- delta: Q,
- }),
- (F += W),
- (D += W * Q));
- }
- }
- break;
- case "ctts":
- {
- const P = this.currentTrack;
- if (!P || !P.sampleTable) break;
- e.skip(4);
- const A = L(e);
- let F = 0;
- for (let D = 0; D < A; D++) {
- const $ = L(e),
- W = Vr(e);
- (P.sampleTable.sampleCompositionTimeOffsets.push({
- startIndex: F,
- count: $,
- offset: W,
- }),
- (F += $));
- }
- }
- break;
- case "stsz":
- {
- const P = this.currentTrack;
- if (!P || !P.sampleTable) break;
- e.skip(4);
- const A = L(e),
- F = L(e);
- if (A === 0)
- for (let D = 0; D < F; D++) {
- const $ = L(e);
- P.sampleTable.sampleSizes.push($);
- }
- else P.sampleTable.sampleSizes.push(A);
- }
- break;
- case "stz2":
- {
- const P = this.currentTrack;
- if (!P || !P.sampleTable) break;
- (e.skip(4), e.skip(3));
- const A = Y(e),
- F = L(e),
- D = Z(e, Math.ceil((F * A) / 8)),
- $ = new pe(D);
- for (let W = 0; W < F; W++) {
- const Q = $.readBits(A);
- P.sampleTable.sampleSizes.push(Q);
- }
- }
- break;
- case "stss":
- {
- const P = this.currentTrack;
- if (!P || !P.sampleTable) break;
- (e.skip(4), (P.sampleTable.keySampleIndices = []));
- const A = L(e);
- for (let F = 0; F < A; F++) {
- const D = L(e) - 1;
- P.sampleTable.keySampleIndices.push(D);
- }
- P.sampleTable.keySampleIndices[0] !== 0 &&
- P.sampleTable.keySampleIndices.unshift(0);
- }
- break;
- case "stsc":
- {
- const P = this.currentTrack;
- if (!P || !P.sampleTable) break;
- e.skip(4);
- const A = L(e);
- for (let D = 0; D < A; D++) {
- const $ = L(e) - 1,
- W = L(e),
- Q = L(e);
- P.sampleTable.sampleToChunk.push({
- startSampleIndex: -1,
- startChunkIndex: $,
- samplesPerChunk: W,
- sampleDescriptionIndex: Q,
- });
- }
- let F = 0;
- for (let D = 0; D < P.sampleTable.sampleToChunk.length; D++)
- if (
- ((P.sampleTable.sampleToChunk[D].startSampleIndex = F),
- D < P.sampleTable.sampleToChunk.length - 1)
- ) {
- const W =
- P.sampleTable.sampleToChunk[D + 1].startChunkIndex -
- P.sampleTable.sampleToChunk[D].startChunkIndex;
- F += W * P.sampleTable.sampleToChunk[D].samplesPerChunk;
- }
- }
- break;
- case "stco":
- {
- const P = this.currentTrack;
- if (!P || !P.sampleTable) break;
- e.skip(4);
- const A = L(e);
- for (let F = 0; F < A; F++) {
- const D = L(e);
- P.sampleTable.chunkOffsets.push(D);
- }
- }
- break;
- case "co64":
- {
- const P = this.currentTrack;
- if (!P || !P.sampleTable) break;
- e.skip(4);
- const A = L(e);
- for (let F = 0; F < A; F++) {
- const D = ft(e);
- P.sampleTable.chunkOffsets.push(D);
- }
- }
- break;
- case "mvex":
- ((this.isFragmented = !0),
- this.readContiguousBoxes(e.slice(i, n.contentSize)));
- break;
- case "mehd":
- {
- const P = Y(e);
- e.skip(3);
- const A = P === 1 ? ft(e) : L(e);
- this.movieDurationInTimescale = A;
- }
- break;
- case "trex":
- {
- e.skip(4);
- const P = L(e),
- A = L(e),
- F = L(e),
- D = L(e),
- $ = L(e);
- this.fragmentTrackDefaults.push({
- trackId: P,
- defaultSampleDescriptionIndex: A,
- defaultSampleDuration: F,
- defaultSampleSize: D,
- defaultSampleFlags: $,
- });
- }
- break;
- case "tfra":
- {
- const P = Y(e);
- e.skip(3);
- const A = L(e),
- F = this.tracks.find((ae) => ae.id === A);
- if (!F) break;
- const D = L(e),
- $ = (D & 48) >> 4,
- W = (D & 12) >> 2,
- Q = D & 3,
- re = [Y, Ve, Zt, L],
- oe = re[$],
- ce = re[W],
- Se = re[Q],
- xe = L(e);
- for (let ae = 0; ae < xe; ae++) {
- const me = P === 1 ? ft(e) : L(e),
- Re = P === 1 ? ft(e) : L(e);
- (oe(e),
- ce(e),
- Se(e),
- F.fragmentLookupTable.push({ timestamp: me, moofOffset: Re }));
- }
- F.fragmentLookupTable.sort((ae, me) => ae.timestamp - me.timestamp);
- for (let ae = 0; ae < F.fragmentLookupTable.length - 1; ae++) {
- const me = F.fragmentLookupTable[ae],
- Re = F.fragmentLookupTable[ae + 1];
- me.timestamp === Re.timestamp &&
- (F.fragmentLookupTable.splice(ae + 1, 1), ae--);
- }
- }
- break;
- case "moof":
- ((this.currentFragment = {
- moofOffset: t,
- moofSize: n.totalSize,
- implicitBaseDataOffset: t,
- trackData: new Map(),
- psshBoxes: [],
- }),
- this.readContiguousBoxes(e.slice(i, n.contentSize)),
- (this.lastReadFragment = this.currentFragment),
- (this.currentFragment = null));
- break;
- case "traf":
- if (
- (T(this.currentFragment),
- this.readContiguousBoxes(e.slice(i, n.contentSize)),
- this.currentTrack)
- ) {
- const P = this.currentFragment.trackData.get(this.currentTrack.id);
- e: if (P) {
- if (P.samples.length === 0) {
- this.currentFragment.trackData.delete(this.currentTrack.id);
- break e;
- }
- P.presentationTimestamps = P.samples
- .map(($, W) => ({
- presentationTimestamp: $.presentationTimestamp,
- sampleIndex: W,
- }))
- .sort(
- ($, W) => $.presentationTimestamp - W.presentationTimestamp,
- );
- for (let $ = 0; $ < P.presentationTimestamps.length; $++) {
- const W = P.presentationTimestamps[$],
- Q = P.samples[W.sampleIndex];
- if (
- (P.firstKeyFrameTimestamp === null &&
- Q.isKeyFrame &&
- (P.firstKeyFrameTimestamp = Q.presentationTimestamp),
- $ < P.presentationTimestamps.length - 1)
- ) {
- const oe =
- P.presentationTimestamps[$ + 1].presentationTimestamp -
- W.presentationTimestamp;
- Q.duration = oe;
- }
- }
- const A = P.samples[P.presentationTimestamps[0].sampleIndex],
- F = P.samples[Ae(P.presentationTimestamps).sampleIndex];
- ((P.startTimestamp = A.presentationTimestamp),
- (P.endTimestamp = F.presentationTimestamp + F.duration));
- const { currentFragmentState: D } = this.currentTrack;
- (T(D),
- D.startTimestamp !== null &&
- (Ds(P, D.startTimestamp), (P.startTimestampIsFinal = !0)),
- D.encryptionAuxInfo &&
- !P.samples[0].encryption &&
- (P.encryptionAuxInfo = D.encryptionAuxInfo));
- }
- ((this.currentTrack.currentFragmentState = null),
- (this.currentTrack = null));
- }
- break;
- case "pssh":
- {
- if (
- (v = this.input._formatOptions.isobmff) != null &&
- v._suppressPsshParsing
- )
- break;
- const P = iu(Z(e, n.contentSize));
- this.currentFragment
- ? this.currentFragment.psshBoxes.push(P)
- : this.currentTrack || this.psshBoxes.push(P);
- }
- break;
- case "tfhd":
- {
- (T(this.currentFragment), e.skip(1));
- const P = Zt(e),
- A = !!(P & 1),
- F = !!(P & 2),
- D = !!(P & 8),
- $ = !!(P & 16),
- W = !!(P & 32),
- Q = !!(P & 65536),
- re = !!(P & 131072),
- oe = L(e),
- ce = this.tracks.find((xe) => xe.id === oe);
- if (!ce) break;
- const Se = this.fragmentTrackDefaults.find((xe) => xe.trackId === oe);
- ((this.currentTrack = ce),
- (ce.currentFragmentState = {
- baseDataOffset: this.currentFragment.implicitBaseDataOffset,
- sampleDescriptionIndex:
- (Se == null ? void 0 : Se.defaultSampleDescriptionIndex) ??
- null,
- defaultSampleDuration:
- (Se == null ? void 0 : Se.defaultSampleDuration) ?? null,
- defaultSampleSize:
- (Se == null ? void 0 : Se.defaultSampleSize) ?? null,
- defaultSampleFlags:
- (Se == null ? void 0 : Se.defaultSampleFlags) ?? null,
- startTimestamp: null,
- encryptionAuxInfo: null,
- }),
- A
- ? (ce.currentFragmentState.baseDataOffset = ft(e))
- : re &&
- (ce.currentFragmentState.baseDataOffset =
- this.currentFragment.moofOffset),
- F && (ce.currentFragmentState.sampleDescriptionIndex = L(e)),
- D && (ce.currentFragmentState.defaultSampleDuration = L(e)),
- $ && (ce.currentFragmentState.defaultSampleSize = L(e)),
- W && (ce.currentFragmentState.defaultSampleFlags = L(e)),
- Q && (ce.currentFragmentState.defaultSampleDuration = 0));
- }
- break;
- case "tfdt":
- {
- const P = this.currentTrack;
- if (!P) break;
- T(P.currentFragmentState);
- const A = Y(e);
- e.skip(3);
- const F = A === 0 ? L(e) : ft(e);
- P.currentFragmentState.startTimestamp = F;
- }
- break;
- case "trun":
- {
- const P = this.currentTrack;
- if (!P) break;
- (T(this.currentFragment), T(P.currentFragmentState), e.skip(1));
- const A = Zt(e),
- F = !!(A & 1),
- D = !!(A & 4),
- $ = !!(A & 256),
- W = !!(A & 512),
- Q = !!(A & 1024),
- re = !!(A & 2048),
- oe = L(e);
- let ce = null;
- F && (ce = Vr(e));
- let Se = null;
- D && (Se = L(e));
- let xe;
- this.currentFragment.trackData.has(P.id)
- ? ((xe = this.currentFragment.trackData.get(P.id)),
- ce !== null &&
- (xe.currentOffset = P.currentFragmentState.baseDataOffset + ce))
- : ((xe = {
- track: P,
- currentTimestamp: 0,
- currentOffset:
- P.currentFragmentState.baseDataOffset + (ce ?? 0),
- startTimestamp: 0,
- endTimestamp: 0,
- firstKeyFrameTimestamp: null,
- samples: [],
- presentationTimestamps: [],
- startTimestampIsFinal: !1,
- encryptionAuxInfo: null,
- }),
- this.currentFragment.trackData.set(P.id, xe));
- for (let ae = 0; ae < oe; ae++) {
- let me;
- $
- ? (me = L(e))
- : (T(P.currentFragmentState.defaultSampleDuration !== null),
- (me = P.currentFragmentState.defaultSampleDuration));
- let Re;
- W
- ? (Re = L(e))
- : (T(P.currentFragmentState.defaultSampleSize !== null),
- (Re = P.currentFragmentState.defaultSampleSize));
- let Xt;
- (Q
- ? (Xt = L(e))
- : (T(P.currentFragmentState.defaultSampleFlags !== null),
- (Xt = P.currentFragmentState.defaultSampleFlags)),
- ae === 0 && Se !== null && (Xt = Se));
- let Ti = 0;
- re && (Ti = Vr(e));
- const sd = !(Xt & 65536);
- (xe.samples.push({
- presentationTimestamp: xe.currentTimestamp + Ti,
- duration: me,
- byteOffset: xe.currentOffset,
- byteSize: Re,
- isKeyFrame: sd,
- encryption: null,
- }),
- (xe.currentOffset += Re),
- (xe.currentTimestamp += me));
- }
- this.currentFragment.implicitBaseDataOffset = xe.currentOffset;
- }
- break;
- case "saiz":
- {
- const P = this.currentTrack;
- if (!P || !P.encryptionInfo) break;
- if ((e.skip(1), Zt(e) & 1)) {
- const Q = Ne(e, 4),
- re = L(e);
- if (Q !== P.encryptionInfo.scheme || re !== 0) break;
- }
- const F = Y(e),
- D = L(e);
- let $ = null;
- F === 0 && D > 0 && ($ = Z(e, D));
- const W = Jo(P);
- ((W.defaultSampleInfoSize = F),
- (W.sampleSizes = $),
- (W.sampleCount = D));
- }
- break;
- case "saio":
- {
- const P = this.currentTrack;
- if (!P || !P.encryptionInfo) break;
- const A = Y(e);
- if (Zt(e) & 1) {
- const Q = Ne(e, 4),
- re = L(e);
- if (Q !== P.encryptionInfo.scheme || re !== 0) break;
- }
- const D = L(e);
- if (D === 0) break;
- D > 1 &&
- te._warn(
- "Multiple saio entries are not supported; using the first offset only.",
- );
- let $ = A === 0 ? L(e) : Number(ft(e));
- this.currentFragment && ($ += this.currentFragment.moofOffset);
- const W = Jo(P);
- W.offset = $;
- }
- break;
- case "senc":
- {
- const P = this.currentTrack;
- if (!P || !P.encryptionInfo) break;
- T(this.currentFragment);
- const A = this.currentFragment.trackData.get(P.id);
- if (!A) break;
- e.skip(1);
- const D = !!(Zt(e) & 2),
- $ = L(e),
- W = P.encryptionInfo.defaultPerSampleIvSize;
- T(W !== null);
- for (let Q = 0; Q < Math.min($, A.samples.length); Q++) {
- const re = new Uint8Array(16);
- W > 0
- ? re.set(Z(e, W), 0)
- : re.set(P.encryptionInfo.defaultConstantIv, 0);
- let oe = null;
- if (D) {
- const Se = Ve(e);
- oe = [];
- for (let xe = 0; xe < Se; xe++) {
- const ae = Ve(e),
- me = L(e);
- oe.push({ clearLen: ae, protectedLen: me });
- }
- }
- const ce = A.samples[Q];
- ce.encryption = { iv: re, subsamples: oe };
- }
- }
- break;
- case "udta":
- {
- const P = this.iterateContiguousBoxes(e.slice(i, n.contentSize));
- for (const { boxInfo: A, slice: F } of P) {
- if (A.name !== "meta" && !this.currentTrack) {
- const D = F.filePos;
- ((I = this.metadataTags).raw ?? (I.raw = {}),
- A.name[0] === "©"
- ? ((w = this.metadataTags.raw)[(x = A.name)] ??
- (w[x] = Dt(F)))
- : ((k = this.metadataTags.raw)[(S = A.name)] ??
- (k[S] = Z(F, A.contentSize))),
- (F.filePos = D));
- }
- switch (A.name) {
- case "meta":
- (F.skip(-A.headerSize), this.traverseBox(F));
- break;
- case "©nam":
- case "name":
- this.currentTrack
- ? (this.currentTrack.name = ot.decode(Z(F, A.contentSize)))
- : ((E = this.metadataTags).title ?? (E.title = Dt(F)));
- break;
- case "©des":
- this.currentTrack ||
- ((B = this.metadataTags).description ??
- (B.description = Dt(F)));
- break;
- case "©ART":
- this.currentTrack ||
- ((R = this.metadataTags).artist ?? (R.artist = Dt(F)));
- break;
- case "©alb":
- this.currentTrack ||
- ((M = this.metadataTags).album ?? (M.album = Dt(F)));
- break;
- case "albr":
- this.currentTrack ||
- ((z = this.metadataTags).albumArtist ??
- (z.albumArtist = Dt(F)));
- break;
- case "©gen":
- this.currentTrack ||
- ((q = this.metadataTags).genre ?? (q.genre = Dt(F)));
- break;
- case "©day":
- if (!this.currentTrack) {
- const D = new Date(Dt(F));
- Number.isNaN(D.getTime()) ||
- ((j = this.metadataTags).date ?? (j.date = D));
- }
- break;
- case "©cmt":
- this.currentTrack ||
- ((se = this.metadataTags).comment ?? (se.comment = Dt(F)));
- break;
- case "©lyr":
- this.currentTrack ||
- ((le = this.metadataTags).lyrics ?? (le.lyrics = Dt(F)));
- break;
- }
- }
- }
- break;
- case "meta":
- {
- if (this.currentTrack) break;
- const A = L(e) !== 0;
- ((this.currentMetadataKeys = new Map()),
- A
- ? this.readContiguousBoxes(e.slice(i, n.contentSize))
- : this.readContiguousBoxes(e.slice(i + 4, n.contentSize - 4)),
- (this.currentMetadataKeys = null));
- }
- break;
- case "keys":
- {
- if (!this.currentMetadataKeys) break;
- e.skip(4);
- const P = L(e);
- for (let A = 0; A < P; A++) {
- const F = L(e);
- e.skip(4);
- const D = ot.decode(Z(e, F - 8));
- this.currentMetadataKeys.set(A + 1, D);
- }
- }
- break;
- case "ilst":
- {
- if (!this.currentMetadataKeys) break;
- const P = this.iterateContiguousBoxes(e.slice(i, n.contentSize));
- for (const { boxInfo: A, slice: F } of P) {
- let D = A.name;
- const $ =
- (D.charCodeAt(0) << 24) +
- (D.charCodeAt(1) << 16) +
- (D.charCodeAt(2) << 8) +
- D.charCodeAt(3);
- this.currentMetadataKeys.has($) &&
- (D = this.currentMetadataKeys.get($));
- const W = qh(F);
- switch (
- ((ue = this.metadataTags).raw ?? (ue.raw = {}),
- ($e = this.metadataTags.raw)[D] ?? ($e[D] = W),
- D)
- ) {
- case "©nam":
- case "titl":
- case "com.apple.quicktime.title":
- case "title":
- typeof W == "string" &&
- ((K = this.metadataTags).title ?? (K.title = W));
- break;
- case "©des":
- case "desc":
- case "dscp":
- case "com.apple.quicktime.description":
- case "description":
- typeof W == "string" &&
- ((ie = this.metadataTags).description ??
- (ie.description = W));
- break;
- case "©ART":
- case "com.apple.quicktime.artist":
- case "artist":
- typeof W == "string" &&
- ((Ie = this.metadataTags).artist ?? (Ie.artist = W));
- break;
- case "©alb":
- case "albm":
- case "com.apple.quicktime.album":
- case "album":
- typeof W == "string" &&
- ((Ge = this.metadataTags).album ?? (Ge.album = W));
- break;
- case "aART":
- case "album_artist":
- typeof W == "string" &&
- ((Fe = this.metadataTags).albumArtist ??
- (Fe.albumArtist = W));
- break;
- case "©cmt":
- case "com.apple.quicktime.comment":
- case "comment":
- typeof W == "string" &&
- ((je = this.metadataTags).comment ?? (je.comment = W));
- break;
- case "©gen":
- case "gnre":
- case "com.apple.quicktime.genre":
- case "genre":
- typeof W == "string" &&
- ((He = this.metadataTags).genre ?? (He.genre = W));
- break;
- case "©lyr":
- case "lyrics":
- typeof W == "string" &&
- ((we = this.metadataTags).lyrics ?? (we.lyrics = W));
- break;
- case "©day":
- case "rldt":
- case "com.apple.quicktime.creationdate":
- case "date":
- if (typeof W == "string") {
- const Q = new Date(W);
- Number.isNaN(Q.getTime()) ||
- ((Oe = this.metadataTags).date ?? (Oe.date = Q));
- }
- break;
- case "tmpo":
- if (W instanceof Uint8Array && W.length >= 2) {
- const Q = ge(W).getInt16(0, !1);
- Q > 0 &&
- ((st = this.metadataTags).beatsPerMinute ??
- (st.beatsPerMinute = Q));
- }
- break;
- case "covr":
- case "com.apple.quicktime.artwork":
- W instanceof fn
- ? ((_t = this.metadataTags).images ?? (_t.images = []),
- this.metadataTags.images.push({
- data: W.data,
- kind: "coverFront",
- mimeType: W.mimeType,
- }))
- : W instanceof Uint8Array &&
- ((At = this.metadataTags).images ?? (At.images = []),
- this.metadataTags.images.push({
- data: W,
- kind: "coverFront",
- mimeType: "image/*",
- }));
- break;
- case "track":
- if (typeof W == "string") {
- const Q = W.split("/"),
- re = Number.parseInt(Q[0], 10),
- oe = Q[1] && Number.parseInt(Q[1], 10);
- (Number.isInteger(re) &&
- re > 0 &&
- ((Ot = this.metadataTags).trackNumber ??
- (Ot.trackNumber = re)),
- oe &&
- Number.isInteger(oe) &&
- oe > 0 &&
- ((wr = this.metadataTags).tracksTotal ??
- (wr.tracksTotal = oe)));
- }
- break;
- case "trkn":
- if (W instanceof Uint8Array && W.length >= 6) {
- const Q = ge(W),
- re = Q.getUint16(2, !1),
- oe = Q.getUint16(4, !1);
- (re > 0 &&
- ((En = this.metadataTags).trackNumber ??
- (En.trackNumber = re)),
- oe > 0 &&
- ((In = this.metadataTags).tracksTotal ??
- (In.tracksTotal = oe)));
- }
- break;
- case "disc":
- case "disk":
- if (W instanceof Uint8Array && W.length >= 6) {
- const Q = ge(W),
- re = Q.getUint16(2, !1),
- oe = Q.getUint16(4, !1);
- (re > 0 &&
- ((_n = this.metadataTags).discNumber ??
- (_n.discNumber = re)),
- oe > 0 &&
- ((An = this.metadataTags).discsTotal ??
- (An.discsTotal = oe)));
- }
- break;
- }
- }
- }
- break;
- }
- return ((e.filePos = s), !0);
- }
-}
-class lu {
- constructor(e) {
- ((this.internalTrack = e),
- (this.packetToSampleIndex = new WeakMap()),
- (this.packetToFragmentLocation = new WeakMap()));
- }
- getId() {
- return this.internalTrack.id;
- }
- getNumber() {
- const e = this.internalTrack.demuxer,
- t = this.internalTrack.trackBacking.getType();
- let n = 0;
- for (const i of e.tracks)
- if ((i.trackBacking.getType() === t && n++, i === this.internalTrack))
- break;
- return n;
- }
- getCodec() {
- throw new Error("Not implemented on base class.");
- }
- getInternalCodecId() {
- return this.internalTrack.internalCodecId;
- }
- getName() {
- return this.internalTrack.name;
- }
- getLanguageCode() {
- return this.internalTrack.languageCode;
- }
- getTimeResolution() {
- return this.internalTrack.timescale;
- }
- isRelativeToUnixEpoch() {
- return !1;
- }
- getUnixTimeForTimestamp() {
- return null;
- }
- getDisposition() {
- return this.internalTrack.disposition;
- }
- getPairingMask() {
- return 1n;
- }
- getBitrate() {
- return this.internalTrack.maxBitrate;
- }
- getAverageBitrate() {
- return this.internalTrack.avgBitrate;
- }
- async getDurationFromMetadata() {
- const e = this.internalTrack;
- if (e.durationInMediaTimescale <= 0) return null;
- T(e.trackBacking);
- const t = await e.trackBacking.getFirstPacket({ metadataOnly: !0 });
- return (
- ((t == null ? void 0 : t.timestamp) ?? 0) +
- e.durationInMediaTimescale / e.timescale
- );
- }
- async getLiveRefreshInterval() {
- return null;
- }
- async getFirstPacket(e) {
- const t = await this.fetchPacketForSampleIndex(0, e);
- return t || !this.internalTrack.demuxer.isFragmented
- ? t
- : this.performFragmentedLookup(
- null,
- (n) =>
- n.trackData.get(this.internalTrack.id)
- ? { sampleIndex: 0, correctSampleFound: !0 }
- : { sampleIndex: -1, correctSampleFound: !1 },
- -1 / 0,
- 1 / 0,
- e,
- );
- }
- mapTimestampIntoTimescale(e) {
- return (
- ni(e * this.internalTrack.timescale) + this.internalTrack.editListOffset
- );
- }
- async getPacket(e, t) {
- const n = this.mapTimestampIntoTimescale(e),
- i = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),
- s = Ca(i, n),
- a = await this.fetchPacketForSampleIndex(s, t);
- return !Zo(i) || !this.internalTrack.demuxer.isFragmented
- ? a
- : this.performFragmentedLookup(
- null,
- (o) => {
- const c = o.trackData.get(this.internalTrack.id);
- if (!c) return { sampleIndex: -1, correctSampleFound: !1 };
- const u = ke(
- c.presentationTimestamps,
- n,
- (f) => f.presentationTimestamp,
- ),
- l = u !== -1 ? c.presentationTimestamps[u].sampleIndex : -1,
- d = u !== -1 && n < c.endTimestamp;
- return { sampleIndex: l, correctSampleFound: d };
- },
- n,
- n,
- t,
- );
- }
- async getNextPacket(e, t) {
- const n = this.packetToSampleIndex.get(e);
- if (n !== void 0) return this.fetchPacketForSampleIndex(n + 1, t);
- const i = this.packetToFragmentLocation.get(e);
- if (i === void 0)
- throw new Error("Packet was not created from this track.");
- return this.performFragmentedLookup(
- i.fragment,
- (s) => {
- if (s === i.fragment) {
- const a = s.trackData.get(this.internalTrack.id);
- if (i.sampleIndex + 1 < a.samples.length)
- return { sampleIndex: i.sampleIndex + 1, correctSampleFound: !0 };
- } else if (s.trackData.get(this.internalTrack.id))
- return { sampleIndex: 0, correctSampleFound: !0 };
- return { sampleIndex: -1, correctSampleFound: !1 };
- },
- -1 / 0,
- 1 / 0,
- t,
- );
- }
- async getKeyPacket(e, t) {
- const n = this.mapTimestampIntoTimescale(e),
- i = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),
- s = Gh(i, n),
- a = await this.fetchPacketForSampleIndex(s, t);
- return !Zo(i) || !this.internalTrack.demuxer.isFragmented
- ? a
- : this.performFragmentedLookup(
- null,
- (o) => {
- const c = o.trackData.get(this.internalTrack.id);
- if (!c) return { sampleIndex: -1, correctSampleFound: !1 };
- const u = Va(
- c.presentationTimestamps,
- (f) =>
- c.samples[f.sampleIndex].isKeyFrame &&
- f.presentationTimestamp <= n,
- ),
- l = u !== -1 ? c.presentationTimestamps[u].sampleIndex : -1,
- d = u !== -1 && n < c.endTimestamp;
- return { sampleIndex: l, correctSampleFound: d };
- },
- n,
- n,
- t,
- );
- }
- async getNextKeyPacket(e, t) {
- const n = this.packetToSampleIndex.get(e);
- if (n !== void 0) {
- const s = this.internalTrack.demuxer.getSampleTableForTrack(
- this.internalTrack,
- ),
- a = Xh(s, n);
- return this.fetchPacketForSampleIndex(a, t);
- }
- const i = this.packetToFragmentLocation.get(e);
- if (i === void 0)
- throw new Error("Packet was not created from this track.");
- return this.performFragmentedLookup(
- i.fragment,
- (s) => {
- if (s === i.fragment) {
- const o = s.trackData
- .get(this.internalTrack.id)
- .samples.findIndex((c, u) => c.isKeyFrame && u > i.sampleIndex);
- if (o !== -1) return { sampleIndex: o, correctSampleFound: !0 };
- } else {
- const a = s.trackData.get(this.internalTrack.id);
- if (a && a.firstKeyFrameTimestamp !== null) {
- const o = a.samples.findIndex((c) => c.isKeyFrame);
- return (T(o !== -1), { sampleIndex: o, correctSampleFound: !0 });
- }
- }
- return { sampleIndex: -1, correctSampleFound: !1 };
- },
- -1 / 0,
- 1 / 0,
- t,
- );
- }
- async fetchPacketForSampleIndex(e, t) {
- if (e === -1) return null;
- const n = this.internalTrack.demuxer.getSampleTableForTrack(
- this.internalTrack,
- ),
- i = Kh(n, e);
- if (!i) return null;
- let s;
- if (t.metadataOnly) s = Tt;
- else {
- let u = this.internalTrack.demuxer.reader.requestSlice(
- i.sampleOffset,
- i.sampleSize,
- );
- if ((O(u) && (u = await u), !u)) return null;
- if (((s = Z(u, i.sampleSize)), this.internalTrack.encryptionInfo)) {
- let l = null;
- if (this.internalTrack.encryptionAuxInfo) {
- const d = await uu(
- this.internalTrack.demuxer.reader,
- this.internalTrack.encryptionInfo,
- this.internalTrack.encryptionAuxInfo,
- );
- e < d.length && (l = d[e]);
- }
- (l ?? (l = ec(this.internalTrack.encryptionInfo)),
- l && (s = await tc(this.internalTrack, l, s, null)));
- }
- }
- const a =
- (i.presentationTimestamp - this.internalTrack.editListOffset) /
- this.internalTrack.timescale,
- o = i.duration / this.internalTrack.timescale,
- c = new Ee(s, i.isKeyFrame ? "key" : "delta", a, o, e, i.sampleSize);
- return (this.packetToSampleIndex.set(c, e), c);
- }
- async fetchPacketInFragment(e, t, n) {
- if (t === -1) return null;
- const s = e.trackData.get(this.internalTrack.id).samples[t];
- T(s);
- let a;
- if (n.metadataOnly) a = Tt;
- else {
- let l = this.internalTrack.demuxer.reader.requestSlice(
- s.byteOffset,
- s.byteSize,
- );
- if ((O(l) && (l = await l), !l)) return null;
- if (((a = Z(l, s.byteSize)), this.internalTrack.encryptionInfo)) {
- const d = s.encryption ?? ec(this.internalTrack.encryptionInfo);
- d && (a = await tc(this.internalTrack, d, a, e));
- }
- }
- const o =
- (s.presentationTimestamp - this.internalTrack.editListOffset) /
- this.internalTrack.timescale,
- c = s.duration / this.internalTrack.timescale,
- u = new Ee(
- a,
- s.isKeyFrame ? "key" : "delta",
- o,
- c,
- e.moofOffset + t,
- s.byteSize,
- );
- return (
- this.packetToFragmentLocation.set(u, { fragment: e, sampleIndex: t }),
- u
- );
- }
- async performFragmentedLookup(e, t, n, i, s) {
- const a = this.internalTrack.demuxer;
- let o = null,
- c = null,
- u = -1;
- if (e) {
- const { sampleIndex: b, correctSampleFound: g } = t(e);
- if (g) return this.fetchPacketInFragment(e, b, s);
- b !== -1 && ((c = e), (u = b));
- }
- const l = ke(this.internalTrack.fragmentLookupTable, n, (b) => b.timestamp),
- d = l !== -1 ? this.internalTrack.fragmentLookupTable[l] : null,
- f = ke(
- this.internalTrack.fragmentPositionCache,
- n,
- (b) => b.startTimestamp,
- ),
- h = f !== -1 ? this.internalTrack.fragmentPositionCache[f] : null,
- p =
- Math.max(
- (d == null ? void 0 : d.moofOffset) ?? 0,
- (h == null ? void 0 : h.moofOffset) ?? 0,
- ) || null;
- let m;
- for (
- e
- ? p === null || e.moofOffset >= p
- ? ((m = e.moofOffset + e.moofSize), (o = e))
- : (m = p)
- : (m = p ?? 0);
- ;
- ) {
- if (o) {
- const C = o.trackData.get(this.internalTrack.id);
- if (C && C.startTimestamp > i) break;
- }
- let b = a.reader.requestSliceRange(m, sr, Hr);
- if ((O(b) && (b = await b), !b)) break;
- const g = m,
- y = Cr(b);
- if (!y) break;
- if (y.name === "moof") {
- o = await a.readFragment(g);
- const { sampleIndex: C, correctSampleFound: _ } = t(o);
- if (_) return this.fetchPacketInFragment(o, C, s);
- C !== -1 && ((c = o), (u = C));
- }
- m = g + y.totalSize;
- }
- if (d && (!c || c.moofOffset < d.moofOffset)) {
- const b = this.internalTrack.fragmentLookupTable[l - 1];
- T(!b || b.timestamp < d.timestamp);
- const g = (b == null ? void 0 : b.timestamp) ?? -1 / 0;
- return this.performFragmentedLookup(null, t, g, i, s);
- }
- return c ? this.fetchPacketInFragment(c, u, s) : null;
- }
-}
-class Ko extends lu {
- constructor(e) {
- (super(e), (this.decoderConfigPromise = null));
- }
- getType() {
- return "video";
- }
- getCodec() {
- return this.internalTrack.info.codec;
- }
- getCodedWidth() {
- return this.internalTrack.info.width;
- }
- getCodedHeight() {
- return this.internalTrack.info.height;
- }
- getSquarePixelWidth() {
- return this.internalTrack.info.squarePixelWidth;
- }
- getSquarePixelHeight() {
- return this.internalTrack.info.squarePixelHeight;
- }
- getTransformationMatrix() {
- return [...this.internalTrack.matrix];
- }
- async getColorSpace() {
- var t, n, i, s;
- const e = await this.getDecoderConfig();
- return e
- ? {
- primaries: (t = e.colorSpace) == null ? void 0 : t.primaries,
- transfer: (n = e.colorSpace) == null ? void 0 : n.transfer,
- matrix: (i = e.colorSpace) == null ? void 0 : i.matrix,
- fullRange: (s = e.colorSpace) == null ? void 0 : s.fullRange,
- }
- : this.internalTrack.info.colorSpace;
- }
- async canBeTransparent() {
- return (
- this.internalTrack.info.codec === "prores" &&
- (this.internalTrack.info.proresFormat === "ap4h" ||
- this.internalTrack.info.proresFormat === "ap4x")
- );
- }
- async getDecoderConfig() {
- return this.internalTrack.info.codec
- ? (this.decoderConfigPromise ??
- (this.decoderConfigPromise = (async () => {
- var t, n, i, s;
- if (
- this.internalTrack.info.codec === "avc" &&
- !this.internalTrack.info.codecDescription
- ) {
- const a = await this.getFirstPacket({});
- this.internalTrack.info.avcCodecInfo = a && bi(a.data);
- } else if (
- this.internalTrack.info.codec === "hevc" &&
- !this.internalTrack.info.codecDescription
- ) {
- const a = await this.getFirstPacket({});
- this.internalTrack.info.hevcCodecInfo = a && wi(a.data);
- } else if (
- this.internalTrack.info.codec === "vp9" &&
- (!this.internalTrack.info.vp9CodecInfo ||
- !ah(this.internalTrack.info.vp9CodecInfo))
- ) {
- const a = await this.getFirstPacket({}),
- o = a && Za(a.data);
- o &&
- (this.internalTrack.info.vp9CodecInfo = {
- ...(this.internalTrack.info.vp9CodecInfo ?? o),
- videoFullRangeFlag: o.videoFullRangeFlag,
- colourPrimaries: o.colourPrimaries,
- transferCharacteristics: o.transferCharacteristics,
- matrixCoefficients: o.matrixCoefficients,
- });
- } else if (
- this.internalTrack.info.codec === "av1" &&
- (!this.internalTrack.info.av1CodecInfo ||
- !Wl(this.internalTrack.info.av1CodecInfo))
- ) {
- const a = await this.getFirstPacket({}),
- o = a && ds(a.data);
- o && (this.internalTrack.info.av1CodecInfo = o);
- } else if (
- this.internalTrack.info.codec === "prores" &&
- !this.internalTrack.info.proresCodecInfo
- ) {
- const a = await this.getFirstPacket({});
- this.internalTrack.info.proresCodecInfo = a && Ul(a.data);
- }
- if (!Ha(this.internalTrack.info.colorSpace)) {
- const a = Ql(this.internalTrack.info);
- ((t = this.internalTrack.info.colorSpace).primaries ??
- (t.primaries = a.primaries),
- (n = this.internalTrack.info.colorSpace).transfer ??
- (n.transfer = a.transfer),
- (i = this.internalTrack.info.colorSpace).matrix ??
- (i.matrix = a.matrix),
- (s = this.internalTrack.info.colorSpace).fullRange ??
- (s.fullRange = a.fullRange));
- }
- const e = {
- codec: hs(this.internalTrack.info),
- codedWidth: this.internalTrack.info.width,
- codedHeight: this.internalTrack.info.height,
- description: this.internalTrack.info.codecDescription ?? void 0,
- colorSpace: this.internalTrack.info.colorSpace,
- };
- return (
- (this.internalTrack.info.width !==
- this.internalTrack.info.squarePixelWidth ||
- this.internalTrack.info.height !==
- this.internalTrack.info.squarePixelHeight) &&
- ((e.displayAspectWidth =
- this.internalTrack.info.squarePixelWidth),
- (e.displayAspectHeight =
- this.internalTrack.info.squarePixelHeight)),
- e
- );
- })()))
- : null;
- }
-}
-class Xo extends lu {
- constructor(e) {
- (super(e), (this.decoderConfigPromise = null));
- }
- getType() {
- return "audio";
- }
- getCodec() {
- return this.internalTrack.info.codec;
- }
- getNumberOfChannels() {
- return this.internalTrack.info.numberOfChannels;
- }
- getSampleRate() {
- return this.internalTrack.info.sampleRate;
- }
- async getDecoderConfig() {
- return this.internalTrack.info.codec
- ? (this.decoderConfigPromise ??
- (this.decoderConfigPromise = (async () => {
- if (
- this.internalTrack.info.codec === "dts" &&
- !this.internalTrack.info.dtsFormat
- ) {
- const e = await this.getFirstPacket({});
- this.internalTrack.info.dtsFormat = e && Kl(e.data);
- }
- return {
- codec: no(this.internalTrack.info),
- numberOfChannels: this.internalTrack.info.numberOfChannels,
- sampleRate: this.internalTrack.info.sampleRate,
- description: this.internalTrack.info.codecDescription ?? void 0,
- };
- })()))
- : null;
- }
-}
-const Ca = (r, e) => {
- if (r.presentationTimestamps) {
- const t = ke(r.presentationTimestamps, e, (n) => n.presentationTimestamp);
- return t === -1 ? -1 : r.presentationTimestamps[t].sampleIndex;
- } else {
- const t = ke(r.sampleTimingEntries, e, (i) => i.startDecodeTimestamp);
- if (t === -1) return -1;
- const n = r.sampleTimingEntries[t];
- return (
- n.startIndex +
- Math.min(
- Math.floor((e - n.startDecodeTimestamp) / n.delta),
- n.count - 1,
- )
- );
- }
- },
- Gh = (r, e) => {
- if (!r.keySampleIndices) return Ca(r, e);
- if (r.presentationTimestamps) {
- const t = ke(r.presentationTimestamps, e, (n) => n.presentationTimestamp);
- if (t === -1) return -1;
- for (let n = t; n >= 0; n--) {
- const i = r.presentationTimestamps[n].sampleIndex;
- if (fi(r.keySampleIndices, i, (a) => a) !== -1) return i;
- }
- return -1;
- } else {
- const t = Ca(r, e),
- n = ke(r.keySampleIndices, t, (i) => i);
- return r.keySampleIndices[n] ?? -1;
- }
- },
- Kh = (r, e) => {
- const t = ke(r.sampleTimingEntries, e, (g) => g.startIndex),
- n = r.sampleTimingEntries[t];
- if (!n || n.startIndex + n.count <= e) return null;
- let s = n.startDecodeTimestamp + (e - n.startIndex) * n.delta;
- const a = ke(r.sampleCompositionTimeOffsets, e, (g) => g.startIndex),
- o = r.sampleCompositionTimeOffsets[a];
- o && e - o.startIndex < o.count && (s += o.offset);
- const c = r.sampleSizes[Math.min(e, r.sampleSizes.length - 1)],
- u = ke(r.sampleToChunk, e, (g) => g.startSampleIndex),
- l = r.sampleToChunk[u];
- T(l);
- const d =
- l.startChunkIndex +
- Math.floor((e - l.startSampleIndex) / l.samplesPerChunk),
- f = r.chunkOffsets[d],
- h = l.startSampleIndex + (d - l.startChunkIndex) * l.samplesPerChunk;
- let p = 0,
- m = f;
- if (r.sampleSizes.length === 1)
- ((m += c * (e - h)), (p += c * l.samplesPerChunk));
- else
- for (let g = h; g < h + l.samplesPerChunk; g++) {
- const y = r.sampleSizes[g];
- (g < e && (m += y), (p += y));
- }
- let b = n.delta;
- if (r.presentationTimestamps) {
- const g = r.presentationTimestampIndexMap[e];
- (T(g !== void 0),
- g < r.presentationTimestamps.length - 1 &&
- (b = r.presentationTimestamps[g + 1].presentationTimestamp - s));
- }
- return {
- presentationTimestamp: s,
- duration: b,
- sampleOffset: m,
- sampleSize: c,
- chunkOffset: f,
- chunkSize: p,
- isKeyFrame: r.keySampleIndices
- ? fi(r.keySampleIndices, e, (g) => g) !== -1
- : !0,
- };
- },
- Xh = (r, e) => {
- if (!r.keySampleIndices) return e + 1;
- const t = ke(r.keySampleIndices, e, (n) => n);
- return r.keySampleIndices[t + 1] ?? -1;
- },
- Ds = (r, e) => {
- ((r.startTimestamp += e), (r.endTimestamp += e));
- for (const t of r.samples) t.presentationTimestamp += e;
- for (const t of r.presentationTimestamps) t.presentationTimestamp += e;
- },
- Qo = (r) => [Dr(r), Dr(r), Ns(r), Dr(r), Dr(r), Ns(r), Dr(r), Dr(r), Ns(r)],
- Yo = (r, e) => {
- const t = r.info;
- if (t.type !== "video") return;
- const { num: n, den: i } = e;
- !(n > 0 && i > 0) ||
- n === i ||
- (n > i
- ? ((t.squarePixelWidth = Math.round((t.width * n) / i)),
- (t.squarePixelHeight = t.height))
- : ((t.squarePixelWidth = t.width),
- (t.squarePixelHeight = Math.round((t.height * i) / n))));
- },
- Zo = (r) => r.sampleSizes.length === 0,
- Jo = (r) => {
- var e;
- return r.currentFragmentState
- ? ((e = r.currentFragmentState).encryptionAuxInfo ??
- (e.encryptionAuxInfo = {
- defaultSampleInfoSize: 0,
- sampleSizes: null,
- sampleCount: 0,
- offset: null,
- resolved: null,
- }))
- : (r.encryptionAuxInfo ??
- (r.encryptionAuxInfo = {
- defaultSampleInfoSize: 0,
- sampleSizes: null,
- sampleCount: 0,
- offset: null,
- resolved: null,
- }));
- },
- uu = async (r, e, t) => {
- if (t.resolved) return t.resolved;
- if (t.offset === null || t.sampleCount === 0)
- throw new Error(
- "Incomplete saiz/saio info; cannot resolve encryption data.",
- );
- let n = 0;
- if (t.defaultSampleInfoSize > 0)
- n = t.defaultSampleInfoSize * t.sampleCount;
- else {
- T(t.sampleSizes);
- for (let o = 0; o < t.sampleCount; o++) n += t.sampleSizes[o];
- }
- let i = r.requestSlice(t.offset, n);
- if ((O(i) && (i = await i), !i))
- throw new Error("Failed to read auxiliary encryption info.");
- const s = e.defaultPerSampleIvSize;
- T(s !== null);
- const a = [];
- for (let o = 0; o < t.sampleCount; o++) {
- const c =
- t.defaultSampleInfoSize > 0
- ? t.defaultSampleInfoSize
- : t.sampleSizes[o],
- u = new Uint8Array(16);
- s > 0 ? u.set(Z(i, s), 0) : u.set(e.defaultConstantIv, 0);
- let l = null;
- if (c > s) {
- const d = Ve(i);
- l = [];
- for (let f = 0; f < d; f++) {
- const h = Ve(i),
- p = L(i);
- l.push({ clearLen: h, protectedLen: p });
- }
- }
- a.push({ iv: u, subsamples: l });
- }
- return ((t.resolved = a), a);
- },
- ec = (r) =>
- r.defaultConstantIv ? { iv: r.defaultConstantIv, subsamples: null } : null,
- tc = async (r, e, t, n) => {
- var c;
- T(r.encryptionInfo);
- const i = r.encryptionInfo;
- T(i.defaultKid !== null);
- const s = i.defaultKid;
- let a;
- const o = r.demuxer.decryptionKeyCache.get(s);
- if (o) a = await o;
- else {
- if (!(
- (c = r.demuxer.input._formatOptions.isobmff) != null && c.resolveKeyId
- ))
- throw new Error(
- "Encrypted media samples encountered. To decrypt them, please provide a callback for InputOptions.formatOptions.isobmff.resolveKeyId.",
- );
- const u = (async () => {
- let l = r.demuxer.psshBoxes;
- if (n) {
- l = [...l, ...n.psshBoxes].filter(
- (f) => f.keyIds === null || f.keyIds.includes(s),
- );
- for (let f = 0; f < l.length - 1; f++)
- for (let h = f + 1; h < l.length; h++)
- su(l[f], l[h]) && (l.splice(h, 1), h--);
- }
- const d = await r.demuxer.input._formatOptions.isobmff.resolveKeyId({
- keyId: s,
- psshBoxes: l,
- });
- if (!(
- (typeof d == "string" && d.length === 32 && Bf.test(d)) ||
- (d instanceof Uint8Array && d.byteLength === 16)
- ))
- throw new TypeError(
- "resolveKeyId must return a 32-character hex string or a 16-byte Uint8Array containing the decryption key.",
- );
- return d instanceof Uint8Array ? d : Ff(d);
- })();
- (r.demuxer.decryptionKeyCache.set(s, u), (a = await u));
- }
- return i.scheme === "cenc" || i.scheme === "cens"
- ? Qh(a, i, e, t)
- : Yh(a, i, e, t);
- },
- Qh = async (r, e, t, n) => {
- const i = new Uint8Array(16);
- i.set(t.iv, 0);
- const s = await crypto.subtle.importKey("raw", r, { name: "AES-CTR" }, !1, [
- "decrypt",
- ]),
- a = async (p) => {
- const m = await crypto.subtle.decrypt(
- { name: "AES-CTR", counter: i, length: 64 },
- s,
- p,
- );
- return new Uint8Array(m);
- };
- if (!t.subsamples) return a(n);
- T(e.defaultCryptByteBlock !== null && e.defaultSkipByteBlock !== null);
- const o = du(t.subsamples, e.defaultCryptByteBlock, e.defaultSkipByteBlock);
- let c = 0;
- for (const p of o) for (const m of p.perSubsample) c += m.length;
- const u = new Uint8Array(c);
- let l = 0;
- for (const p of o)
- for (const m of p.perSubsample)
- (u.set(n.subarray(m.offset, m.offset + m.length), l), (l += m.length));
- const d = await a(u),
- f = new Uint8Array(n);
- let h = 0;
- for (const p of o)
- for (const m of p.perSubsample)
- (f.set(d.subarray(h, h + m.length), m.offset), (h += m.length));
- return f;
- },
- Yh = (r, e, t, n) => {
- const i = new cu();
- i.init({ key: r, iv: t.iv });
- const s = e.defaultCryptByteBlock,
- a = e.defaultSkipByteBlock;
- if ((T(s !== null && a !== null), !t.subsamples)) {
- const l = new Uint8Array(n),
- d = Math.floor(n.length / 16);
- for (let f = 0; f < d; f++) {
- const h = f * 16;
- (i.in.set(n.subarray(h, h + 16)), i.decrypt(), l.set(i.out, h));
- }
- return l;
- }
- if (s === 0 && a === 0)
- throw new Error("cbcs with subsamples requires pattern encryption.");
- const o = new Uint8Array(n),
- c = du(t.subsamples, s, a),
- u = new DataView(t.iv.buffer, t.iv.byteOffset, 16);
- for (const l of c) {
- ((i.iv[0] = u.getUint32(0, !1)),
- (i.iv[1] = u.getUint32(4, !1)),
- (i.iv[2] = u.getUint32(8, !1)),
- (i.iv[3] = u.getUint32(12, !1)));
- for (const d of l.perSubsample) {
- const f = d.length / 16;
- for (let h = 0; h < f; h++) {
- const p = d.offset + h * 16;
- (i.in.set(n.subarray(p, p + 16)), i.decrypt(), o.set(i.out, p));
- }
- }
- }
- return o;
- },
- du = (r, e, t) => {
- const n = [],
- i = e !== 0 || t !== 0;
- let s = 0;
- for (const a of r) {
- s += a.clearLen;
- const o = [];
- if (!i)
- (a.protectedLen > 0 && o.push({ offset: s, length: a.protectedLen }),
- (s += a.protectedLen));
- else {
- let c = a.protectedLen,
- u = s;
- for (; c > 0 && !(c < 16 * e);) {
- const l = 16 * e;
- (o.push({ offset: u, length: l }), (u += l), (c -= l));
- const d = Math.min(16 * t, c);
- ((u += d), (c -= d));
- }
- s += a.protectedLen;
- }
- n.push({ perSubsample: o });
- }
- return n;
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ var N;
-(function (r) {
- ((r[(r.EBML = 440786851)] = "EBML"),
- (r[(r.EBMLVersion = 17030)] = "EBMLVersion"),
- (r[(r.EBMLReadVersion = 17143)] = "EBMLReadVersion"),
- (r[(r.EBMLMaxIDLength = 17138)] = "EBMLMaxIDLength"),
- (r[(r.EBMLMaxSizeLength = 17139)] = "EBMLMaxSizeLength"),
- (r[(r.DocType = 17026)] = "DocType"),
- (r[(r.DocTypeVersion = 17031)] = "DocTypeVersion"),
- (r[(r.DocTypeReadVersion = 17029)] = "DocTypeReadVersion"),
- (r[(r.Void = 236)] = "Void"),
- (r[(r.Segment = 408125543)] = "Segment"),
- (r[(r.SeekHead = 290298740)] = "SeekHead"),
- (r[(r.Seek = 19899)] = "Seek"),
- (r[(r.SeekID = 21419)] = "SeekID"),
- (r[(r.SeekPosition = 21420)] = "SeekPosition"),
- (r[(r.Duration = 17545)] = "Duration"),
- (r[(r.Info = 357149030)] = "Info"),
- (r[(r.TimestampScale = 2807729)] = "TimestampScale"),
- (r[(r.MuxingApp = 19840)] = "MuxingApp"),
- (r[(r.WritingApp = 22337)] = "WritingApp"),
- (r[(r.Tracks = 374648427)] = "Tracks"),
- (r[(r.TrackEntry = 174)] = "TrackEntry"),
- (r[(r.TrackNumber = 215)] = "TrackNumber"),
- (r[(r.TrackUID = 29637)] = "TrackUID"),
- (r[(r.TrackType = 131)] = "TrackType"),
- (r[(r.FlagEnabled = 185)] = "FlagEnabled"),
- (r[(r.FlagDefault = 136)] = "FlagDefault"),
- (r[(r.FlagForced = 21930)] = "FlagForced"),
- (r[(r.FlagOriginal = 21934)] = "FlagOriginal"),
- (r[(r.FlagHearingImpaired = 21931)] = "FlagHearingImpaired"),
- (r[(r.FlagVisualImpaired = 21932)] = "FlagVisualImpaired"),
- (r[(r.FlagCommentary = 21935)] = "FlagCommentary"),
- (r[(r.FlagLacing = 156)] = "FlagLacing"),
- (r[(r.Name = 21358)] = "Name"),
- (r[(r.Language = 2274716)] = "Language"),
- (r[(r.LanguageBCP47 = 2274717)] = "LanguageBCP47"),
- (r[(r.CodecID = 134)] = "CodecID"),
- (r[(r.CodecPrivate = 25506)] = "CodecPrivate"),
- (r[(r.CodecDelay = 22186)] = "CodecDelay"),
- (r[(r.SeekPreRoll = 22203)] = "SeekPreRoll"),
- (r[(r.DefaultDuration = 2352003)] = "DefaultDuration"),
- (r[(r.Video = 224)] = "Video"),
- (r[(r.PixelWidth = 176)] = "PixelWidth"),
- (r[(r.PixelHeight = 186)] = "PixelHeight"),
- (r[(r.DisplayWidth = 21680)] = "DisplayWidth"),
- (r[(r.DisplayHeight = 21690)] = "DisplayHeight"),
- (r[(r.DisplayUnit = 21682)] = "DisplayUnit"),
- (r[(r.AlphaMode = 21440)] = "AlphaMode"),
- (r[(r.Audio = 225)] = "Audio"),
- (r[(r.SamplingFrequency = 181)] = "SamplingFrequency"),
- (r[(r.Channels = 159)] = "Channels"),
- (r[(r.BitDepth = 25188)] = "BitDepth"),
- (r[(r.SimpleBlock = 163)] = "SimpleBlock"),
- (r[(r.BlockGroup = 160)] = "BlockGroup"),
- (r[(r.Block = 161)] = "Block"),
- (r[(r.BlockAdditions = 30113)] = "BlockAdditions"),
- (r[(r.BlockMore = 166)] = "BlockMore"),
- (r[(r.BlockAdditional = 165)] = "BlockAdditional"),
- (r[(r.BlockAddID = 238)] = "BlockAddID"),
- (r[(r.BlockDuration = 155)] = "BlockDuration"),
- (r[(r.ReferenceBlock = 251)] = "ReferenceBlock"),
- (r[(r.Cluster = 524531317)] = "Cluster"),
- (r[(r.Timestamp = 231)] = "Timestamp"),
- (r[(r.Cues = 475249515)] = "Cues"),
- (r[(r.CuePoint = 187)] = "CuePoint"),
- (r[(r.CueTime = 179)] = "CueTime"),
- (r[(r.CueTrackPositions = 183)] = "CueTrackPositions"),
- (r[(r.CueTrack = 247)] = "CueTrack"),
- (r[(r.CueClusterPosition = 241)] = "CueClusterPosition"),
- (r[(r.Colour = 21936)] = "Colour"),
- (r[(r.MatrixCoefficients = 21937)] = "MatrixCoefficients"),
- (r[(r.TransferCharacteristics = 21946)] = "TransferCharacteristics"),
- (r[(r.Primaries = 21947)] = "Primaries"),
- (r[(r.Range = 21945)] = "Range"),
- (r[(r.Projection = 30320)] = "Projection"),
- (r[(r.ProjectionType = 30321)] = "ProjectionType"),
- (r[(r.ProjectionPoseYaw = 30323)] = "ProjectionPoseYaw"),
- (r[(r.ProjectionPosePitch = 30324)] = "ProjectionPosePitch"),
- (r[(r.ProjectionPoseRoll = 30325)] = "ProjectionPoseRoll"),
- (r[(r.Attachments = 423732329)] = "Attachments"),
- (r[(r.AttachedFile = 24999)] = "AttachedFile"),
- (r[(r.FileDescription = 18046)] = "FileDescription"),
- (r[(r.FileName = 18030)] = "FileName"),
- (r[(r.FileMediaType = 18016)] = "FileMediaType"),
- (r[(r.FileData = 18012)] = "FileData"),
- (r[(r.FileUID = 18094)] = "FileUID"),
- (r[(r.Chapters = 272869232)] = "Chapters"),
- (r[(r.Tags = 307544935)] = "Tags"),
- (r[(r.Tag = 29555)] = "Tag"),
- (r[(r.Targets = 25536)] = "Targets"),
- (r[(r.TargetTypeValue = 26826)] = "TargetTypeValue"),
- (r[(r.TargetType = 25546)] = "TargetType"),
- (r[(r.TagTrackUID = 25541)] = "TagTrackUID"),
- (r[(r.TagEditionUID = 25545)] = "TagEditionUID"),
- (r[(r.TagChapterUID = 25540)] = "TagChapterUID"),
- (r[(r.TagAttachmentUID = 25542)] = "TagAttachmentUID"),
- (r[(r.SimpleTag = 26568)] = "SimpleTag"),
- (r[(r.TagName = 17827)] = "TagName"),
- (r[(r.TagLanguage = 17530)] = "TagLanguage"),
- (r[(r.TagString = 17543)] = "TagString"),
- (r[(r.TagBinary = 17541)] = "TagBinary"),
- (r[(r.ContentEncodings = 28032)] = "ContentEncodings"),
- (r[(r.ContentEncoding = 25152)] = "ContentEncoding"),
- (r[(r.ContentEncodingOrder = 20529)] = "ContentEncodingOrder"),
- (r[(r.ContentEncodingScope = 20530)] = "ContentEncodingScope"),
- (r[(r.ContentCompression = 20532)] = "ContentCompression"),
- (r[(r.ContentCompAlgo = 16980)] = "ContentCompAlgo"),
- (r[(r.ContentCompSettings = 16981)] = "ContentCompSettings"),
- (r[(r.ContentEncryption = 20533)] = "ContentEncryption"));
-})(N || (N = {}));
-const Zh = [N.EBML, N.Segment],
- li = [
- N.SeekHead,
- N.Info,
- N.Cluster,
- N.Tracks,
- N.Cues,
- N.Attachments,
- N.Chapters,
- N.Tags,
- ],
- Ni = [...Zh, ...li],
- va = 8,
- gt = 2,
- Lt = 2 * va,
- fu = (r) => {
- if (r.remainingLength < 1) return null;
- const e = Y(r);
- if ((r.skip(-1), e === 0)) return null;
- let t = 1,
- n = 128;
- for (; (e & n) === 0;) (t++, (n >>= 1));
- return r.remainingLength < t ? null : t;
- },
- jn = (r) => {
- if (r.remainingLength < 1) return null;
- const e = Y(r);
- if (e === 0) return null;
- let t = 1,
- n = 128;
- for (; (e & n) === 0;) (t++, (n >>= 1));
- if (r.remainingLength < t - 1) return null;
- let i = e & (n - 1);
- for (let s = 1; s < t; s++) ((i *= 256), (i += Y(r)));
- return i;
- },
- he = (r, e) => {
- if (e < 1 || e > 8) throw new Error("Bad unsigned int size " + e);
- let t = 0;
- for (let n = 0; n < e; n++) ((t *= 256), (t += Y(r)));
- return t;
- },
- Jh = (r, e) => {
- if (e < 1) throw new Error("Bad unsigned int size " + e);
- let t = 0n;
- for (let n = 0; n < e; n++) ((t <<= 8n), (t += BigInt(Y(r))));
- return t;
- },
- ao = (r) => {
- const e = fu(r);
- return e === null || r.remainingLength < e ? null : he(r, e);
- },
- hu = (r) => {
- if (r.remainingLength < 1) return null;
- if (Y(r) === 255) return;
- r.skip(-1);
- const t = jn(r);
- if (t === null) return null;
- if (t !== 72057594037927940) return t;
- },
- Vt = (r) => {
- T(r.remainingLength >= gt);
- const e = ao(r);
- if (e === null) return null;
- const t = hu(r);
- return t === null ? null : { id: e, size: t };
- },
- an = (r, e) => {
- const t = Z(r, e);
- let n = 0;
- for (; n < e && t[n] !== 0;) n += 1;
- return String.fromCharCode(...t.subarray(0, n));
- },
- Fn = (r, e) => {
- const t = Z(r, e);
- let n = 0;
- for (; n < e && t[n] !== 0;) n += 1;
- return ot.decode(t.subarray(0, n));
- },
- Rn = (r, e) => {
- if (e === 0) return 0;
- if (e !== 4 && e !== 8) throw new Error("Bad float size " + e);
- return e === 4 ? t0(r) : Lu(r);
- },
- Ea = async (r, e, t, n) => {
- const i = new Set(t);
- let s = e;
- for (; n === null || s < n;) {
- let a = r.requestSliceRange(s, gt, Lt);
- if ((O(a) && (a = await a), !a)) break;
- const o = Vt(a);
- if (!o) break;
- if (i.has(o.id)) return { pos: s, found: !0 };
- (Yt(o.size), (s = a.filePos + o.size));
- }
- return { pos: n !== null && n > s ? n : s, found: !1 };
- },
- mu = async (r, e, t, n) => {
- const s = new Set(t);
- let a = e;
- for (; a < n;) {
- let o = r.requestSliceRange(a, 0, Math.min(65536, n - a));
- if ((O(o) && (o = await o), !o || o.length < va)) break;
- for (let c = 0; c < o.length - va; c++) {
- o.filePos = a;
- const u = ao(o);
- if (u !== null && s.has(u)) return a;
- a++;
- }
- }
- return null;
- },
- at = {
- avc: "V_MPEG4/ISO/AVC",
- hevc: "V_MPEGH/ISO/HEVC",
- vp8: "V_VP8",
- vp9: "V_VP9",
- av1: "V_AV1",
- prores: "V_PRORES",
- aac: "A_AAC",
- mp3: "A_MPEG/L3",
- opus: "A_OPUS",
- vorbis: "A_VORBIS",
- flac: "A_FLAC",
- ac3: "A_AC3",
- eac3: "A_EAC3",
- dts: "A_DTS",
- };
-function Yt(r) {
- if (r === void 0)
- throw new Error(
- "Undefined element size is used in a place where it is not supported.",
- );
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const em = (r) => {
- let t =
- (r.hasVideo ? "video/" : r.hasAudio ? "audio/" : "application/") +
- (r.isWebM ? "webm" : "x-matroska");
- if (r.codecStrings.length > 0) {
- const n = [...new Set(r.codecStrings.filter(Boolean))];
- t += `; codecs="${n.join(", ")}"`;
- }
- return t;
-};
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ var Jt;
-(function (r) {
- ((r[(r.None = 0)] = "None"),
- (r[(r.Xiph = 1)] = "Xiph"),
- (r[(r.FixedSize = 2)] = "FixedSize"),
- (r[(r.Ebml = 3)] = "Ebml"));
-})(Jt || (Jt = {}));
-var Ki;
-(function (r) {
- ((r[(r.Block = 1)] = "Block"),
- (r[(r.Private = 2)] = "Private"),
- (r[(r.Next = 4)] = "Next"));
-})(Ki || (Ki = {}));
-var Xn;
-(function (r) {
- ((r[(r.Zlib = 0)] = "Zlib"),
- (r[(r.Bzlib = 1)] = "Bzlib"),
- (r[(r.lzo1x = 2)] = "lzo1x"),
- (r[(r.HeaderStripping = 3)] = "HeaderStripping"));
-})(Xn || (Xn = {}));
-const zs = [
- { id: N.SeekHead, flag: "seekHeadSeen" },
- { id: N.Info, flag: "infoSeen" },
- { id: N.Tracks, flag: "tracksSeen" },
- { id: N.Cues, flag: "cuesSeen" },
- ],
- pu = 10 * 2 ** 20;
-class tm extends br {
- constructor(e) {
- (super(e),
- (this.readMetadataPromise = null),
- (this.segments = []),
- (this.currentSegment = null),
- (this.currentTrack = null),
- (this.currentCluster = null),
- (this.currentBlock = null),
- (this.currentBlockAdditional = null),
- (this.currentCueTime = null),
- (this.currentDecodingInstruction = null),
- (this.currentTagTargetIsMovie = !0),
- (this.currentSimpleTagName = null),
- (this.currentAttachedFile = null),
- (this.isWebM = !1),
- (this.reader = e._reader));
- }
- async getTrackBackings() {
- return (
- await this.readMetadata(),
- this.segments.flatMap((e) => e.tracks.map((t) => t.trackBacking))
- );
- }
- async getMimeType() {
- await this.readMetadata();
- const e = await this.getTrackBackings(),
- t = await Promise.all(
- e.map((n) =>
- n
- .getDecoderConfig()
- .then((i) => (i == null ? void 0 : i.codec) ?? null),
- ),
- );
- return em({
- isWebM: this.isWebM,
- hasVideo: this.segments.some((n) =>
- n.tracks.some((i) => {
- var s;
- return ((s = i.info) == null ? void 0 : s.type) === "video";
- }),
- ),
- hasAudio: this.segments.some((n) =>
- n.tracks.some((i) => {
- var s;
- return ((s = i.info) == null ? void 0 : s.type) === "audio";
- }),
- ),
- codecStrings: t.filter(Boolean),
- });
- }
- async getMetadataTags() {
- await this.readMetadata();
- for (const t of this.segments)
- t.metadataTagsCollected ||
- (this.reader.fileSize !== null && (await this.loadSegmentMetadata(t)),
- (t.metadataTagsCollected = !0));
- let e = {};
- for (const t of this.segments) e = { ...e, ...t.metadataTags };
- return e;
- }
- readMetadata() {
- return (
- this.readMetadataPromise ??
- (this.readMetadataPromise = (async () => {
- let e = 0;
- for (;;) {
- let t = this.reader.requestSliceRange(e, gt, Lt);
- if ((O(t) && (t = await t), !t)) break;
- const n = Vt(t);
- if (!n) break;
- const i = n.id;
- let s = n.size;
- const a = t.filePos;
- if (i === N.EBML) {
- Yt(s);
- let o = this.reader.requestSlice(a, s);
- if ((O(o) && (o = await o), !o)) break;
- this.readContiguousElements(o);
- } else if (i === N.Segment) {
- if (
- (await this.readSegment(a, s),
- s === void 0 || this.reader.fileSize === null)
- )
- break;
- } else if (i === N.Cluster) {
- if (this.reader.fileSize === null) break;
- s === void 0 &&
- (s =
- (await Ea(this.reader, a, Ni, this.reader.fileSize)).pos - a);
- const o = Ae(this.segments);
- o && (o.elementEndPos = a + s);
- }
- (Yt(s), (e = a + s));
- }
- })())
- );
- }
- async readSegment(e, t) {
- ((this.currentSegment = {
- seekHeadSeen: !1,
- infoSeen: !1,
- tracksSeen: !1,
- cuesSeen: !1,
- tagsSeen: !1,
- attachmentsSeen: !1,
- timestampScale: -1,
- timestampFactor: -1,
- duration: -1,
- seekEntries: [],
- tracks: [],
- cuePoints: [],
- dataStartPos: e,
- elementEndPos: t === void 0 ? null : e + t,
- clusterSeekStartPos: e,
- lastReadCluster: null,
- metadataTags: {},
- metadataTagsCollected: !1,
- }),
- this.segments.push(this.currentSegment));
- let n = e;
- const i = new Set();
- for (
- ;
- this.currentSegment.elementEndPos === null ||
- n < this.currentSegment.elementEndPos;
- ) {
- let c = this.reader.requestSliceRange(n, gt, Lt);
- if ((O(c) && (c = await c), !c)) break;
- const u = n,
- l = Vt(c);
- if (!l || (!li.includes(l.id) && l.id !== N.Void)) {
- const m = await mu(
- this.reader,
- u,
- li,
- Math.min(this.currentSegment.elementEndPos ?? 1 / 0, u + pu),
- );
- if (m) {
- n = m;
- continue;
- } else break;
- }
- const { id: d, size: f } = l,
- h = c.filePos,
- p = zs.findIndex((m) => m.id === d);
- if (p !== -1) {
- const m = zs[p].flag;
- ((this.currentSegment[m] = !0),
- d === N.SeekHead && i.add(u - e),
- Yt(f));
- let b = this.reader.requestSlice(h, f);
- (O(b) && (b = await b), b && this.readContiguousElements(b));
- } else if (d === N.Tags || d === N.Attachments) {
- (d === N.Tags
- ? (this.currentSegment.tagsSeen = !0)
- : (this.currentSegment.attachmentsSeen = !0),
- Yt(f));
- let m = this.reader.requestSlice(h, f);
- (O(m) && (m = await m), m && this.readContiguousElements(m));
- } else if (d === N.Cluster) {
- this.currentSegment.clusterSeekStartPos = u;
- break;
- }
- if (f === void 0) break;
- n = h + f;
- }
- if (this.reader.fileSize !== null)
- for (;;) {
- const c = this.currentSegment.seekEntries.find(
- (h) => h.id === N.SeekHead && !i.has(h.segmentPosition),
- );
- if (!c) break;
- i.add(c.segmentPosition);
- let u = this.reader.requestSliceRange(e + c.segmentPosition, gt, Lt);
- if ((O(u) && (u = await u), !u)) continue;
- const l = Vt(u);
- if (!l || l.id !== N.SeekHead) continue;
- const { size: d } = l;
- Yt(d);
- let f = this.reader.requestSlice(u.filePos, d);
- (O(f) && (f = await f), f && this.readContiguousElements(f));
- }
- if (
- (this.currentSegment.seekEntries.sort(
- (c, u) => c.segmentPosition - u.segmentPosition,
- ),
- this.reader.fileSize !== null)
- )
- for (const c of this.currentSegment.seekEntries) {
- const u = zs.find((m) => m.id === c.id);
- if (!u || this.currentSegment[u.flag]) continue;
- let l = this.reader.requestSliceRange(e + c.segmentPosition, gt, Lt);
- if ((O(l) && (l = await l), !l)) continue;
- const d = Vt(l);
- if (!d) continue;
- const { id: f, size: h } = d;
- if (f !== u.id) continue;
- (Yt(h), (this.currentSegment[u.flag] = !0));
- let p = this.reader.requestSlice(l.filePos, h);
- (O(p) && (p = await p), p && this.readContiguousElements(p));
- }
- this.currentSegment.timestampScale === -1 &&
- ((this.currentSegment.timestampScale = 1e6),
- (this.currentSegment.timestampFactor = 1e9 / 1e6));
- for (const c of this.currentSegment.tracks)
- c.defaultDurationNs !== null &&
- (c.defaultDuration =
- (this.currentSegment.timestampFactor * c.defaultDurationNs) / 1e9);
- const s = new Map(this.currentSegment.tracks.map((c) => [c.id, c]));
- for (const c of this.currentSegment.cuePoints) {
- const u = s.get(c.trackId);
- u && u.cuePoints.push(c);
- }
- for (const c of this.currentSegment.tracks) {
- c.cuePoints.sort((u, l) => u.time - l.time);
- for (let u = 0; u < c.cuePoints.length - 1; u++) {
- const l = c.cuePoints[u],
- d = c.cuePoints[u + 1];
- l.time === d.time && (c.cuePoints.splice(u + 1, 1), u--);
- }
- }
- let a = null,
- o = -1 / 0;
- for (const c of this.currentSegment.tracks)
- c.cuePoints.length > o && ((o = c.cuePoints.length), (a = c));
- for (const c of this.currentSegment.tracks)
- c.cuePoints.length === 0 && (c.cuePoints = a.cuePoints);
- this.currentSegment = null;
- }
- async readCluster(e, t) {
- var d;
- if (((d = t.lastReadCluster) == null ? void 0 : d.elementStartPos) === e)
- return t.lastReadCluster;
- let n = this.reader.requestSliceRange(e, gt, Lt);
- (O(n) && (n = await n), T(n));
- const i = e,
- s = Vt(n);
- T(s);
- const a = s.id;
- T(a === N.Cluster);
- let o = s.size;
- const c = n.filePos;
- o === void 0 &&
- (o = (await Ea(this.reader, c, Ni, t.elementEndPos)).pos - c);
- let u = this.reader.requestSlice(c, o);
- O(u) && (u = await u);
- const l = {
- segment: t,
- elementStartPos: i,
- elementEndPos: c + o,
- dataStartPos: c,
- timestamp: -1,
- trackData: new Map(),
- };
- if (((this.currentCluster = l), u)) {
- const f = this.readContiguousElements(u, Ni);
- l.elementEndPos = f;
- }
- for (const [, f] of l.trackData) {
- const h = f.track;
- T(f.blocks.length > 0);
- let p = !1;
- for (let y = 0; y < f.blocks.length; y++) {
- const C = f.blocks[y];
- ((C.timestamp += l.timestamp), p || (p = C.lacing !== Jt.None));
- }
- f.presentationTimestamps = f.blocks
- .map((y, C) => ({ timestamp: y.timestamp, blockIndex: C }))
- .sort((y, C) => y.timestamp - C.timestamp);
- for (let y = 0; y < f.presentationTimestamps.length; y++) {
- const C = f.presentationTimestamps[y],
- _ = f.blocks[C.blockIndex];
- if (
- (f.firstKeyFrameTimestamp === null &&
- _.isKeyFrame &&
- (f.firstKeyFrameTimestamp = _.timestamp),
- y < f.presentationTimestamps.length - 1)
- ) {
- const v = f.presentationTimestamps[y + 1];
- _.duration = v.timestamp - _.timestamp;
- } else
- _.duration === 0 &&
- h.defaultDuration != null &&
- _.lacing === Jt.None &&
- (_.duration = h.defaultDuration);
- }
- p &&
- (this.expandLacedBlocks(f.blocks, h),
- (f.presentationTimestamps = f.blocks
- .map((y, C) => ({ timestamp: y.timestamp, blockIndex: C }))
- .sort((y, C) => y.timestamp - C.timestamp)));
- const m = f.blocks[f.presentationTimestamps[0].blockIndex],
- b = f.blocks[Ae(f.presentationTimestamps).blockIndex];
- ((f.startTimestamp = m.timestamp),
- (f.endTimestamp = b.timestamp + b.duration));
- const g = ke(
- h.clusterPositionCache,
- f.startTimestamp,
- (y) => y.startTimestamp,
- );
- (g === -1 || h.clusterPositionCache[g].elementStartPos !== i) &&
- h.clusterPositionCache.splice(g + 1, 0, {
- elementStartPos: l.elementStartPos,
- startTimestamp: f.startTimestamp,
- });
- }
- return ((t.lastReadCluster = l), l);
- }
- getTrackDataInCluster(e, t) {
- let n = e.trackData.get(t);
- if (!n) {
- const i = e.segment.tracks.find((s) => s.id === t);
- if (!i) return null;
- ((n = {
- track: i,
- startTimestamp: 0,
- endTimestamp: 0,
- firstKeyFrameTimestamp: null,
- blocks: [],
- presentationTimestamps: [],
- }),
- e.trackData.set(t, n));
- }
- return n;
- }
- expandLacedBlocks(e, t) {
- for (let n = 0; n < e.length; n++) {
- const i = e[n];
- if (i.lacing === Jt.None) continue;
- i.decoded ||
- ((i.data = this.decodeBlockData(t, i.data)), (i.decoded = !0));
- const s = yt.tempFromBytes(i.data),
- a = [],
- o = Y(s) + 1;
- switch (i.lacing) {
- case Jt.Xiph:
- {
- let u = 0;
- for (let l = 0; l < o - 1; l++) {
- let d = 0;
- for (; s.bufferPos < s.length;) {
- const f = Y(s);
- if (((d += f), f < 255)) {
- (a.push(d), (u += d));
- break;
- }
- }
- }
- a.push(s.length - (s.bufferPos + u));
- }
- break;
- case Jt.FixedSize:
- {
- const u = s.length - 1,
- l = Math.floor(u / o);
- for (let d = 0; d < o; d++) a.push(l);
- }
- break;
- case Jt.Ebml:
- {
- const u = jn(s);
- T(u !== null);
- let l = u;
- a.push(l);
- let d = l;
- for (let f = 1; f < o - 1; f++) {
- const h = s.bufferPos,
- p = jn(s);
- T(p !== null);
- const m = p,
- g = (1 << ((s.bufferPos - h) * 7 - 1)) - 1,
- y = m - g;
- ((l += y), a.push(l), (d += l));
- }
- a.push(s.length - (s.bufferPos + d));
- }
- break;
- default:
- T(!1);
- }
- (T(a.length === o), e.splice(n, 1));
- const c = i.duration || o * (t.defaultDuration ?? 0);
- for (let u = 0; u < o; u++) {
- const l = a[u],
- d = Z(s, l),
- f = i.timestamp + (c * u) / o,
- h = c / o;
- e.splice(n + u, 0, {
- timestamp: f,
- duration: h,
- isKeyFrame: i.isKeyFrame,
- data: d,
- lacing: Jt.None,
- decoded: !0,
- postProcessed: !1,
- mainAdditional: i.mainAdditional,
- });
- }
- ((n += o), n--);
- }
- }
- async loadSegmentMetadata(e) {
- for (const t of e.seekEntries) {
- if (!(t.id === N.Tags && !e.tagsSeen)) {
- if (!(t.id === N.Attachments && !e.attachmentsSeen)) continue;
- }
- let n = this.reader.requestSliceRange(
- e.dataStartPos + t.segmentPosition,
- gt,
- Lt,
- );
- if ((O(n) && (n = await n), !n)) continue;
- const i = Vt(n);
- if (!i || i.id !== t.id) continue;
- const { size: s } = i;
- (Yt(s), T(!this.currentSegment), (this.currentSegment = e));
- let a = this.reader.requestSlice(n.filePos, s);
- (O(a) && (a = await a),
- a && this.readContiguousElements(a),
- (this.currentSegment = null),
- t.id === N.Tags
- ? (e.tagsSeen = !0)
- : t.id === N.Attachments && (e.attachmentsSeen = !0));
- }
- }
- readContiguousElements(e, t) {
- for (; e.remainingLength >= gt;) {
- const n = e.filePos;
- if (!this.traverseElement(e, t)) return n;
- }
- return e.filePos;
- }
- traverseElement(e, t) {
- var o,
- c,
- u,
- l,
- d,
- f,
- h,
- p,
- m,
- b,
- g,
- y,
- C,
- _,
- v,
- I,
- w,
- x,
- k,
- S,
- E,
- B,
- R,
- M,
- z,
- q,
- j,
- se,
- le,
- ue,
- $e,
- K,
- ie,
- Ie,
- Ge,
- Fe,
- je,
- He,
- we,
- Oe,
- st,
- _t,
- At,
- Ot,
- wr,
- En,
- In,
- _n,
- An,
- P;
- const n = Vt(e);
- if (!n || (t && t.includes(n.id))) return !1;
- const { id: i, size: s } = n,
- a = e.filePos;
- switch ((Yt(s), i)) {
- case N.DocType:
- this.isWebM = an(e, s) === "webm";
- break;
- case N.Seek:
- {
- if (!this.currentSegment) break;
- const A = { id: -1, segmentPosition: -1 };
- (this.currentSegment.seekEntries.push(A),
- this.readContiguousElements(e.slice(a, s)),
- (A.id === -1 || A.segmentPosition === -1) &&
- this.currentSegment.seekEntries.pop());
- }
- break;
- case N.SeekID:
- {
- const A =
- (o = this.currentSegment) == null
- ? void 0
- : o.seekEntries[this.currentSegment.seekEntries.length - 1];
- if (!A) break;
- A.id = he(e, s);
- }
- break;
- case N.SeekPosition:
- {
- const A =
- (c = this.currentSegment) == null
- ? void 0
- : c.seekEntries[this.currentSegment.seekEntries.length - 1];
- if (!A) break;
- A.segmentPosition = he(e, s);
- }
- break;
- case N.TimestampScale:
- {
- if (!this.currentSegment) break;
- ((this.currentSegment.timestampScale = he(e, s)),
- (this.currentSegment.timestampFactor =
- 1e9 / this.currentSegment.timestampScale));
- }
- break;
- case N.Duration:
- {
- if (!this.currentSegment) break;
- this.currentSegment.duration = Rn(e, s);
- }
- break;
- case N.TrackEntry:
- {
- if (
- !this.currentSegment ||
- ((this.currentTrack = {
- id: -1,
- segment: this.currentSegment,
- demuxer: this,
- clusterPositionCache: [],
- cuePoints: [],
- disposition: { ...gr, primary: !1 },
- trackBacking: null,
- codecId: null,
- codecPrivate: null,
- defaultDuration: null,
- defaultDurationNs: null,
- name: null,
- languageCode: "eng",
- hasLanguageBcp47: !1,
- decodingInstructions: [],
- info: null,
- }),
- this.readContiguousElements(e.slice(a, s)),
- !this.currentTrack)
- )
- break;
- if (
- (this.currentTrack.decodingInstructions.some((A) => {
- var F;
- return (
- ((F = A.data) == null ? void 0 : F.type) !== "decompress" ||
- A.scope !== Ki.Block ||
- A.data.algorithm !== Xn.HeaderStripping
- );
- }) &&
- (te._warn(
- `Track #${this.currentTrack.id} has an unsupported content encoding; dropping.`,
- ),
- (this.currentTrack = null)),
- this.currentTrack &&
- this.currentTrack.id !== -1 &&
- this.currentTrack.codecId &&
- this.currentTrack.info)
- ) {
- const A = this.currentTrack.codecId.indexOf("/"),
- F =
- A === -1
- ? this.currentTrack.codecId
- : this.currentTrack.codecId.slice(0, A);
- if (
- this.currentTrack.info.type === "video" &&
- this.currentTrack.info.width !== -1 &&
- this.currentTrack.info.height !== -1
- ) {
- if (
- ((this.currentTrack.info.squarePixelWidth =
- this.currentTrack.info.width),
- (this.currentTrack.info.squarePixelHeight =
- this.currentTrack.info.height),
- this.currentTrack.info.displayWidth !== null &&
- this.currentTrack.info.displayHeight !== null)
- ) {
- const $ =
- this.currentTrack.info.displayWidth *
- this.currentTrack.info.height,
- W =
- this.currentTrack.info.displayHeight *
- this.currentTrack.info.width;
- $ > 0 &&
- W > 0 &&
- ($ > W
- ? (this.currentTrack.info.squarePixelWidth = Math.round(
- (this.currentTrack.info.width * $) / W,
- ))
- : (this.currentTrack.info.squarePixelHeight = Math.round(
- (this.currentTrack.info.height * W) / $,
- )));
- }
- if (this.currentTrack.codecId === at.avc)
- ((this.currentTrack.info.codec = "avc"),
- (this.currentTrack.info.codecDescription =
- this.currentTrack.codecPrivate));
- else if (this.currentTrack.codecId === at.hevc)
- ((this.currentTrack.info.codec = "hevc"),
- (this.currentTrack.info.codecDescription =
- this.currentTrack.codecPrivate));
- else if (F === at.vp8) this.currentTrack.info.codec = "vp8";
- else if (F === at.vp9) this.currentTrack.info.codec = "vp9";
- else if (F === at.av1) this.currentTrack.info.codec = "av1";
- else if (F === at.prores) {
- const $ = this.currentTrack.codecPrivate
- ? ot.decode(this.currentTrack.codecPrivate)
- : "";
- qr.includes($) &&
- ((this.currentTrack.info.codec = "prores"),
- (this.currentTrack.info.proresFormat = $));
- }
- const D = this.currentTrack;
- ((this.currentTrack.trackBacking = new rm(D)),
- this.currentSegment.tracks.push(this.currentTrack));
- } else if (this.currentTrack.info.type === "audio") {
- F === at.aac
- ? ((this.currentTrack.info.codec = "aac"),
- (this.currentTrack.info.aacCodecInfo = {
- isMpeg2: this.currentTrack.codecId.includes("MPEG2"),
- objectType: null,
- }),
- (this.currentTrack.info.codecDescription =
- this.currentTrack.codecPrivate))
- : this.currentTrack.codecId === at.mp3
- ? (this.currentTrack.info.codec = "mp3")
- : F === at.opus
- ? ((this.currentTrack.info.codec = "opus"),
- (this.currentTrack.info.codecDescription =
- this.currentTrack.codecPrivate),
- (this.currentTrack.info.sampleRate = ms))
- : F === at.vorbis
- ? ((this.currentTrack.info.codec = "vorbis"),
- (this.currentTrack.info.codecDescription =
- this.currentTrack.codecPrivate))
- : F === at.flac
- ? ((this.currentTrack.info.codec = "flac"),
- (this.currentTrack.info.codecDescription =
- this.currentTrack.codecPrivate))
- : F === at.ac3
- ? ((this.currentTrack.info.codec = "ac3"),
- (this.currentTrack.info.codecDescription =
- this.currentTrack.codecPrivate))
- : F === at.eac3
- ? ((this.currentTrack.info.codec = "eac3"),
- (this.currentTrack.info.codecDescription =
- this.currentTrack.codecPrivate))
- : F === at.dts
- ? ((this.currentTrack.info.codec = "dts"),
- this.currentTrack.codecId === "A_DTS/EXPRESS"
- ? (this.currentTrack.info.dtsFormat = "dtse")
- : this.currentTrack.codecId ===
- "A_DTS/LOSSLESS" &&
- (this.currentTrack.info.dtsFormat = "dtsl"))
- : this.currentTrack.codecId === "A_PCM/INT/LIT"
- ? this.currentTrack.info.bitDepth === 8
- ? (this.currentTrack.info.codec = "pcm-u8")
- : this.currentTrack.info.bitDepth === 16
- ? (this.currentTrack.info.codec = "pcm-s16")
- : this.currentTrack.info.bitDepth === 24
- ? (this.currentTrack.info.codec =
- "pcm-s24")
- : this.currentTrack.info.bitDepth ===
- 32 &&
- (this.currentTrack.info.codec =
- "pcm-s32")
- : this.currentTrack.codecId === "A_PCM/INT/BIG"
- ? this.currentTrack.info.bitDepth === 8
- ? (this.currentTrack.info.codec = "pcm-u8")
- : this.currentTrack.info.bitDepth === 16
- ? (this.currentTrack.info.codec =
- "pcm-s16be")
- : this.currentTrack.info.bitDepth === 24
- ? (this.currentTrack.info.codec =
- "pcm-s24be")
- : this.currentTrack.info.bitDepth ===
- 32 &&
- (this.currentTrack.info.codec =
- "pcm-s32be")
- : this.currentTrack.codecId ===
- "A_PCM/FLOAT/IEEE" &&
- (this.currentTrack.info.bitDepth === 32
- ? (this.currentTrack.info.codec =
- "pcm-f32")
- : this.currentTrack.info.bitDepth ===
- 64 &&
- (this.currentTrack.info.codec =
- "pcm-f64"));
- const D = this.currentTrack;
- ((this.currentTrack.trackBacking = new nm(D)),
- this.currentSegment.tracks.push(this.currentTrack));
- }
- }
- this.currentTrack = null;
- }
- break;
- case N.TrackNumber:
- {
- if (!this.currentTrack) break;
- this.currentTrack.id = he(e, s);
- }
- break;
- case N.TrackType:
- {
- if (!this.currentTrack) break;
- const A = he(e, s);
- A === 1
- ? (this.currentTrack.info = {
- type: "video",
- width: -1,
- height: -1,
- displayWidth: null,
- displayHeight: null,
- displayUnit: null,
- squarePixelWidth: -1,
- squarePixelHeight: -1,
- horizontalScale: 1,
- verticalScale: 1,
- rotation: 0,
- codec: null,
- codecDescription: null,
- colorSpace: { ...Pl },
- alphaMode: !1,
- proresFormat: null,
- })
- : A === 2 &&
- (this.currentTrack.info = {
- type: "audio",
- numberOfChannels: 1,
- sampleRate: 8e3,
- bitDepth: -1,
- codec: null,
- codecDescription: null,
- aacCodecInfo: null,
- dtsFormat: null,
- });
- }
- break;
- case N.FlagEnabled:
- {
- if (!this.currentTrack) break;
- he(e, s) || (this.currentTrack = null);
- }
- break;
- case N.FlagDefault:
- {
- if (!this.currentTrack) break;
- this.currentTrack.disposition.default = !!he(e, s);
- }
- break;
- case N.FlagForced:
- {
- if (!this.currentTrack) break;
- this.currentTrack.disposition.forced = !!he(e, s);
- }
- break;
- case N.FlagOriginal:
- {
- if (!this.currentTrack) break;
- this.currentTrack.disposition.original = !!he(e, s);
- }
- break;
- case N.FlagHearingImpaired:
- {
- if (!this.currentTrack) break;
- this.currentTrack.disposition.hearingImpaired = !!he(e, s);
- }
- break;
- case N.FlagVisualImpaired:
- {
- if (!this.currentTrack) break;
- this.currentTrack.disposition.visuallyImpaired = !!he(e, s);
- }
- break;
- case N.FlagCommentary:
- {
- if (!this.currentTrack) break;
- this.currentTrack.disposition.commentary = !!he(e, s);
- }
- break;
- case N.CodecID:
- {
- if (!this.currentTrack) break;
- this.currentTrack.codecId = an(e, s);
- }
- break;
- case N.CodecPrivate:
- {
- if (!this.currentTrack) break;
- this.currentTrack.codecPrivate = Z(e, s);
- }
- break;
- case N.DefaultDuration:
- {
- if (!this.currentTrack) break;
- this.currentTrack.defaultDurationNs = he(e, s);
- }
- break;
- case N.Name:
- {
- if (!this.currentTrack) break;
- this.currentTrack.name = Fn(e, s);
- }
- break;
- case N.Language:
- {
- if (!this.currentTrack || this.currentTrack.hasLanguageBcp47) break;
- ((this.currentTrack.languageCode = an(e, s)),
- qa(this.currentTrack.languageCode) ||
- (this.currentTrack.languageCode = nt));
- }
- break;
- case N.LanguageBCP47:
- {
- if (!this.currentTrack) break;
- const F = an(e, s).split("-")[0];
- (F
- ? (this.currentTrack.languageCode = F)
- : (this.currentTrack.languageCode = nt),
- (this.currentTrack.hasLanguageBcp47 = !0));
- }
- break;
- case N.Video:
- {
- if (
- ((l = (u = this.currentTrack) == null ? void 0 : u.info) == null
- ? void 0
- : l.type) !== "video"
- )
- break;
- this.readContiguousElements(e.slice(a, s));
- }
- break;
- case N.PixelWidth:
- {
- if (
- ((f = (d = this.currentTrack) == null ? void 0 : d.info) == null
- ? void 0
- : f.type) !== "video"
- )
- break;
- this.currentTrack.info.width = he(e, s);
- }
- break;
- case N.PixelHeight:
- {
- if (
- ((p = (h = this.currentTrack) == null ? void 0 : h.info) == null
- ? void 0
- : p.type) !== "video"
- )
- break;
- this.currentTrack.info.height = he(e, s);
- }
- break;
- case N.DisplayWidth:
- {
- if (
- ((b = (m = this.currentTrack) == null ? void 0 : m.info) == null
- ? void 0
- : b.type) !== "video"
- )
- break;
- this.currentTrack.info.displayWidth = he(e, s);
- }
- break;
- case N.DisplayHeight:
- {
- if (
- ((y = (g = this.currentTrack) == null ? void 0 : g.info) == null
- ? void 0
- : y.type) !== "video"
- )
- break;
- this.currentTrack.info.displayHeight = he(e, s);
- }
- break;
- case N.DisplayUnit:
- {
- if (
- ((_ = (C = this.currentTrack) == null ? void 0 : C.info) == null
- ? void 0
- : _.type) !== "video"
- )
- break;
- this.currentTrack.info.displayUnit = he(e, s);
- }
- break;
- case N.AlphaMode:
- {
- if (
- ((I = (v = this.currentTrack) == null ? void 0 : v.info) == null
- ? void 0
- : I.type) !== "video"
- )
- break;
- this.currentTrack.info.alphaMode = he(e, s) === 1;
- }
- break;
- case N.Colour:
- {
- if (
- ((x = (w = this.currentTrack) == null ? void 0 : w.info) == null
- ? void 0
- : x.type) !== "video"
- )
- break;
- this.readContiguousElements(e.slice(a, s));
- }
- break;
- case N.MatrixCoefficients:
- {
- if (
- ((S = (k = this.currentTrack) == null ? void 0 : k.info) == null
- ? void 0
- : S.type) !== "video"
- )
- break;
- const A = he(e, s),
- F = ir[A];
- this.currentTrack.info.colorSpace.matrix = F;
- }
- break;
- case N.Range:
- {
- if (
- ((B = (E = this.currentTrack) == null ? void 0 : E.info) == null
- ? void 0
- : B.type) !== "video"
- )
- break;
- const A = he(e, s);
- this.currentTrack.info.colorSpace.fullRange =
- A === 1 || A === 2 ? A === 2 : void 0;
- }
- break;
- case N.TransferCharacteristics:
- {
- if (
- ((M = (R = this.currentTrack) == null ? void 0 : R.info) == null
- ? void 0
- : M.type) !== "video"
- )
- break;
- const A = he(e, s),
- F = nr[A];
- this.currentTrack.info.colorSpace.transfer = F;
- }
- break;
- case N.Primaries:
- {
- if (
- ((q = (z = this.currentTrack) == null ? void 0 : z.info) == null
- ? void 0
- : q.type) !== "video"
- )
- break;
- const A = he(e, s),
- F = rr[A];
- this.currentTrack.info.colorSpace.primaries = F;
- }
- break;
- case N.Projection:
- {
- if (
- ((se = (j = this.currentTrack) == null ? void 0 : j.info) == null
- ? void 0
- : se.type) !== "video"
- )
- break;
- this.readContiguousElements(e.slice(a, s));
- }
- break;
- case N.ProjectionPoseYaw:
- {
- if (
- ((ue = (le = this.currentTrack) == null ? void 0 : le.info) == null
- ? void 0
- : ue.type) !== "video"
- )
- break;
- const A = Rn(e, s);
- try {
- const F = Gn(A);
- this.currentTrack.info.horizontalScale = Math.round(
- Math.cos(F * ma),
- );
- } catch {}
- }
- break;
- case N.ProjectionPosePitch:
- {
- if (
- ((K = ($e = this.currentTrack) == null ? void 0 : $e.info) == null
- ? void 0
- : K.type) !== "video"
- )
- break;
- const A = Rn(e, s);
- try {
- const F = Gn(A);
- this.currentTrack.info.verticalScale = Math.round(Math.cos(F * ma));
- } catch {}
- }
- break;
- case N.ProjectionPoseRoll:
- {
- if (
- ((Ie = (ie = this.currentTrack) == null ? void 0 : ie.info) == null
- ? void 0
- : Ie.type) !== "video"
- )
- break;
- const F = -Rn(e, s);
- try {
- this.currentTrack.info.rotation = Gn(F);
- } catch {}
- }
- break;
- case N.Audio:
- {
- if (
- ((Fe = (Ge = this.currentTrack) == null ? void 0 : Ge.info) == null
- ? void 0
- : Fe.type) !== "audio"
- )
- break;
- this.readContiguousElements(e.slice(a, s));
- }
- break;
- case N.SamplingFrequency:
- {
- if (
- ((He = (je = this.currentTrack) == null ? void 0 : je.info) == null
- ? void 0
- : He.type) !== "audio"
- )
- break;
- this.currentTrack.info.sampleRate = Rn(e, s);
- }
- break;
- case N.Channels:
- {
- if (
- ((Oe = (we = this.currentTrack) == null ? void 0 : we.info) == null
- ? void 0
- : Oe.type) !== "audio"
- )
- break;
- this.currentTrack.info.numberOfChannels = he(e, s);
- }
- break;
- case N.BitDepth:
- {
- if (
- ((_t = (st = this.currentTrack) == null ? void 0 : st.info) == null
- ? void 0
- : _t.type) !== "audio"
- )
- break;
- this.currentTrack.info.bitDepth = he(e, s);
- }
- break;
- case N.CuePoint:
- {
- if (!this.currentSegment) break;
- (this.readContiguousElements(e.slice(a, s)),
- (this.currentCueTime = null));
- }
- break;
- case N.CueTime:
- this.currentCueTime = he(e, s);
- break;
- case N.CueTrackPositions:
- {
- if (this.currentCueTime === null) break;
- T(this.currentSegment);
- const A = {
- time: this.currentCueTime,
- trackId: -1,
- clusterPosition: -1,
- };
- (this.currentSegment.cuePoints.push(A),
- this.readContiguousElements(e.slice(a, s)),
- (A.trackId === -1 || A.clusterPosition === -1) &&
- this.currentSegment.cuePoints.pop());
- }
- break;
- case N.CueTrack:
- {
- const A =
- (At = this.currentSegment) == null
- ? void 0
- : At.cuePoints[this.currentSegment.cuePoints.length - 1];
- if (!A) break;
- A.trackId = he(e, s);
- }
- break;
- case N.CueClusterPosition:
- {
- const A =
- (Ot = this.currentSegment) == null
- ? void 0
- : Ot.cuePoints[this.currentSegment.cuePoints.length - 1];
- if (!A) break;
- (T(this.currentSegment),
- (A.clusterPosition = this.currentSegment.dataStartPos + he(e, s)));
- }
- break;
- case N.Timestamp:
- {
- if (!this.currentCluster) break;
- this.currentCluster.timestamp = he(e, s);
- }
- break;
- case N.SimpleBlock:
- {
- if (!this.currentCluster) break;
- const A = jn(e);
- if (A === null) break;
- const F = this.getTrackDataInCluster(this.currentCluster, A);
- if (!F) break;
- const D = Na(e),
- $ = Y(e),
- W = ($ >> 1) & 3;
- let Q = !!($ & 128);
- ((wr = F.track.info) == null ? void 0 : wr.type) === "audio" &&
- F.track.info.codec &&
- (Q = !0);
- const re = Z(e, s - (e.filePos - a)),
- oe = F.track.decodingInstructions.length > 0;
- F.blocks.push({
- timestamp: D,
- duration: 0,
- isKeyFrame: Q,
- data: re,
- lacing: W,
- decoded: !oe,
- postProcessed: !1,
- mainAdditional: null,
- });
- }
- break;
- case N.BlockGroup:
- {
- if (!this.currentCluster) break;
- (this.readContiguousElements(e.slice(a, s)),
- (this.currentBlock = null));
- }
- break;
- case N.Block:
- {
- if (!this.currentCluster) break;
- const A = jn(e);
- if (A === null) break;
- const F = this.getTrackDataInCluster(this.currentCluster, A);
- if (!F) break;
- const D = Na(e),
- W = (Y(e) >> 1) & 3,
- Q = Z(e, s - (e.filePos - a)),
- re = F.track.decodingInstructions.length > 0;
- ((this.currentBlock = {
- timestamp: D,
- duration: 0,
- isKeyFrame: !0,
- data: Q,
- lacing: W,
- decoded: !re,
- postProcessed: !1,
- mainAdditional: null,
- }),
- F.blocks.push(this.currentBlock));
- }
- break;
- case N.BlockAdditions:
- this.readContiguousElements(e.slice(a, s));
- break;
- case N.BlockMore:
- {
- if (!this.currentBlock) break;
- ((this.currentBlockAdditional = { addId: 1, data: null }),
- this.readContiguousElements(e.slice(a, s)),
- this.currentBlockAdditional.data &&
- this.currentBlockAdditional.addId === 1 &&
- (this.currentBlock.mainAdditional =
- this.currentBlockAdditional.data),
- (this.currentBlockAdditional = null));
- }
- break;
- case N.BlockAdditional:
- {
- if (!this.currentBlockAdditional) break;
- this.currentBlockAdditional.data = Z(e, s);
- }
- break;
- case N.BlockAddID:
- {
- if (!this.currentBlockAdditional) break;
- this.currentBlockAdditional.addId = he(e, s);
- }
- break;
- case N.BlockDuration:
- {
- if (!this.currentBlock) break;
- this.currentBlock.duration = he(e, s);
- }
- break;
- case N.ReferenceBlock:
- {
- if (!this.currentBlock) break;
- this.currentBlock.isKeyFrame = !1;
- }
- break;
- case N.Tag:
- ((this.currentTagTargetIsMovie = !0),
- this.readContiguousElements(e.slice(a, s)));
- break;
- case N.Targets:
- this.readContiguousElements(e.slice(a, s));
- break;
- case N.TargetTypeValue:
- he(e, s) !== 50 && (this.currentTagTargetIsMovie = !1);
- break;
- case N.TagTrackUID:
- case N.TagEditionUID:
- case N.TagChapterUID:
- case N.TagAttachmentUID:
- this.currentTagTargetIsMovie = !1;
- break;
- case N.SimpleTag:
- {
- if (!this.currentTagTargetIsMovie) break;
- ((this.currentSimpleTagName = null),
- this.readContiguousElements(e.slice(a, s)));
- }
- break;
- case N.TagName:
- this.currentSimpleTagName = Fn(e, s);
- break;
- case N.TagString:
- {
- if (!this.currentSimpleTagName) break;
- const A = Fn(e, s);
- this.processTagValue(this.currentSimpleTagName, A);
- }
- break;
- case N.TagBinary:
- {
- if (!this.currentSimpleTagName) break;
- const A = Z(e, s);
- this.processTagValue(this.currentSimpleTagName, A);
- }
- break;
- case N.AttachedFile:
- {
- if (!this.currentSegment) break;
- ((this.currentAttachedFile = {
- fileUid: null,
- fileName: null,
- fileMediaType: null,
- fileData: null,
- fileDescription: null,
- }),
- this.readContiguousElements(e.slice(a, s)));
- const A = this.currentSegment.metadataTags;
- if (
- (this.currentAttachedFile.fileUid &&
- this.currentAttachedFile.fileData &&
- (A.raw ?? (A.raw = {}),
- (A.raw[this.currentAttachedFile.fileUid.toString()] = new _l(
- this.currentAttachedFile.fileData,
- this.currentAttachedFile.fileMediaType ?? void 0,
- this.currentAttachedFile.fileName ?? void 0,
- this.currentAttachedFile.fileDescription ?? void 0,
- ))),
- (En = this.currentAttachedFile.fileMediaType) != null &&
- En.startsWith("image/") &&
- this.currentAttachedFile.fileData)
- ) {
- const F = this.currentAttachedFile.fileName;
- let D = "unknown";
- if (F) {
- const $ = F.toLowerCase();
- $.startsWith("cover.")
- ? (D = "coverFront")
- : $.startsWith("back.") && (D = "coverBack");
- }
- (A.images ?? (A.images = []),
- A.images.push({
- data: this.currentAttachedFile.fileData,
- mimeType: this.currentAttachedFile.fileMediaType,
- kind: D,
- name: this.currentAttachedFile.fileName ?? void 0,
- description: this.currentAttachedFile.fileDescription ?? void 0,
- }));
- }
- this.currentAttachedFile = null;
- }
- break;
- case N.FileUID:
- {
- if (!this.currentAttachedFile) break;
- this.currentAttachedFile.fileUid = Jh(e, s);
- }
- break;
- case N.FileName:
- {
- if (!this.currentAttachedFile) break;
- this.currentAttachedFile.fileName = Fn(e, s);
- }
- break;
- case N.FileMediaType:
- {
- if (!this.currentAttachedFile) break;
- this.currentAttachedFile.fileMediaType = an(e, s);
- }
- break;
- case N.FileData:
- {
- if (!this.currentAttachedFile) break;
- this.currentAttachedFile.fileData = Z(e, s);
- }
- break;
- case N.FileDescription:
- {
- if (!this.currentAttachedFile) break;
- this.currentAttachedFile.fileDescription = Fn(e, s);
- }
- break;
- case N.ContentEncodings:
- {
- if (!this.currentTrack) break;
- (this.readContiguousElements(e.slice(a, s)),
- this.currentTrack.decodingInstructions.sort(
- (A, F) => F.order - A.order,
- ));
- }
- break;
- case N.ContentEncoding:
- ((this.currentDecodingInstruction = {
- order: 0,
- scope: Ki.Block,
- data: null,
- }),
- this.readContiguousElements(e.slice(a, s)),
- this.currentDecodingInstruction.data &&
- this.currentTrack.decodingInstructions.push(
- this.currentDecodingInstruction,
- ),
- (this.currentDecodingInstruction = null));
- break;
- case N.ContentEncodingOrder:
- {
- if (!this.currentDecodingInstruction) break;
- this.currentDecodingInstruction.order = he(e, s);
- }
- break;
- case N.ContentEncodingScope:
- {
- if (!this.currentDecodingInstruction) break;
- this.currentDecodingInstruction.scope = he(e, s);
- }
- break;
- case N.ContentCompression:
- {
- if (!this.currentDecodingInstruction) break;
- ((this.currentDecodingInstruction.data = {
- type: "decompress",
- algorithm: Xn.Zlib,
- settings: null,
- }),
- this.readContiguousElements(e.slice(a, s)));
- }
- break;
- case N.ContentCompAlgo:
- {
- if (
- ((_n =
- (In = this.currentDecodingInstruction) == null
- ? void 0
- : In.data) == null
- ? void 0
- : _n.type) !== "decompress"
- )
- break;
- this.currentDecodingInstruction.data.algorithm = he(e, s);
- }
- break;
- case N.ContentCompSettings:
- {
- if (
- ((P =
- (An = this.currentDecodingInstruction) == null
- ? void 0
- : An.data) == null
- ? void 0
- : P.type) !== "decompress"
- )
- break;
- this.currentDecodingInstruction.data.settings = Z(e, s);
- }
- break;
- case N.ContentEncryption:
- {
- if (!this.currentDecodingInstruction) break;
- this.currentDecodingInstruction.data = { type: "decrypt" };
- }
- break;
- }
- return ((e.filePos = a + s), !0);
- }
- decodeBlockData(e, t) {
- T(e.decodingInstructions.length > 0);
- let n = t;
- for (const i of e.decodingInstructions)
- switch ((T(i.data), i.data.type)) {
- case "decompress":
- switch (i.data.algorithm) {
- case Xn.HeaderStripping:
- if (i.data.settings && i.data.settings.length > 0) {
- const s = i.data.settings,
- a = new Uint8Array(s.length + n.length);
- (a.set(s, 0), a.set(n, s.length), (n = a));
- }
- break;
- }
- break;
- }
- return n;
- }
- processTagValue(e, t) {
- var i, s;
- if (!((i = this.currentSegment) != null && i.metadataTags)) return;
- const n = this.currentSegment.metadataTags;
- if (
- (n.raw ?? (n.raw = {}),
- (s = n.raw)[e] ?? (s[e] = t),
- typeof t == "string")
- )
- switch (e.toLowerCase()) {
- case "title":
- n.title ?? (n.title = t);
- break;
- case "description":
- n.description ?? (n.description = t);
- break;
- case "artist":
- n.artist ?? (n.artist = t);
- break;
- case "album":
- n.album ?? (n.album = t);
- break;
- case "album_artist":
- n.albumArtist ?? (n.albumArtist = t);
- break;
- case "genre":
- n.genre ?? (n.genre = t);
- break;
- case "bpm":
- {
- const a = Number.parseInt(t, 10);
- Number.isInteger(a) &&
- a > 0 &&
- (n.beatsPerMinute ?? (n.beatsPerMinute = a));
- }
- break;
- case "comment":
- n.comment ?? (n.comment = t);
- break;
- case "lyrics":
- n.lyrics ?? (n.lyrics = t);
- break;
- case "date":
- {
- const a = new Date(t);
- Number.isNaN(a.getTime()) || (n.date ?? (n.date = a));
- }
- break;
- case "track_number":
- case "part_number":
- {
- const a = t.split("/"),
- o = Number.parseInt(a[0], 10),
- c = a[1] && Number.parseInt(a[1], 10);
- (Number.isInteger(o) &&
- o > 0 &&
- (n.trackNumber ?? (n.trackNumber = o)),
- c &&
- Number.isInteger(c) &&
- c > 0 &&
- (n.tracksTotal ?? (n.tracksTotal = c)));
- }
- break;
- case "disc_number":
- case "disc":
- {
- const a = t.split("/"),
- o = Number.parseInt(a[0], 10),
- c = a[1] && Number.parseInt(a[1], 10);
- (Number.isInteger(o) &&
- o > 0 &&
- (n.discNumber ?? (n.discNumber = o)),
- c &&
- Number.isInteger(c) &&
- c > 0 &&
- (n.discsTotal ?? (n.discsTotal = c)));
- }
- break;
- }
- }
- getDurationFromMetadata(e) {
- return e.duration <= 0 ? null : e.duration / e.timestampFactor;
- }
-}
-class gu {
- constructor(e) {
- ((this.internalTrack = e), (this.packetToClusterLocation = new WeakMap()));
- }
- getId() {
- return this.internalTrack.id;
- }
- getNumber() {
- const e = this.internalTrack.demuxer,
- t = this.internalTrack.trackBacking.getType();
- let n = 0;
- for (const i of e.segments)
- for (const s of i.tracks)
- if ((s.trackBacking.getType() === t && n++, s === this.internalTrack))
- break;
- return n;
- }
- getCodec() {
- throw new Error("Not implemented on base class.");
- }
- getInternalCodecId() {
- return this.internalTrack.codecId;
- }
- getName() {
- return this.internalTrack.name;
- }
- getLanguageCode() {
- return this.internalTrack.languageCode;
- }
- getTimeResolution() {
- return this.internalTrack.segment.timestampFactor;
- }
- isRelativeToUnixEpoch() {
- return !1;
- }
- getUnixTimeForTimestamp() {
- return null;
- }
- getDisposition() {
- return this.internalTrack.disposition;
- }
- getPairingMask() {
- return 1n;
- }
- getBitrate() {
- return null;
- }
- getAverageBitrate() {
- return null;
- }
- async getDurationFromMetadata() {
- return this.internalTrack.demuxer.getDurationFromMetadata(
- this.internalTrack.segment,
- );
- }
- async getLiveRefreshInterval() {
- return null;
- }
- async getFirstPacket(e) {
- return this.performClusterLookup(
- null,
- (t) =>
- t.trackData.get(this.internalTrack.id)
- ? { blockIndex: 0, correctBlockFound: !0 }
- : { blockIndex: -1, correctBlockFound: !1 },
- -1 / 0,
- 1 / 0,
- e,
- );
- }
- intoTimescale(e) {
- return ni(e * this.internalTrack.segment.timestampFactor);
- }
- async getPacket(e, t) {
- const n = this.intoTimescale(e);
- return this.performClusterLookup(
- null,
- (i) => {
- const s = i.trackData.get(this.internalTrack.id);
- if (!s) return { blockIndex: -1, correctBlockFound: !1 };
- const a = ke(s.presentationTimestamps, n, (u) => u.timestamp),
- o = a !== -1 ? s.presentationTimestamps[a].blockIndex : -1,
- c = a !== -1 && n < s.endTimestamp;
- return { blockIndex: o, correctBlockFound: c };
- },
- n,
- n,
- t,
- );
- }
- async getNextPacket(e, t) {
- const n = this.packetToClusterLocation.get(e);
- if (n === void 0)
- throw new Error("Packet was not created from this track.");
- return this.performClusterLookup(
- n.cluster,
- (i) => {
- if (i === n.cluster) {
- const s = i.trackData.get(this.internalTrack.id);
- if (n.blockIndex + 1 < s.blocks.length)
- return { blockIndex: n.blockIndex + 1, correctBlockFound: !0 };
- } else if (i.trackData.get(this.internalTrack.id))
- return { blockIndex: 0, correctBlockFound: !0 };
- return { blockIndex: -1, correctBlockFound: !1 };
- },
- -1 / 0,
- 1 / 0,
- t,
- );
- }
- async getKeyPacket(e, t) {
- const n = this.intoTimescale(e);
- return this.performClusterLookup(
- null,
- (i) => {
- const s = i.trackData.get(this.internalTrack.id);
- if (!s) return { blockIndex: -1, correctBlockFound: !1 };
- const a = Va(
- s.presentationTimestamps,
- (u) => s.blocks[u.blockIndex].isKeyFrame && u.timestamp <= n,
- ),
- o = a !== -1 ? s.presentationTimestamps[a].blockIndex : -1,
- c = a !== -1 && n < s.endTimestamp;
- return { blockIndex: o, correctBlockFound: c };
- },
- n,
- n,
- t,
- );
- }
- async getNextKeyPacket(e, t) {
- const n = this.packetToClusterLocation.get(e);
- if (n === void 0)
- throw new Error("Packet was not created from this track.");
- return this.performClusterLookup(
- n.cluster,
- (i) => {
- if (i === n.cluster) {
- const a = i.trackData
- .get(this.internalTrack.id)
- .blocks.findIndex((o, c) => o.isKeyFrame && c > n.blockIndex);
- if (a !== -1) return { blockIndex: a, correctBlockFound: !0 };
- } else {
- const s = i.trackData.get(this.internalTrack.id);
- if (s && s.firstKeyFrameTimestamp !== null) {
- const a = s.blocks.findIndex((o) => o.isKeyFrame);
- return (T(a !== -1), { blockIndex: a, correctBlockFound: !0 });
- }
- }
- return { blockIndex: -1, correctBlockFound: !1 };
- },
- -1 / 0,
- 1 / 0,
- t,
- );
- }
- async fetchPacketInCluster(e, t, n) {
- var d, f;
- if (t === -1) return null;
- const s = e.trackData.get(this.internalTrack.id).blocks[t];
- if (
- (T(s),
- s.decoded ||
- ((s.data = this.internalTrack.demuxer.decodeBlockData(
- this.internalTrack,
- s.data,
- )),
- (s.decoded = !0)),
- !s.postProcessed)
- ) {
- if (
- ((d = this.internalTrack.info) == null ? void 0 : d.codec) ===
- "prores" &&
- !(
- s.data.length >= 8 &&
- s.data[4] === 105 &&
- s.data[5] === 99 &&
- s.data[6] === 112 &&
- s.data[7] === 102
- )
- ) {
- const p = new Uint8Array(s.data.length + 8);
- (ge(p).setUint32(0, p.length, !1),
- (p[4] = 105),
- (p[5] = 99),
- (p[6] = 112),
- (p[7] = 102),
- p.set(s.data, 8),
- (s.data = p));
- }
- s.postProcessed = !0;
- }
- const a = n.metadataOnly ? Tt : s.data,
- o = s.timestamp / this.internalTrack.segment.timestampFactor,
- c = s.duration / this.internalTrack.segment.timestampFactor,
- u = {};
- s.mainAdditional &&
- ((f = this.internalTrack.info) == null ? void 0 : f.type) === "video" &&
- this.internalTrack.info.alphaMode &&
- ((u.alpha = n.metadataOnly ? Tt : s.mainAdditional),
- (u.alphaByteLength = s.mainAdditional.byteLength));
- const l = new Ee(
- a,
- s.isKeyFrame ? "key" : "delta",
- o,
- c,
- e.dataStartPos + t,
- s.data.byteLength,
- u,
- );
- return (
- this.packetToClusterLocation.set(l, { cluster: e, blockIndex: t }),
- l
- );
- }
- async performClusterLookup(e, t, n, i, s) {
- const { demuxer: a, segment: o } = this.internalTrack;
- let c = null,
- u = null,
- l = -1;
- if (e) {
- const { blockIndex: g, correctBlockFound: y } = t(e);
- if (y) return this.fetchPacketInCluster(e, g, s);
- g !== -1 && ((u = e), (l = g));
- }
- const d = ke(this.internalTrack.cuePoints, n, (g) => g.time),
- f = d !== -1 ? this.internalTrack.cuePoints[d] : null,
- h = ke(
- this.internalTrack.clusterPositionCache,
- n,
- (g) => g.startTimestamp,
- ),
- p = h !== -1 ? this.internalTrack.clusterPositionCache[h] : null,
- m =
- Math.max(
- (f == null ? void 0 : f.clusterPosition) ?? 0,
- (p == null ? void 0 : p.elementStartPos) ?? 0,
- ) || null;
- let b;
- for (
- e
- ? m === null || e.elementStartPos >= m
- ? ((b = e.elementEndPos), (c = e))
- : (b = m)
- : (b = m ?? o.clusterSeekStartPos);
- o.elementEndPos === null || b <= o.elementEndPos - gt;
- ) {
- if (c) {
- const x = c.trackData.get(this.internalTrack.id);
- if (x && x.startTimestamp > i) break;
- }
- let g = a.reader.requestSliceRange(b, gt, Lt);
- if ((O(g) && (g = await g), !g)) break;
- const y = b,
- C = Vt(g);
- if (!C || (!li.includes(C.id) && C.id !== N.Void)) {
- const x = await mu(
- a.reader,
- y,
- li,
- Math.min(o.elementEndPos ?? 1 / 0, y + pu),
- );
- if (x) {
- b = x;
- continue;
- } else break;
- }
- const _ = C.id;
- let v = C.size;
- const I = g.filePos;
- if (_ === N.Cluster) {
- ((c = await a.readCluster(y, o)), (v = c.elementEndPos - I));
- const { blockIndex: x, correctBlockFound: k } = t(c);
- if (k) return this.fetchPacketInCluster(c, x, s);
- x !== -1 && ((u = c), (l = x));
- }
- v === void 0 &&
- (T(_ !== N.Cluster),
- (v = (await Ea(a.reader, I, Ni, o.elementEndPos)).pos - I));
- const w = I + v;
- if (o.elementEndPos === null) {
- let x = a.reader.requestSliceRange(w, gt, Lt);
- if ((O(x) && (x = await x), !x)) break;
- if (ao(x) === N.Segment) {
- o.elementEndPos = w;
- break;
- }
- }
- b = w;
- }
- if (f && (!u || u.elementStartPos < f.clusterPosition)) {
- const g = this.internalTrack.cuePoints[d - 1];
- T(!g || g.time < f.time);
- const y = (g == null ? void 0 : g.time) ?? -1 / 0;
- return this.performClusterLookup(null, t, y, i, s);
- }
- return u ? this.fetchPacketInCluster(u, l, s) : null;
- }
-}
-class rm extends gu {
- constructor(e) {
- (super(e), (this.decoderConfigPromise = null));
- }
- getType() {
- return "video";
- }
- getCodec() {
- return this.internalTrack.info.codec;
- }
- getCodedWidth() {
- return this.internalTrack.info.width;
- }
- getCodedHeight() {
- return this.internalTrack.info.height;
- }
- getSquarePixelWidth() {
- return this.internalTrack.info.squarePixelWidth;
- }
- getSquarePixelHeight() {
- return this.internalTrack.info.squarePixelHeight;
- }
- getTransformationMatrix() {
- const e = this.internalTrack.info,
- t = ti(Sl(e.horizontalScale, e.verticalScale), xl(e.rotation));
- return kl(t, e.width, e.height);
- }
- async getColorSpace() {
- var t, n, i, s;
- const e = await this.getDecoderConfig();
- return e
- ? {
- primaries: (t = e.colorSpace) == null ? void 0 : t.primaries,
- transfer: (n = e.colorSpace) == null ? void 0 : n.transfer,
- matrix: (i = e.colorSpace) == null ? void 0 : i.matrix,
- fullRange: (s = e.colorSpace) == null ? void 0 : s.fullRange,
- }
- : this.internalTrack.info.colorSpace;
- }
- async canBeTransparent() {
- return (
- this.internalTrack.info.alphaMode ||
- (this.internalTrack.info.codec === "prores" &&
- (this.internalTrack.info.proresFormat === "ap4h" ||
- this.internalTrack.info.proresFormat === "ap4x"))
- );
- }
- async getDecoderConfig() {
- return this.internalTrack.info.codec
- ? (this.decoderConfigPromise ??
- (this.decoderConfigPromise = (async () => {
- var s, a, o, c;
- let e = null;
- (this.internalTrack.info.codec === "vp9" ||
- this.internalTrack.info.codec === "av1" ||
- this.internalTrack.info.codec === "prores" ||
- (this.internalTrack.info.codec === "avc" &&
- !this.internalTrack.info.codecDescription) ||
- (this.internalTrack.info.codec === "hevc" &&
- !this.internalTrack.info.codecDescription)) &&
- (e = await this.getFirstPacket({}));
- const n = {
- width: this.internalTrack.info.width,
- height: this.internalTrack.info.height,
- codec: this.internalTrack.info.codec,
- codecDescription: this.internalTrack.info.codecDescription,
- colorSpace: this.internalTrack.info.colorSpace,
- avcType: 1,
- avcCodecInfo:
- this.internalTrack.info.codec === "avc" && e
- ? bi(e.data)
- : null,
- hevcCodecInfo:
- this.internalTrack.info.codec === "hevc" && e
- ? wi(e.data)
- : null,
- vp9CodecInfo:
- this.internalTrack.info.codec === "vp9" && e
- ? Za(e.data)
- : null,
- av1CodecInfo:
- this.internalTrack.info.codec === "av1" && e
- ? ds(e.data)
- : null,
- proresCodecInfo:
- this.internalTrack.info.codec === "prores" && e
- ? Ul(e.data)
- : null,
- proresFormat: this.internalTrack.info.proresFormat,
- };
- if (!Ha(this.internalTrack.info.colorSpace)) {
- const u = Ql(n);
- ((s = this.internalTrack.info.colorSpace).primaries ??
- (s.primaries = u.primaries),
- (a = this.internalTrack.info.colorSpace).transfer ??
- (a.transfer = u.transfer),
- (o = this.internalTrack.info.colorSpace).matrix ??
- (o.matrix = u.matrix),
- (c = this.internalTrack.info.colorSpace).fullRange ??
- (c.fullRange = u.fullRange));
- }
- const i = {
- codec: hs(n),
- codedWidth: this.internalTrack.info.width,
- codedHeight: this.internalTrack.info.height,
- description: this.internalTrack.info.codecDescription ?? void 0,
- colorSpace: this.internalTrack.info.colorSpace,
- };
- return (
- (this.internalTrack.info.width !==
- this.internalTrack.info.squarePixelWidth ||
- this.internalTrack.info.height !==
- this.internalTrack.info.squarePixelHeight) &&
- ((i.displayAspectWidth =
- this.internalTrack.info.squarePixelWidth),
- (i.displayAspectHeight =
- this.internalTrack.info.squarePixelHeight)),
- i
- );
- })()))
- : null;
- }
-}
-class nm extends gu {
- constructor(e) {
- (super(e), (this.decoderConfigPromise = null));
- }
- getType() {
- return "audio";
- }
- getCodec() {
- return this.internalTrack.info.codec;
- }
- getNumberOfChannels() {
- return this.internalTrack.info.numberOfChannels;
- }
- getSampleRate() {
- return this.internalTrack.info.sampleRate;
- }
- async getDecoderConfig() {
- return this.internalTrack.info.codec
- ? (this.decoderConfigPromise ??
- (this.decoderConfigPromise = (async () => {
- if (
- this.internalTrack.info.codec === "dts" &&
- !this.internalTrack.info.dtsFormat
- ) {
- const e = await this.getFirstPacket({});
- this.internalTrack.info.dtsFormat = e && Kl(e.data);
- }
- return {
- codec: no({
- codec: this.internalTrack.info.codec,
- codecDescription: this.internalTrack.info.codecDescription,
- aacCodecInfo: this.internalTrack.info.aacCodecInfo,
- dtsFormat: this.internalTrack.info.dtsFormat,
- }),
- numberOfChannels: this.internalTrack.info.numberOfChannels,
- sampleRate: this.internalTrack.info.sampleRate,
- description: this.internalTrack.info.codecDescription ?? void 0,
- };
- })()))
- : null;
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const Ia = async (r, e, t, n = null) => {
- let s = e;
- for (; t === null || s < t;) {
- const a = t !== null ? Math.min(65536, t - s) : 65536;
- let o = r.requestSliceRange(s, jr, a);
- if ((O(o) && (o = await o), !o || o.length < jr)) break;
- for (; o.remainingLength >= jr;) {
- const c = o.filePos,
- u = L(o),
- l = r.fileSize !== null ? r.fileSize - s : null,
- d = io(u, l);
- if (
- d.header &&
- (!n ||
- (d.header.sampleRate === n.sampleRate &&
- d.header.mpegVersionId === n.mpegVersionId &&
- d.header.layer === n.layer &&
- ci(d.header.channel) === ci(n.channel)))
- )
- return { header: d.header, startPos: s };
- ((o.filePos = c + d.bytesAdvanced), (s = o.filePos));
- }
- }
- return null;
-};
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class im extends br {
- constructor(e) {
- (super(e),
- (this.metadataPromise = null),
- (this.firstFrameHeader = null),
- (this.firstFrameHeaderPos = null),
- (this.xingFrameHeader = null),
- (this.xingFrameHeaderPos = null),
- (this.loadedSamples = []),
- (this.metadataTags = null),
- (this.xingData = null),
- (this.trackBackings = []),
- (this.readingMutex = new Cn()),
- (this.lastSampleLoaded = !1),
- (this.lastLoadedPos = 0),
- (this.nextTimestampInSamples = 0),
- (this.reader = e._reader));
- }
- async readMetadata() {
- return (
- this.metadataPromise ??
- (this.metadataPromise = (async () => {
- for (; !this.firstFrameHeader && !this.lastSampleLoaded;)
- await this.advanceReader();
- if (
- (!this.firstFrameHeader &&
- this.xingFrameHeader &&
- ((this.firstFrameHeader = this.xingFrameHeader),
- (this.firstFrameHeaderPos = this.xingFrameHeaderPos)),
- !this.firstFrameHeader)
- )
- throw new Error("No valid MP3 frame found.");
- this.trackBackings = [new sm(this)];
- })())
- );
- }
- async advanceReader() {
- if (this.lastLoadedPos === 0)
- for (;;) {
- let o = this.reader.requestSlice(this.lastLoadedPos, Et);
- if ((O(o) && (o = await o), !o)) {
- this.lastSampleLoaded = !0;
- return;
- }
- const c = hr(o);
- if (!c) break;
- this.lastLoadedPos = o.filePos + c.size;
- }
- const e = await Ia(
- this.reader,
- this.lastLoadedPos,
- this.reader.fileSize,
- this.firstFrameHeader,
- );
- if (!e) {
- this.lastSampleLoaded = !0;
- return;
- }
- const t = e.header;
- this.lastLoadedPos = e.startPos + t.totalSize - 1;
- const n = ru(t.mpegVersionId, t.channel);
- let i = this.reader.requestSlice(e.startPos + n, 4);
- if ((O(i) && (i = await i), i)) {
- const o = L(i);
- if (o === eu || o === tu) {
- if (
- (this.xingFrameHeader ||
- ((this.xingFrameHeader = t),
- (this.xingFrameHeaderPos = e.startPos)),
- !this.xingData)
- ) {
- let u = this.reader.requestSlice(e.startPos + n + 4, 12);
- if ((O(u) && (u = await u), u)) {
- const l = Z(u, 12),
- d = ge(l),
- f = d.getUint32(0, !1);
- this.xingData = {
- frameCount: f & Gi.FrameCount ? d.getUint32(4, !1) : null,
- fileSize: f & Gi.FileSize ? d.getUint32(8, !1) : null,
- };
- }
- }
- return;
- }
- }
- this.firstFrameHeader ||
- ((this.firstFrameHeader = t), (this.firstFrameHeaderPos = e.startPos));
- const s = t.audioSamplesInFrame / this.firstFrameHeader.sampleRate,
- a = {
- timestamp:
- this.nextTimestampInSamples / this.firstFrameHeader.sampleRate,
- duration: s,
- dataStart: e.startPos,
- dataSize: t.totalSize,
- };
- (this.loadedSamples.push(a),
- (this.nextTimestampInSamples += t.audioSamplesInFrame));
- }
- async getMimeType() {
- return "audio/mpeg";
- }
- async getTrackBackings() {
- return (await this.readMetadata(), this.trackBackings);
- }
- async getMetadataTags() {
- const e = await this.readingMutex.acquire();
- try {
- if ((await this.readMetadata(), this.metadataTags))
- return this.metadataTags;
- this.metadataTags = {};
- let t = 0,
- n = !1;
- for (;;) {
- let i = this.reader.requestSlice(t, Et);
- if ((O(i) && (i = await i), !i)) break;
- const s = hr(i);
- if (!s) break;
- n = !0;
- let a = this.reader.requestSlice(i.filePos, s.size);
- if ((O(a) && (a = await a), !a)) break;
- (ks(a, s, this.metadataTags), (t = i.filePos + s.size));
- }
- if (!n && this.reader.fileSize !== null && this.reader.fileSize >= Di) {
- let i = this.reader.requestSlice(this.reader.fileSize - Di, Di);
- (O(i) && (i = await i),
- T(i),
- Ne(i, 3) === "TAG" && r0(i, this.metadataTags));
- }
- return this.metadataTags;
- } finally {
- e();
- }
- }
-}
-class sm {
- constructor(e) {
- this.demuxer = e;
- }
- getType() {
- return "audio";
- }
- getId() {
- return 1;
- }
- getNumber() {
- return 1;
- }
- getTimeResolution() {
- return (
- T(this.demuxer.firstFrameHeader),
- this.demuxer.firstFrameHeader.sampleRate /
- this.demuxer.firstFrameHeader.audioSamplesInFrame
- );
- }
- isRelativeToUnixEpoch() {
- return !1;
- }
- getUnixTimeForTimestamp() {
- return null;
- }
- getPairingMask() {
- return 1n;
- }
- getBitrate() {
- return null;
- }
- getAverageBitrate() {
- return null;
- }
- async getDurationFromMetadata() {
- const e = this.demuxer;
- if (
- (T(e.firstFrameHeader !== null),
- T(e.firstFrameHeaderPos !== null),
- e.xingData)
- ) {
- if (e.xingData.frameCount !== null)
- return (
- (e.xingData.frameCount * e.firstFrameHeader.audioSamplesInFrame) /
- e.firstFrameHeader.sampleRate
- );
- } else if (e.reader.fileSize !== null) {
- const t = Lh(
- e.firstFrameHeader.lowSamplingFrequency,
- e.firstFrameHeader.layer,
- e.firstFrameHeader.bitrate,
- e.firstFrameHeader.sampleRate,
- ),
- n = (e.reader.fileSize - e.firstFrameHeaderPos) / t;
- return (
- (Math.round(n) * e.firstFrameHeader.audioSamplesInFrame) /
- e.firstFrameHeader.sampleRate
- );
- }
- return null;
- }
- async getLiveRefreshInterval() {
- return null;
- }
- getName() {
- return null;
- }
- getLanguageCode() {
- return nt;
- }
- getCodec() {
- return "mp3";
- }
- getInternalCodecId() {
- return null;
- }
- getNumberOfChannels() {
- return (
- T(this.demuxer.firstFrameHeader),
- ci(this.demuxer.firstFrameHeader.channel)
- );
- }
- getSampleRate() {
- return (
- T(this.demuxer.firstFrameHeader),
- this.demuxer.firstFrameHeader.sampleRate
- );
- }
- getDisposition() {
- return { ...gr };
- }
- async getDecoderConfig() {
- return (
- T(this.demuxer.firstFrameHeader),
- {
- codec: "mp3",
- numberOfChannels: ci(this.demuxer.firstFrameHeader.channel),
- sampleRate: this.demuxer.firstFrameHeader.sampleRate,
- }
- );
- }
- async getPacketAtIndex(e, t) {
- if (e === -1) return null;
- const n = this.demuxer.loadedSamples[e];
- if (!n) return null;
- let i;
- if (t.metadataOnly) i = Tt;
- else {
- let s = this.demuxer.reader.requestSlice(n.dataStart, n.dataSize);
- if ((O(s) && (s = await s), !s)) return null;
- i = Z(s, n.dataSize);
- }
- return new Ee(i, "key", n.timestamp, n.duration, e, n.dataSize);
- }
- getFirstPacket(e) {
- return this.getPacketAtIndex(0, e);
- }
- async getNextPacket(e, t) {
- const n = await this.demuxer.readingMutex.acquire();
- try {
- const i = fi(this.demuxer.loadedSamples, e.timestamp, (a) => a.timestamp);
- if (i === -1) throw new Error("Packet was not created from this track.");
- const s = i + 1;
- for (
- ;
- s >= this.demuxer.loadedSamples.length &&
- !this.demuxer.lastSampleLoaded;
- )
- await this.demuxer.advanceReader();
- return this.getPacketAtIndex(s, t);
- } finally {
- n();
- }
- }
- async getPacket(e, t) {
- const n = await this.demuxer.readingMutex.acquire();
- try {
- for (;;) {
- const i = ke(this.demuxer.loadedSamples, e, (s) => s.timestamp);
- if (i === -1 && this.demuxer.loadedSamples.length > 0) return null;
- if (this.demuxer.lastSampleLoaded) return this.getPacketAtIndex(i, t);
- if (i >= 0 && i + 1 < this.demuxer.loadedSamples.length)
- return this.getPacketAtIndex(i, t);
- await this.demuxer.advanceReader();
- }
- } finally {
- n();
- }
- }
- getKeyPacket(e, t) {
- return this.getPacket(e, t);
- }
- getNextKeyPacket(e, t) {
- return this.getNextPacket(e, t);
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const bu = 1399285583,
- am = 79764919,
- wu = new Uint32Array(256);
-for (let r = 0; r < 256; r++) {
- let e = r << 24;
- for (let t = 0; t < 8; t++) e = e & 2147483648 ? (e << 1) ^ am : e << 1;
- wu[r] = (e >>> 0) & 4294967295;
-}
-const om = (r) => {
- const e = ge(r),
- t = e.getUint32(22, !0);
- e.setUint32(22, 0, !0);
- let n = 0;
- for (let i = 0; i < r.length; i++) {
- const s = r[i];
- n = ((n << 8) ^ wu[(n >>> 24) ^ s]) >>> 0;
- }
- return (e.setUint32(22, t, !0), n);
- },
- rc = (r, e, t) => {
- let n = 0,
- i = null;
- if (r.length > 0)
- if (e.codec === "vorbis") {
- T(e.vorbisInfo);
- const s = e.vorbisInfo.modeBlockflags.length,
- o = ((1 << Df(s - 1)) - 1) << 1,
- c = (r[0] & o) >> 1;
- if (c >= e.vorbisInfo.modeBlockflags.length)
- throw new Error("Invalid mode number.");
- let u = t;
- const l = e.vorbisInfo.modeBlockflags[c];
- if (((i = e.vorbisInfo.blocksizes[l]), l === 1)) {
- const d = (o | 1) + 1,
- f = r[0] & d ? 1 : 0;
- u = e.vorbisInfo.blocksizes[f];
- }
- n = u !== null ? (u + i) >> 2 : 0;
- } else e.codec === "opus" && (n = ch(r).durationInSamples);
- return { durationInSamples: n, vorbisBlockSize: i };
- },
- cm = (r) => {
- let e = "audio/ogg";
- if (r.codecStrings) {
- const t = [...new Set(r.codecStrings)];
- e += `; codecs="${t.join(", ")}"`;
- }
- return e;
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const Ir = 27,
- mn = 282,
- lm = mn + 65025,
- Qn = (r) => {
- const e = r.filePos;
- if (ln(r) !== bu) return null;
- r.skip(1);
- const n = Y(r),
- i = e0(r),
- s = ln(r),
- a = ln(r),
- o = ln(r),
- c = Y(r),
- u = new Uint8Array(c);
- for (let h = 0; h < c; h++) u[h] = Y(r);
- const l = 27 + c,
- d = u.reduce((h, p) => h + p, 0),
- f = l + d;
- return {
- headerStartPos: e,
- totalSize: f,
- dataStartPos: e + l,
- dataSize: d,
- headerType: n,
- granulePosition: i,
- serialNumber: s,
- sequenceNumber: a,
- checksum: o,
- lacingValues: u,
- };
- },
- um = (r, e) => {
- for (; r.filePos < e - 3;) {
- const t = ln(r),
- n = t & 255,
- i = (t >>> 8) & 255,
- s = (t >>> 16) & 255,
- a = (t >>> 24) & 255,
- o = 79;
- if (!(n !== o && i !== o && s !== o && a !== o)) {
- if ((r.skip(-4), t === bu)) return !0;
- r.skip(1);
- }
- }
- return !1;
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class dm extends br {
- constructor(e) {
- (super(e),
- (this.metadataPromise = null),
- (this.bitstreams = []),
- (this.trackBackings = []),
- (this.metadataTags = {}),
- (this.reader = e._reader));
- }
- async readMetadata() {
- return (
- this.metadataPromise ??
- (this.metadataPromise = (async () => {
- let e = 0;
- for (;;) {
- let t = this.reader.requestSliceRange(e, Ir, mn);
- if ((O(t) && (t = await t), !t)) break;
- const n = Qn(t);
- if (!n || !!!(n.headerType & 2)) break;
- (this.bitstreams.push({
- serialNumber: n.serialNumber,
- bosPage: n,
- description: null,
- numberOfChannels: -1,
- sampleRate: -1,
- codecInfo: { codec: null, vorbisInfo: null, opusInfo: null },
- lastMetadataPacket: null,
- }),
- (e = n.headerStartPos + n.totalSize));
- }
- for (const t of this.bitstreams) {
- const n = await this.readPacket(t.bosPage, 0);
- n &&
- (n.data.byteLength >= 7 &&
- n.data[0] === 1 &&
- n.data[1] === 118 &&
- n.data[2] === 111 &&
- n.data[3] === 114 &&
- n.data[4] === 98 &&
- n.data[5] === 105 &&
- n.data[6] === 115
- ? await this.readVorbisMetadata(n, t)
- : n.data.byteLength >= 8 &&
- n.data[0] === 79 &&
- n.data[1] === 112 &&
- n.data[2] === 117 &&
- n.data[3] === 115 &&
- n.data[4] === 72 &&
- n.data[5] === 101 &&
- n.data[6] === 97 &&
- n.data[7] === 100 &&
- (await this.readOpusMetadata(n, t)),
- t.codecInfo.codec !== null &&
- this.trackBackings.push(new fm(t, this)));
- }
- })())
- );
- }
- async readVorbisMetadata(e, t) {
- let n = await this.findNextPacketStart(e);
- if (!n) return;
- const i = await this.readPacket(n.startPage, n.startSegmentIndex);
- if (!i || ((n = await this.findNextPacketStart(i)), !n)) return;
- const s = await this.readPacket(n.startPage, n.startSegmentIndex);
- if (!s || i.data[0] !== 3 || s.data[0] !== 5) return;
- const a = [],
- o = (d) => {
- for (; a.push(Math.min(255, d)), !(d < 255);) d -= 255;
- };
- (o(e.data.length), o(i.data.length));
- const c = new Uint8Array(
- 1 + a.length + e.data.length + i.data.length + s.data.length,
- );
- ((c[0] = 2),
- c.set(a, 1),
- c.set(e.data, 1 + a.length),
- c.set(i.data, 1 + a.length + e.data.length),
- c.set(s.data, 1 + a.length + e.data.length + i.data.length),
- (t.codecInfo.codec = "vorbis"),
- (t.description = c),
- (t.lastMetadataPacket = s));
- const u = ge(e.data);
- ((t.numberOfChannels = u.getUint8(11)),
- (t.sampleRate = u.getUint32(12, !0)));
- const l = u.getUint8(28);
- ((t.codecInfo.vorbisInfo = {
- blocksizes: [1 << (l & 15), 1 << (l >> 4)],
- modeBlockflags: lh(s.data).modeBlockflags,
- }),
- xa(i.data.subarray(7), this.metadataTags));
- }
- async readOpusMetadata(e, t) {
- const n = await this.findNextPacketStart(e);
- if (!n) return;
- const i = await this.readPacket(n.startPage, n.startSegmentIndex);
- if (!i) return;
- ((t.codecInfo.codec = "opus"),
- (t.description = e.data),
- (t.lastMetadataPacket = i));
- const s = Hl(e.data);
- ((t.numberOfChannels = s.outputChannelCount),
- (t.sampleRate = ms),
- (t.codecInfo.opusInfo = { preSkip: s.preSkip }),
- xa(i.data.subarray(8), this.metadataTags));
- }
- async readPacket(e, t) {
- T(t < e.lacingValues.length);
- let n = 0;
- for (let d = 0; d < t; d++) n += e.lacingValues[d];
- let i = e,
- s = n,
- a = t;
- const o = [];
- e: for (;;) {
- let d = this.reader.requestSlice(i.dataStartPos, i.dataSize);
- (O(d) && (d = await d), T(d));
- const f = Z(d, i.dataSize);
- for (;;) {
- if (a === i.lacingValues.length) {
- o.push(f.subarray(n, s));
- break;
- }
- const p = i.lacingValues[a];
- if (((s += p), p < 255)) {
- o.push(f.subarray(n, s));
- break e;
- }
- a++;
- }
- let h = i.headerStartPos + i.totalSize;
- for (;;) {
- let p = this.reader.requestSliceRange(h, Ir, mn);
- if ((O(p) && (p = await p), !p)) return null;
- const m = Qn(p);
- if (!m) return null;
- if (((i = m), i.serialNumber === e.serialNumber)) break;
- h = i.headerStartPos + i.totalSize;
- }
- ((n = 0), (s = 0), (a = 0));
- }
- const c = o.reduce((d, f) => d + f.length, 0);
- if (c === 0) return null;
- const u = new Uint8Array(c);
- let l = 0;
- for (let d = 0; d < o.length; d++) {
- const f = o[d];
- (u.set(f, l), (l += f.length));
- }
- return { data: u, endPage: i, endSegmentIndex: a };
- }
- async findNextPacketStart(e) {
- if (e.endSegmentIndex < e.endPage.lacingValues.length - 1)
- return { startPage: e.endPage, startSegmentIndex: e.endSegmentIndex + 1 };
- if (!!(e.endPage.headerType & 4)) return null;
- let n = e.endPage.headerStartPos + e.endPage.totalSize;
- for (;;) {
- let i = this.reader.requestSliceRange(n, Ir, mn);
- if ((O(i) && (i = await i), !i)) return null;
- const s = Qn(i);
- if (!s) return null;
- if (s.serialNumber === e.endPage.serialNumber)
- return { startPage: s, startSegmentIndex: 0 };
- n = s.headerStartPos + s.totalSize;
- }
- }
- async getMimeType() {
- await this.readMetadata();
- const e = await Promise.all(
- this.trackBackings.map((t) =>
- t
- .getDecoderConfig()
- .then((n) => (n == null ? void 0 : n.codec) ?? null),
- ),
- );
- return cm({ codecStrings: e.filter(Boolean) });
- }
- async getTrackBackings() {
- return (await this.readMetadata(), this.trackBackings);
- }
- async getMetadataTags() {
- return (await this.readMetadata(), this.metadataTags);
- }
-}
-class fm {
- constructor(e, t) {
- ((this.bitstream = e),
- (this.demuxer = t),
- (this.encodedPacketToMetadata = new WeakMap()),
- (this.sequentialScanCache = []),
- (this.sequentialScanMutex = new Cn()),
- (this.firstTimestampInSamplesPromise = null),
- (this.internalSampleRate =
- e.codecInfo.codec === "opus" ? ms : e.sampleRate));
- }
- getType() {
- return "audio";
- }
- getId() {
- return this.bitstream.serialNumber;
- }
- getNumber() {
- const e = this.demuxer.trackBackings.findIndex(
- (t) => t.bitstream === this.bitstream,
- );
- return (T(e !== -1), e + 1);
- }
- getNumberOfChannels() {
- return this.bitstream.numberOfChannels;
- }
- getSampleRate() {
- return this.bitstream.sampleRate;
- }
- getTimeResolution() {
- return this.bitstream.sampleRate;
- }
- isRelativeToUnixEpoch() {
- return !1;
- }
- getUnixTimeForTimestamp() {
- return null;
- }
- getPairingMask() {
- return 1n;
- }
- getBitrate() {
- return null;
- }
- getAverageBitrate() {
- return null;
- }
- async getDurationFromMetadata() {
- return null;
- }
- async getLiveRefreshInterval() {
- return null;
- }
- getCodec() {
- return this.bitstream.codecInfo.codec;
- }
- getInternalCodecId() {
- return null;
- }
- async getDecoderConfig() {
- return (
- T(this.bitstream.codecInfo.codec),
- {
- codec: this.bitstream.codecInfo.codec,
- numberOfChannels: this.bitstream.numberOfChannels,
- sampleRate: this.bitstream.sampleRate,
- description: this.bitstream.description ?? void 0,
- }
- );
- }
- getName() {
- return null;
- }
- getLanguageCode() {
- return nt;
- }
- getDisposition() {
- return { ...gr, primary: !1 };
- }
- granulePositionToTimestampInSamples(e) {
- return this.bitstream.codecInfo.codec === "opus"
- ? (T(this.bitstream.codecInfo.opusInfo),
- e - this.bitstream.codecInfo.opusInfo.preSkip)
- : e;
- }
- createEncodedPacketFromOggPacket(e, t, n) {
- if (!e) return null;
- const i = rc(e.data, this.bitstream.codecInfo, t.vorbisLastBlocksize),
- { vorbisBlockSize: s } = i;
- let { durationInSamples: a } = i;
- if (
- !!(e.endPage.headerType & 4) &&
- e.endSegmentIndex === e.endPage.lacingValues.length - 1
- ) {
- const d = this.granulePositionToTimestampInSamples(
- e.endPage.granulePosition,
- );
- a = De(d - t.timestampInSamples, 0, a);
- }
- const c = Math.max(t.timestampInSamples, 0),
- u = Math.max(t.timestampInSamples + a, 0),
- l = new Ee(
- n.metadataOnly ? Tt : e.data,
- "key",
- c / this.internalSampleRate,
- (u - c) / this.internalSampleRate,
- e.endPage.headerStartPos + e.endSegmentIndex,
- e.data.byteLength,
- );
- return (
- this.encodedPacketToMetadata.set(l, {
- packet: e,
- timestampInSamples: t.timestampInSamples,
- durationInSamples: a,
- vorbisLastBlockSize: t.vorbisLastBlocksize,
- vorbisBlockSize: s,
- }),
- l
- );
- }
- getFirstTimestampInSamples() {
- return (
- this.firstTimestampInSamplesPromise ??
- (this.firstTimestampInSamplesPromise = (async () => {
- const e = this.granulePositionToTimestampInSamples(0);
- T(this.bitstream.lastMetadataPacket);
- let t = await this.demuxer.findNextPacketStart(
- this.bitstream.lastMetadataPacket,
- );
- if (!t) return e;
- let n = null,
- i = 0,
- s = null;
- for (; t;) {
- const a = await this.demuxer.readPacket(
- t.startPage,
- t.startSegmentIndex,
- );
- if (
- !a ||
- (n ?? (n = a.endPage),
- a.endPage.headerStartPos !== n.headerStartPos)
- )
- break;
- const { durationInSamples: o, vorbisBlockSize: c } = rc(
- a.data,
- this.bitstream.codecInfo,
- s,
- );
- ((i += o), (s = c), (t = await this.demuxer.findNextPacketStart(a)));
- }
- return n ? e + Math.max(n.granulePosition - i, 0) : e;
- })())
- );
- }
- async getFirstPacket(e) {
- T(this.bitstream.lastMetadataPacket);
- const t = await this.demuxer.findNextPacketStart(
- this.bitstream.lastMetadataPacket,
- );
- if (!t) return null;
- const n = await this.getFirstTimestampInSamples(),
- i = await this.demuxer.readPacket(t.startPage, t.startSegmentIndex);
- return this.createEncodedPacketFromOggPacket(
- i,
- { timestampInSamples: n, vorbisLastBlocksize: null },
- e,
- );
- }
- async getNextPacket(e, t) {
- const n = this.encodedPacketToMetadata.get(e);
- if (!n) throw new Error("Packet was not created from this track.");
- const i = await this.demuxer.findNextPacketStart(n.packet);
- if (!i) return null;
- const s = n.timestampInSamples + n.durationInSamples,
- a = await this.demuxer.readPacket(i.startPage, i.startSegmentIndex);
- return this.createEncodedPacketFromOggPacket(
- a,
- { timestampInSamples: s, vorbisLastBlocksize: n.vorbisBlockSize },
- t,
- );
- }
- async getPacket(e, t) {
- if (this.demuxer.reader.fileSize === null)
- return this.getPacketSequential(e, t);
- const n = ni(e * this.internalSampleRate),
- i = await this.getFirstTimestampInSamples();
- if (n === Math.max(i, 0)) return this.getFirstPacket(t);
- if (n < Math.max(i, 0)) return null;
- T(this.bitstream.lastMetadataPacket);
- const s = await this.demuxer.findNextPacketStart(
- this.bitstream.lastMetadataPacket,
- );
- if (!s) return null;
- let a = s.startPage,
- o = this.demuxer.reader.fileSize;
- const c = [a];
- e: for (; a.headerStartPos + a.totalSize < o;) {
- const C = a.headerStartPos,
- _ = Math.floor((C + o) / 2);
- let v = _;
- for (;;) {
- const I = Math.min(v + lm, o - Ir);
- let w = this.demuxer.reader.requestSlice(v, I - v);
- if ((O(w) && (w = await w), T(w), !um(w, I))) {
- if (o <= _ + Ir) break e;
- o = _ + Ir;
- continue e;
- }
- let k = this.demuxer.reader.requestSliceRange(w.filePos, Ir, mn);
- (O(k) && (k = await k), T(k));
- const S = Qn(k);
- T(S);
- let E = !1;
- if (S.serialNumber === this.bitstream.serialNumber) E = !0;
- else {
- let R = this.demuxer.reader.requestSlice(
- S.headerStartPos,
- S.totalSize,
- );
- (O(R) && (R = await R), T(R));
- const M = Z(R, S.totalSize);
- E = om(M) === S.checksum;
- }
- if (!E) {
- v = S.headerStartPos + 4;
- continue;
- }
- if (E && S.serialNumber !== this.bitstream.serialNumber) {
- v = S.headerStartPos + S.totalSize;
- continue;
- }
- if (S.granulePosition === -1) {
- v = S.headerStartPos + S.totalSize;
- continue;
- }
- this.granulePositionToTimestampInSamples(S.granulePosition) > n
- ? (o = S.headerStartPos)
- : ((a = S), c.push(S));
- continue e;
- }
- }
- let u = s.startPage;
- for (const C of c) {
- if (C.granulePosition === a.granulePosition) break;
- (!u || C.headerStartPos > u.headerStartPos) && (u = C);
- }
- let l = u;
- const d = [l];
- for (
- ;
- !(
- l.serialNumber === this.bitstream.serialNumber &&
- l.granulePosition === a.granulePosition
- );
- ) {
- const C = l.headerStartPos + l.totalSize;
- let _ = this.demuxer.reader.requestSliceRange(C, Ir, mn);
- (O(_) && (_ = await _), T(_));
- const v = Qn(_);
- (T(v),
- (l = v),
- l.serialNumber === this.bitstream.serialNumber && d.push(l));
- }
- T(l.granulePosition !== -1);
- let f = null,
- h,
- p,
- m = l,
- b = 0;
- if (l.headerStartPos === s.startPage.headerStartPos)
- ((h = i), (p = !0), (f = 0));
- else {
- ((h = 0), (p = !1));
- for (let v = l.lacingValues.length - 1; v >= 0; v--)
- if (l.lacingValues[v] < 255) {
- f = v + 1;
- break;
- }
- if (f === null)
- throw new Error(
- "Invalid page with granule position: no packets end on this page.",
- );
- b = f - 1;
- const C = { data: Tt, endPage: m, endSegmentIndex: b };
- if (await this.demuxer.findNextPacketStart(C)) {
- const v = ic(d, l, f);
- T(v);
- const I = nc(d, v.page, v.segmentIndex);
- I && ((l = I.page), (f = I.segmentIndex));
- } else
- for (;;) {
- const v = ic(d, l, f);
- if (!v) break;
- const I = nc(d, v.page, v.segmentIndex);
- if (!I) break;
- if (
- ((l = I.page),
- (f = I.segmentIndex),
- v.page.headerStartPos !== m.headerStartPos)
- ) {
- ((m = v.page), (b = v.segmentIndex));
- break;
- }
- }
- }
- let g = null,
- y = null;
- for (; l !== null;) {
- T(f !== null);
- const C = await this.demuxer.readPacket(l, f);
- if (!C) break;
- if (!(
- l.headerStartPos === s.startPage.headerStartPos &&
- f < s.startSegmentIndex
- )) {
- let I = this.createEncodedPacketFromOggPacket(
- C,
- {
- timestampInSamples: h,
- vorbisLastBlocksize:
- (y == null ? void 0 : y.vorbisBlockSize) ?? null,
- },
- t,
- );
- T(I);
- let w = this.encodedPacketToMetadata.get(I);
- if (
- (T(w),
- !p &&
- C.endPage.headerStartPos === m.headerStartPos &&
- C.endSegmentIndex === b
- ? ((h = this.granulePositionToTimestampInSamples(
- l.granulePosition,
- )),
- (p = !0),
- (I = this.createEncodedPacketFromOggPacket(
- C,
- {
- timestampInSamples: h - w.durationInSamples,
- vorbisLastBlocksize:
- (y == null ? void 0 : y.vorbisBlockSize) ?? null,
- },
- t,
- )),
- T(I),
- (w = this.encodedPacketToMetadata.get(I)),
- T(w))
- : (h += w.durationInSamples),
- (g = I),
- (y = w),
- p && (Math.max(h, 0) > n || Math.max(w.timestampInSamples, 0) === n))
- )
- break;
- }
- const v = await this.demuxer.findNextPacketStart(C);
- if (!v) break;
- ((l = v.startPage), (f = v.startSegmentIndex));
- }
- return g;
- }
- async getPacketSequential(e, t) {
- const n = await this.sequentialScanMutex.acquire();
- try {
- const i = ni(e * this.internalSampleRate);
- e = i / this.internalSampleRate;
- const s = ke(this.sequentialScanCache, i, (c) => c.timestampInSamples);
- let a;
- if (s !== -1) {
- const c = this.sequentialScanCache[s];
- a = this.createEncodedPacketFromOggPacket(
- c.packet,
- {
- timestampInSamples: c.timestampInSamples,
- vorbisLastBlocksize: c.vorbisLastBlockSize,
- },
- t,
- );
- } else if (((a = await this.getFirstPacket(t)), a && a.timestamp > e))
- return null;
- let o = 0;
- for (; a && a.timestamp < e;) {
- const c = await this.getNextPacket(a, t);
- if (!c || c.timestamp > e) break;
- if (((a = c), o++, o === 100)) {
- o = 0;
- const u = this.encodedPacketToMetadata.get(a);
- (T(u),
- this.sequentialScanCache.length > 0 &&
- T(
- Ae(this.sequentialScanCache).timestampInSamples <=
- u.timestampInSamples,
- ),
- this.sequentialScanCache.push(u));
- }
- }
- return a;
- } finally {
- n();
- }
- }
- getKeyPacket(e, t) {
- return this.getPacket(e, t);
- }
- getNextKeyPacket(e, t) {
- return this.getNextPacket(e, t);
- }
-}
-const nc = (r, e, t) => {
- let n = e,
- i = t;
- e: for (;;) {
- for (i--, i; i >= 0; i--)
- if (n.lacingValues[i] < 255) {
- i++;
- break e;
- }
- if ((T(i === -1), !(n.headerType & 1))) {
- i = 0;
- break;
- }
- const a = Cl(r, (o) => o.headerStartPos < n.headerStartPos);
- if (!a) return null;
- ((n = a), (i = n.lacingValues.length));
- }
- if ((T(i !== -1), i === n.lacingValues.length)) {
- const s = r[r.indexOf(n) + 1];
- (T(s), (n = s), (i = 0));
- }
- return { page: n, segmentIndex: i };
- },
- ic = (r, e, t) => {
- if (t > 0) return { page: e, segmentIndex: t - 1 };
- const n = Cl(r, (i) => i.headerStartPos < e.headerStartPos);
- return n ? { page: n, segmentIndex: n.lacingValues.length - 1 } : null;
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ var it;
-(function (r) {
- ((r[(r.PCM = 1)] = "PCM"),
- (r[(r.IEEE_FLOAT = 3)] = "IEEE_FLOAT"),
- (r[(r.ALAW = 6)] = "ALAW"),
- (r[(r.MULAW = 7)] = "MULAW"),
- (r[(r.EXTENSIBLE = 65534)] = "EXTENSIBLE"));
-})(it || (it = {}));
-class hm extends br {
- constructor(e) {
- (super(e),
- (this.metadataPromise = null),
- (this.dataStart = -1),
- (this.dataSize = -1),
- (this.audioInfo = null),
- (this.trackBackings = []),
- (this.lastKnownPacketIndex = 0),
- (this.metadataTags = {}),
- (this.reader = e._reader));
- }
- async readMetadata() {
- return (
- this.metadataPromise ??
- (this.metadataPromise = (async () => {
- let e = this.reader.requestSlice(0, 12);
- (O(e) && (e = await e), T(e));
- const t = Ne(e, 4),
- n = t !== "RIFX",
- i = t === "RF64",
- s = Br(e, n);
- let a = i
- ? this.reader.fileSize
- : Math.min(s + 8, this.reader.fileSize ?? 1 / 0);
- if (Ne(e, 4) !== "WAVE")
- throw new Error("Invalid WAVE file - wrong format");
- let c = 0,
- u = null,
- l = e.filePos;
- for (; a === null || l < a;) {
- let f = this.reader.requestSlice(l, 8);
- if ((O(f) && (f = await f), !f)) break;
- const h = Ne(f, 4),
- p = Br(f, n),
- m = f.filePos;
- if (i && c === 0 && h !== "ds64")
- throw new Error('Invalid RF64 file: First chunk must be "ds64".');
- if (h === "fmt ") await this.parseFmtChunk(m, p, n);
- else if (h === "data") {
- if (
- (u ?? (u = p),
- (this.dataStart = f.filePos),
- (this.dataSize = Math.min(u, (a ?? 1 / 0) - this.dataStart)),
- this.reader.fileSize === null)
- )
- break;
- } else if (h === "ds64") {
- let b = this.reader.requestSlice(m, p);
- if ((O(b) && (b = await b), !b)) break;
- const g = zc(b, n);
- ((u = zc(b, n)),
- (a = Math.min(g + 8, this.reader.fileSize ?? 1 / 0)));
- } else
- h === "LIST"
- ? await this.parseListChunk(m, p, n)
- : (h === "ID3 " || h === "id3 ") &&
- (await this.parseId3Chunk(m, p));
- ((l = m + p + (p & 1)), c++);
- }
- if (!this.audioInfo)
- throw new Error('Invalid WAVE file - missing "fmt " chunk');
- if (this.dataStart === -1)
- throw new Error('Invalid WAVE file - missing "data" chunk');
- const d = this.audioInfo.blockSizeInBytes;
- ((this.dataSize = Math.floor(this.dataSize / d) * d),
- this.trackBackings.push(new mm(this)));
- })())
- );
- }
- async parseFmtChunk(e, t, n) {
- let i = this.reader.requestSlice(e, t);
- if ((O(i) && (i = await i), !i)) return;
- let s = Un(i, n);
- const a = Un(i, n),
- o = Br(i, n);
- i.skip(4);
- const c = Un(i, n);
- let u;
- if ((t === 14 ? (u = 8) : (u = Un(i, n)), t >= 18 && s !== 357)) {
- const l = Un(i, n),
- d = t - 18;
- if (Math.min(d, l) >= 22 && s === it.EXTENSIBLE) {
- i.skip(6);
- const h = Z(i, 16);
- s = h[0] | (h[1] << 8);
- }
- }
- if (
- ((s === it.MULAW || s === it.ALAW) && (u = 8),
- s !== it.PCM && s !== it.IEEE_FLOAT && s !== it.ALAW && s !== it.MULAW)
- )
- throw new Error(
- `Unsupported WAVE codec (format tag ${s}). Only integer/float PCM, A-law, and μ-law are supported.`,
- );
- if (s === it.PCM && ![8, 16, 24, 32].includes(u))
- throw new Error(
- `Unsupported WAVE PCM bit depth (${u}). Only 8, 16, 24, and 32 bits are supported.`,
- );
- if (s === it.IEEE_FLOAT && ![32, 64].includes(u))
- throw new Error(
- `Unsupported WAVE float bit depth (${u}). Only 32 and 64 bits are supported.`,
- );
- this.audioInfo = {
- format: s,
- numberOfChannels: a,
- sampleRate: o,
- sampleSizeInBytes: Math.ceil(u / 8),
- blockSizeInBytes: c,
- };
- }
- async parseListChunk(e, t, n) {
- var o, c, u, l, d, f, h, p, m, b, g;
- let i = this.reader.requestSlice(e, t);
- if ((O(i) && (i = await i), !i)) return;
- const s = Ne(i, 4);
- if (s !== "INFO" && s !== "INF0") return;
- let a = i.filePos;
- for (; a <= e + t - 8;) {
- i.filePos = a;
- const y = Ne(i, 4),
- C = Br(i, n),
- _ = Z(i, C);
- let v = 0;
- for (let w = 0; w < _.length && _[w] !== 0; w++) v++;
- const I = String.fromCharCode(..._.subarray(0, v));
- switch (
- ((o = this.metadataTags).raw ?? (o.raw = {}),
- (this.metadataTags.raw[y] = I),
- y)
- ) {
- case "INAM":
- case "TITL":
- (c = this.metadataTags).title ?? (c.title = I);
- break;
- case "TIT3":
- (u = this.metadataTags).description ?? (u.description = I);
- break;
- case "IART":
- (l = this.metadataTags).artist ?? (l.artist = I);
- break;
- case "IPRD":
- (d = this.metadataTags).album ?? (d.album = I);
- break;
- case "IPRT":
- case "ITRK":
- case "TRCK":
- {
- const w = I.split("/"),
- x = Number.parseInt(w[0], 10),
- k = w[1] && Number.parseInt(w[1], 10);
- (Number.isInteger(x) &&
- x > 0 &&
- ((f = this.metadataTags).trackNumber ?? (f.trackNumber = x)),
- k &&
- Number.isInteger(k) &&
- k > 0 &&
- ((h = this.metadataTags).tracksTotal ?? (h.tracksTotal = k)));
- }
- break;
- case "ICRD":
- case "IDIT":
- {
- const w = new Date(I);
- Number.isNaN(w.getTime()) ||
- ((p = this.metadataTags).date ?? (p.date = w));
- }
- break;
- case "YEAR":
- {
- const w = Number.parseInt(I, 10);
- Number.isInteger(w) &&
- w > 0 &&
- ((m = this.metadataTags).date ?? (m.date = new Date(w, 0, 1)));
- }
- break;
- case "IGNR":
- case "GENR":
- (b = this.metadataTags).genre ?? (b.genre = I);
- break;
- case "ICMT":
- case "CMNT":
- case "COMM":
- (g = this.metadataTags).comment ?? (g.comment = I);
- break;
- }
- a += 8 + C + (C & 1);
- }
- }
- async parseId3Chunk(e, t) {
- let n = this.reader.requestSlice(e, t);
- if ((O(n) && (n = await n), !n)) return;
- const i = hr(n);
- if (i) {
- const s = t - Et;
- if (((i.size = Math.min(i.size, s)), i.size > 0)) {
- const a = n.slice(e + Et, i.size);
- ks(a, i, this.metadataTags);
- }
- }
- }
- getCodec() {
- if ((T(this.audioInfo), this.audioInfo.format === it.MULAW)) return "ulaw";
- if (this.audioInfo.format === it.ALAW) return "alaw";
- if (this.audioInfo.format === it.PCM) {
- if (this.audioInfo.sampleSizeInBytes === 1) return "pcm-u8";
- if (this.audioInfo.sampleSizeInBytes === 2) return "pcm-s16";
- if (this.audioInfo.sampleSizeInBytes === 3) return "pcm-s24";
- if (this.audioInfo.sampleSizeInBytes === 4) return "pcm-s32";
- }
- if (this.audioInfo.format === it.IEEE_FLOAT) {
- if (this.audioInfo.sampleSizeInBytes === 4) return "pcm-f32";
- if (this.audioInfo.sampleSizeInBytes === 8) return "pcm-f64";
- }
- T(!1);
- }
- async getMimeType() {
- return "audio/wav";
- }
- async getTrackBackings() {
- return (await this.readMetadata(), this.trackBackings);
- }
- async getMetadataTags() {
- return (await this.readMetadata(), this.metadataTags);
- }
-}
-const Zr = 2048;
-class mm {
- constructor(e) {
- this.demuxer = e;
- }
- getType() {
- return "audio";
- }
- getId() {
- return 1;
- }
- getNumber() {
- return 1;
- }
- getCodec() {
- return this.demuxer.getCodec();
- }
- getInternalCodecId() {
- return (T(this.demuxer.audioInfo), this.demuxer.audioInfo.format);
- }
- async getDecoderConfig() {
- const e = this.demuxer.getCodec();
- return e
- ? (T(this.demuxer.audioInfo),
- {
- codec: e,
- numberOfChannels: this.demuxer.audioInfo.numberOfChannels,
- sampleRate: this.demuxer.audioInfo.sampleRate,
- })
- : null;
- }
- getNumberOfChannels() {
- return (T(this.demuxer.audioInfo), this.demuxer.audioInfo.numberOfChannels);
- }
- getSampleRate() {
- return (T(this.demuxer.audioInfo), this.demuxer.audioInfo.sampleRate);
- }
- getTimeResolution() {
- return (T(this.demuxer.audioInfo), this.demuxer.audioInfo.sampleRate);
- }
- isRelativeToUnixEpoch() {
- return !1;
- }
- getUnixTimeForTimestamp() {
- return null;
- }
- getPairingMask() {
- return 1n;
- }
- getBitrate() {
- return null;
- }
- getAverageBitrate() {
- return null;
- }
- async getDurationFromMetadata() {
- return (
- T(this.demuxer.dataSize !== -1),
- this.demuxer.dataSize /
- this.demuxer.audioInfo.blockSizeInBytes /
- this.demuxer.audioInfo.sampleRate
- );
- }
- async getLiveRefreshInterval() {
- return null;
- }
- getName() {
- return null;
- }
- getLanguageCode() {
- return nt;
- }
- getDisposition() {
- return { ...gr };
- }
- async getPacketAtIndex(e, t) {
- (T(e >= 0), T(this.demuxer.audioInfo));
- const n = e * Zr * this.demuxer.audioInfo.blockSizeInBytes;
- if (n >= this.demuxer.dataSize) return null;
- const i = Math.min(
- Zr * this.demuxer.audioInfo.blockSizeInBytes,
- this.demuxer.dataSize - n,
- );
- if (this.demuxer.reader.fileSize === null) {
- let c = this.demuxer.reader.requestSlice(this.demuxer.dataStart + n, i);
- if ((O(c) && (c = await c), !c)) return null;
- }
- let s;
- if (t.metadataOnly) s = Tt;
- else {
- let c = this.demuxer.reader.requestSlice(this.demuxer.dataStart + n, i);
- (O(c) && (c = await c), T(c), (s = Z(c, i)));
- }
- const a = (e * Zr) / this.demuxer.audioInfo.sampleRate,
- o =
- i /
- this.demuxer.audioInfo.blockSizeInBytes /
- this.demuxer.audioInfo.sampleRate;
- return (
- (this.demuxer.lastKnownPacketIndex = Math.max(
- e,
- this.demuxer.lastKnownPacketIndex,
- )),
- new Ee(s, "key", a, o, e, i)
- );
- }
- getFirstPacket(e) {
- return this.getPacketAtIndex(0, e);
- }
- async getPacket(e, t) {
- T(this.demuxer.audioInfo);
- const n = Math.floor(
- Math.min(
- (e * this.demuxer.audioInfo.sampleRate) / Zr,
- (this.demuxer.dataSize - 1) /
- (Zr * this.demuxer.audioInfo.blockSizeInBytes),
- ),
- );
- if (n < 0) return null;
- const i = await this.getPacketAtIndex(n, t);
- if (i) return i;
- if (n === 0) return null;
- T(this.demuxer.reader.fileSize === null);
- let s = await this.getPacketAtIndex(this.demuxer.lastKnownPacketIndex, t);
- for (; s;) {
- const a = await this.getNextPacket(s, t);
- if (!a) break;
- s = a;
- }
- return s;
- }
- getNextPacket(e, t) {
- T(this.demuxer.audioInfo);
- const n = Math.round(
- (e.timestamp * this.demuxer.audioInfo.sampleRate) / Zr,
- );
- return this.getPacketAtIndex(n + 1, t);
- }
- getKeyPacket(e, t) {
- return this.getPacket(e, t);
- }
- getNextKeyPacket(e, t) {
- return this.getNextPacket(e, t);
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const Xi = 7,
- $r = 9,
- Xr = (r) => {
- const e = r.filePos,
- t = Z(r, 9),
- n = new pe(t);
- if (n.readBits(12) !== 4095 || (n.skipBits(1), n.readBits(2) !== 0))
- return null;
- const a = n.readBits(1),
- o = n.readBits(2) + 1,
- c = n.readBits(4);
- if (c === 15) return null;
- n.skipBits(1);
- const u = n.readBits(3);
- if (u === 0)
- throw new Error(
- "ADTS frames with channel configuration 0 are not supported.",
- );
- (n.skipBits(1), n.skipBits(1), n.skipBits(1), n.skipBits(1));
- const l = n.readBits(13);
- n.skipBits(11);
- const d = n.readBits(2) + 1;
- if (d !== 1)
- throw new Error(
- "ADTS frames with more than one AAC frame are not supported.",
- );
- let f = null;
- return (
- a === 1 ? (r.filePos -= 2) : (f = n.readBits(16)),
- {
- objectType: o,
- samplingFrequencyIndex: c,
- channelConfiguration: u,
- frameLength: l,
- numberOfAacFrames: d,
- crcCheck: f,
- startPos: e,
- }
- );
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const Qi = 1024;
-class pm extends br {
- constructor(e) {
- (super(e),
- (this.metadataPromise = null),
- (this.firstFrameHeader = null),
- (this.loadedSamples = []),
- (this.metadataTags = null),
- (this.trackBackings = []),
- (this.readingMutex = new Cn()),
- (this.lastSampleLoaded = !1),
- (this.lastLoadedPos = 0),
- (this.nextTimestampInSamples = 0),
- (this.reader = e._reader));
- }
- async readMetadata() {
- return (
- this.metadataPromise ??
- (this.metadataPromise = (async () => {
- for (; !this.firstFrameHeader && !this.lastSampleLoaded;)
- await this.advanceReader();
- (T(this.firstFrameHeader), (this.trackBackings = [new gm(this)]));
- })())
- );
- }
- async advanceReader() {
- if (this.lastLoadedPos === 0)
- for (;;) {
- let a = this.reader.requestSlice(this.lastLoadedPos, Et);
- if ((O(a) && (a = await a), !a)) {
- this.lastSampleLoaded = !0;
- return;
- }
- const o = hr(a);
- if (!o) break;
- this.lastLoadedPos = a.filePos + o.size;
- }
- let e = this.reader.requestSliceRange(this.lastLoadedPos, Xi, $r);
- if ((O(e) && (e = await e), !e)) {
- this.lastSampleLoaded = !0;
- return;
- }
- const t = Xr(e);
- if (!t) {
- this.lastSampleLoaded = !0;
- return;
- }
- if (
- this.reader.fileSize !== null &&
- t.startPos + t.frameLength > this.reader.fileSize
- ) {
- this.lastSampleLoaded = !0;
- return;
- }
- this.firstFrameHeader || (this.firstFrameHeader = t);
- const n = Kr[t.samplingFrequencyIndex];
- T(n !== void 0);
- const i = Qi / n,
- s = {
- timestamp: this.nextTimestampInSamples / n,
- duration: i,
- dataStart: t.startPos,
- dataSize: t.frameLength,
- };
- (this.loadedSamples.push(s),
- (this.nextTimestampInSamples += Qi),
- (this.lastLoadedPos = t.startPos + t.frameLength));
- }
- async getMimeType() {
- return "audio/aac";
- }
- async getTrackBackings() {
- return (await this.readMetadata(), this.trackBackings);
- }
- async getMetadataTags() {
- const e = await this.readingMutex.acquire();
- try {
- if ((await this.readMetadata(), this.metadataTags))
- return this.metadataTags;
- this.metadataTags = {};
- let t = 0;
- for (;;) {
- let n = this.reader.requestSlice(t, Et);
- if ((O(n) && (n = await n), !n)) break;
- const i = hr(n);
- if (!i) break;
- let s = this.reader.requestSlice(n.filePos, i.size);
- if ((O(s) && (s = await s), !s)) break;
- (ks(s, i, this.metadataTags), (t = n.filePos + i.size));
- }
- return this.metadataTags;
- } finally {
- e();
- }
- }
-}
-class gm {
- constructor(e) {
- this.demuxer = e;
- }
- getType() {
- return "audio";
- }
- getId() {
- return 1;
- }
- getNumber() {
- return 1;
- }
- getTimeResolution() {
- return this.getSampleRate() / Qi;
- }
- isRelativeToUnixEpoch() {
- return !1;
- }
- getUnixTimeForTimestamp() {
- return null;
- }
- getPairingMask() {
- return 1n;
- }
- getBitrate() {
- return null;
- }
- getAverageBitrate() {
- return null;
- }
- async getDurationFromMetadata() {
- return null;
- }
- async getLiveRefreshInterval() {
- return null;
- }
- getName() {
- return null;
- }
- getLanguageCode() {
- return nt;
- }
- getCodec() {
- return "aac";
- }
- getInternalCodecId() {
- return (
- T(this.demuxer.firstFrameHeader),
- this.demuxer.firstFrameHeader.objectType
- );
- }
- getNumberOfChannels() {
- T(this.demuxer.firstFrameHeader);
- const e = pi[this.demuxer.firstFrameHeader.channelConfiguration];
- return (T(e !== void 0), e);
- }
- getSampleRate() {
- T(this.demuxer.firstFrameHeader);
- const e = Kr[this.demuxer.firstFrameHeader.samplingFrequencyIndex];
- return (T(e !== void 0), e);
- }
- getDisposition() {
- return { ...gr };
- }
- async getDecoderConfig() {
- return (
- T(this.demuxer.firstFrameHeader),
- {
- codec: `mp4a.40.${this.demuxer.firstFrameHeader.objectType}`,
- numberOfChannels: this.getNumberOfChannels(),
- sampleRate: this.getSampleRate(),
- }
- );
- }
- async getPacketAtIndex(e, t) {
- if (e === -1) return null;
- const n = this.demuxer.loadedSamples[e];
- if (!n) return null;
- let i;
- if (t.metadataOnly) i = Tt;
- else {
- let s = this.demuxer.reader.requestSlice(n.dataStart, n.dataSize);
- if ((O(s) && (s = await s), !s)) return null;
- i = Z(s, n.dataSize);
- }
- return new Ee(i, "key", n.timestamp, n.duration, e, n.dataSize);
- }
- getFirstPacket(e) {
- return this.getPacketAtIndex(0, e);
- }
- async getNextPacket(e, t) {
- const n = await this.demuxer.readingMutex.acquire();
- try {
- const i = fi(this.demuxer.loadedSamples, e.timestamp, (a) => a.timestamp);
- if (i === -1) throw new Error("Packet was not created from this track.");
- const s = i + 1;
- for (
- ;
- s >= this.demuxer.loadedSamples.length &&
- !this.demuxer.lastSampleLoaded;
- )
- await this.demuxer.advanceReader();
- return this.getPacketAtIndex(s, t);
- } finally {
- n();
- }
- }
- async getPacket(e, t) {
- const n = await this.demuxer.readingMutex.acquire();
- try {
- for (;;) {
- const i = ke(this.demuxer.loadedSamples, e, (s) => s.timestamp);
- if (i === -1 && this.demuxer.loadedSamples.length > 0) return null;
- if (this.demuxer.lastSampleLoaded) return this.getPacketAtIndex(i, t);
- if (i >= 0 && i + 1 < this.demuxer.loadedSamples.length)
- return this.getPacketAtIndex(i, t);
- await this.demuxer.advanceReader();
- }
- } finally {
- n();
- }
- }
- getKeyPacket(e, t) {
- return this.getPacket(e, t);
- }
- getNextKeyPacket(e, t) {
- return this.getNextPacket(e, t);
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const bm = (r) =>
- r === 0
- ? null
- : r === 1
- ? 192
- : r >= 2 && r <= 5
- ? 144 * 2 ** r
- : r === 6
- ? "uncommon-u8"
- : r === 7
- ? "uncommon-u16"
- : r >= 8 && r <= 15
- ? 2 ** r
- : null,
- wm = (r, e) => {
- switch (r) {
- case 0:
- return e;
- case 1:
- return 88200;
- case 2:
- return 176400;
- case 3:
- return 192e3;
- case 4:
- return 8e3;
- case 5:
- return 16e3;
- case 6:
- return 22050;
- case 7:
- return 24e3;
- case 8:
- return 32e3;
- case 9:
- return 44100;
- case 10:
- return 48e3;
- case 11:
- return 96e3;
- case 12:
- return "uncommon-u8";
- case 13:
- return "uncommon-u16";
- case 14:
- return "uncommon-u16-10";
- default:
- return null;
- }
- },
- ym = (r) => {
- let e = 0;
- const t = new pe(Z(r, 1));
- for (; t.readBits(1) === 1;) e++;
- if (e === 0) return t.readBits(7);
- const n = [],
- i = e - 1,
- s = new pe(Z(r, i)),
- a = 8 - e - 1;
- for (let c = 0; c < a; c++) n.unshift(t.readBits(1));
- for (let c = 0; c < i; c++)
- for (let u = 0; u < 8; u++) {
- const l = s.readBits(1);
- u < 2 || n.unshift(l);
- }
- return n.reduce((c, u, l) => c | (u << l), 0);
- },
- km = (r, e) => {
- if (e === "uncommon-u16") return Ve(r) + 1;
- if (e === "uncommon-u8") return Y(r) + 1;
- if (typeof e == "number") return e;
- (pr(e), T(!1));
- },
- Tm = (r, e) =>
- e === "uncommon-u16"
- ? Ve(r)
- : e === "uncommon-u16-10"
- ? Ve(r) * 10
- : e === "uncommon-u8"
- ? Y(r)
- : typeof e == "number"
- ? e
- : null,
- xm = (r) => {
- let t = 0;
- for (const n of r) {
- t ^= n;
- for (let i = 0; i < 8; i++)
- ((t & 128) !== 0 ? (t = (t << 1) ^ 7) : (t <<= 1), (t &= 255));
- }
- return t;
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class Sm extends br {
- constructor(e) {
- (super(e),
- (this.loadedSamples = []),
- (this.metadataPromise = null),
- (this.trackBacking = null),
- (this.metadataTags = {}),
- (this.audioInfo = null),
- (this.lastLoadedPos = null),
- (this.blockingBit = null),
- (this.readingMutex = new Cn()),
- (this.lastSampleLoaded = !1),
- (this.reader = e._reader));
- }
- async getMetadataTags() {
- return (await this.readMetadata(), this.metadataTags);
- }
- async getTrackBackings() {
- return (
- await this.readMetadata(),
- T(this.trackBacking),
- [this.trackBacking]
- );
- }
- async getMimeType() {
- return "audio/flac";
- }
- async readMetadata() {
- return (
- this.metadataPromise ??
- (this.metadataPromise = (async () => {
- var t;
- let e = 0;
- for (;;) {
- let n = this.reader.requestSlice(e, Et);
- if ((O(n) && (n = await n), !n)) {
- this.lastSampleLoaded = !0;
- return;
- }
- const i = hr(n);
- if (!i) break;
- let s = this.reader.requestSlice(n.filePos, i.size);
- (O(s) && (s = await s),
- T(s),
- ks(s, i, this.metadataTags),
- (e = n.filePos + i.size));
- }
- for (
- e += 4;
- this.reader.fileSize === null || e < this.reader.fileSize;
- ) {
- let n = this.reader.requestSlice(e, 4);
- if ((O(n) && (n = await n), (e += 4), n === null))
- throw new Error(
- `Metadata block at position ${e} is too small! Corrupted file.`,
- );
- T(n);
- const i = Y(n),
- s = Zt(n),
- a = (i & 128) !== 0;
- switch (i & 127) {
- case hn.STREAMINFO: {
- let c = this.reader.requestSlice(e, s);
- if ((O(c) && (c = await c), T(c), c === null))
- throw new Error(
- `StreamInfo block at position ${e} is too small! Corrupted file.`,
- );
- const u = Z(c, 34),
- l = new pe(u),
- d = l.readBits(16),
- f = l.readBits(16),
- h = l.readBits(24),
- p = l.readBits(24),
- m = l.readBits(20),
- b = l.readBits(3) + 1;
- l.readBits(5);
- const g = l.readBits(36);
- l.skipBits(128);
- const y = new Uint8Array(42);
- (y.set(new Uint8Array([102, 76, 97, 67]), 0),
- y.set(new Uint8Array([128, 0, 0, 34]), 4),
- y.set(u, 8),
- (this.audioInfo = {
- numberOfChannels: b,
- sampleRate: m,
- totalSamples: g,
- minimumBlockSize: d,
- maximumBlockSize: f,
- minimumFrameSize: h,
- maximumFrameSize: p,
- description: y,
- }),
- (this.trackBacking = new Pm(this)));
- break;
- }
- case hn.VORBIS_COMMENT: {
- let c = this.reader.requestSlice(e, s);
- (O(c) && (c = await c), T(c), xa(Z(c, s), this.metadataTags));
- break;
- }
- case hn.PICTURE: {
- let c = this.reader.requestSlice(e, s);
- (O(c) && (c = await c), T(c));
- const u = L(c),
- l = L(c),
- d = ot.decode(Z(c, l)),
- f = L(c),
- h = ot.decode(Z(c, f));
- c.skip(16);
- const p = L(c),
- m = Z(c, p);
- ((t = this.metadataTags).images ?? (t.images = []),
- this.metadataTags.images.push({
- data: m,
- mimeType: d,
- kind:
- u === 3 ? "coverFront" : u === 4 ? "coverBack" : "unknown",
- description: h,
- }));
- break;
- }
- }
- if (((e += s), a)) {
- this.lastLoadedPos = e;
- break;
- }
- }
- if (!this.audioInfo)
- throw new Error(
- "Missing STREAMINFO metadata block! Corrupted FLAC file.",
- );
- })())
- );
- }
- async readNextFlacFrame({ startPos: e, isFirstPacket: t }) {
- T(this.audioInfo);
- const n = 6,
- i = 16,
- s = 10,
- a =
- this.audioInfo.maximumBlockSize * this.audioInfo.numberOfChannels * 4 +
- i +
- 2,
- o = this.audioInfo.minimumFrameSize || s,
- u = (this.audioInfo.maximumFrameSize || a) + i,
- l = await this.reader.requestSliceRange(e, i, u);
- if (!l) return null;
- const d = this.readFlacFrameHeader({ slice: l, isFirstPacket: t });
- if (!d) return null;
- for (l.filePos = e + o; ;) {
- if (l.filePos > l.end - n)
- return {
- num: d.num,
- blockSize: d.blockSize,
- sampleRate: d.sampleRate,
- size: l.end - e,
- isLastFrame: !0,
- };
- if (Y(l) === 255) {
- const h = l.filePos,
- p = Y(l),
- m = this.blockingBit === 1 ? 249 : 248;
- if (p !== m) {
- l.filePos = h;
- continue;
- }
- l.skip(-2);
- const b = l.filePos - e,
- g = this.readFlacFrameHeader({ slice: l, isFirstPacket: !1 });
- if (!g) {
- l.filePos = h;
- continue;
- }
- if (this.blockingBit === 0) {
- if (g.num - d.num !== 1) {
- l.filePos = h;
- continue;
- }
- } else if (g.num - d.num !== d.blockSize) {
- l.filePos = h;
- continue;
- }
- return {
- num: d.num,
- blockSize: d.blockSize,
- sampleRate: d.sampleRate,
- size: b,
- isLastFrame: !1,
- };
- }
- }
- }
- readFlacFrameHeader({ slice: e, isFirstPacket: t }) {
- const n = e.filePos,
- i = Z(e, 4),
- s = new pe(i);
- if (s.readBits(15) !== 32764) return null;
- if (this.blockingBit === null) {
- T(t);
- const b = s.readBits(1);
- this.blockingBit = b;
- } else if (this.blockingBit === 1) {
- if ((T(!t), s.readBits(1) !== 1)) return null;
- } else if (this.blockingBit === 0) {
- if ((T(!t), s.readBits(1) !== 0)) return null;
- } else throw new Error("Invalid blocking bit");
- const o = bm(s.readBits(4));
- if (!o) return null;
- T(this.audioInfo);
- const c = wm(s.readBits(4), this.audioInfo.sampleRate);
- if (!c || (s.readBits(4), s.readBits(3), s.readBits(1) !== 0)) return null;
- const l = ym(e),
- d = km(e, o),
- f = Tm(e, c);
- if (f === null || f !== this.audioInfo.sampleRate) return null;
- const h = e.filePos - n,
- p = Y(e);
- (e.skip(-h), e.skip(-1));
- const m = xm(Z(e, h));
- return p !== m ? null : { num: l, blockSize: d, sampleRate: f };
- }
- async advanceReader() {
- (await this.readMetadata(),
- T(this.lastLoadedPos !== null),
- T(this.audioInfo));
- const e = this.lastLoadedPos,
- t = await this.readNextFlacFrame({
- startPos: e,
- isFirstPacket: this.loadedSamples.length === 0,
- });
- if (!t) {
- this.lastSampleLoaded = !0;
- return;
- }
- const n = this.loadedSamples[this.loadedSamples.length - 1],
- s = {
- blockOffset: n ? n.blockOffset + n.blockSize : 0,
- blockSize: t.blockSize,
- byteOffset: e,
- byteSize: t.size,
- };
- if (
- ((this.lastLoadedPos = this.lastLoadedPos + t.size),
- this.loadedSamples.push(s),
- t.isLastFrame)
- ) {
- this.lastSampleLoaded = !0;
- return;
- }
- }
-}
-class Pm {
- constructor(e) {
- this.demuxer = e;
- }
- getType() {
- return "audio";
- }
- getId() {
- return 1;
- }
- getNumber() {
- return 1;
- }
- getCodec() {
- return "flac";
- }
- getInternalCodecId() {
- return null;
- }
- getNumberOfChannels() {
- return (T(this.demuxer.audioInfo), this.demuxer.audioInfo.numberOfChannels);
- }
- getSampleRate() {
- return (T(this.demuxer.audioInfo), this.demuxer.audioInfo.sampleRate);
- }
- getName() {
- return null;
- }
- getLanguageCode() {
- return nt;
- }
- getTimeResolution() {
- return (T(this.demuxer.audioInfo), this.demuxer.audioInfo.sampleRate);
- }
- isRelativeToUnixEpoch() {
- return !1;
- }
- getUnixTimeForTimestamp() {
- return null;
- }
- getPairingMask() {
- return 1n;
- }
- getBitrate() {
- return null;
- }
- getAverageBitrate() {
- return null;
- }
- async getDurationFromMetadata() {
- return (
- T(this.demuxer.audioInfo),
- this.demuxer.audioInfo.totalSamples === 0
- ? null
- : this.demuxer.audioInfo.totalSamples /
- this.demuxer.audioInfo.sampleRate
- );
- }
- async getLiveRefreshInterval() {
- return null;
- }
- getDisposition() {
- return { ...gr };
- }
- async getDecoderConfig() {
- return (
- T(this.demuxer.audioInfo),
- {
- codec: "flac",
- numberOfChannels: this.demuxer.audioInfo.numberOfChannels,
- sampleRate: this.demuxer.audioInfo.sampleRate,
- description: this.demuxer.audioInfo.description,
- }
- );
- }
- async getPacket(e, t) {
- if ((T(this.demuxer.audioInfo), e < 0)) return null;
- const n = await this.demuxer.readingMutex.acquire();
- try {
- for (;;) {
- const i = ke(
- this.demuxer.loadedSamples,
- e,
- (c) => c.blockOffset / this.demuxer.audioInfo.sampleRate,
- );
- if (i === -1) {
- await this.demuxer.advanceReader();
- continue;
- }
- const s = this.demuxer.loadedSamples[i],
- a = s.blockOffset / this.demuxer.audioInfo.sampleRate,
- o = s.blockSize / this.demuxer.audioInfo.sampleRate;
- if (a + o <= e) {
- if (this.demuxer.lastSampleLoaded)
- return this.getPacketAtIndex(
- this.demuxer.loadedSamples.length - 1,
- t,
- );
- await this.demuxer.advanceReader();
- continue;
- }
- return this.getPacketAtIndex(i, t);
- }
- } finally {
- n();
- }
- }
- async getNextPacket(e, t) {
- const n = await this.demuxer.readingMutex.acquire();
- try {
- const i = e.sequenceNumber + 1;
- if (
- this.demuxer.lastSampleLoaded &&
- i >= this.demuxer.loadedSamples.length
- )
- return null;
- for (
- ;
- i >= this.demuxer.loadedSamples.length &&
- !this.demuxer.lastSampleLoaded;
- )
- await this.demuxer.advanceReader();
- return this.getPacketAtIndex(i, t);
- } finally {
- n();
- }
- }
- getKeyPacket(e, t) {
- return this.getPacket(e, t);
- }
- getNextKeyPacket(e, t) {
- return this.getNextPacket(e, t);
- }
- async getPacketAtIndex(e, t) {
- const n = this.demuxer.loadedSamples[e];
- if (!n) return null;
- let i;
- if (t.metadataOnly) i = Tt;
- else {
- let o = this.demuxer.reader.requestSlice(n.byteOffset, n.byteSize);
- if ((O(o) && (o = await o), !o)) return null;
- i = Z(o, n.byteSize);
- }
- T(this.demuxer.audioInfo);
- const s = n.blockOffset / this.demuxer.audioInfo.sampleRate,
- a = n.blockSize / this.demuxer.audioInfo.sampleRate;
- return new Ee(i, "key", s, a, e, n.byteSize);
- }
- async getFirstPacket(e) {
- for (
- ;
- this.demuxer.loadedSamples.length === 0 && !this.demuxer.lastSampleLoaded;
- )
- await this.demuxer.advanceReader();
- return this.getPacketAtIndex(0, e);
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const Ft = 9e4,
- Ws = 2 ** 33,
- ht = 188,
- Cm = (r) => {
- let e = "video/MP2T";
- const t = [...new Set(r.filter(Boolean))];
- return (t.length > 0 && (e += `; codecs="${t.join(", ")}"`), e);
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const yu =
- "PES packet is missing PTS where it was expected. PES packets without PTS are not currently supported. If you think this file should be supported, please report it.",
- sc = 5,
- vm = 1212435798,
- Em = 1212436562,
- Im = 1146376960,
- _m = new Set([133, 134, 162]),
- ac = new Set();
-class Am extends br {
- constructor(e) {
- (super(e),
- (this.metadataPromise = null),
- (this.elementaryStreams = []),
- (this.trackBackingEntries = []),
- (this.packetOffset = 0),
- (this.packetStride = -1),
- (this.sectionEndPositions = []),
- (this.seekChunkSize = 5 * 1024 * 1024),
- (this.minReferencePointByteDistance = -1),
- (this.timestampWrapInfo = null),
- (this.reader = e._reader));
- }
- async readMetadata() {
- return (
- this.metadataPromise ??
- (this.metadataPromise = (async () => {
- const e = ht + 16 + 1;
- let t = this.reader.requestSlice(0, e);
- (O(t) && (t = await t), T(t));
- const n = Z(t, e);
- if (n[0] === 71 && n[ht] === 71)
- ((this.packetOffset = 0), (this.packetStride = ht));
- else if (n[0] === 71 && n[ht + 16] === 71)
- ((this.packetOffset = 0), (this.packetStride = ht + 16));
- else if (n[4] === 71 && n[4 + ht + 4] === 71)
- ((this.packetOffset = 4), (this.packetStride = ht + 4));
- else throw new Error("Unreachable.");
- const i = 256;
- this.minReferencePointByteDistance = i * this.packetStride;
- let s = this.packetOffset,
- a = null,
- o = !1,
- c = !1;
- for (;;) {
- const u = await this.readPacketHeader(s);
- if (!u) break;
- if (u.payloadUnitStartIndicator === 0) {
- s += this.packetStride;
- continue;
- }
- if (c && !this.elementaryStreams.some((m) => m.pid === u.pid)) {
- s += this.packetStride;
- continue;
- }
- const l = await this.readSection(s, !0, !c);
- if (!l) break;
- const d = 3,
- f = 32;
- let h = !1;
- if (
- !c &&
- l.pid !== 0 &&
- !(l.payload[0] === 0 && l.payload[1] === 0 && l.payload[2] === 1)
- ) {
- const b = new pe(l.payload),
- g = b.readAlignedByte();
- (b.skipBits(8 * g), (h = b.readBits(8) === 2));
- }
- if (l.pid === 0 && !o) {
- const m = new pe(l.payload),
- b = m.readAlignedByte();
- (m.skipBits(8 * b), m.skipBits(14));
- const g = m.readBits(10);
- for (m.skipBits(40); 8 * (g + d) - m.pos > f;) {
- const y = m.readBits(16);
- m.skipBits(3);
- const C = m.readBits(13);
- if (y !== 0) {
- if (a !== null)
- throw new Error(
- "Only files with a single program are supported.",
- );
- a = C;
- }
- }
- if (a === null)
- throw new Error(
- "Program Association Table must link to a Program Map Table.",
- );
- o = !0;
- } else if ((l.pid === a || h) && !c) {
- const m = new pe(l.payload),
- b = m.readAlignedByte();
- (m.skipBits(8 * b), m.skipBits(12));
- const g = m.readBits(12);
- (m.skipBits(43), m.readBits(13), m.skipBits(6));
- const y = m.readBits(10),
- C = m.pos + 8 * y;
- let _ = !1;
- for (; m.pos < C;) {
- const v = m.readBits(8),
- I = m.readBits(8),
- w = m.pos + 8 * I;
- if (v === sc && I >= 4) {
- const x = m.readBits(32);
- _ || (_ = x === vm || x === Em);
- }
- m.pos = w;
- }
- for (m.pos = C; 8 * (g + d) - m.pos > f;) {
- const v = m.readBits(8);
- m.skipBits(3);
- const I = m.readBits(13);
- m.skipBits(6);
- const w = m.readBits(10),
- x = m.pos + 8 * w;
- let k = !1,
- S = !1,
- E = !1;
- for (; m.pos < x;) {
- const M = m.readBits(8),
- z = m.readBits(8),
- q = m.pos + 8 * z;
- if (M === 106) k = !0;
- else if (M === 122 || M === 204) S = !0;
- else if (M === 123) E = !0;
- else if (M === sc && z >= 4) {
- const j = m.readBits(32);
- E || (E = (j & 4294967040) === Im);
- }
- m.pos = q;
- }
- let B = null;
- const R = _ && _m.has(v) ? 130 : v;
- switch (R) {
- case 27:
- case 36:
- B = {
- type: "video",
- codec: v === 27 ? "avc" : "hevc",
- decoderConfig: null,
- avcCodecInfo: null,
- hevcCodecInfo: null,
- colorSpace: {
- primaries: null,
- transfer: null,
- matrix: null,
- fullRange: null,
- },
- width: -1,
- height: -1,
- squarePixelWidth: -1,
- squarePixelHeight: -1,
- reorderSize: -1,
- };
- break;
- case 3:
- case 4:
- case 15:
- case 129:
- case 135:
- case 130:
- case 138:
- {
- let M;
- (R === 3 || R === 4
- ? (M = "mp3")
- : R === 15
- ? (M = "aac")
- : R === 129
- ? (M = "ac3")
- : R === 135
- ? (M = "eac3")
- : (M = "dts"),
- (B = {
- type: "audio",
- codec: M,
- decoderConfig: null,
- aacCodecInfo: null,
- dtsFormat: null,
- numberOfChannels: -1,
- sampleRate: -1,
- }));
- }
- break;
- case 6:
- S
- ? (B = {
- type: "audio",
- codec: "eac3",
- decoderConfig: null,
- aacCodecInfo: null,
- dtsFormat: null,
- numberOfChannels: -1,
- sampleRate: -1,
- })
- : k
- ? (B = {
- type: "audio",
- codec: "ac3",
- decoderConfig: null,
- aacCodecInfo: null,
- dtsFormat: null,
- numberOfChannels: -1,
- sampleRate: -1,
- })
- : E &&
- (B = {
- type: "audio",
- codec: "dts",
- decoderConfig: null,
- aacCodecInfo: null,
- dtsFormat: null,
- numberOfChannels: -1,
- sampleRate: -1,
- });
- break;
- default:
- ac.has(v) ||
- (te._warn(
- `Note: MPEG-TS streams with stream_type 0x${v.toString(16)} are not currently supported.`,
- ),
- ac.add(v));
- }
- B &&
- this.elementaryStreams.push({
- demuxer: this,
- pid: I,
- streamType: v,
- initialized: !1,
- firstSection: null,
- canBeTrustedWithKeyPackets: !1,
- info: B,
- referencePesPackets: [],
- });
- }
- c = !0;
- } else {
- const m = this.elementaryStreams.find((b) => b.pid === l.pid);
- e: if (m && !m.initialized) {
- const b = cn(this, l, !0);
- if (!b)
- throw new Error(
- `Couldn't read first PES packet for Elementary Stream with PID ${m.pid}`,
- );
- if (
- ((m.firstSection = l),
- (m.canBeTrustedWithKeyPackets = l.randomAccessIndicator === 1),
- this.input._initInput)
- ) {
- const C = (
- await this.input._initInput._getDemuxer()
- ).elementaryStreams.find(
- (_) => _.pid === l.pid && _.info.codec === m.info.codec,
- );
- if (C) {
- ((m.info = C.info), (m.initialized = !0));
- break e;
- }
- }
- const g = new $n(m, b);
- if (m.info.type === "video") {
- for (;;) {
- const y = g;
- if (
- ((y.suppliedPacket = null),
- await g.markNextPacket(),
- m.info.codec === "avc")
- ) {
- if (!g.suppliedPacket)
- throw new Error(
- "Invalid AVC video stream; could not extract AVCDecoderConfigurationRecord from any packet.",
- );
- if (
- ((m.info.avcCodecInfo = bi(g.suppliedPacket.data)),
- !m.info.avcCodecInfo)
- )
- continue;
- const C = m.info.avcCodecInfo.sequenceParameterSets[0];
- T(C);
- const _ = bn(C);
- ((m.info.width = _.displayWidth),
- (m.info.height = _.displayHeight));
- const v = _.pixelAspectRatio.num,
- I = _.pixelAspectRatio.den;
- ((m.info.squarePixelWidth = m.info.width),
- (m.info.squarePixelHeight = m.info.height),
- v > 0 &&
- I > 0 &&
- (v > I
- ? (m.info.squarePixelWidth = Math.round(
- (m.info.width * v) / I,
- ))
- : (m.info.squarePixelHeight = Math.round(
- (m.info.height * I) / v,
- ))),
- (m.info.colorSpace = {
- primaries: rr[_.colourPrimaries],
- transfer: nr[_.transferCharacteristics],
- matrix: ir[_.matrixCoefficients],
- fullRange: !!_.fullRangeFlag,
- }),
- (m.info.reorderSize = _.maxDecFrameBuffering));
- break;
- } else if (m.info.codec === "hevc") {
- if (!g.suppliedPacket)
- throw new Error(
- "Invalid HEVC video stream; could not extract HVCDecoderConfigurationRecord from first packet.",
- );
- if (
- ((m.info.hevcCodecInfo = wi(g.suppliedPacket.data)),
- !m.info.hevcCodecInfo)
- )
- continue;
- const _ = m.info.hevcCodecInfo.arrays.find(
- (x) => x.nalUnitType === ze.SPS_NUT,
- ).nalUnits[0];
- T(_);
- const v = us(_);
- ((m.info.width = v.displayWidth),
- (m.info.height = v.displayHeight));
- const I = v.pixelAspectRatio.num,
- w = v.pixelAspectRatio.den;
- ((m.info.squarePixelWidth = m.info.width),
- (m.info.squarePixelHeight = m.info.height),
- I > 0 &&
- w > 0 &&
- (I > w
- ? (m.info.squarePixelWidth = Math.round(
- (m.info.width * I) / w,
- ))
- : (m.info.squarePixelHeight = Math.round(
- (m.info.height * w) / I,
- ))),
- (m.info.colorSpace = {
- primaries: rr[v.colourPrimaries],
- transfer: nr[v.transferCharacteristics],
- matrix: ir[v.matrixCoefficients],
- fullRange: !!v.fullRangeFlag,
- }),
- (m.info.reorderSize = v.maxDecFrameBuffering));
- break;
- } else throw new Error("Unhandled.");
- }
- ((m.info.decoderConfig = {
- codec: hs({
- width: m.info.width,
- height: m.info.height,
- codec: m.info.codec,
- codecDescription: null,
- colorSpace: m.info.colorSpace,
- avcType: 1,
- avcCodecInfo: m.info.avcCodecInfo,
- hevcCodecInfo: m.info.hevcCodecInfo,
- vp9CodecInfo: null,
- av1CodecInfo: null,
- proresFormat: null,
- }),
- codedWidth: m.info.width,
- codedHeight: m.info.height,
- colorSpace: m.info.colorSpace,
- }),
- (m.info.width !== m.info.squarePixelWidth ||
- m.info.height !== m.info.squarePixelHeight) &&
- ((m.info.decoderConfig.displayAspectWidth =
- m.info.squarePixelWidth),
- (m.info.decoderConfig.displayAspectHeight =
- m.info.squarePixelHeight)),
- (m.initialized = !0));
- } else {
- if ((await g.markNextPacket(), !g.suppliedPacket))
- throw new Error(
- `Couldn't parse first media packet for Elementary Stream with PID ${m.pid}`,
- );
- if (m.info.codec === "aac") {
- const y = yt.tempFromBytes(g.suppliedPacket.data),
- C = Xr(y);
- if (!C)
- throw new Error(
- "Invalid AAC audio stream; could not read ADTS frame header from first packet.",
- );
- ((m.info.aacCodecInfo = {
- isMpeg2: !1,
- objectType: C.objectType,
- }),
- (m.info.numberOfChannels = pi[C.channelConfiguration]),
- (m.info.sampleRate = Kr[C.samplingFrequencyIndex]));
- } else if (m.info.codec === "mp3") {
- const y = L(yt.tempFromBytes(g.suppliedPacket.data)),
- C = io(y, g.suppliedPacket.data.byteLength);
- if (!C.header)
- throw new Error(
- "Invalid MP3 audio stream; could not read frame header from first packet.",
- );
- ((m.info.numberOfChannels = ci(C.header.channel)),
- (m.info.sampleRate = C.header.sampleRate));
- } else if (m.info.codec === "ac3") {
- const y = Vl(g.suppliedPacket.data);
- if (!y)
- throw new Error(
- "Invalid AC-3 audio stream; could not read sync frame from first packet.",
- );
- if (y.fscod === 3)
- throw new Error(
- "Invalid AC-3 audio stream; reserved sample rate code found in first packet.",
- );
- ((m.info.numberOfChannels = Ja[y.acmod] + y.lfeon),
- (m.info.sampleRate = cs[y.fscod]));
- } else if (m.info.codec === "eac3") {
- const y = ql(g.suppliedPacket.data);
- if (!y)
- throw new Error(
- "Invalid E-AC-3 audio stream; could not read sync frame from first packet.",
- );
- const C = jl(y);
- if (C === null)
- throw new Error(
- "Invalid E-AC-3 audio stream; reserved sample rate code found in first packet.",
- );
- ((m.info.numberOfChannels = $l(y)), (m.info.sampleRate = C));
- } else if (m.info.codec === "dts") {
- const y = to(g.suppliedPacket.data);
- if (!y)
- throw new Error(
- "Invalid DTS audio stream; could not read frame header from first packet.",
- );
- ((m.info.numberOfChannels = y.numberOfChannels),
- (m.info.sampleRate = y.sampleRate),
- y.core &&
- (m.info.dtsFormat = y.hasExtensions ? "dtsh" : "dtsc"));
- } else throw new Error("Unhandled.");
- ((m.info.decoderConfig = {
- codec: no({
- codec: m.info.codec,
- codecDescription: null,
- aacCodecInfo: m.info.aacCodecInfo,
- dtsFormat: m.info.dtsFormat,
- }),
- numberOfChannels: m.info.numberOfChannels,
- sampleRate: m.info.sampleRate,
- }),
- (m.initialized = !0));
- }
- }
- }
- if (c && this.elementaryStreams.every((m) => m.initialized)) break;
- s += this.packetStride;
- }
- if (!c)
- throw o
- ? new Error("No Program Map Table found in the file.")
- : new Error("No Program Association Table found in the file.");
- for (const u of this.elementaryStreams)
- u.initialized &&
- (u.info.type === "video"
- ? this.trackBackingEntries.push(new Bm(u))
- : this.trackBackingEntries.push(new Fm(u)));
- })())
- );
- }
- async getTrackBackings() {
- return (await this.readMetadata(), this.trackBackingEntries);
- }
- async getMetadataTags() {
- return {};
- }
- async getMimeType() {
- await this.readMetadata();
- const e = await Promise.all(
- this.trackBackingEntries.map((t) =>
- t
- .getDecoderConfig()
- .then((n) => (n == null ? void 0 : n.codec) ?? null),
- ),
- );
- return Cm(e);
- }
- async readSection(e, t, n = !1) {
- let i = e,
- s = e;
- const a = [];
- let o = 0,
- c = null,
- u = !0,
- l = 0;
- for (;;) {
- const f = await this.readPacket(s);
- if (((s += this.packetStride), !f)) break;
- if (c) {
- if (f.pid !== c.pid) {
- if (n) break;
- continue;
- }
- if (f.payloadUnitStartIndicator === 1) break;
- } else {
- if (f.payloadUnitStartIndicator === 0) break;
- c = f;
- }
- const h = !!(f.adaptationFieldControl & 2),
- p = !!(f.adaptationFieldControl & 1);
- let m = 0;
- if (
- (h &&
- ((m = 1 + f.body[0]), f === c && m > 1 && (l = (f.body[1] >> 6) & 1)),
- p &&
- (m === 0
- ? (a.push(f.body), (o += f.body.byteLength))
- : (a.push(f.body.subarray(m)), (o += f.body.byteLength - m))),
- (i = s),
- !t && o >= 64)
- ) {
- u = !1;
- break;
- }
- if (fi(this.sectionEndPositions, i, (g) => g) !== -1) {
- u = !1;
- break;
- }
- }
- if (u) {
- const f = ke(this.sectionEndPositions, i, (h) => h);
- this.sectionEndPositions.splice(f + 1, 0, i);
- }
- if (!c) return null;
- let d;
- if (a.length === 1) d = a[0];
- else {
- const f = a.reduce((p, m) => p + m.length, 0);
- d = new Uint8Array(f);
- let h = 0;
- for (const p of a) (d.set(p, h), (h += p.length));
- }
- return {
- startPos: e,
- endPos: t ? i : null,
- pid: c.pid,
- payload: d,
- randomAccessIndicator: l,
- };
- }
- async readPacketHeader(e) {
- let t = this.reader.requestSlice(e, 4);
- if ((O(t) && (t = await t), !t)) return null;
- if (Y(t) !== 71)
- throw new Error(
- "Invalid TS packet sync byte. Likely an internal bug, please report this file.",
- );
- const i = Ve(t),
- s = (i >> 14) & 1,
- a = i & 8191,
- c = (Y(t) >> 4) & 3;
- return { payloadUnitStartIndicator: s, pid: a, adaptationFieldControl: c };
- }
- async readPacket(e) {
- let t = this.reader.requestSlice(e, ht);
- if ((O(t) && (t = await t), !t)) return null;
- const n = Z(t, ht);
- if (n[0] !== 71)
- throw new Error(
- "Invalid TS packet sync byte. Likely an internal bug, please report this file.",
- );
- const s = (n[1] << 8) + n[2],
- a = (s >> 14) & 1,
- o = s & 8191,
- u = (n[3] >> 4) & 3;
- return {
- payloadUnitStartIndicator: a,
- pid: o,
- adaptationFieldControl: u,
- body: n.subarray(4),
- };
- }
- normalizeTimestamp(e) {
- if (!this.timestampWrapInfo) {
- const i = 60 * Ft;
- this.timestampWrapInfo = {
- reference: e - i,
- offset: e >= Ws - i ? -Ws : Ws,
- };
- }
- const { reference: t, offset: n } = this.timestampWrapInfo;
- return (n < 0 && e >= t) || (n > 0 && e < t) ? e + n : e;
- }
-}
-const zr = (r, e, t) => {
- if (e.payload.byteLength < 3) return null;
- const n = new pe(e.payload);
- if (n.readBits(24) !== 1) return null;
- const s = n.readBits(8);
- if (
- (n.skipBits(16),
- s === 188 ||
- s === 190 ||
- s === 191 ||
- s === 240 ||
- s === 241 ||
- s === 255 ||
- s === 242 ||
- s === 248)
- )
- return null;
- n.skipBits(8);
- const a = n.readBits(2);
- n.skipBits(14);
- let o = null;
- if (a === 2 || a === 3)
- ((o = 0),
- n.skipBits(4),
- (o += n.readBits(3) * (1 << 30)),
- n.skipBits(1),
- (o += n.readBits(15) * 32768),
- n.skipBits(1),
- (o += n.readBits(15)),
- (o = r.normalizeTimestamp(o)));
- else if (t) throw new Error(yu);
- return {
- sectionStartPos: e.startPos,
- sectionEndPos: e.endPos,
- pts: o,
- randomAccessIndicator: e.randomAccessIndicator,
- };
- },
- cn = (r, e, t) => {
- T(e.endPos !== null);
- const n = zr(r, e, t);
- if (!n) return null;
- const i = new pe(e.payload);
- i.skipBits(32);
- const s = i.readBits(16),
- a = 6;
- i.skipBits(16);
- const o = i.readBits(8),
- c = i.pos + 8 * o;
- i.pos = c;
- const u = c / 8;
- T(Number.isInteger(u));
- const l = e.payload.subarray(u, s > 0 ? a + s : e.payload.byteLength);
- return { ...n, data: l };
- };
-class ps {
- constructor(e) {
- ((this.elementaryStream = e),
- (this.packetBuffers = new WeakMap()),
- (this.packetSectionStarts = new WeakMap()));
- }
- getId() {
- return this.elementaryStream.pid;
- }
- getNumber() {
- const e = this.elementaryStream.demuxer,
- t = this.elementaryStream.info.type;
- let n = 0;
- for (const i of e.trackBackingEntries)
- if (
- (i.getType() === t && n++,
- T(i instanceof ps),
- i.elementaryStream === this.elementaryStream)
- )
- break;
- return n;
- }
- getCodec() {
- throw new Error("Not implemented on base class.");
- }
- getInternalCodecId() {
- return this.elementaryStream.streamType;
- }
- getName() {
- return null;
- }
- getLanguageCode() {
- return nt;
- }
- getDisposition() {
- return { ...gr, primary: !1 };
- }
- getTimeResolution() {
- return Ft;
- }
- isRelativeToUnixEpoch() {
- return !1;
- }
- getUnixTimeForTimestamp() {
- return null;
- }
- getPairingMask() {
- return 1n;
- }
- getBitrate() {
- return null;
- }
- getAverageBitrate() {
- return null;
- }
- async getDurationFromMetadata() {
- return null;
- }
- async getLiveRefreshInterval() {
- return null;
- }
- createEncodedPacket(e, t, n) {
- let i;
- return (
- this.allPacketsAreKeyPackets()
- ? (i = "key")
- : (i = e.randomAccessIndicator === 1 ? "key" : "delta"),
- new Ee(
- n.metadataOnly ? Tt : e.data,
- i,
- e.pts / Ft,
- Math.max(t / Ft, 0),
- e.sequenceNumber,
- e.data.byteLength,
- )
- );
- }
- async getFirstPacket(e) {
- const t = this.elementaryStream.firstSection;
- T(t);
- const n = cn(this.elementaryStream.demuxer, t, !0);
- T(n);
- const i = new $n(this.elementaryStream, n),
- s = new Us(this, i),
- a = await s.readNext();
- if (!a) return null;
- const o = this.createEncodedPacket(a.packet, a.duration, e);
- return (
- this.packetBuffers.set(o, s),
- this.packetSectionStarts.set(o, a.packet.sectionStartPos),
- o
- );
- }
- async getNextPacket(e, t) {
- let n = this.packetBuffers.get(e);
- if (n) {
- const l = await n.readNext();
- if (!l) return null;
- this.packetBuffers.delete(e);
- const d = this.createEncodedPacket(l.packet, l.duration, t);
- return (
- this.packetBuffers.set(d, n),
- this.packetSectionStarts.set(d, l.packet.sectionStartPos),
- d
- );
- }
- const i = this.packetSectionStarts.get(e);
- if (i === void 0)
- throw new Error("Packet was not created from this track.");
- const s = this.elementaryStream.demuxer,
- a = await s.readSection(i, !0);
- T(a);
- const o = cn(s, a, !0);
- T(o);
- const c = new $n(this.elementaryStream, o);
- n = new Us(this, c);
- const u = e.sequenceNumber;
- for (;;) {
- const l = await n.readNext();
- if (!l) return null;
- if (l.packet.sequenceNumber > u) {
- const d = this.createEncodedPacket(l.packet, l.duration, t);
- return (
- this.packetBuffers.set(d, n),
- this.packetSectionStarts.set(d, l.packet.sectionStartPos),
- d
- );
- }
- }
- }
- async getNextKeyPacket(e, t) {
- let n = e;
- for (;;) {
- if (((n = await this.getNextPacket(n, t)), !n)) return null;
- if (n.type === "key") return n;
- }
- }
- getPacket(e, t) {
- return this.doPacketLookup(e, !1, t);
- }
- getKeyPacket(e, t) {
- return this.doPacketLookup(e, !0, t);
- }
- async doPacketLookup(e, t, n) {
- var _;
- const i = ni(e * Ft),
- s = this.elementaryStream.demuxer,
- { reader: a, seekChunkSize: o } = s,
- c = this.elementaryStream.pid,
- u = async (v, I, w) => {
- let x = v;
- for (; x < I;) {
- const k = await s.readPacketHeader(x);
- if (!k) return null;
- if (k.pid === c && k.payloadUnitStartIndicator === 1) {
- const S = await s.readSection(x, w);
- if (!S) return null;
- const E = zr(s, S, !1);
- if (E && E.pts !== null) return { pesPacketHeader: E, section: S };
- }
- x += s.packetStride;
- }
- return null;
- },
- l = this.elementaryStream.firstSection;
- T(l);
- const d = zr(s, l, !0);
- if ((T(d), i < d.pts)) return null;
- let f;
- const h = this.elementaryStream.referencePesPackets,
- p = ke(h, i, (v) => v.pts),
- m = p !== -1 ? h[p] : null;
- if (m && i - m.pts < Ft / 2) f = m.sectionStartPos;
- else {
- let v = 0;
- if (a.fileSize !== null) {
- const I = Math.ceil(a.fileSize / o);
- if (I > 1) {
- let w = 0,
- x = I - 1;
- for (v = w; w <= x;) {
- const k = Math.floor((w + x) / 2),
- S = vs(k * o, s.packetStride) + d.sectionStartPos,
- E = S + o,
- B = await u(S, E, !1);
- if (!B) {
- x = k - 1;
- continue;
- }
- B.pesPacketHeader.pts <= i ? ((v = k), (w = k + 1)) : (x = k - 1);
- }
- }
- }
- f = vs(v * o, s.packetStride) + d.sectionStartPos;
- }
- const b = await u(f, a.fileSize ?? 1 / 0, !1);
- let g = (b == null ? void 0 : b.pesPacketHeader) ?? null;
- g || (g = d);
- const y = this.getReorderSize(),
- C = async (v, I) => {
- var q;
- const w = await s.readSection(v, !0);
- T(w);
- const x = cn(s, w, !0);
- T(x);
- const k = new $n(this.elementaryStream, x),
- S = new Us(this, k);
- for (
- ;
- !(
- (((q = Ae(S.presentationOrderPackets)) == null ? void 0 : q.pts) ??
- -1 / 0) >= i || !(await S.readNextPacket())
- );
- );
- const E = Va(S.presentationOrderPackets, I);
- if (E === -1) return null;
- const B = S.presentationOrderPackets[E],
- R = E === 0 ? 0 : B.pts - S.presentationOrderPackets[E - 1].pts;
- for (; S.decodeOrderPackets[0] !== B;) S.decodeOrderPackets.shift();
- S.lastDuration = R;
- const M = await S.readNext();
- T(M);
- const z = this.createEncodedPacket(M.packet, M.duration, n);
- return (
- this.packetBuffers.set(z, S),
- this.packetSectionStarts.set(z, M.packet.sectionStartPos),
- z
- );
- };
- if (!t || this.allPacketsAreKeyPackets()) {
- e: for (;;) {
- let v = g.sectionStartPos + s.packetStride;
- for (;;) {
- const I = await s.readPacketHeader(v);
- if (!I) break e;
- if (I.pid === c && I.payloadUnitStartIndicator === 1) {
- const w = await s.readSection(v, !1);
- if (w) {
- const x = zr(s, w, !1);
- if (x && x.pts !== null) {
- if (x.pts > i) break e;
- ((g = x), _a(this.elementaryStream, g));
- break;
- }
- }
- }
- v += s.packetStride;
- }
- }
- e: for (let v = 0; v < y + 1; v++) {
- let I = g.sectionStartPos - s.packetStride;
- for (; I >= s.packetOffset;) {
- const w = await s.readPacketHeader(I);
- if (!w) break e;
- if (w.pid === c && w.payloadUnitStartIndicator === 1) {
- const x = await s.readSection(I, !1);
- if (x) {
- const k = zr(s, x, !1);
- if (k && k.pts !== null) {
- g = k;
- break;
- }
- }
- }
- I -= s.packetStride;
- }
- }
- return C(g.sectionStartPos, (v) => v.pts <= i);
- } else {
- let v = f,
- I = null;
- const w = !this.elementaryStream.canBeTrustedWithKeyPackets;
- for (;;) {
- let x = null;
- const k = v <= d.sectionStartPos;
- let S,
- E = null;
- if (k) ((S = d), (E = l));
- else {
- const M = await u(v, a.fileSize ?? 1 / 0, w);
- ((S = (M == null ? void 0 : M.pesPacketHeader) ?? null),
- (E = (M == null ? void 0 : M.section) ?? null));
- }
- let B = !1,
- R = 0;
- e: for (; S && !(I !== null && S.sectionStartPos >= I);) {
- if (S.pts <= i) {
- let z;
- if (this.elementaryStream.canBeTrustedWithKeyPackets)
- z = S.randomAccessIndicator === 1;
- else {
- T(E);
- const q = cn(s, E, !0);
- T(q);
- const j = new $n(this.elementaryStream, q);
- (await j.markNextPacket(),
- (z =
- ((_ = j.suppliedPacket) == null
- ? void 0
- : _.randomAccessIndicator) === 1));
- }
- z && (x = S);
- }
- if ((S.pts > i && (B = !0), B && (R++, R > y))) break;
- let M = S.sectionStartPos + s.packetStride;
- for (;;) {
- const z = await s.readPacketHeader(M);
- if (!z) break e;
- if (z.pid === c && z.payloadUnitStartIndicator === 1) {
- const q = await s.readSection(M, w);
- if (q) {
- const j = zr(s, q, !1);
- if (j && j.pts !== null) {
- ((S = j), (E = q), _a(this.elementaryStream, S));
- break;
- }
- }
- }
- M += s.packetStride;
- }
- }
- if (x) {
- let M = x;
- if (R === 0)
- e: for (let q = 0; q < y; q++) {
- let j = M.sectionStartPos - s.packetStride;
- for (; j >= s.packetOffset;) {
- const se = await s.readPacketHeader(j);
- if (!se) break e;
- if (se.pid === c && se.payloadUnitStartIndicator === 1) {
- const le = await s.readSection(j, w);
- if (le) {
- const ue = zr(s, le, !1);
- if (ue && ue.pts !== null) {
- M = ue;
- break;
- }
- }
- }
- j -= s.packetStride;
- }
- }
- const z = await C(
- M.sectionStartPos,
- (q) => q.pts <= i && q.randomAccessIndicator === 1,
- );
- return (T(z), z);
- }
- if (k) return null;
- ((I = v),
- (v = Math.max(
- vs(v - d.sectionStartPos - o, s.packetStride) + d.sectionStartPos,
- d.sectionStartPos,
- )));
- }
- }
- }
-}
-class Bm extends ps {
- getType() {
- return "video";
- }
- getCodec() {
- return this.elementaryStream.info.codec;
- }
- getCodedWidth() {
- return this.elementaryStream.info.width;
- }
- getCodedHeight() {
- return this.elementaryStream.info.height;
- }
- getSquarePixelWidth() {
- return this.elementaryStream.info.squarePixelWidth;
- }
- getSquarePixelHeight() {
- return this.elementaryStream.info.squarePixelHeight;
- }
- getTransformationMatrix() {
- return [...ei];
- }
- async getColorSpace() {
- return this.elementaryStream.info.colorSpace;
- }
- async canBeTransparent() {
- return !1;
- }
- async getDecoderConfig() {
- return (
- T(this.elementaryStream.info.decoderConfig),
- this.elementaryStream.info.decoderConfig
- );
- }
- allPacketsAreKeyPackets() {
- return !1;
- }
- getReorderSize() {
- return this.elementaryStream.info.reorderSize;
- }
-}
-class Fm extends ps {
- getType() {
- return "audio";
- }
- getCodec() {
- return this.elementaryStream.info.codec;
- }
- getNumberOfChannels() {
- return this.elementaryStream.info.numberOfChannels;
- }
- getSampleRate() {
- return this.elementaryStream.info.sampleRate;
- }
- async getDecoderConfig() {
- return (
- T(this.elementaryStream.info.decoderConfig),
- this.elementaryStream.info.decoderConfig
- );
- }
- allPacketsAreKeyPackets() {
- return !0;
- }
- getReorderSize() {
- return 0;
- }
-}
-const _a = (r, e) => {
- const t = r.referencePesPackets,
- n = ke(t, e.sectionStartPos, (i) => i.sectionStartPos);
- if (n >= 0) {
- const i = t[n];
- if (e.pts <= i.pts) return !1;
- const s = r.demuxer.minReferencePointByteDistance;
- if (e.sectionStartPos - i.sectionStartPos < s) return !1;
- if (n < t.length - 1) {
- const a = t[n + 1];
- if (a.pts < e.pts || a.sectionStartPos - e.sectionStartPos < s) return !1;
- }
- }
- return (t.splice(n + 1, 0, e), !0);
-};
-class $n {
- constructor(e, t) {
- ((this.currentPos = 0),
- (this.pesPackets = []),
- (this.currentPesPacketIndex = 0),
- (this.currentPesPacketPos = 0),
- (this.endPos = 0),
- (this.lastSuppliedPesPacket = null),
- (this.nextPts = null),
- (this.suppliedPacket = null),
- (this.elementaryStream = e),
- (this.pid = e.pid),
- (this.demuxer = e.demuxer),
- (this.startingPesPacket = t));
- }
- ensureBuffered(e) {
- const t = this.endPos - this.currentPos;
- return t >= e
- ? e
- : this.bufferData(e - t).then(() =>
- Math.min(this.endPos - this.currentPos, e),
- );
- }
- getCurrentPesPacket() {
- const e = this.pesPackets[this.currentPesPacketIndex];
- return (T(e), e);
- }
- async bufferData(e) {
- const t = this.endPos + e;
- for (; this.endPos < t;) {
- let n;
- if (this.pesPackets.length === 0) n = this.startingPesPacket;
- else {
- let i = Ae(this.pesPackets).sectionEndPos;
- for (T(i !== null); ;) {
- const s = await this.demuxer.readPacketHeader(i);
- if (!s) return;
- if (s.pid === this.pid) {
- const a = await this.demuxer.readSection(i, !0);
- if (!a) return;
- const o = cn(this.demuxer, a, !1);
- if (o) {
- n = o;
- break;
- }
- }
- i += this.demuxer.packetStride;
- }
- }
- (this.pesPackets.push(n), (this.endPos += n.data.byteLength));
- }
- }
- readBytes(e) {
- const t = this.getCurrentPesPacket(),
- n = this.currentPos - this.currentPesPacketPos,
- i = n + e;
- if (((this.currentPos += e), i <= t.data.byteLength))
- return t.data.subarray(n, i);
- const s = new Uint8Array(e);
- s.set(t.data.subarray(n));
- let a = t.data.byteLength - n;
- for (;;) {
- this.advanceCurrentPacket();
- const o = this.getCurrentPesPacket(),
- c = e - a;
- if (c <= o.data.byteLength) {
- s.set(o.data.subarray(0, c), a);
- break;
- }
- (s.set(o.data, a), (a += o.data.byteLength));
- }
- return s;
- }
- readU8() {
- let e = this.getCurrentPesPacket();
- const t = this.currentPos - this.currentPesPacketPos;
- return (
- this.currentPos++,
- t < e.data.byteLength
- ? e.data[t]
- : (this.advanceCurrentPacket(),
- (e = this.getCurrentPesPacket()),
- e.data[0])
- );
- }
- seekTo(e) {
- if (e !== this.currentPos) {
- if (e < this.currentPos)
- for (; e < this.currentPesPacketPos;) {
- this.currentPesPacketIndex--;
- const t = this.getCurrentPesPacket();
- this.currentPesPacketPos -= t.data.byteLength;
- }
- else
- for (;;) {
- const t = this.getCurrentPesPacket(),
- n = this.currentPesPacketPos + t.data.byteLength;
- if (e < n) break;
- ((this.currentPesPacketPos += t.data.byteLength),
- this.currentPesPacketIndex++);
- }
- this.currentPos = e;
- }
- }
- skip(e) {
- this.seekTo(this.currentPos + e);
- }
- advanceCurrentPacket() {
- ((this.currentPesPacketPos += this.getCurrentPesPacket().data.byteLength),
- this.currentPesPacketIndex++);
- }
- async markNextPacket() {
- var t;
- T(!this.suppliedPacket);
- const e = this.elementaryStream;
- if (e.info.type === "video") {
- const n = e.info.codec,
- i = 1024;
- if (n !== "avc" && n !== "hevc") throw new Error("Unhandled.");
- const s = n === "avc" ? 1 : 2;
- let a = null,
- o = !1,
- c = 0;
- for (;;) {
- let u = this.ensureBuffered(i);
- if ((O(u) && (u = await u), u === 0)) break;
- const l = this.currentPos,
- d = this.readBytes(u),
- f = d.byteLength;
- let h = 0;
- for (; h < f;) {
- const p = d.indexOf(0, h);
- if (p === -1 || p >= f) break;
- h = p;
- const m = l + h;
- if (h + 3 >= f) {
- this.seekTo(m);
- break;
- }
- const b = d[h + 1],
- g = d[h + 2],
- y = d[h + 3];
- let C = 0;
- if (
- (b === 0 && g === 0 && y === 1
- ? (C = 4)
- : b === 0 && g === 1 && (C = 3),
- C === 0)
- ) {
- h++;
- continue;
- }
- const _ = m;
- a ?? (a = _);
- const v = h + C,
- I = v + s,
- w = 6;
- if (I + (n === "avc" ? w : 1) > f) {
- this.seekTo(m);
- break;
- }
- const k = d[v];
- let S, E, B;
- if (n === "avc")
- ((S = ai(k)),
- (E =
- S === Xe.NON_IDR_SLICE || S === Xe.SLICE_DPA || S === Xe.IDR),
- (B =
- S === Xe.SEI || S === Xe.SPS || S === Xe.PPS || S === Xe.AUD));
- else {
- if (((S = wn(k)), (((k & 1) << 5) | (d[v + 1] >> 3)) > 0)) {
- h += C;
- continue;
- }
- ((E = S <= ze.RASL_R || (S >= ze.BLA_W_LP && S <= 21)),
- (B =
- (S >= ze.VPS_NUT && S <= 37) ||
- S === ze.PREFIX_SEI_NUT ||
- (S >= 41 && S <= 44) ||
- (S >= 48 && S <= 55)));
- }
- let R = !1;
- if (E) {
- let M;
- if (n === "avc") {
- const z = d.subarray(I, I + w),
- q = G(new pe(z));
- ((M = !o || q <= c), (c = q));
- } else M = d[I] >> 7 === 1;
- M && (o ? (R = !0) : (o = !0));
- } else B && o && (R = !0);
- if (R) {
- const M = _ - a;
- return (this.seekTo(a), this.supplyPacket(M, 0));
- }
- h += C;
- }
- if (u < i) break;
- }
- if (a !== null && this.endPos > a) {
- const u = this.endPos - a;
- return (this.seekTo(a), this.supplyPacket(u, 0));
- }
- } else {
- const n = e.info.codec,
- i = 128;
- for (;;) {
- let s = this.ensureBuffered(i);
- O(s) && (s = await s);
- const a = this.currentPos;
- for (; this.currentPos - a < s;) {
- const o = this.readU8();
- if (n === "aac") {
- if (o !== 255) continue;
- this.skip(-1);
- const c = this.currentPos;
- let u = this.ensureBuffered($r);
- if ((O(u) && (u = await u), u < $r)) return;
- const l = this.readBytes($r),
- d = Xr(yt.tempFromBytes(l));
- if (d) {
- this.seekTo(c);
- let f = this.ensureBuffered(d.frameLength);
- return (
- O(f) && (f = await f),
- this.supplyPacket(f, Math.round((Qi * Ft) / e.info.sampleRate))
- );
- } else this.seekTo(c + 1);
- } else if (n === "mp3") {
- if (o !== 255) continue;
- this.skip(-1);
- const c = this.currentPos;
- let u = this.ensureBuffered(jr);
- if ((O(u) && (u = await u), u < jr)) return;
- const l = this.readBytes(jr),
- d = ge(l).getUint32(0),
- f = io(d, null);
- if (f.header) {
- this.seekTo(c);
- let h = this.ensureBuffered(f.header.totalSize);
- O(h) && (h = await h);
- const p = (f.header.audioSamplesInFrame * Ft) / e.info.sampleRate;
- return this.supplyPacket(h, Math.round(p));
- } else this.seekTo(c + 1);
- } else if (n === "ac3") {
- if (o !== 11) continue;
- this.skip(-1);
- const c = this.currentPos;
- let u = this.ensureBuffered(5);
- if ((O(u) && (u = await u), u < 5)) return;
- const l = this.readBytes(5);
- if (l[0] !== 11 || l[1] !== 119) {
- this.seekTo(c + 1);
- continue;
- }
- const d = l[4] >> 6,
- f = l[4] & 63;
- if (d === 3 || f > 37) {
- this.seekTo(c + 1);
- continue;
- }
- const h = uh[3 * f + d];
- (T(h !== void 0),
- this.seekTo(c),
- (u = this.ensureBuffered(h)),
- O(u) && (u = await u));
- const p = Math.round((dh * Ft) / e.info.sampleRate);
- return this.supplyPacket(u, p);
- } else if (n === "eac3") {
- if (o !== 11) continue;
- this.skip(-1);
- const c = this.currentPos;
- let u = this.ensureBuffered(5);
- if ((O(u) && (u = await u), u < 5)) return;
- const l = this.readBytes(5);
- if (l[0] !== 11 || l[1] !== 119) {
- this.seekTo(c + 1);
- continue;
- }
- const f = ((((l[2] & 7) << 8) | l[3]) + 1) * 2,
- p = l[4] >> 6 === 3 ? 3 : (l[4] >> 4) & 3,
- m = Ll[p];
- (this.seekTo(c),
- (u = this.ensureBuffered(f)),
- O(u) && (u = await u));
- const b = m * 256,
- g = Math.round((b * Ft) / e.info.sampleRate);
- return this.supplyPacket(u, g);
- } else if (n === "dts") {
- if (o !== 127 && o !== 100) continue;
- this.skip(-1);
- const c = this.currentPos;
- let u = this.ensureBuffered(Ri);
- if ((O(u) && (u = await u), u < Ri)) return;
- const l = this.readBytes(Ri),
- d = Xl(l);
- let f = d ? null : Mi(l);
- if (!d && !f) {
- this.seekTo(c + 1);
- continue;
- }
- if (f && !f.asset) {
- this.seekTo(c);
- const b = Math.min(f.frameSize, mh);
- let g = this.ensureBuffered(b);
- (O(g) && (g = await g), (f = Mi(this.readBytes(g)) ?? f));
- }
- let h = d ? d.frameSize : f.frameSize;
- if (d) {
- let b = Math.ceil(d.frameSize / 4) * 4;
- for (;;) {
- this.seekTo(c);
- const g = b + Sa;
- let y = this.ensureBuffered(g);
- if ((O(y) && (y = await y), y < g)) break;
- this.seekTo(c + b);
- const C = Mi(this.readBytes(Sa));
- if (!C) break;
- ((b += C.frameSize), (h = b));
- }
- }
- const p =
- (d == null ? void 0 : d.sampleCount) ??
- ((t = f.asset) == null ? void 0 : t.sampleCount);
- if (p === void 0) {
- this.seekTo(c + 1);
- continue;
- }
- (this.seekTo(c),
- (u = this.ensureBuffered(h)),
- O(u) && (u = await u));
- const m = Math.round((p * Ft) / e.info.sampleRate);
- return this.supplyPacket(u, m);
- } else throw new Error("Unhandled.");
- }
- if (s < i) break;
- }
- }
- }
- supplyPacket(e, t) {
- const n = this.getCurrentPesPacket();
- let i;
- if (this.lastSuppliedPesPacket === n)
- (T(this.nextPts !== null), (i = this.nextPts));
- else {
- if (n.pts === null) throw new Error(yu);
- ((i = n.pts), _a(this.elementaryStream, n));
- }
- ((this.lastSuppliedPesPacket = n), (this.nextPts = i + t));
- const s = n.sectionStartPos,
- a = s + (this.currentPos - this.currentPesPacketPos),
- o = this.readBytes(e);
- let c = n.randomAccessIndicator;
- if (c === 0 && !this.elementaryStream.canBeTrustedWithKeyPackets) {
- if (this.elementaryStream.info.type === "audio") c = 1;
- else if (this.elementaryStream.info.decoderConfig) {
- const u =
- fs(
- this.elementaryStream.info.codec,
- this.elementaryStream.info.decoderConfig,
- o,
- ) === "key";
- c = Number(u);
- }
- }
- ((this.suppliedPacket = {
- pts: i,
- data: o,
- sequenceNumber: a,
- sectionStartPos: s,
- randomAccessIndicator: c,
- }),
- this.pesPackets.splice(0, this.currentPesPacketIndex),
- (this.currentPesPacketIndex = 0));
- }
-}
-class Us {
- constructor(e, t) {
- ((this.decodeOrderPackets = []),
- (this.reorderBuffer = []),
- (this.presentationOrderPackets = []),
- (this.reachedEnd = !1),
- (this.lastDuration = 0),
- (this.backing = e),
- (this.context = t),
- (this.reorderSize = e.getReorderSize()),
- T(this.reorderSize >= 0));
- }
- async readNext() {
- if (this.decodeOrderPackets.length === 0 && !(await this.readNextPacket()))
- return null;
- await this.ensureCurrentPacketHasNext();
- const e = this.decodeOrderPackets[0],
- t = this.presentationOrderPackets.indexOf(e);
- T(t !== -1);
- let n;
- for (
- t === this.presentationOrderPackets.length - 1
- ? (n = this.lastDuration)
- : ((n = this.presentationOrderPackets[t + 1].pts - e.pts),
- (this.lastDuration = n)),
- this.decodeOrderPackets.shift();
- this.presentationOrderPackets.length > 0;
- ) {
- const i = this.presentationOrderPackets[0];
- if (this.decodeOrderPackets.includes(i)) break;
- this.presentationOrderPackets.shift();
- }
- return { packet: e, duration: n };
- }
- async readNextPacket() {
- if (this.reachedEnd) return !1;
- let e;
- return (
- this.context.suppliedPacket
- ? (e = this.context.suppliedPacket)
- : (await this.context.markNextPacket(),
- (e = this.context.suppliedPacket)),
- (this.context.suppliedPacket = null),
- e
- ? (this.decodeOrderPackets.push(e),
- this.processPacketThroughReorderBuffer(e),
- !0)
- : ((this.reachedEnd = !0), this.flushReorderBuffer(), !1)
- );
- }
- async ensureCurrentPacketHasNext() {
- const e = this.decodeOrderPackets[0];
- for (T(e); ;) {
- const t = this.presentationOrderPackets.indexOf(e);
- if (
- (t !== -1 && t <= this.presentationOrderPackets.length - 2) ||
- !(await this.readNextPacket())
- )
- break;
- }
- }
- processPacketThroughReorderBuffer(e) {
- if (
- (this.reorderBuffer.push(e), this.reorderBuffer.length > this.reorderSize)
- ) {
- let t = 0;
- for (let i = 1; i < this.reorderBuffer.length; i++)
- this.reorderBuffer[i].pts < this.reorderBuffer[t].pts && (t = i);
- const n = this.reorderBuffer[t];
- (this.presentationOrderPackets.push(n), this.reorderBuffer.splice(t, 1));
- }
- }
- flushReorderBuffer() {
- (this.reorderBuffer.sort((e, t) => e.pts - t.pts),
- this.presentationOrderPackets.push(...this.reorderBuffer),
- (this.reorderBuffer.length = 0));
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const ku = "application/vnd.apple.mpegurl",
- oc = "#EXT-X-STREAM-INF:",
- cc = "#EXT-X-I-FRAME-STREAM-INF:",
- lc = "#EXT-X-MEDIA:",
- Yi = "#EXT-X-DEFINE:",
- Aa = "#EXTINF:",
- uc = "#EXT-X-MAP:",
- dc = "#EXT-X-KEY:",
- fc = "#EXT-X-MEDIA-SEQUENCE:",
- hc = "#EXT-X-BYTERANGE:",
- mc = "#EXT-X-PROGRAM-DATE-TIME:",
- Rm = "#EXT-X-DISCONTINUITY",
- pc = "#EXT-X-TARGETDURATION:",
- Mm = "#EXT-X-ENDLIST",
- gc = "#EXT-X-PLAYLIST-TYPE:",
- Nm = "#EXT-X-I-FRAMES-ONLY",
- Tu = (r) => r.length === 0 || (r.startsWith("#") && !r.startsWith("#EXT"));
-class pn {
- constructor(e, t) {
- this._attributes = {};
- let n = "",
- i = "",
- s = !1,
- a = !1,
- o = !1;
- const c = () => {
- if (!n) return;
- const u = n.trim().toLowerCase();
- Object.prototype.hasOwnProperty.call(this._attributes, u) &&
- te._warn(`Duplicate AttributeName "${u}"; using last value`);
- const l = o || i.startsWith("0x") || i.startsWith("0X");
- ((this._attributes[u] = l && t ? t.substitute(i) : i),
- (n = ""),
- (i = ""),
- (s = !1),
- (o = !1));
- };
- for (let u = 0; u < e.length; u++) {
- const l = e[u];
- l === '"'
- ? (s && !a && i.length === 0 && (o = !0), (a = !a))
- : l === "=" && !s && !a
- ? (s = !0)
- : l === "," && !a
- ? c()
- : s
- ? (i += l)
- : (n += l);
- }
- if (a)
- throw new Error(
- "Invalid M3U8 file; unterminated quoted-string AttributeValue.",
- );
- c();
- }
- get(e) {
- return this._attributes[e.toLowerCase()] ?? null;
- }
- getAsNumber(e) {
- const t = this.get(e);
- if (t === null) return null;
- const n = Number(t);
- return Number.isFinite(n) ? n : null;
- }
- merge(e) {
- Object.assign(this._attributes, e._attributes);
- }
-}
-const Om = /^[A-Za-z0-9_-]+$/,
- Dm = /\{\$([A-Za-z0-9_-]+)\}/g;
-class xu {
- constructor(e, t) {
- ((this.playlistPath = e),
- (this.importedVariables = t),
- (this.variables = new Map()));
- }
- define(e) {
- var o;
- const t = new pn(e, this),
- n = t.get("name"),
- i = t.get("import"),
- s = t.get("queryparam");
- if ([n, i, s].filter((c) => c !== null).length !== 1)
- throw new Error(
- "Invalid #EXT-X-DEFINE tag; exactly one of NAME, IMPORT, or QUERYPARAM must be present.",
- );
- if (n !== null) {
- const c = t.get("value");
- if (c === null)
- throw new Error("Invalid #EXT-X-DEFINE tag; NAME requires VALUE.");
- this.set(n, c);
- } else if (i !== null) {
- const c = (o = this.importedVariables) == null ? void 0 : o.get(i);
- if (c === void 0)
- throw new Error(
- `Invalid #EXT-X-DEFINE tag; cannot import undefined variable "${i}".`,
- );
- this.set(i, c);
- } else if (s !== null) {
- const c = Lf(this.playlistPath, s);
- if (c === null)
- throw new Error(
- `Invalid #EXT-X-DEFINE tag; query parameter "${s}" is missing.`,
- );
- this.set(s, c);
- }
- }
- substitute(e) {
- return e.replaceAll(Dm, (t, n) => {
- const i = this.variables.get(n);
- if (i === void 0)
- throw new Error(
- `Invalid M3U8 file; variable "${n}" is referenced before being defined.`,
- );
- return i;
- });
- }
- get(e) {
- return this.variables.get(e);
- }
- set(e, t) {
- if (!Om.test(e))
- throw new Error(
- `Invalid #EXT-X-DEFINE tag; invalid variable name "${e}".`,
- );
- if (this.variables.has(e))
- throw new Error(
- `Invalid #EXT-X-DEFINE tag; variable "${e}" is already defined.`,
- );
- this.variables.set(e, t);
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class zm {
- constructor(e, t, n) {
- ((this.nextInputCacheAge = 0),
- (this.inputCache = []),
- (this.trackBackingsPromise = null),
- (this.firstSegment = null),
- (this.firstSegmentFirstTimestamps = new WeakMap()),
- (this.firstTimestampCache = new WeakMap()),
- (this.input = e),
- (this.path = t),
- (this.trackDeclarations = n));
- }
- async getDurationFromMetadata(e) {
- const t = await this.getSegmentAt(1 / 0, { skipLiveWait: e.skipLiveWait });
- return t ? t.timestamp + t.duration : null;
- }
- async getUnixTimeForTimestamp(e) {
- let t = await this.getSegmentAt(e, {});
- if (
- (t ?? (t = await this.getFirstSegment({})),
- !t || t.unixEpochTimestamp === null)
- )
- return null;
- const n = e - t.timestamp;
- return t.unixEpochTimestamp + n;
- }
- async getTrackBackings() {
- return (
- this.trackBackingsPromise ??
- (this.trackBackingsPromise = (async () => {
- const e = [];
- if (this.trackDeclarations) {
- for (const t of this.trackDeclarations)
- if (t.type === "video") {
- const n = qn(e, (i) => i.getType() === "video") + 1;
- e.push(new bc(this, t, n));
- } else if (t.type === "audio") {
- const n = qn(e, (i) => i.getType() === "audio") + 1;
- e.push(new wc(this, t, n));
- }
- } else {
- if (
- ((this.firstSegment = await this.getFirstSegment({})),
- !this.firstSegment)
- )
- return [];
- const n = await this.getInputForSegment(
- this.firstSegment,
- ).getTracks();
- for (const i of n)
- if (i.type === "video") {
- const s = qn(e, (a) => a.getType() === "video") + 1;
- e.push(new bc(this, { id: e.length + 1, type: "video" }, s));
- } else if (i.type === "audio") {
- const s = qn(e, (a) => a.getType() === "audio") + 1;
- e.push(new wc(this, { id: e.length + 1, type: "audio" }, s));
- }
- }
- return e;
- })())
- );
- }
- async getFirstTimestampForInput(e) {
- const t = this.firstTimestampCache.get(e);
- if (t !== void 0) return t;
- const n = await e.getFirstTimestamp();
- return (this.firstTimestampCache.set(e, n), n);
- }
- async getMediaOffset(e, t) {
- const n = e.firstSegment ?? e;
- let i;
- if (this.firstSegmentFirstTimestamps.has(n))
- i = this.firstSegmentFirstTimestamps.get(n);
- else {
- const u = this.getInputForSegment(n);
- ((i = await this.getFirstTimestampForInput(u)),
- this.firstSegmentFirstTimestamps.set(n, i));
- }
- if (n === e) return n.timestamp - i;
- const s = await this.getFirstTimestampForInput(t),
- a = e.timestamp - n.timestamp,
- c = s - i - a;
- return Math.abs(c) <= Math.min(0.25, a) ? n.timestamp - i : e.timestamp - s;
- }
- dispose() {
- for (const e of this.inputCache) e.input.dispose();
- this.inputCache.length = 0;
- }
-}
-class Su {
- constructor(e, t, n) {
- ((this.packetInfos = new WeakMap()),
- (this.hydrationPromise = null),
- (this.firstInputTrack = null),
- (this.firstSegment = null),
- (this.segmentedInput = e),
- (this.decl = t),
- (this.number = n));
- }
- hydrate() {
- return (
- this.hydrationPromise ??
- (this.hydrationPromise = (async () => {
- var n;
- if (
- ((n = this.segmentedInput).firstSegment ??
- (n.firstSegment = await this.segmentedInput.getFirstSegment({})),
- !this.segmentedInput.firstSegment)
- )
- throw new Error("Missing first segment, can't retrieve track.");
- let e = this.segmentedInput.firstSegment,
- t = null;
- for (
- ;
- e &&
- ((t =
- (await this.segmentedInput.getInputForSegment(e).getTracks()).find(
- (a) => a.type === this.decl.type && a.number === this.number,
- ) ?? null),
- !t);
- )
- e = await this.segmentedInput.getNextSegment(e, {});
- if (!t)
- throw new Error("No matching track found in underlying media data.");
- ((this.firstInputTrack = t), (this.firstSegment = e));
- })())
- );
- }
- getId() {
- return this.decl.id;
- }
- getType() {
- return this.decl.type;
- }
- getNumber() {
- return this.number;
- }
- delegate(e) {
- return this.firstInputTrack ? e() : this.hydrate().then(e);
- }
- async getDecoderConfig() {
- return this.delegate(() =>
- this.firstInputTrack._backing.getDecoderConfig(),
- );
- }
- getHasOnlyKeyPackets() {
- return this.delegate(() => {
- var e, t;
- return (
- ((t = (e = this.firstInputTrack._backing).getHasOnlyKeyPackets) == null
- ? void 0
- : t.call(e)) ?? null
- );
- });
- }
- getPairingMask() {
- return 1n;
- }
- getCodec() {
- return this.delegate(() => this.firstInputTrack._backing.getCodec());
- }
- getInternalCodecId() {
- return this.delegate(() =>
- this.firstInputTrack._backing.getInternalCodecId(),
- );
- }
- getDisposition() {
- return this.delegate(() => this.firstInputTrack._backing.getDisposition());
- }
- getLanguageCode() {
- return this.delegate(() => this.firstInputTrack._backing.getLanguageCode());
- }
- getName() {
- return this.delegate(() => this.firstInputTrack._backing.getName());
- }
- getTimeResolution() {
- return this.delegate(() =>
- this.firstInputTrack._backing.getTimeResolution(),
- );
- }
- async isRelativeToUnixEpoch() {
- return (
- await this.hydrate(),
- T(this.segmentedInput.firstSegment),
- this.segmentedInput.firstSegment.unixEpochTimestamp ===
- this.segmentedInput.firstSegment.timestamp
- );
- }
- getUnixTimeForTimestamp(e) {
- return this.segmentedInput.getUnixTimeForTimestamp(e);
- }
- getBitrate() {
- return this.delegate(() => this.firstInputTrack._backing.getBitrate());
- }
- getAverageBitrate() {
- return this.delegate(() =>
- this.firstInputTrack._backing.getAverageBitrate(),
- );
- }
- getDurationFromMetadata(e) {
- return this.segmentedInput.getDurationFromMetadata(e);
- }
- getLiveRefreshInterval() {
- return this.segmentedInput.getLiveRefreshInterval();
- }
- async createAdjustedPacket(e, t, n) {
- (T(e.sequenceNumber >= 0), T(this.segmentedInput.firstSegment));
- const i = await this.segmentedInput.getMediaOffset(t, n.input),
- s = t.timestamp - this.segmentedInput.firstSegment.timestamp,
- a = e.clone({
- timestamp: Hi(e.timestamp + i, await n.getTimeResolution()),
- sequenceNumber: Math.floor(1e8 * s) + e.sequenceNumber,
- });
- return (
- this.packetInfos.set(a, { segment: t, track: n, sourcePacket: e }),
- a
- );
- }
- async getFirstPacket(e) {
- (await this.hydrate(), T(this.firstInputTrack), T(this.firstSegment));
- let t = this.firstInputTrack,
- n = this.firstSegment;
- for (;;) {
- if (t) {
- const a = await t._backing.getFirstPacket(e);
- if (a) return this.createAdjustedPacket(a, n, t);
- }
- if (
- ((n = await this.segmentedInput.getNextSegment(n, {
- skipLiveWait: e.skipLiveWait,
- })),
- !n)
- )
- break;
- t =
- (await this.segmentedInput.getInputForSegment(n).getTracks()).find(
- (a) =>
- a.type === this.firstInputTrack.type &&
- a.number === this.firstInputTrack.number,
- ) ?? null;
- }
- return null;
- }
- getNextPacket(e, t) {
- return this._getNextInternal(e, t, !1);
- }
- getNextKeyPacket(e, t) {
- return this._getNextInternal(e, t, !0);
- }
- async _getNextInternal(e, t, n) {
- const i = this.packetInfos.get(e);
- if (!i) throw new Error("Packet was not created from this track.");
- const s = n
- ? await i.track._backing.getNextKeyPacket(i.sourcePacket, t)
- : await i.track._backing.getNextPacket(i.sourcePacket, t);
- if (s) return this.createAdjustedPacket(s, i.segment, i.track);
- let a = i.segment;
- for (;;) {
- const o = await this.segmentedInput.getNextSegment(a, {
- skipLiveWait: t.skipLiveWait,
- });
- if (!o) return null;
- const l = (
- await this.segmentedInput.getInputForSegment(o).getTracks()
- ).find((f) => f.type === i.track.type && f.number === i.track.number);
- if (!l) {
- a = o;
- continue;
- }
- const d = await l._backing.getFirstPacket(t);
- return d ? this.createAdjustedPacket(d, o, l) : null;
- }
- }
- getPacket(e, t) {
- return this._getPacketInternal(e, t, !1);
- }
- getKeyPacket(e, t) {
- return this._getPacketInternal(e, t, !0);
- }
- async _getPacketInternal(e, t, n) {
- let i = await this.segmentedInput.getSegmentAt(e, {
- skipLiveWait: t.skipLiveWait,
- });
- if (!i) return null;
- for (await this.hydrate(); i;) {
- const s = this.segmentedInput.getInputForSegment(i),
- o = (await s.getTracks()).find(
- (d) =>
- d.type === this.firstInputTrack.type &&
- d.number === this.firstInputTrack.number,
- );
- if (!o) {
- i = await this.segmentedInput.getPreviousSegment(i, {
- skipLiveWait: t.skipLiveWait,
- });
- continue;
- }
- const c = await this.segmentedInput.getMediaOffset(i, s),
- u = e - c,
- l = n
- ? await o._backing.getKeyPacket(u, t)
- : await o._backing.getPacket(u, t);
- if (!l) {
- i = await this.segmentedInput.getPreviousSegment(i, {
- skipLiveWait: t.skipLiveWait,
- });
- continue;
- }
- return this.createAdjustedPacket(l, i, o);
- }
- return null;
- }
-}
-class bc extends Su {
- getType() {
- return "video";
- }
- getCodec() {
- return this.delegate(() => this.firstInputTrack._backing.getCodec());
- }
- getCodedWidth() {
- return this.delegate(() => this.firstInputTrack._backing.getCodedWidth());
- }
- getCodedHeight() {
- return this.delegate(() => this.firstInputTrack._backing.getCodedHeight());
- }
- getSquarePixelWidth() {
- return this.delegate(() =>
- this.firstInputTrack._backing.getSquarePixelWidth(),
- );
- }
- getSquarePixelHeight() {
- return this.delegate(() =>
- this.firstInputTrack._backing.getSquarePixelHeight(),
- );
- }
- getTransformationMatrix() {
- return this.delegate(() =>
- this.firstInputTrack._backing.getTransformationMatrix(),
- );
- }
- async getColorSpace() {
- return this.delegate(() => this.firstInputTrack._backing.getColorSpace());
- }
- async canBeTransparent() {
- return this.delegate(() =>
- this.firstInputTrack._backing.canBeTransparent(),
- );
- }
- async getDecoderConfig() {
- return this.delegate(() =>
- this.firstInputTrack._backing.getDecoderConfig(),
- );
- }
-}
-class wc extends Su {
- getType() {
- return "audio";
- }
- getCodec() {
- return this.delegate(() => this.firstInputTrack._backing.getCodec());
- }
- getNumberOfChannels() {
- return this.delegate(() =>
- this.firstInputTrack._backing.getNumberOfChannels(),
- );
- }
- getSampleRate() {
- return this.delegate(() => this.firstInputTrack._backing.getSampleRate());
- }
- async getDecoderConfig() {
- return this.delegate(() =>
- this.firstInputTrack._backing.getDecoderConfig(),
- );
- }
-}
-const Wm = new Proxy(
- {},
- {
- get(r, e) {
- throw new Error(
- `Module "" has been externalized for browser compatibility. Cannot access ".${e}" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`,
- );
- },
- },
- ),
- S1 = Object.freeze(
- Object.defineProperty(
- { __proto__: null, default: Wm },
- Symbol.toStringTag,
- { value: "Module" },
- ),
- );
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ Ga();
-const Pu = 0,
- Cu = 1 / 0;
-typeof FinalizationRegistry < "u" &&
- new FinalizationRegistry((r) => {
- r();
- });
-class dr extends mi {
- constructor() {
- (super(),
- (this._disposed = !1),
- (this._refCount = 0),
- (this._usedForHls = !1),
- (this._refFinalizationRegistry = null),
- (this._sizePromise = null),
- (this.onread = null),
- typeof FinalizationRegistry < "u" &&
- (this._refFinalizationRegistry = new FinalizationRegistry((e) => {
- e._decrementRefCount();
- })));
- }
- async getSizeOrNull() {
- if (this._disposed) throw new rt();
- return (
- this._sizePromise ??
- (this._sizePromise = (async () => {
- let e = this._getFileSize();
- return (
- e !== void 0 ||
- (await this._read(0, 1, Pu, Cu),
- (e = this._getFileSize()),
- T(e !== void 0)),
- e
- );
- })())
- );
- }
- async getSize() {
- if (this._disposed) throw new rt();
- const e = await this.getSizeOrNull();
- if (e === null)
- throw new Error("Cannot determine the size of an unsized source.");
- return e;
- }
- slice(e, t) {
- if (!Number.isInteger(e) || e < 0)
- throw new TypeError("offset must be a non-negative integer.");
- if (t !== void 0 && (!Number.isInteger(t) || t < 0))
- throw new TypeError(
- "length, when provided, must be a non-negative integer.",
- );
- return new Gm(this, e, t);
- }
- _dispatchRead(e, t) {
- var n;
- ((n = this.onread) == null || n.call(this, e, t),
- this._emit("read", { start: e, end: t }));
- }
- ref() {
- return new oo(this);
- }
- _incrementRefCount() {
- this._refCount++;
- }
- _decrementRefCount() {
- (this._refCount--,
- this._refCount === 0 && (this._dispose(), (this._disposed = !0)));
- }
-}
-class oo {
- constructor(e) {
- var t;
- if (((this._freed = !1), e._disposed))
- throw new Error("Cannot ref a disposed source.");
- (e._incrementRefCount(),
- (t = e._refFinalizationRegistry) == null || t.register(this, e, this),
- (this._source = e));
- }
- get source() {
- if (!this._source)
- throw new Error("Can't get source; ref has already been freed.");
- return this._source;
- }
- get freed() {
- return this._freed;
- }
- free() {
- var t;
- if (this._freed)
- throw new Error("Illegal operation: double free on SourceRef.");
- const e = this.source;
- (T(e._refCount > 0),
- e._decrementRefCount(),
- (t = e._refFinalizationRegistry) == null || t.unregister(this),
- (this._freed = !0),
- (this._source = null));
- }
- [Symbol.dispose]() {
- this.freed || this.free();
- }
-}
-class vn extends dr {
- constructor(e, t) {
- if (typeof e != "string") throw new TypeError("rootPath must be a string.");
- if (typeof t != "function")
- throw new TypeError("requestHandler must be a function.");
- (super(), (this.rootPath = e), (this.requestHandler = t));
- }
- _resolveRequest(e) {
- const t = this.requestHandler(e),
- n = (i) => {
- var a;
- if (!(i instanceof dr || i instanceof oo))
- throw new TypeError(
- "requestHandler must return or resolve to a Source or SourceRef.",
- );
- const s = i instanceof dr ? i.ref() : i;
- return (
- (a = s.source)._usedForHls || (a._usedForHls = this._usedForHls),
- s
- );
- };
- return O(t) ? t.then(n) : n(t);
- }
-}
-const yc = (r, e) => r.path === e.path;
-class Um extends vn {
- constructor() {
- (super(...arguments), (this._root = null), (this._rootRequest = null));
- }
- _read(e, t, n, i) {
- if (!this._root) {
- if (!this._rootRequest) {
- const s = this._resolveRequest({ path: this.rootPath, isRoot: !0 }),
- a = (o) => {
- const c = o instanceof dr ? o.ref() : o;
- return ((this._root = c), (this._rootRequest = null), c);
- };
- O(s) ? (this._rootRequest = s.then(a)) : (a(s), T(this._root));
- }
- if (this._rootRequest)
- return this._rootRequest.then((s) => s.source._read(e, t, n, i));
- }
- return this._root.source._read(e, t, n, i);
- }
- _getFileSize() {
- if (this._root) return this._root.source._getFileSize();
- }
- _dispose() {
- this._root
- ? this._root.free()
- : this._rootRequest && this._rootRequest.then((e) => e.free());
- }
-}
-typeof FinalizationRegistry < "u" &&
- new FinalizationRegistry((r) => {
- r.cancel().catch(() => {});
- });
-const Hm = 0.5 * 2 ** 20,
- Vm = (r, e, t) => {
- if (
- e instanceof Error &&
- (e.message.includes("Failed to fetch") ||
- e.message.includes("Load failed") ||
- e.message.includes("NetworkError when attempting to fetch resource")) &&
- typeof window < "u"
- ) {
- let i = null;
- try {
- typeof window < "u" &&
- typeof window.location < "u" &&
- (i = new URL(t instanceof Request ? t.url : t, window.location.href)
- .origin);
- } catch {}
- if (
- (typeof navigator < "u" && typeof navigator.onLine == "boolean"
- ? navigator.onLine
- : !0) &&
- i !== null &&
- i !== window.location.origin
- )
- return (
- te._warn(
- "Request will not be retried because a CORS error was suspected due to different origins. You can modify this behavior by providing your own function for the 'getRetryDelay' option.",
- ),
- null
- );
- }
- return Math.min(2 ** (r - 2), 16);
- },
- kc = new Set();
-class co extends vn {
- constructor(e, t = {}) {
- var a;
- if (
- typeof e != "string" &&
- !(e instanceof URL) &&
- !(typeof Request < "u" && e instanceof Request)
- )
- throw new TypeError("url must be a string, URL or Request.");
- if (!t || typeof t != "object")
- throw new TypeError("options must be an object.");
- if (
- t.requestInit !== void 0 &&
- (!t.requestInit || typeof t.requestInit != "object")
- )
- throw new TypeError(
- "options.requestInit, when provided, must be an object.",
- );
- if (t.getRetryDelay !== void 0 && typeof t.getRetryDelay != "function")
- throw new TypeError(
- "options.getRetryDelay, when provided, must be a function.",
- );
- if (
- t.maxCacheSize !== void 0 &&
- (!hi(t.maxCacheSize) || t.maxCacheSize < 0)
- )
- throw new TypeError(
- "options.maxCacheSize, when provided, must be a non-negative number.",
- );
- if (
- t.parallelism !== void 0 &&
- (!Number.isInteger(t.parallelism) || t.parallelism < 1)
- )
- throw new TypeError(
- "options.parallelism, when provided, must be a positive number.",
- );
- if (t.fetchFn !== void 0 && typeof t.fetchFn != "function")
- throw new TypeError(
- "options.fetchFn, when provided, must be a function.",
- );
- if (
- t.handleUnhandledError !== void 0 &&
- typeof t.handleUnhandledError != "function"
- )
- throw new TypeError(
- "options.handleUnhandledError, when provided, must be a function.",
- );
- const n = e instanceof Request ? e.url : e instanceof URL ? e.href : e;
- (super(n, (o) => new co(o.path, this._options)),
- (this._offset = 0),
- (this._length = null),
- (this._fileSizeDetermined = !1),
- (this._sequentialBacking = null),
- (this._abortControllers = new Map()),
- (this._sequentialAbortController = null),
- (this._url = e),
- (this._options = t),
- (this._getRetryDelay = t.getRetryDelay ?? Vm),
- (this._requestInit = { ...t.requestInit }));
- let i = null;
- if ((a = t.requestInit) != null && a.headers) {
- const o = { ...wa(t.requestInit.headers) },
- c = Object.keys(o).find((u) => u.toLowerCase() === "range");
- c !== void 0 &&
- ((i = o[c]), delete o[c], (this._requestInit.headers = o));
- }
- if (e instanceof Request) {
- const o = e.headers.get("Range");
- if (o !== null) {
- i ?? (i = o);
- const c = new Request(e);
- (c.headers.delete("Range"), (this._url = c));
- }
- }
- if (i !== null) {
- const o = qm(i);
- o && ((this._offset = o.offset), (this._length = o.length));
- }
- const s = 2;
- this._orchestrator = new $m({
- maxCacheSize: t.maxCacheSize ?? 64 * 2 ** 20,
- maxWorkerCount: t.parallelism ?? s,
- runWorker: this._runWorker.bind(this),
- onIdleWorkerRemoved: (o) => this._abortControllers.delete(o),
- prefetchProfile: jm.network,
- handleUnhandledError: t.handleUnhandledError,
- });
- }
- _getFileSize() {
- if (!this._fileSizeDetermined)
- return this._length !== null ? this._length : void 0;
- const e = this._sequentialBacking
- ? this._sequentialBacking._endIndex
- : this._orchestrator.fileSize;
- return e === null
- ? this._length !== null
- ? this._length
- : null
- : De(e - this._offset, 0, this._length ?? 1 / 0);
- }
- _read(e, t, n, i) {
- if (this._length !== null && t > this._length) return null;
- const s = this._offset,
- a = this._sequentialBacking
- ? this._sequentialBacking._read(s + e, s + t)
- : this._orchestrator.read(
- s + e,
- s + t,
- Math.max(s + n, s),
- s + Math.min(i, this._length ?? 1 / 0),
- ),
- o = (c) => (c ? ((c.offset -= this._offset), c) : null);
- return O(a) ? a.then(o) : o(a);
- }
- async _runWorker(e) {
- for (;;) {
- if (e.aborted) {
- this._orchestrator.signalWorkerStoppedRunning(e);
- return;
- }
- const t = new AbortController();
- this._abortControllers.set(e, t);
- const n = await Oo(
- this._options.fetchFn ?? fetch,
- this._url,
- No(this._requestInit, {
- headers: { Range: `bytes=${e.currentPos}-` },
- signal: t.signal,
- }),
- this._getRetryDelay,
- () => t.signal.aborted,
- );
- if (!n.ok)
- throw new Error(
- `Error fetching ${String(this._url)}: ${n.status} ${n.statusText}`,
- );
- n.redirected && (this.rootPath = n.url);
- e: if (
- this._orchestrator.fileSize === null &&
- !n.headers.has("Content-Encoding") &&
- (n.status === 206 || n.type === "basic")
- ) {
- const s = n.headers.get("Content-Range");
- if (s) {
- const o = /\/(\d+)/.exec(s);
- if (o) {
- this._orchestrator.supplyFileSize(Number(o[1]));
- break e;
- }
- }
- const a = n.headers.get("Content-Length");
- if (a) {
- const o = n.status === 206 ? e.currentPos : 0;
- this._orchestrator.supplyFileSize(o + Number(a));
- }
- }
- if (((this._fileSizeDetermined = !0), !n.body))
- throw new Error(
- "Missing HTTP response body stream. The used fetch function must provide the response body as a ReadableStream.",
- );
- if (n.status !== 206) {
- if (this._sequentialBacking) {
- n.body.cancel().catch(() => {});
- return;
- }
- if (!this._usedForHls) {
- const s = new URL(
- this._url instanceof Request ? this._url.url : this._url,
- typeof window < "u" ? window.location.href : void 0,
- );
- s.origin !== "null" &&
- !(s.pathname.endsWith(".m3u8") || s.pathname.endsWith(".m3u")) &&
- (kc.has(s.origin) ||
- (te._warn(
- `HTTP server (origin ${s.origin}) did not respond to a range request with 206 Partial Content, meaning the resource will now be streamed sequentially, with old data being evicted from the cache. Reads into evicted regions will throw. To enable efficient media file streaming across a network, please make sure your server supports range requests. Alternatively, set maxCacheSize to Infinity in the UrlSource options to keep the entire resource in memory.`,
- ),
- kc.add(s.origin)));
- }
- (this._abortControllers.delete(e),
- this._transitionToSequentialMode(n.body, t));
- return;
- }
- const i = n.body.getReader();
- for (;;) {
- if (e.currentPos >= e.targetPos || e.aborted) {
- (t.abort(), this._orchestrator.signalWorkerStoppedRunning(e));
- return;
- }
- let s;
- try {
- s = await i.read();
- } catch (c) {
- if (t.signal.aborted) throw c;
- const u = this._getRetryDelay(1, c, this._url);
- if (u !== null) {
- (te._error(
- "Error while reading response stream. Attempting to resume.",
- c,
- ),
- await si(1e3 * u));
- break;
- } else throw c;
- }
- if (e.aborted) continue;
- const { done: a, value: o } = s;
- if (a) {
- if (e.currentPos >= e.targetPos) {
- this._orchestrator.onWorkerFinished(e);
- return;
- }
- if (e.strictTarget) break;
- this._orchestrator.onWorkerFinished(e);
- return;
- }
- (this._dispatchRead(e.currentPos, e.currentPos + o.length),
- this._orchestrator.supplyWorkerData(e, o));
- }
- }
- }
- _transitionToSequentialMode(e, t) {
- this._sequentialAbortController = t;
- let n = e.getReader(),
- i = 0,
- s = 0;
- const a = new ReadableStream({
- pull: async (u) => {
- for (;;) {
- let l;
- try {
- l = await n.read();
- } catch (f) {
- if (this._disposed) throw f;
- const h = this._getRetryDelay(1, f, this._url);
- if (h === null) throw f;
- (te._error(
- "Error while reading response stream. Attempting to resume.",
- f,
- ),
- await si(1e3 * h),
- (this._sequentialAbortController = new AbortController()),
- this._disposed && this._sequentialAbortController.abort());
- const p = await Oo(
- this._options.fetchFn ?? fetch,
- this._url,
- No(this._requestInit, {
- headers: { Range: `bytes=${i}-` },
- signal: this._sequentialAbortController.signal,
- }),
- this._getRetryDelay,
- () => this._disposed,
- );
- if (!p.ok)
- throw new Error(
- `Error fetching ${String(this._url)}: ${p.status} ${p.statusText}`,
- );
- if (!p.body)
- throw new Error(
- "Missing HTTP response body stream. The used fetch function must provide the response body as a ReadableStream.",
- );
- ((n = p.body.getReader()), (s = p.status === 206 ? 0 : i));
- continue;
- }
- if (l.done) {
- u.close();
- return;
- }
- let d = l.value;
- if (s > 0) {
- const f = Math.min(s, d.length);
- ((s -= f), (d = d.subarray(f)));
- }
- if (d.length !== 0) {
- ((i += d.length), u.enqueue(d));
- return;
- }
- }
- },
- cancel: () => n.cancel().catch(() => {}),
- }),
- o = new vu(a, {
- maxCacheSize: this._orchestrator.options.maxCacheSize,
- handleUnhandledError: this._options.handleUnhandledError,
- });
- ((o._endIndex = this._orchestrator.fileSize),
- (o._cacheMissErrorMessage =
- "Attempted to read data from an already-evicted part of the cache. Because the HTTP server did not honor the range request, data can only be read sequentially, with old data being evicted from the cache. To fix this issue, either ensure your server responds to range requests with 206 Partial Content, or set maxCacheSize to Infinity in the UrlSource options. Note that the latter will store the entire file in the cache if needed, no matter how large."),
- o.on("read", ({ start: u, end: l }) => this._dispatchRead(u, l)),
- (this._sequentialBacking = o));
- const c = new Set();
- for (const u of this._orchestrator.workers) {
- for (const l of u.pendingSlices) c.add(l);
- ((u.aborted = !0), (u.pendingSlices.length = 0));
- }
- for (const u of this._orchestrator.queuedReads)
- for (const l of u.pendingSlices) c.add(l);
- ((this._orchestrator.workers.length = 0),
- (this._orchestrator.queuedReads.length = 0));
- for (const [, u] of this._abortControllers) u.abort();
- this._abortControllers.clear();
- for (const u of c) {
- const l = o._read(u.start, u.start + u.bytes.length);
- O(l)
- ? l.then(
- (d) => {
- d
- ? (T(d.offset === u.start), u.resolve(d.bytes))
- : u.resolve(null);
- },
- (d) => u.reject(d),
- )
- : (T(l === null), u.resolve(null));
- }
- }
- _dispose() {
- var e;
- this._orchestrator.dispose();
- for (const [, t] of this._abortControllers) t.abort();
- (this._abortControllers.clear(),
- (e = this._sequentialAbortController) == null || e.abort(),
- this._sequentialBacking &&
- ((this._sequentialBacking._disposed = !0),
- this._sequentialBacking._dispose()));
- }
-}
-const Lm = /^bytes=(\d+)-(\d*)$/,
- qm = (r) => {
- const e = Lm.exec(r.trim());
- if (!e) return null;
- const t = Number(e[1]),
- n = e[2] === "" ? null : Number(e[2]);
- return n !== null && n < t
- ? null
- : { offset: t, length: n !== null ? n - t + 1 : null };
- };
-class vu extends dr {
- constructor(e, t = {}) {
- if (!(e instanceof ReadableStream))
- throw new TypeError("stream must be a ReadableStream.");
- if (!t || typeof t != "object")
- throw new TypeError("options must be an object.");
- if (
- t.handleUnhandledError !== void 0 &&
- typeof t.handleUnhandledError != "function"
- )
- throw new TypeError(
- "options.handleUnhandledError, when provided, must be a function.",
- );
- if (
- t.maxCacheSize !== void 0 &&
- (!hi(t.maxCacheSize) || t.maxCacheSize < 0)
- )
- throw new TypeError(
- "options.maxCacheSize, when provided, must be a non-negative number.",
- );
- (super(),
- (this._reader = null),
- (this._cache = []),
- (this._pendingSlices = []),
- (this._currentIndex = 0),
- (this._targetIndex = 0),
- (this._maxRequestedIndex = 0),
- (this._endIndex = null),
- (this._pulling = !1),
- (this._cacheMissErrorMessage =
- "Attempted to read data from an already-evicted part of the cache. With ReadableStreamSource, you must access the data more sequentially or increase the size of its cache."),
- (this._stream = e),
- (this._maxCacheSize = t.maxCacheSize ?? 32 * 2 ** 20),
- (this._handleUnhandledError = t.handleUnhandledError));
- }
- _getFileSize() {
- return this._endIndex;
- }
- _read(e, t) {
- if (this._endIndex !== null && t > this._endIndex) return null;
- this._maxRequestedIndex = Math.max(this._maxRequestedIndex, t);
- const n = ke(this._cache, e, (l) => l.start),
- i = n !== -1 ? this._cache[n] : null;
- if (i && i.start <= e && t <= i.end)
- return { bytes: i.bytes, view: i.view, offset: i.start };
- let s = e;
- const a = new Uint8Array(t - e);
- if (n !== -1)
- for (let l = n; l < this._cache.length; l++) {
- const d = this._cache[l];
- if (d.start >= t) break;
- const f = Math.max(e, d.start);
- f > s && this._throwDueToCacheMiss();
- const h = Math.min(t, d.end);
- f < h &&
- (a.set(d.bytes.subarray(f - d.start, h - d.start), f - e), (s = h));
- }
- if (s === t) return { bytes: a, view: ge(a), offset: e };
- this._currentIndex > s && this._throwDueToCacheMiss();
- const { promise: o, resolve: c, reject: u } = Ke();
- return (
- this._pendingSlices.push({
- start: e,
- end: t,
- bytes: a,
- resolve: c,
- reject: u,
- }),
- (this._targetIndex = Math.max(this._targetIndex, t)),
- this._pulling ||
- ((this._pulling = !0),
- this._pull().catch((l) => {
- if (((this._pulling = !1), this._pendingSlices.length > 0))
- (this._pendingSlices.forEach((d) => d.reject(l)),
- (this._pendingSlices.length = 0));
- else if (this._handleUnhandledError) this._handleUnhandledError(l);
- else throw l;
- })),
- o
- );
- }
- _throwDueToCacheMiss() {
- throw new Error(this._cacheMissErrorMessage);
- }
- async _pull() {
- for (
- this._reader ?? (this._reader = this._stream.getReader());
- this._currentIndex < this._targetIndex && !this._disposed;
- ) {
- const { done: e, value: t } = await this._reader.read();
- if (e) {
- for (const s of this._pendingSlices) s.resolve(null);
- ((this._pendingSlices.length = 0),
- (this._endIndex = this._currentIndex));
- break;
- }
- const n = this._currentIndex,
- i = this._currentIndex + t.byteLength;
- this._dispatchRead(n, i);
- for (let s = 0; s < this._pendingSlices.length; s++) {
- const a = this._pendingSlices[s],
- o = Math.max(n, a.start),
- c = Math.min(i, a.end);
- o < c &&
- (a.bytes.set(t.subarray(o - n, c - n), o - a.start),
- c === a.end &&
- (a.resolve({ bytes: a.bytes, view: ge(a.bytes), offset: a.start }),
- this._pendingSlices.splice(s, 1),
- s--));
- }
- for (
- this._cache.push({ start: n, end: i, bytes: t, view: ge(t), age: 0 });
- this._cache.length > 0;
- ) {
- const s = this._cache[0];
- if (this._maxRequestedIndex - s.end <= this._maxCacheSize) break;
- this._cache.shift();
- }
- this._currentIndex += t.byteLength;
- }
- this._pulling = !1;
- }
- _dispose() {
- var e;
- for (const t of this._pendingSlices) t.reject(new rt());
- ((this._pendingSlices.length = 0),
- (this._cache.length = 0),
- (e = this._reader) == null || e.cancel().catch(() => {}));
- }
-}
-const jm = {
- network: (r, e, t) => {
- r = Math.max(0, Math.floor((r - 65536) / 65536) * 65536);
- for (const i of t) {
- const a = Math.max((i.startPos + i.targetPos) / 2, i.targetPos - 8388608);
- if (ka(r, e, a, i.targetPos)) {
- const o = i.targetPos - i.startPos,
- c = Math.ceil((o + 1) / 8388608) * 8388608,
- u = 2 ** Math.ceil(Math.log2(o + 1)),
- l = Math.min(u, c);
- e = Math.max(e, i.startPos + l);
- }
- }
- return ((e = Math.max(e, r + Hm)), { start: r, end: e });
- },
-};
-class $m {
- constructor(e) {
- ((this.options = e),
- (this.fileSize = null),
- (this.nextAge = 0),
- (this.workers = []),
- (this.cache = []),
- (this.currentCacheSize = 0),
- (this.disposed = !1),
- (this.queuedReads = []));
- }
- read(e, t, n, i) {
- T(!this.disposed);
- const s = this.options.prefetchProfile(e, t, this.workers),
- a = Math.max(s.start, n),
- o = Math.min(s.end, this.fileSize ?? 1 / 0, i);
- T(a <= e && t <= o);
- let c = null;
- const u = ke(this.cache, e, (v) => v.start),
- l = u !== -1 ? this.cache[u] : null;
- l &&
- l.start <= e &&
- t <= l.end &&
- ((l.age = this.nextAge++),
- (c = { bytes: l.bytes, view: l.view, offset: l.start }));
- const d = ke(this.cache, a, (v) => v.start),
- f = c ? null : new Uint8Array(t - e);
- let h = 0,
- p = a;
- const m = [];
- if (d !== -1) {
- for (let v = d; v < this.cache.length; v++) {
- const I = this.cache[v];
- if (I.start >= o) break;
- if (I.end <= a) continue;
- const w = Math.max(a, I.start),
- x = Math.min(o, I.end);
- if ((T(w <= x), p < w && m.push({ start: p, end: w }), (p = x), f)) {
- const k = Math.max(e, I.start),
- S = Math.min(t, I.end);
- if (k < S) {
- const E = k - e;
- (f.set(I.bytes.subarray(k - I.start, S - I.start), E),
- E === h && (h = S - e));
- }
- }
- I.age = this.nextAge++;
- }
- p < o && m.push({ start: p, end: o });
- } else m.push({ start: a, end: o });
- if (
- (f && h >= f.length && (c = { bytes: f, view: ge(f), offset: e }),
- m.length === 0)
- )
- return (T(c), c);
- const { promise: b, resolve: g, reject: y } = Ke(),
- C = [];
- for (const v of m) {
- const I = Math.max(e, v.start),
- w = Math.min(t, v.end);
- I === v.start && w === v.end
- ? C.push(v)
- : I < w && C.push({ start: I, end: w });
- }
- const _ = f && { start: e, bytes: f, holes: C, resolve: g, reject: y };
- e: for (const v of m) {
- for (const x of this.workers)
- if (this.checkHoleAgainstWorker(x, v, _ ? [_] : [])) {
- this.checkQueuedReadsAgainstWorker(x);
- continue e;
- }
- const I = v.end < o || this.fileSize !== null,
- w = this.createWorker(v.start, v.end, I);
- if (w) (_ && (w.pendingSlices = [_]), this.runWorker(w));
- else {
- let x = ke(this.queuedReads, v.start, (S) => S.hole.start),
- k = x !== -1 ? this.queuedReads[x] : null;
- for (
- k && v.start <= k.hole.end
- ? ((k.hole.end = Math.max(k.hole.end, v.end)),
- k.strictTarget && (k.strictTarget = I),
- _ && k.pendingSlices.push(_))
- : (x++,
- (k = {
- hole: { start: v.start, end: v.end },
- strictTarget: I,
- pendingSlices: _ ? [_] : [],
- age: this.nextAge++,
- }),
- this.queuedReads.splice(x, 0, k));
- x + 1 < this.queuedReads.length;
- ) {
- const S = this.queuedReads[x + 1];
- if (S.hole.start > k.hole.end) break;
- ((k.hole.end = Math.max(k.hole.end, S.hole.end)),
- k.pendingSlices.push(...S.pendingSlices),
- k.strictTarget && (k.strictTarget = S.strictTarget),
- (k.age = Math.min(k.age, S.age)),
- this.queuedReads.splice(x + 1, 1));
- }
- }
- }
- return (
- c
- ? b.catch((v) => {
- if (!this.disposed)
- if (this.options.handleUnhandledError)
- this.options.handleUnhandledError(v);
- else throw v;
- })
- : (T(f),
- (c = b.then((v) => v && { bytes: v, view: ge(v), offset: e }))),
- c
- );
- }
- checkHoleAgainstWorker(e, t, n) {
- if (ka(t.start - 131072, t.start, e.currentPos, e.targetPos)) {
- e.targetPos = Math.max(e.targetPos, t.end);
- for (let s = 0; s < n.length; s++) {
- const a = n[s];
- e.pendingSlices.includes(a) || e.pendingSlices.push(a);
- }
- return (e.running || this.runWorker(e), !0);
- }
- return !1;
- }
- checkQueuedReadsAgainstWorker(e) {
- let t = !1;
- for (let n = 0; n < this.queuedReads.length; n++) {
- const i = this.queuedReads[n];
- if (this.checkHoleAgainstWorker(e, i.hole, i.pendingSlices))
- (this.queuedReads.splice(n, 1), n--, (t = !0));
- else if (t) break;
- }
- }
- createWorker(e, t, n) {
- var s, a;
- if (this.workers.length >= this.options.maxWorkerCount) {
- let o = null,
- c = null;
- for (let u = 0; u < this.workers.length; u++) {
- const l = this.workers[u];
- !l.running &&
- l.pendingSlices.length === 0 &&
- (!o || l.age < o.age) &&
- ((c = u), (o = l));
- }
- if (o)
- (T(c !== null),
- T(o.pendingSlices.length === 0),
- this.workers.splice(c, 1),
- (a = (s = this.options).onIdleWorkerRemoved) == null || a.call(s, o));
- else return null;
- }
- const i = {
- startPos: e,
- currentPos: e,
- targetPos: t,
- strictTarget: n,
- running: !1,
- aborted: this.disposed,
- pendingSlices: [],
- age: this.nextAge++,
- };
- return (this.workers.push(i), i);
- }
- runWorker(e) {
- (T(!e.running),
- T(e.currentPos < e.targetPos),
- (e.running = !0),
- (e.age = this.nextAge++),
- this.options
- .runWorker(e)
- .catch((t) => {
- if (((e.running = !1), e.pendingSlices.length > 0))
- (e.pendingSlices.forEach((n) => n.reject(t)),
- (e.pendingSlices.length = 0));
- else if (!e.aborted && !this.disposed)
- if (this.options.handleUnhandledError)
- this.options.handleUnhandledError(t);
- else throw t;
- })
- .finally(() => {
- if (!e.running && this.queuedReads.length > 0) {
- let t = 0;
- for (let s = 1; s < this.queuedReads.length; s++)
- this.queuedReads[s].age < this.queuedReads[t].age && (t = s);
- const n = this.queuedReads[t],
- i = this.createWorker(n.hole.start, n.hole.end, n.strictTarget);
- if (!i) return;
- (this.queuedReads.splice(t, 1),
- (i.pendingSlices = n.pendingSlices),
- this.runWorker(i));
- }
- }));
- }
- supplyWorkerData(e, t) {
- var s, a;
- T(!e.aborted);
- const n = e.currentPos,
- i = n + t.length;
- (this.insertIntoCache({
- start: n,
- end: i,
- bytes: t,
- view: ge(t),
- age: this.nextAge++,
- }),
- (e.currentPos += t.length),
- e.currentPos > e.targetPos &&
- ((e.targetPos = e.currentPos), this.checkQueuedReadsAgainstWorker(e)));
- for (let o = 0; o < e.pendingSlices.length; o++) {
- const c = e.pendingSlices[o],
- u = Math.max(n, c.start),
- l = Math.min(i, c.start + c.bytes.length);
- u < l && c.bytes.set(t.subarray(u - n, l - n), u - c.start);
- for (let d = 0; d < c.holes.length; d++) {
- const f = c.holes[d];
- (n <= f.start && i > f.start && (f.start = i),
- f.end <= f.start && (c.holes.splice(d, 1), d--));
- }
- c.holes.length === 0 &&
- (c.resolve(c.bytes), e.pendingSlices.splice(o, 1), o--);
- }
- for (let o = 0; o < this.workers.length; o++) {
- const c = this.workers[o];
- e === c ||
- c.running ||
- (ka(n, i, c.currentPos, c.targetPos) &&
- (this.workers.splice(o, 1),
- (a = (s = this.options).onIdleWorkerRemoved) == null || a.call(s, c),
- o--));
- }
- }
- supplyFileSize(e) {
- (T(this.fileSize === null), (this.fileSize = e));
- for (const t of this.workers) {
- ((t.targetPos = Math.min(t.targetPos, e)), (t.strictTarget = !0));
- for (let n = 0; n < t.pendingSlices.length; n++) {
- const i = t.pendingSlices[n];
- for (const s of i.holes)
- if (s.end > e) {
- (i.resolve(null), t.pendingSlices.splice(n, 1), n--);
- break;
- }
- }
- }
- for (let t = 0; t < this.queuedReads.length; t++) {
- const n = this.queuedReads[t];
- if (n.hole.start >= e) {
- for (const i of n.pendingSlices) i.resolve(null);
- (this.queuedReads.splice(t, 1), t--);
- } else if (n.hole.end > e) {
- ((n.hole.end = e), (n.strictTarget = !0));
- for (let i = 0; i < n.pendingSlices.length; i++) {
- const s = n.pendingSlices[i];
- s.start >= e && (s.resolve(null), n.pendingSlices.splice(i, 1), i--);
- }
- }
- }
- }
- signalWorkerStoppedRunning(e) {
- ((e.running = !1), e.aborted || (e.pendingSlices.length = 0));
- }
- onWorkerFinished(e) {
- var n, i;
- const t = this.workers.indexOf(e);
- (T(t !== -1),
- (e.running = !1),
- this.workers.splice(t, 1),
- (i = (n = this.options).onIdleWorkerRemoved) == null || i.call(n, e),
- this.fileSize === null && this.supplyFileSize(e.currentPos));
- for (const s of e.pendingSlices) s.resolve(null);
- }
- insertIntoCache(e) {
- if (this.options.maxCacheSize === 0) return;
- let t = ke(this.cache, e.start, (n) => n.start) + 1;
- if (t > 0) {
- const n = this.cache[t - 1];
- if (n.end >= e.end) return;
- if (n.end > e.start) {
- const i = new Uint8Array(e.end - n.start);
- (i.set(n.bytes, 0),
- i.set(e.bytes, e.start - n.start),
- (this.currentCacheSize += e.end - n.end),
- (n.bytes = i),
- (n.view = ge(i)),
- (n.end = e.end),
- t--,
- (e = n));
- } else
- (this.cache.splice(t, 0, e), (this.currentCacheSize += e.bytes.length));
- } else
- (this.cache.splice(t, 0, e), (this.currentCacheSize += e.bytes.length));
- for (let n = t + 1; n < this.cache.length; n++) {
- const i = this.cache[n];
- if (e.end <= i.start) break;
- if (e.end >= i.end) {
- (this.cache.splice(n, 1),
- (this.currentCacheSize -= i.bytes.length),
- n--);
- continue;
- }
- const s = new Uint8Array(i.end - e.start);
- (s.set(e.bytes, 0),
- s.set(i.bytes, i.start - e.start),
- (this.currentCacheSize -= e.end - i.start),
- (e.bytes = s),
- (e.view = ge(s)),
- (e.end = i.end),
- this.cache.splice(n, 1));
- break;
- }
- for (; this.currentCacheSize > this.options.maxCacheSize;) {
- let n = 0,
- i = this.cache[0];
- for (let s = 1; s < this.cache.length; s++) {
- const a = this.cache[s];
- a.age < i.age && ((n = s), (i = a));
- }
- if (this.currentCacheSize - i.bytes.length <= this.options.maxCacheSize)
- break;
- (this.cache.splice(n, 1), (this.currentCacheSize -= i.bytes.length));
- }
- }
- dispose() {
- var e, t;
- for (const n of this.workers) {
- for (const i of n.pendingSlices) i.reject(new rt());
- ((n.pendingSlices.length = 0),
- (n.aborted = !0),
- n.running ||
- (t = (e = this.options).onIdleWorkerRemoved) == null ||
- t.call(e, n));
- }
- for (const n of this.queuedReads)
- for (const i of n.pendingSlices) i.reject(new rt());
- ((this.workers.length = 0),
- (this.cache.length = 0),
- (this.queuedReads.length = 0),
- (this.disposed = !0));
- }
-}
-class Gm extends dr {
- constructor(e, t, n) {
- if ((super(), (this._ref = null), e._disposed))
- throw new Error("Cannot create a slice of a disposed source.");
- ((this._baseSource = e), (this._offset = t), (this._length = n ?? null));
- }
- _getFileSize() {
- const e = this._baseSource._getFileSize();
- return e === void 0
- ? this._length !== null
- ? this._length
- : void 0
- : e === null
- ? this._length !== null
- ? this._length
- : null
- : De(e - this._offset, 0, this._length ?? 1 / 0);
- }
- _read(e, t, n, i) {
- if (this._length !== null && t > this._length) return null;
- const s = this._baseSource._read(
- this._offset + e,
- this._offset + t,
- this._offset + n,
- this._offset + i,
- ),
- a = (o) => (o ? ((o.offset -= this._offset), o) : null);
- return O(s) ? s.then(a) : a(s);
- }
- _dispose() {
- var e;
- (e = this._ref) == null || e.free();
- }
- ref() {
- return (this._ref ?? (this._ref = this._baseSource.ref()), super.ref());
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ var Tc = function (r, e, t) {
- if (e != null) {
- if (typeof e != "object" && typeof e != "function")
- throw new TypeError("Object expected.");
- var n, i;
- if (t) {
- if (!Symbol.asyncDispose)
- throw new TypeError("Symbol.asyncDispose is not defined.");
- n = e[Symbol.asyncDispose];
- }
- if (n === void 0) {
- if (!Symbol.dispose)
- throw new TypeError("Symbol.dispose is not defined.");
- ((n = e[Symbol.dispose]), t && (i = n));
- }
- if (typeof n != "function") throw new TypeError("Object not disposable.");
- (i &&
- (n = function () {
- try {
- i.call(this);
- } catch (s) {
- return Promise.reject(s);
- }
- }),
- r.stack.push({ value: e, dispose: n, async: t }));
- } else t && r.stack.push({ async: !0 });
- return e;
- },
- xc = (function (r) {
- return function (e) {
- function t(a) {
- ((e.error = e.hasError
- ? new r(a, e.error, "An error was suppressed during disposal.")
- : a),
- (e.hasError = !0));
- }
- var n,
- i = 0;
- function s() {
- for (; (n = e.stack.pop());)
- try {
- if (!n.async && i === 1)
- return ((i = 0), e.stack.push(n), Promise.resolve().then(s));
- if (n.dispose) {
- var a = n.dispose.call(n.value);
- if (n.async)
- return (
- (i |= 2),
- Promise.resolve(a).then(s, function (o) {
- return (t(o), s());
- })
- );
- } else i |= 1;
- } catch (o) {
- t(o);
- }
- if (i === 1)
- return e.hasError ? Promise.reject(e.error) : Promise.resolve();
- if (e.hasError) throw e.error;
- }
- return s();
- };
- })(
- typeof SuppressedError == "function"
- ? SuppressedError
- : function (r, e, t) {
- var n = new Error(t);
- return (
- (n.name = "SuppressedError"),
- (n.error = r),
- (n.suppressed = e),
- n
- );
- },
- );
-const Km = /^0[xX][0-9a-fA-F]+$/,
- Xm = /^data:.*;base64,/i;
-class Sc extends zm {
- constructor(e, t, n, i) {
- (super(e.input, t, n),
- (this.segments = []),
- (this.nextLines = null),
- (this.currentUpdateSegmentsPromise = null),
- (this.streamHasEnded = !1),
- (this.lastSegmentUpdateTime = -1 / 0),
- (this.refreshInterval = 5),
- (this.rootPath = t),
- (this.demuxer = e),
- (this.nextLines = i));
- }
- runUpdateSegments() {
- return (
- this.currentUpdateSegmentsPromise ??
- (this.currentUpdateSegmentsPromise = (async () => {
- try {
- const e = this.getRemainingWaitTimeMs();
- (e > 0 && (await si(e)),
- (this.lastSegmentUpdateTime = performance.now()),
- await this.updateSegments());
- } finally {
- this.currentUpdateSegmentsPromise = null;
- }
- })())
- );
- }
- getRemainingWaitTimeMs() {
- const e = performance.now() - this.lastSegmentUpdateTime,
- t = Math.max(0, 1e3 * this.refreshInterval - e);
- return t <= 50 ? 0 : t;
- }
- async updateSegments() {
- var _;
- let e = this.nextLines;
- if (((this.nextLines = null), !e)) {
- const v = { stack: [], error: void 0, hasError: !1 };
- try {
- const I = Tc(
- v,
- await this.demuxer.input._getSourceUncached({
- path: this.rootPath,
- isRoot: !1,
- }),
- !1,
- ),
- x = await new Oi(I.source).requestEntireFile();
- (T(x),
- (e = qu(x, x.length, { ignore: Tu })),
- I.source instanceof vn && (this.rootPath = I.source.rootPath));
- } catch (I) {
- ((v.error = I), (v.hasError = !0));
- } finally {
- xc(v);
- }
- }
- const t =
- ((_ = this.input._formatOptions.hls) == null
- ? void 0
- : _.offsetTimestampsByDateTime) !== !1,
- n = new xu(
- this.rootPath,
- this.demuxer.hasMasterPlaylist
- ? this.demuxer.masterPlaylistVariables
- : null,
- );
- let i = !1,
- s = 0,
- a = null,
- o = null,
- c = null,
- u = 0,
- l = null,
- d = null,
- f = null,
- h = null,
- p = null,
- m = null,
- b = !1,
- g = Ae(this.segments) ?? null;
- const y = (v) => {
- const I = v.indexOf("@"),
- w = Number(I === -1 ? v : v.slice(0, I));
- if (!Number.isInteger(w) || w < 0)
- throw new Error(`Invalid #EXT-X-BYTERANGE length '${v}'.`);
- let x = null;
- if (
- I !== -1 &&
- ((x = Number(v.slice(I + 1))), !Number.isInteger(x) || x < 0)
- )
- throw new Error(`Invalid #EXT-X-BYTERANGE offset '${v}'.`);
- return { length: w, offset: x };
- },
- C = (v) => {
- ((u = v),
- g &&
- (T(g.sequenceNumber !== null),
- g.sequenceNumber < v &&
- ((s = g.timestamp + g.duration),
- (l = g.firstSegment),
- (d = g.initSegment),
- (p = g.lastProgramDateTimeSeconds),
- (a =
- g.unixEpochTimestamp !== null
- ? g.unixEpochTimestamp + g.duration
- : null),
- (g = null))));
- };
- for (let v = 0; v < e.length; v++) {
- const I = e[v];
- if (!i) {
- if (I !== "#EXTM3U")
- throw new Error(
- "Invalid M3U8 file; expected first line to be #EXTM3U.",
- );
- i = !0;
- continue;
- }
- if (!I.startsWith("#")) {
- if (!g) {
- if (o === null)
- throw new Error(
- "Invalid M3U8 file; a segment must be preceded by an #EXTINF tag.",
- );
- let w = c;
- if (w && w.method === "AES-128" && !w.iv) {
- const E = new Uint8Array(Ht),
- B = ge(E);
- (B.setUint32(8, Math.floor(u / 2 ** 32)),
- B.setUint32(12, u),
- (w = { ...w, iv: E }));
- }
- const k = {
- path: Er(this.rootPath, n.substitute(I)),
- offset: (h == null ? void 0 : h.offset) ?? 0,
- length: (h == null ? void 0 : h.length) ?? null,
- },
- S = {
- timestamp: s,
- unixEpochTimestamp: a,
- firstSegment: l,
- sequenceNumber: u,
- location: k,
- duration: o,
- encryption: w,
- initSegment: d,
- lastProgramDateTimeSeconds: p,
- };
- (l ?? (l = S),
- (s += o),
- a !== null && (a += o),
- this.segments.push(S));
- }
- ((o = null), h === null ? (f = null) : (h = null), C(u + 1));
- }
- if (I.startsWith(Aa)) {
- if (g) {
- b = !0;
- continue;
- }
- b || (p === null && u > 0 && m !== null && (s = u * m), (b = !0));
- const w = I.slice(Aa.length),
- x = w.indexOf(","),
- k = x === -1 ? w : w.slice(0, x),
- S = Number(k);
- if (!Number.isFinite(S) || S < 0)
- throw new Error(`Invalid #EXTINF tag duration '${k}'.`);
- o = S;
- } else if (I.startsWith(Yi)) n.define(I.slice(Yi.length));
- else if (I.startsWith(uc)) {
- const w = new pn(I.slice(uc.length), n),
- x = w.get("uri");
- if (!x)
- throw new Error("Invalid #EXT-X-MAP tag; missing URI attribute.");
- const k = w.get("byterange");
- let S = null;
- if ((k !== null && (S = y(k)), S && S.offset === null))
- throw new Error(
- "Invalid #EXT-X-MAP tag; BYTERANGE attribute must have a specified offset.",
- );
- if (!g) {
- const B = {
- path: Er(this.rootPath, x),
- offset: (S == null ? void 0 : S.offset) ?? 0,
- length: (S == null ? void 0 : S.length) ?? null,
- };
- if ((c == null ? void 0 : c.method) === "AES-128" && !c.iv)
- throw new Error(
- "IV attribute must be set on #EXT-X-KEY tag preceding the #EXT-X-MAP tag.",
- );
- d = {
- timestamp: s,
- unixEpochTimestamp: a,
- firstSegment: null,
- sequenceNumber: null,
- location: B,
- duration: 0,
- encryption: c,
- initSegment: null,
- lastProgramDateTimeSeconds: p,
- };
- }
- ((o = null), h === null ? (f = null) : (h = null));
- } else if (I.startsWith(dc)) {
- const w = new pn(I.slice(dc.length), n),
- x = w.get("method");
- if (x === "NONE") c = null;
- else if (x === "AES-128") {
- const k = w.get("uri");
- if (!k)
- throw new Error(
- "Invalid #EXT-X-KEY: AES-128 requires a URI attribute.",
- );
- let S = null;
- const E = w.get("iv");
- if (E) {
- if (!Km.test(E)) throw new Error(`Unsupported IV format '${E}'.`);
- let R = E.slice(2);
- ((R = R.padStart(2 * Ht, "0")),
- (R = R.slice(-2 * Ht)),
- (S = new Uint8Array(Ht)));
- for (let M = 0; M < Ht; M++) {
- const z = 2 * M;
- S[M] = parseInt(R.slice(z, z + 2), 16);
- }
- }
- const B = w.get("keyformat") ?? "identity";
- if (B !== "identity")
- throw new Error(
- "For AES-128 encryption, only the 'identity' KEYFORMAT is currently supported. If you think other formats should be supported, please raise an issue.",
- );
- c = {
- method: "AES-128",
- keyUri: Er(this.rootPath, k),
- iv: S,
- keyFormat: B,
- };
- } else if (x === "SAMPLE-AES" || x === "SAMPLE-AES-CTR") {
- const k = w.get("uri");
- if (!k)
- throw new Error(
- `Invalid #EXT-X-KEY: ${x} requires a URI attribute.`,
- );
- if ((w.get("keyformat") ?? "identity") === "identity")
- throw new Error(
- "For SAMPLE-AES and SAMPLE-AES-CTR encryption, the 'identity' KEYFORMAT is not supported. If you think this format should be supported, please raise an issue.",
- );
- let E = null;
- if (Xm.test(k)) {
- const B = k.indexOf(","),
- R = Il(k.slice(B + 1));
- if (
- R.length >= 8 &&
- R[4] === 112 &&
- R[5] === 115 &&
- R[6] === 115 &&
- R[7] === 104
- ) {
- const M = ge(R).getUint32(0);
- E = iu(R.subarray(8, Math.min(M, R.length)));
- }
- }
- c = { method: x, psshBox: E };
- } else
- throw new Error(
- `Unsupported encryption method '${x}'. If you think this method should be supported, please raise an issue.`,
- );
- } else if (I.startsWith(fc)) {
- const w = I.slice(fc.length),
- x = Number(w);
- if (!Number.isInteger(x) || x < 0)
- throw new Error(`Invalid EXT-X-MEDIA-SEQUENCE value '${w}'.`);
- C(x);
- } else if (I.startsWith(hc)) {
- const w = y(I.slice(hc.length));
- if (w.offset === null) {
- if (f === null)
- throw new Error(
- "Invalid M3U8 file; #EXT-X-BYTERANGE without offset requires a previous byte range.",
- );
- w.offset = f;
- }
- ((h = w), (f = w.offset + w.length));
- } else if (I.startsWith(mc)) {
- if (g) continue;
- const w = I.slice(mc.length),
- x = Date.parse(w);
- if (!Number.isFinite(x)) continue;
- const k = x / 1e3;
- if (p === k) continue;
- if (p === null && this.segments.length > 0) {
- const S = Ae(this.segments),
- E = S.timestamp + S.duration,
- B = k - E;
- for (const R of this.segments)
- ((R.unixEpochTimestamp = R.timestamp + B),
- t && (R.timestamp = R.unixEpochTimestamp));
- }
- ((p = k), (a = k), t && (s = k));
- } else if (I === Rm) l = null;
- else if (I.startsWith(pc)) {
- const w = I.slice(pc.length),
- x = Number(w);
- if (!Number.isFinite(x) || x < 0)
- throw new Error(`Invalid EXT-X-TARGETDURATION value '${w}'.`);
- ((this.refreshInterval = x), (m = x));
- } else if (I === Mm) {
- this.streamHasEnded = !0;
- break;
- } else
- I.startsWith(gc) &&
- I.slice(gc.length).toLowerCase() === "vod" &&
- (this.streamHasEnded = !0);
- }
- if (!i) throw new Error("Invalid M3U8 file; no #EXTM3U header.");
- }
- async getFirstSegment() {
- return (
- this.segments.length === 0 && (await this.runUpdateSegments()),
- this.segments[0] ?? null
- );
- }
- async getSegmentAt(e, t) {
- this.segments.length === 0 && (await this.runUpdateSegments());
- let n = !!t.skipLiveWait && this.getRemainingWaitTimeMs() > 0;
- for (;;) {
- const i = ke(this.segments, e, (a) => a.timestamp);
- if (i === -1) return null;
- if (i < this.segments.length - 1 || this.streamHasEnded || n)
- return this.segments[i];
- const s = this.segments[i];
- if (e < s.timestamp + s.duration) return s;
- (await this.runUpdateSegments(), t.skipLiveWait && (n = !0));
- }
- }
- async getNextSegment(e, t) {
- const n = this.segments.indexOf(e);
- T(n !== -1);
- const i = n + 1;
- let s = !!t.skipLiveWait && this.getRemainingWaitTimeMs() > 0;
- for (;;) {
- if (i < this.segments.length) return this.segments[i];
- if (this.streamHasEnded || s) return null;
- (await this.runUpdateSegments(), t.skipLiveWait && (s = !0));
- }
- }
- async getPreviousSegment(e) {
- const t = this.segments.indexOf(e);
- return (T(t !== -1), this.segments[t - 1] ?? null);
- }
- getInputForSegment(e) {
- var c;
- const t = e,
- n = this.inputCache.find((u) => u.segment === t);
- if (n) return ((n.age = this.nextInputCacheAge++), n.input);
- let i = null;
- (t.initSegment || t.firstSegment) &&
- (i = this.getInputForSegment(t.initSegment ?? t.firstSegment));
- const s = {
- ...this.input._formatOptions,
- isobmff: {
- ...this.input._formatOptions.isobmff,
- resolveKeyId:
- ((c = this.input._formatOptions.isobmff) == null
- ? void 0
- : c.resolveKeyId) &&
- ((u) => {
- if (
- !t.encryption ||
- !(
- t.encryption.method === "SAMPLE-AES" ||
- t.encryption.method === "SAMPLE-AES-CTR"
- ) ||
- !t.encryption.psshBox
- )
- return this.input._formatOptions.isobmff.resolveKeyId(u);
- let l = u.psshBoxes;
- const { psshBox: d } = t.encryption;
- return (
- (d.keyIds === null || d.keyIds.includes(u.keyId)) &&
- !l.some((f) => su(f, d)) &&
- (l = [...l, d]),
- this.input._formatOptions.isobmff.resolveKeyId({
- ...u,
- psshBoxes: l,
- })
- );
- }),
- },
- },
- a = new ys({
- source: new Um(t.location.path, async (u) => {
- T(u.isRoot);
- const l = { ...u, isRoot: !1 };
- let d;
- const f = t.location.offset > 0 || t.location.length !== null;
- if (
- !t.encryption ||
- t.encryption.method === "SAMPLE-AES" ||
- t.encryption.method === "SAMPLE-AES-CTR"
- ) {
- if (((d = await this.input._getSourceCached(l)), f)) {
- const p = d.source
- .slice(t.location.offset, t.location.length ?? void 0)
- .ref();
- (d.free(), (d = p));
- }
- } else if (t.encryption.method === "AES-128") {
- const h = t.encryption;
- T(h.iv);
- let p = await this.input._getSourceCached(l);
- if (f) {
- const y = p.source
- .slice(t.location.offset, t.location.length ?? void 0)
- .ref();
- (p.free(), (p = y));
- }
- const m = new Oi(p.source),
- b = $h(
- m,
- async () => {
- const g = { stack: [], error: void 0, hasError: !1 };
- try {
- const y = Tc(
- g,
- await this.input._getSourceCached(
- { path: h.keyUri, isRoot: !1 },
- Yp,
- ),
- !1,
- ),
- _ = await new Oi(y.source).requestSlice(0, Ht);
- if (!_)
- throw new Error(
- "Invalid AES-128 key; expected at least 16 bytes of data.",
- );
- return { key: Z(_, Ht), iv: h.iv };
- } catch (y) {
- ((g.error = y), (g.hasError = !0));
- } finally {
- xc(g);
- }
- },
- () => {
- p.free();
- },
- );
- d = new vu(b).ref();
- } else T(!1);
- return d;
- }),
- formats: this.input._formats.filter((u) => !(u instanceof Fu)),
- initInput: i ?? void 0,
- formatOptions: s,
- });
- if (
- ((a._onFormatDetermined = (u) => {
- var l, d;
- if (
- (((l = t.encryption) == null ? void 0 : l.method) === "SAMPLE-AES" ||
- ((d = t.encryption) == null ? void 0 : d.method) ===
- "SAMPLE-AES-CTR") &&
- !u._isIsobmff
- )
- throw new Error(
- "The SAMPLE-AES and SAMPLE-AES-CTR encryption methods are currently only supported for ISOBMFF files.",
- );
- }),
- this.inputCache.push({
- segment: t,
- input: a,
- age: this.nextInputCacheAge++,
- }),
- this.inputCache.length > 4)
- ) {
- const u = Ka(this.inputCache, (l) => l.age);
- (T(u !== -1), this.inputCache.splice(u, 1));
- }
- return a;
- }
- async getLiveRefreshInterval() {
- return (
- this.getRemainingWaitTimeMs() === 0 && (await this.runUpdateSegments()),
- this.streamHasEnded ? null : this.refreshInterval
- );
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class Qm extends br {
- constructor(e) {
- (super(e),
- (this.metadataPromise = null),
- (this.trackBackings = null),
- (this.internalTracks = null),
- (this.segmentedInputs = []),
- (this.hasMasterPlaylist = !0),
- (this.masterPlaylistVariables = null));
- }
- readMetadata() {
- return (
- this.metadataPromise ??
- (this.metadataPromise = (async () => {
- T(this.input._rootSource instanceof vn);
- const e = await this.input._reader.requestEntireFile();
- T(e);
- const t = qu(e, e.length, { ignore: Tu }),
- { rootPath: n } = this.input._rootSource,
- i = new xu(n, null),
- s = [],
- a = [];
- for (let l = 1; l < t.length; l++) {
- const d = t[l];
- if (d.startsWith(Yi)) i.define(d.slice(Yi.length));
- else if (d.startsWith(oc)) {
- const f = l;
- let h = t[++l];
- if (h === void 0)
- throw new Error(
- "Incorrect M3U8 file; a line must follow the #EXT-X-STREAM-INF tag.",
- );
- h = i.substitute(h);
- const p = Er(n, h),
- m = new pn(d.slice(oc.length), i);
- if (m.getAsNumber("bandwidth") === null)
- throw new Error(
- "Invalid M3U8 file; #EXT-X-STREAM-INF tag requires a BANDWIDTH attribute with a valid numerical value.",
- );
- s.push({
- fullPath: p,
- attributes: m,
- lineNumber: f,
- hasOnlyKeyPackets: !1,
- });
- } else if (d.startsWith(cc)) {
- const f = new pn(d.slice(cc.length), i),
- h = f.get("uri");
- if (h === null)
- throw new Error(
- "Invalid M3U8 file; #EXT-X-I-FRAME-STREAM-INF tag requires a URI attribute.",
- );
- if (f.getAsNumber("bandwidth") === null)
- throw new Error(
- "Invalid M3U8 file; #EXT-X-I-FRAME-STREAM-INF tag requires a BANDWIDTH attribute with a valid numerical value.",
- );
- const m = Er(n, h);
- s.push({
- fullPath: m,
- attributes: f,
- lineNumber: l,
- hasOnlyKeyPackets: !0,
- });
- } else if (d.startsWith(lc)) {
- const f = new pn(d.slice(lc.length), i);
- if (f.get("type") === null)
- throw new Error(
- "Invalid M3U8 file; #EXT-X-MEDIA tag requires a TYPE attribute.",
- );
- if (f.get("group-id") === null)
- throw new Error(
- "Invalid M3U8 file; #EXT-X-MEDIA tag requires a GROUP-ID attribute.",
- );
- let m = null;
- const b = f.get("uri");
- (b !== null && (m = Er(n, b)),
- a.push({ fullPath: m, attributes: f, lineNumber: l }));
- } else if (d !== Nm) {
- if (d.startsWith(Aa)) {
- const f = new Sc(this, n, null, t);
- ((this.segmentedInputs = [f]),
- (this.hasMasterPlaylist = !1),
- (this.trackBackings = await f.getTrackBackings()));
- return;
- }
- }
- }
- this.masterPlaylistVariables = i;
- const o = await Promise.all(
- s.map(async (l, d) => {
- const f = [],
- h = l.attributes.get("codecs");
- let p;
- if (h) p = h.split(",").map((x) => x.trim());
- else {
- const k = await this.getSegmentedInputForPath(
- l.fullPath,
- ).getTrackBackings(),
- S = await Promise.all(
- k.map(async (E) => ({
- track: E,
- codec: await E.getCodec(),
- })),
- );
- p = await Promise.all(
- S.filter((E) => E.codec !== null).map((E) =>
- E.track.getDecoderConfig().then((B) => B.codec),
- ),
- );
- }
- const m = l.attributes.get("video"),
- b = l.attributes.get("audio"),
- g = p.some((x) => Rt.includes(ur(x))),
- y = p.some((x) => fr.includes(ur(x)));
- if (m !== null && !g) {
- const x = a.find((k) => {
- const S = k.attributes.get("group-id"),
- E = k.attributes.get("type");
- return S === m && E.toLowerCase() === "video";
- });
- e: if (x) {
- const k = x.attributes.get("uri");
- if (k === null) break e;
- const S = Er(n, k),
- R = (
- await this.getSegmentedInputForPath(S).getTrackBackings()
- ).find((z) => z.getType() === "video");
- if (!R || (await R.getCodec()) === null) break e;
- const M = await R.getDecoderConfig().then(
- (z) => (z == null ? void 0 : z.codec) ?? null,
- );
- (T(M !== null), p.push(M));
- }
- }
- if (b !== null && !y) {
- const x = a.find((k) => {
- const S = k.attributes.get("group-id"),
- E = k.attributes.get("type");
- return S === b && E.toLowerCase() === "audio";
- });
- e: if (x) {
- const k = x.attributes.get("uri");
- if (k === null) break e;
- const S = Er(n, k),
- R = (
- await this.getSegmentedInputForPath(S).getTrackBackings()
- ).find((z) => z.getType() === "audio");
- if (!R || (await R.getCodec()) === null) break e;
- const M = await R.getDecoderConfig().then(
- (z) => (z == null ? void 0 : z.codec) ?? null,
- );
- (T(M !== null), p.push(M));
- }
- }
- p = [...new Set(p)];
- let C = null,
- _ = null;
- const v = l.attributes.getAsNumber("bandwidth");
- T(v !== null);
- const I = l.attributes.getAsNumber("average-bandwidth"),
- w = l.attributes.get("name");
- for (const x of p) {
- const k = ur(x);
- if (k !== null) {
- if (Rt.includes(k)) {
- if (C !== null)
- throw new Error(
- "Unsupported M3U8 file; multiple video codecs found in the CODECS attribute of a variant stream.",
- );
- C = x;
- const S = l.attributes.get("video");
- if (S === null) {
- const E = l.attributes.get("resolution");
- let B = null,
- R = null;
- if (E) {
- const M = E.match(/^(\d+)x(\d+)$/);
- M && ((B = Number(M[1])), (R = Number(M[2])));
- }
- f.push({
- id: -1,
- demuxer: this,
- backingTrack: null,
- default: !0,
- autoselect: !0,
- languageCode: nt,
- lineNumber: l.lineNumber,
- fullPath: l.fullPath,
- fullCodecString: C,
- pairingMask: 1n << BigInt(d),
- peakBitrate: v,
- averageBitrate: I,
- name: w,
- hasOnlyKeyPackets: l.hasOnlyKeyPackets,
- info: { type: "video", width: B, height: R },
- });
- } else
- for (const E of a) {
- const B = E.attributes.get("group-id"),
- R = E.attributes.get("type");
- if (B !== S || R.toLowerCase() !== "video") continue;
- const M =
- E.attributes.get("resolution") ??
- l.attributes.get("resolution");
- let z = null,
- q = null;
- if (M) {
- const j = M.match(/^(\d+)x(\d+)$/);
- j && ((z = Number(j[1])), (q = Number(j[2])));
- }
- f.push({
- id: -1,
- demuxer: this,
- backingTrack: null,
- default: Ci(E.attributes),
- autoselect: Ci(E.attributes) || Pc(E.attributes),
- languageCode: Cc(E.attributes.get("language")),
- lineNumber: E.lineNumber,
- fullPath: E.fullPath ?? l.fullPath,
- fullCodecString: C,
- pairingMask: 1n << BigInt(d),
- peakBitrate: E.fullPath === null ? v : null,
- averageBitrate: E.fullPath === null ? I : null,
- name: E.attributes.get("name"),
- hasOnlyKeyPackets: l.hasOnlyKeyPackets,
- info: { type: "video", width: z, height: q },
- });
- }
- } else if (fr.includes(k)) {
- if (_ !== null)
- throw new Error(
- "Unsupported M3U8 file; multiple audio codecs found in the CODECS attribute of a variant stream.",
- );
- _ = x;
- const S = l.attributes.get("audio");
- if (S === null) {
- const E = l.attributes.get("channels"),
- B = E !== null ? Number(E.split("/")[0]) : null;
- f.push({
- id: -1,
- demuxer: this,
- backingTrack: null,
- default: !0,
- autoselect: !0,
- languageCode: nt,
- lineNumber: l.lineNumber,
- fullPath: l.fullPath,
- fullCodecString: _,
- pairingMask: 1n << BigInt(d),
- peakBitrate: v,
- averageBitrate: I,
- name: w,
- hasOnlyKeyPackets: l.hasOnlyKeyPackets,
- info: {
- type: "audio",
- numberOfChannels:
- B !== null && Number.isInteger(B) && B > 0
- ? B
- : null,
- },
- });
- } else
- for (const E of a) {
- const B = E.attributes.get("group-id"),
- R = E.attributes.get("type");
- if (B !== S || R.toLowerCase() !== "audio") continue;
- const M =
- E.attributes.get("channels") ??
- l.attributes.get("channels"),
- z = M !== null ? Number(M.split("/")[0]) : null;
- f.push({
- id: -1,
- demuxer: this,
- backingTrack: null,
- default: Ci(E.attributes),
- autoselect: Ci(E.attributes) || Pc(E.attributes),
- languageCode: Cc(E.attributes.get("language")),
- lineNumber: E.lineNumber,
- fullPath: E.fullPath ?? l.fullPath,
- fullCodecString: _,
- pairingMask: 1n << BigInt(d),
- peakBitrate: E.fullPath === null ? v : null,
- averageBitrate: E.fullPath === null ? I : null,
- name: E.attributes.get("name"),
- hasOnlyKeyPackets: l.hasOnlyKeyPackets,
- info: {
- type: "audio",
- numberOfChannels:
- z !== null && Number.isInteger(z) && z > 0
- ? z
- : null,
- },
- });
- }
- }
- }
- }
- return f;
- }),
- ),
- c = [],
- u = (l) => {
- const d = c.find(
- (f) => f.fullPath === l.fullPath && f.info.type === l.info.type,
- );
- d
- ? ((d.pairingMask |= l.pairingMask),
- d.default || (d.default = l.default),
- d.autoselect || (d.autoselect = l.autoselect),
- (d.lineNumber = Math.min(d.lineNumber, l.lineNumber)),
- l.peakBitrate !== null &&
- (d.peakBitrate = Math.max(
- d.peakBitrate ?? -1 / 0,
- l.peakBitrate,
- )),
- l.averageBitrate !== null &&
- (d.averageBitrate = Math.max(
- d.averageBitrate ?? -1 / 0,
- l.averageBitrate,
- )),
- d.languageCode === nt && (d.languageCode = l.languageCode))
- : ((l.id = c.length + 1), c.push(l));
- };
- for (const l of o) for (const d of l) u(d);
- (c.sort((l, d) => l.lineNumber - d.lineNumber),
- (this.trackBackings = []));
- for (const l of c)
- l.info.type === "video"
- ? this.trackBackings.push(new Iu(l))
- : this.trackBackings.push(new _u(l));
- this.internalTracks = c;
- })())
- );
- }
- async getTrackBackings() {
- return (
- await this.readMetadata(),
- T(this.trackBackings),
- this.trackBackings
- );
- }
- getSegmentedInputForPath(e) {
- let t = this.segmentedInputs.find((i) => i.path === e);
- if (t) return t;
- let n = null;
- return (
- this.internalTracks &&
- (n = this.internalTracks
- .filter((s) => s.fullPath === e)
- .map((s) => ({ id: s.id, type: s.info.type }))),
- (t = new Sc(this, e, n, null)),
- this.segmentedInputs.push(t),
- t
- );
- }
- async getMetadataTags() {
- return {};
- }
- async getMimeType() {
- return ku;
- }
- dispose() {
- if (this.segmentedInputs) {
- for (const e of this.segmentedInputs) e.dispose();
- this.segmentedInputs.length = 0;
- }
- }
-}
-class Eu {
- constructor(e) {
- ((this.internalTrack = e), (this.hydrationPromise = null));
- }
- hydrate() {
- return (
- this.hydrationPromise ??
- (this.hydrationPromise = (async () => {
- const e = this.internalTrack.demuxer.getSegmentedInputForPath(
- this.internalTrack.fullPath,
- );
- let t = null;
- const i = (await e.getTrackBackings()).filter(
- (s) => s.getType() === this.getType(),
- );
- if (i.length === 1) t = i[0];
- else if (this instanceof Iu) {
- for (const s of i)
- if ((await s.getCodec()) === this.getCodec()) {
- t = s;
- break;
- }
- } else {
- T(this instanceof _u);
- for (const s of i)
- if ((await s.getCodec()) === this.getCodec()) {
- t = s;
- break;
- }
- }
- if (!t)
- throw new Error(
- "Could not find matching track in underlying media data.",
- );
- this.internalTrack.backingTrack = t;
- })())
- );
- }
- delegate(e) {
- return this.internalTrack.backingTrack ? e() : this.hydrate().then(e);
- }
- getCodec() {
- throw new Error("Not implemented on base class.");
- }
- getDisposition() {
- return {
- ...gr,
- default: this.internalTrack.autoselect,
- primary: this.internalTrack.default,
- };
- }
- getId() {
- return this.internalTrack.id;
- }
- getPairingMask() {
- return this.internalTrack.pairingMask;
- }
- getInternalCodecId() {
- return null;
- }
- getLanguageCode() {
- return this.internalTrack.languageCode;
- }
- getName() {
- return this.internalTrack.name;
- }
- getNumber() {
- T(this.internalTrack.demuxer.internalTracks);
- const e = this.internalTrack.info.type;
- let t = 0;
- for (const n of this.internalTrack.demuxer.internalTracks)
- if ((n.info.type === e && t++, n === this.internalTrack)) break;
- return t;
- }
- getTimeResolution() {
- return this.delegate(() =>
- this.internalTrack.backingTrack.getTimeResolution(),
- );
- }
- isRelativeToUnixEpoch() {
- return this.delegate(() =>
- this.internalTrack.backingTrack.isRelativeToUnixEpoch(),
- );
- }
- getUnixTimeForTimestamp(e) {
- return this.delegate(() =>
- this.internalTrack.backingTrack.getUnixTimeForTimestamp(e),
- );
- }
- getBitrate() {
- return this.internalTrack.peakBitrate;
- }
- getAverageBitrate() {
- return this.internalTrack.averageBitrate;
- }
- async getDurationFromMetadata(e) {
- return (
- await this.hydrate(),
- this.internalTrack.backingTrack.getDurationFromMetadata(e)
- );
- }
- async getLiveRefreshInterval() {
- return (
- await this.hydrate(),
- this.internalTrack.backingTrack.getLiveRefreshInterval()
- );
- }
- getHasOnlyKeyPackets() {
- return this.internalTrack.hasOnlyKeyPackets || null;
- }
- async getFirstPacket(e) {
- return (
- await this.hydrate(),
- this.internalTrack.backingTrack.getFirstPacket(e)
- );
- }
- async getPacket(e, t) {
- return (
- await this.hydrate(),
- this.internalTrack.backingTrack.getPacket(e, t)
- );
- }
- async getKeyPacket(e, t) {
- return (
- await this.hydrate(),
- this.internalTrack.backingTrack.getKeyPacket(e, t)
- );
- }
- async getNextPacket(e, t) {
- return (
- await this.hydrate(),
- this.internalTrack.backingTrack.getNextPacket(e, t)
- );
- }
- async getNextKeyPacket(e, t) {
- return (
- await this.hydrate(),
- this.internalTrack.backingTrack.getNextKeyPacket(e, t)
- );
- }
-}
-class Iu extends Eu {
- constructor(e) {
- super(e);
- }
- get backingVideoTrack() {
- return this.internalTrack.backingTrack;
- }
- getType() {
- return "video";
- }
- getCodec() {
- return ur(this.internalTrack.fullCodecString);
- }
- getCodedWidth() {
- return this.delegate(() => this.backingVideoTrack.getCodedWidth());
- }
- getCodedHeight() {
- return this.delegate(() => this.backingVideoTrack.getCodedHeight());
- }
- getSquarePixelWidth() {
- return this.delegate(() => this.backingVideoTrack.getSquarePixelWidth());
- }
- getSquarePixelHeight() {
- return this.delegate(() => this.backingVideoTrack.getSquarePixelHeight());
- }
- getMetadataDisplayWidth() {
- return this.backingVideoTrack ? null : this.internalTrack.info.width;
- }
- getMetadataDisplayHeight() {
- return this.backingVideoTrack ? null : this.internalTrack.info.height;
- }
- getTransformationMatrix() {
- return this.delegate(() =>
- this.backingVideoTrack.getTransformationMatrix(),
- );
- }
- async getColorSpace() {
- return (await this.hydrate(), this.backingVideoTrack.getColorSpace());
- }
- async canBeTransparent() {
- return (await this.hydrate(), this.backingVideoTrack.canBeTransparent());
- }
- getMetadataCodecParameterString() {
- return this.backingVideoTrack ? null : this.internalTrack.fullCodecString;
- }
- async getDecoderConfig() {
- return (await this.hydrate(), this.backingVideoTrack.getDecoderConfig());
- }
-}
-class _u extends Eu {
- constructor(e) {
- super(e);
- }
- get backingAudioTrack() {
- return this.internalTrack.backingTrack;
- }
- getType() {
- return "audio";
- }
- getCodec() {
- return ur(this.internalTrack.fullCodecString);
- }
- getNumberOfChannels() {
- return this.internalTrack.info.numberOfChannels !== null
- ? this.internalTrack.info.numberOfChannels
- : this.delegate(() => this.backingAudioTrack.getNumberOfChannels());
- }
- getSampleRate() {
- return this.delegate(() => this.backingAudioTrack.getSampleRate());
- }
- getMetadataCodecParameterString() {
- return this.backingAudioTrack ? null : this.internalTrack.fullCodecString;
- }
- async getDecoderConfig() {
- return (await this.hydrate(), this.backingAudioTrack.getDecoderConfig());
- }
-}
-const Ci = (r) => {
- const e = r.get("default");
- if (e === null) return !1;
- const t = e.toUpperCase();
- if (t === "YES") return !0;
- if (t === "NO") return !1;
- throw new Error(
- `Invalid M3U8 file; #EXT-X-MEDIA DEFAULT attribute must be YES or NO, got "${e}".`,
- );
- },
- Pc = (r) => {
- const e = r.get("autoselect");
- if (e === null) return !1;
- const t = e.toUpperCase();
- if (t === "YES") return !0;
- if (t === "NO") return !1;
- throw new Error(
- `Invalid M3U8 file; #EXT-X-MEDIA AUTOSELECT attribute must be YES or NO, got "${e}".`,
- );
- },
- Cc = (r) => {
- if (r === null) return nt;
- const e = r.split("-")[0];
- return e || nt;
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class Kt {
- constructor() {
- this._isIsobmff = !1;
- }
-}
-class Au extends Kt {
- constructor() {
- (super(...arguments), (this._isIsobmff = !0));
- }
- async _getMajorBrand(e) {
- let t = e._reader.requestSlice(0, 12);
- if ((O(t) && (t = await t), !t)) return null;
- t.skip(4);
- const n = Ne(t, 4);
- return n !== "ftyp" && n !== "styp" ? null : Ne(t, 4);
- }
- _createDemuxer(e) {
- return new so(e);
- }
-}
-class Ym extends Au {
- async _canReadInput(e) {
- const t = await this._getMajorBrand(e);
- if (t !== null) return t !== "qt ";
- let n = 0;
- for (let i = 0; i < 10; i++) {
- let s = e._reader.requestSlice(n, 8);
- if ((O(s) && (s = await s), !s)) return !1;
- let a = L(s),
- o = 8;
- if (a === 1) {
- let u = e._reader.requestSlice(n + 8, 8);
- if ((O(u) && (u = await u), !u)) return !1;
- ((a = ft(u)), (o = 16));
- }
- if (a < o) return !1;
- const c = Ne(s, 4);
- if (c === "moof" || c === "sidx") return !0;
- if (c === "emsg" || c === "prft" || c === "free") n += a;
- else return !1;
- }
- return !1;
- }
- get name() {
- return "MP4";
- }
- get mimeType() {
- return "video/mp4";
- }
-}
-class Zm extends Au {
- async _canReadInput(e) {
- return (await this._getMajorBrand(e)) === "qt ";
- }
- get name() {
- return "QuickTime File Format";
- }
- get mimeType() {
- return "video/quicktime";
- }
-}
-class Bu extends Kt {
- async isSupportedEBMLOfDocType(e, t) {
- let n = e._reader.requestSlice(0, Lt);
- if ((O(n) && (n = await n), !n)) return !1;
- const i = fu(n);
- if (i === null || i < 1 || i > 8 || he(n, i) !== N.EBML) return !1;
- const a = hu(n);
- if (typeof a != "number") return !1;
- let o = e._reader.requestSlice(n.filePos, a);
- if ((O(o) && (o = await o), !o)) return !1;
- const c = n.filePos;
- for (; o.filePos <= c + a - gt;) {
- const u = Vt(o);
- if (!u) break;
- const { id: l, size: d } = u,
- f = o.filePos;
- if (d === void 0) return !1;
- switch (l) {
- case N.EBMLVersion:
- if (he(o, d) !== 1) return !1;
- break;
- case N.EBMLReadVersion:
- if (he(o, d) !== 1) return !1;
- break;
- case N.DocType:
- if (an(o, d) !== t) return !1;
- break;
- case N.DocTypeVersion:
- if (he(o, d) > 4) return !1;
- break;
- }
- o.filePos = f + d;
- }
- return !0;
- }
- _canReadInput(e) {
- return this.isSupportedEBMLOfDocType(e, "matroska");
- }
- _createDemuxer(e) {
- return new tm(e);
- }
- get name() {
- return "Matroska";
- }
- get mimeType() {
- return "video/x-matroska";
- }
-}
-class Jm extends Bu {
- _canReadInput(e) {
- return this.isSupportedEBMLOfDocType(e, "webm");
- }
- get name() {
- return "WebM";
- }
- get mimeType() {
- return "video/webm";
- }
-}
-class ep extends Kt {
- async _canReadInput(e) {
- let t = 0;
- for (;;) {
- let d = e._reader.requestSlice(t, Et);
- if ((O(d) && (d = await d), !d)) break;
- const f = hr(d);
- if (!f) break;
- t = d.filePos + f.size;
- }
- const n = await Ia(e._reader, t, t + 4096);
- if (!n) return !1;
- const i = n.header,
- s = ru(i.mpegVersionId, i.channel);
- let a = e._reader.requestSlice(n.startPos + s, 4);
- if ((O(a) && (a = await a), !a)) return !1;
- const o = L(a);
- if (o === eu || o === tu) return !0;
- t = n.startPos + n.header.totalSize;
- const u = await Ia(e._reader, t, t + jr);
- if (!u) return !1;
- const l = u.header;
- return !(i.channel !== l.channel || i.sampleRate !== l.sampleRate);
- }
- _createDemuxer(e) {
- return new im(e);
- }
- get name() {
- return "MP3";
- }
- get mimeType() {
- return "audio/mpeg";
- }
-}
-class tp extends Kt {
- async _canReadInput(e) {
- let t = e._reader.requestSlice(0, 12);
- if ((O(t) && (t = await t), !t)) return !1;
- const n = Ne(t, 4);
- return n !== "RIFF" && n !== "RIFX" && n !== "RF64"
- ? !1
- : (t.skip(4), Ne(t, 4) === "WAVE");
- }
- _createDemuxer(e) {
- return new hm(e);
- }
- get name() {
- return "WAVE";
- }
- get mimeType() {
- return "audio/wav";
- }
-}
-class rp extends Kt {
- async _canReadInput(e) {
- let t = e._reader.requestSlice(0, 4);
- return (O(t) && (t = await t), t ? Ne(t, 4) === "OggS" : !1);
- }
- _createDemuxer(e) {
- return new dm(e);
- }
- get name() {
- return "Ogg";
- }
- get mimeType() {
- return "application/ogg";
- }
-}
-class np extends Kt {
- async _canReadInput(e) {
- let t = 0;
- for (;;) {
- let i = e._reader.requestSlice(t, Et);
- if ((O(i) && (i = await i), !i)) break;
- const s = hr(i);
- if (!s) break;
- t = i.filePos + s.size;
- }
- let n = e._reader.requestSlice(t, 4);
- return (O(n) && (n = await n), n ? Ne(n, 4) === "fLaC" : !1);
- }
- get name() {
- return "FLAC";
- }
- get mimeType() {
- return "audio/flac";
- }
- _createDemuxer(e) {
- return new Sm(e);
- }
-}
-class ip extends Kt {
- async _canReadInput(e) {
- let t = 0;
- for (;;) {
- let a = e._reader.requestSlice(t, Et);
- if ((O(a) && (a = await a), !a)) break;
- const o = hr(a);
- if (!o) break;
- t = a.filePos + o.size;
- }
- let n = e._reader.requestSliceRange(t, Xi, $r);
- if ((O(n) && (n = await n), !n)) return !1;
- const i = Xr(n);
- if (
- !i ||
- ((t += i.frameLength),
- (n = e._reader.requestSliceRange(t, Xi, $r)),
- O(n) && (n = await n),
- !n)
- )
- return !1;
- const s = Xr(n);
- return s
- ? i.objectType === s.objectType &&
- i.samplingFrequencyIndex === s.samplingFrequencyIndex &&
- i.channelConfiguration === s.channelConfiguration
- : !1;
- }
- _createDemuxer(e) {
- return new pm(e);
- }
- get name() {
- return "ADTS";
- }
- get mimeType() {
- return "audio/aac";
- }
-}
-class sp extends Kt {
- async _canReadInput(e) {
- const t = ht + 16 + 1;
- let n = e._reader.requestSlice(0, t);
- if ((O(n) && (n = await n), !n)) return !1;
- const i = Z(n, t);
- return (i[0] === 71 && i[ht] === 71) || (i[0] === 71 && i[ht + 16] === 71)
- ? !0
- : i[4] === 71 && i[4 + ht + 4] === 71;
- }
- _createDemuxer(e) {
- return new Am(e);
- }
- get name() {
- return "MPEG Transport Stream";
- }
- get mimeType() {
- return "video/MP2T";
- }
-}
-class Fu extends Kt {
- async _canReadInput(e) {
- let t = e._reader.requestSlice(0, 7);
- if ((O(t) && (t = await t), !t || !(Ne(t, 7) === "#EXTM3U"))) return !1;
- if (!(e._rootSource instanceof vn))
- throw new TypeError(
- "HLS inputs require `InputOptions.source` to be a PathedSource or a ref to one.",
- );
- return ((e._rootSource._usedForHls = !0), !0);
- }
- _createDemuxer(e) {
- return new Qm(e);
- }
- get name() {
- return "HTTP Live Streaming (HLS)";
- }
- get mimeType() {
- return ku;
- }
-}
-const ap = new Ym(),
- op = new Zm(),
- cp = new Bu(),
- lp = new Jm(),
- up = new ep(),
- dp = new tp(),
- fp = new rp(),
- hp = new ip(),
- mp = new np(),
- pp = new sp(),
- gp = new Fu(),
- bp = [gp, ap, op, cp, lp, dp, fp, mp, up, hp, pp],
- wp = (r, e) => {
- if (!r || typeof r != "object")
- throw new TypeError(`${e}, when provided, must be an object.`);
- if (r.isobmff !== void 0) {
- if (!r.isobmff || typeof r.isobmff != "object")
- throw new TypeError(`${e}.isobmff, when provided, must be an object.`);
- if (
- r.isobmff.resolveKeyId !== void 0 &&
- typeof r.isobmff.resolveKeyId != "function"
- )
- throw new TypeError(
- `${e}.isobmff.resolveKeyId, when provided, must be a function.`,
- );
- }
- if (r.hls !== void 0) {
- if (!r.hls || typeof r.hls != "object")
- throw new TypeError(`${e}.hls, when provided, must be an object.`);
- if (
- r.hls.offsetTimestampsByDateTime !== void 0 &&
- typeof r.hls.offsetTimestampsByDateTime != "boolean"
- )
- throw new TypeError(
- `${e}.hls.offsetTimestampsByDateTime, when provided, must be a boolean.`,
- );
- }
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ var yp = function (r, e, t) {
- if (e != null) {
- if (typeof e != "object" && typeof e != "function")
- throw new TypeError("Object expected.");
- var n, i;
- if (t) {
- if (!Symbol.asyncDispose)
- throw new TypeError("Symbol.asyncDispose is not defined.");
- n = e[Symbol.asyncDispose];
- }
- if (n === void 0) {
- if (!Symbol.dispose)
- throw new TypeError("Symbol.dispose is not defined.");
- ((n = e[Symbol.dispose]), t && (i = n));
- }
- if (typeof n != "function") throw new TypeError("Object not disposable.");
- (i &&
- (n = function () {
- try {
- i.call(this);
- } catch (s) {
- return Promise.reject(s);
- }
- }),
- r.stack.push({ value: e, dispose: n, async: t }));
- } else t && r.stack.push({ async: !0 });
- return e;
- },
- kp = (function (r) {
- return function (e) {
- function t(a) {
- ((e.error = e.hasError
- ? new r(a, e.error, "An error was suppressed during disposal.")
- : a),
- (e.hasError = !0));
- }
- var n,
- i = 0;
- function s() {
- for (; (n = e.stack.pop());)
- try {
- if (!n.async && i === 1)
- return ((i = 0), e.stack.push(n), Promise.resolve().then(s));
- if (n.dispose) {
- var a = n.dispose.call(n.value);
- if (n.async)
- return (
- (i |= 2),
- Promise.resolve(a).then(s, function (o) {
- return (t(o), s());
- })
- );
- } else i |= 1;
- } catch (o) {
- t(o);
- }
- if (i === 1)
- return e.hasError ? Promise.reject(e.error) : Promise.resolve();
- if (e.hasError) throw e.error;
- }
- return s();
- };
- })(
- typeof SuppressedError == "function"
- ? SuppressedError
- : function (r, e, t) {
- var n = new Error(t);
- return (
- (n.name = "SuppressedError"),
- (n.error = r),
- (n.suppressed = e),
- n
- );
- },
- );
-Ga();
-let vc = -1 / 0,
- Ec = -1 / 0,
- bt = null;
-typeof FinalizationRegistry < "u" &&
- (bt = new FinalizationRegistry((r) => {
- const e = performance.now();
- r.type === "video"
- ? (e - vc >= 1e3 &&
- (te._error(
- "A VideoSample was garbage collected without first being closed. For proper resource management, make sure to call close() on all your VideoSamples as soon as you're done using them.",
- ),
- (vc = e)),
- typeof VideoFrame < "u" &&
- r.data instanceof VideoFrame &&
- r.data.close())
- : (e - Ec >= 1e3 &&
- (te._error(
- "An AudioSample was garbage collected without first being closed. For proper resource management, make sure to call close() on all your AudioSamples as soon as you're done using them.",
- ),
- (Ec = e)),
- typeof AudioData < "u" &&
- r.data instanceof AudioData &&
- r.data.close());
- }));
-class Mr {
- constructor() {
- ((this._referenceCount = 0), (this._lastAllocationBuffer = null));
- }
-}
-const Ba = [
- "I420",
- "I420P10",
- "I420P12",
- "I420A",
- "I420AP10",
- "I420AP12",
- "I422",
- "I422P10",
- "I422P12",
- "I422A",
- "I422AP10",
- "I422AP12",
- "I444",
- "I444P10",
- "I444P12",
- "I444A",
- "I444AP10",
- "I444AP12",
- "NV12",
- "RGBA",
- "RGBX",
- "BGRA",
- "BGRX",
- ],
- Tp = new Set(Ba);
-class tt {
- get codedWidth() {
- return this.visibleRect.width;
- }
- get codedHeight() {
- return this.visibleRect.height;
- }
- get displayWidth() {
- return this.rotation % 180 === 0
- ? this.squarePixelWidth
- : this.squarePixelHeight;
- }
- get displayHeight() {
- return this.rotation % 180 === 0
- ? this.squarePixelHeight
- : this.squarePixelWidth;
- }
- get microsecondTimestamp() {
- return Math.trunc(_r * this.timestamp);
- }
- get microsecondDuration() {
- return Math.trunc(_r * this.duration);
- }
- get hasAlpha() {
- return this.format && this.format.includes("A");
- }
- constructor(e, t) {
- var n, i, s, a, o, c, u, l;
- if (
- ((this._closed = !1),
- e instanceof ArrayBuffer ||
- (typeof SharedArrayBuffer < "u" && e instanceof SharedArrayBuffer) ||
- ArrayBuffer.isView(e))
- ) {
- if (!t || typeof t != "object")
- throw new TypeError("init must be an object.");
- if (t.format === void 0 || !Tp.has(t.format))
- throw new TypeError("init.format must be one of: " + Ba.join(", "));
- if (!Number.isInteger(t.codedWidth) || t.codedWidth <= 0)
- throw new TypeError("init.codedWidth must be a positive integer.");
- if (!Number.isInteger(t.codedHeight) || t.codedHeight <= 0)
- throw new TypeError("init.codedHeight must be a positive integer.");
- if (t.rotation !== void 0 && ![0, 90, 180, 270].includes(t.rotation))
- throw new TypeError(
- "init.rotation, when provided, must be 0, 90, 180, or 270.",
- );
- if (t.flip !== void 0 && typeof t.flip != "boolean")
- throw new TypeError("init.flip, when provided, must be a boolean.");
- if (!Number.isFinite(t.timestamp))
- throw new TypeError("init.timestamp must be a number.");
- if (
- t.duration !== void 0 &&
- (!Number.isFinite(t.duration) || t.duration < 0)
- )
- throw new TypeError(
- "init.duration, when provided, must be a non-negative number.",
- );
- if (t.layout !== void 0) {
- if (!Array.isArray(t.layout))
- throw new TypeError("init.layout, when provided, must be an array.");
- for (const h of t.layout) {
- if (!h || typeof h != "object" || Array.isArray(h))
- throw new TypeError("Each entry in init.layout must be an object.");
- if (!Number.isInteger(h.offset) || h.offset < 0)
- throw new TypeError("plane.offset must be a non-negative integer.");
- if (!Number.isInteger(h.stride) || h.stride < 0)
- throw new TypeError("plane.stride must be a non-negative integer.");
- }
- }
- if (
- (t.visibleRect !== void 0 && As(t.visibleRect, "init.visibleRect"),
- t.displayWidth !== void 0 &&
- (!Number.isInteger(t.displayWidth) || t.displayWidth <= 0))
- )
- throw new TypeError(
- "init.displayWidth, when provided, must be a positive integer.",
- );
- if (
- t.displayHeight !== void 0 &&
- (!Number.isInteger(t.displayHeight) || t.displayHeight <= 0)
- )
- throw new TypeError(
- "init.displayHeight, when provided, must be a positive integer.",
- );
- if ((t.displayWidth !== void 0) != (t.displayHeight !== void 0))
- throw new TypeError(
- "init.displayWidth and init.displayHeight must be either both provided or both omitted.",
- );
- ((this.format = t.format),
- (this.rotation = t.rotation ?? 0),
- (this.flip = t.flip ?? !1),
- (this.timestamp = t.timestamp),
- (this.duration = t.duration ?? 0));
- const d = t.layout ?? Pp(t.format, t.codedWidth, t.codedHeight);
- let f = t.colorSpace ?? null;
- (f === null &&
- (this.format === "RGBA" ||
- this.format === "RGBX" ||
- this.format === "BGRA" ||
- this.format === "BGRX"
- ? (f = {
- primaries: "bt709",
- transfer: "iec61966-2-1",
- matrix: "rgb",
- fullRange: !0,
- })
- : (f = {
- primaries: "bt709",
- transfer: "bt709",
- matrix: "bt709",
- fullRange: !1,
- })),
- (this.visibleRect = {
- left: ((n = t.visibleRect) == null ? void 0 : n.left) ?? 0,
- top: ((i = t.visibleRect) == null ? void 0 : i.top) ?? 0,
- width:
- ((s = t.visibleRect) == null ? void 0 : s.width) ?? t.codedWidth,
- height:
- ((a = t.visibleRect) == null ? void 0 : a.height) ?? t.codedHeight,
- }),
- t.displayWidth !== void 0
- ? ((this.squarePixelWidth =
- this.rotation % 180 === 0 ? t.displayWidth : t.displayHeight),
- (this.squarePixelHeight =
- this.rotation % 180 === 0 ? t.displayHeight : t.displayWidth))
- : ((this.squarePixelWidth = this.visibleRect.width),
- (this.squarePixelHeight = this.visibleRect.height)),
- (this._data = t._doNotCopy ? Ze(e) : Ze(e).slice()),
- (this._layout = d),
- (this.colorSpace = new Hs(f)));
- } else if (typeof VideoFrame < "u" && e instanceof VideoFrame) {
- if (
- (t == null ? void 0 : t.rotation) !== void 0 &&
- ![0, 90, 180, 270].includes(t.rotation)
- )
- throw new TypeError(
- "init.rotation, when provided, must be 0, 90, 180, or 270.",
- );
- if (
- (t == null ? void 0 : t.flip) !== void 0 &&
- typeof t.flip != "boolean"
- )
- throw new TypeError("init.flip, when provided, must be a boolean.");
- if (
- (t == null ? void 0 : t.timestamp) !== void 0 &&
- !Number.isFinite(t == null ? void 0 : t.timestamp)
- )
- throw new TypeError("init.timestamp, when provided, must be a number.");
- if (
- (t == null ? void 0 : t.duration) !== void 0 &&
- (!Number.isFinite(t.duration) || t.duration < 0)
- )
- throw new TypeError(
- "init.duration, when provided, must be a non-negative number.",
- );
- ((t == null ? void 0 : t.visibleRect) !== void 0 &&
- As(t.visibleRect, "init.visibleRect"),
- (this._data = e),
- (this._layout = null),
- (this.format = e.format),
- (this.visibleRect = {
- left: ((o = e.visibleRect) == null ? void 0 : o.x) ?? 0,
- top: ((c = e.visibleRect) == null ? void 0 : c.y) ?? 0,
- width:
- ((u = e.visibleRect) == null ? void 0 : u.width) ?? e.codedWidth,
- height:
- ((l = e.visibleRect) == null ? void 0 : l.height) ?? e.codedHeight,
- }),
- (this.rotation = (t == null ? void 0 : t.rotation) ?? 0),
- (this.flip = (t == null ? void 0 : t.flip) ?? !1),
- (this.squarePixelWidth = e.displayWidth),
- (this.squarePixelHeight = e.displayHeight),
- (this.timestamp =
- (t == null ? void 0 : t.timestamp) ?? e.timestamp / 1e6),
- (this.duration =
- (t == null ? void 0 : t.duration) ?? (e.duration ?? 0) / 1e6),
- (this.colorSpace = new Hs(e.colorSpace)));
- } else if (
- (typeof HTMLImageElement < "u" && e instanceof HTMLImageElement) ||
- (typeof SVGImageElement < "u" && e instanceof SVGImageElement) ||
- (typeof ImageBitmap < "u" && e instanceof ImageBitmap) ||
- (typeof HTMLVideoElement < "u" && e instanceof HTMLVideoElement) ||
- (typeof HTMLCanvasElement < "u" && e instanceof HTMLCanvasElement) ||
- (typeof OffscreenCanvas < "u" && e instanceof OffscreenCanvas)
- ) {
- if (!t || typeof t != "object")
- throw new TypeError("init must be an object.");
- if (t.rotation !== void 0 && ![0, 90, 180, 270].includes(t.rotation))
- throw new TypeError(
- "init.rotation, when provided, must be 0, 90, 180, or 270.",
- );
- if (t.flip !== void 0 && typeof t.flip != "boolean")
- throw new TypeError("init.flip, when provided, must be a boolean.");
- if (!Number.isFinite(t.timestamp))
- throw new TypeError("init.timestamp must be a number.");
- if (
- t.duration !== void 0 &&
- (!Number.isFinite(t.duration) || t.duration < 0)
- )
- throw new TypeError(
- "init.duration, when provided, must be a non-negative number.",
- );
- if (
- (t.visibleRect !== void 0 && As(t.visibleRect, "init.visibleRect"),
- typeof VideoFrame < "u")
- )
- return new tt(
- new VideoFrame(e, {
- timestamp: Math.trunc(t.timestamp * _r),
- duration: Math.trunc((t.duration ?? 0) * _r) || void 0,
- visibleRect: t.visibleRect && {
- x: t.visibleRect.left,
- y: t.visibleRect.top,
- width: t.visibleRect.width,
- height: t.visibleRect.height,
- },
- }),
- t,
- );
- let d = 0,
- f = 0;
- if (
- ("naturalWidth" in e
- ? ((d = e.naturalWidth), (f = e.naturalHeight))
- : "videoWidth" in e
- ? ((d = e.videoWidth), (f = e.videoHeight))
- : "width" in e && ((d = Number(e.width)), (f = Number(e.height))),
- !d || !f)
- )
- throw new TypeError("Could not determine dimensions.");
- const h = t.visibleRect ?? { left: 0, top: 0, width: d, height: f },
- p = new OffscreenCanvas(h.width, h.height),
- m = p.getContext("2d", { alpha: Vi(), willReadFrequently: !0 });
- if (!m)
- throw new Error(
- "OffscreenCanvas must have support for the '2d' context in order to create a VideoSample from this data.",
- );
- (m.drawImage(e, -h.left, -h.top),
- (this._data = p),
- (this._layout = null),
- (this.format = "RGBX"),
- (this.visibleRect = {
- left: 0,
- top: 0,
- width: h.width,
- height: h.height,
- }),
- (this.squarePixelWidth = h.width),
- (this.squarePixelHeight = h.height),
- (this.rotation = t.rotation ?? 0),
- (this.flip = t.flip ?? !1),
- (this.timestamp = t.timestamp),
- (this.duration = t.duration ?? 0),
- (this.colorSpace = new Hs({
- matrix: "rgb",
- primaries: "bt709",
- transfer: "iec61966-2-1",
- fullRange: !0,
- })));
- } else if (e instanceof Mr) {
- if (!t || typeof t != "object")
- throw new TypeError("init must be an object.");
- if (t.rotation !== void 0 && ![0, 90, 180, 270].includes(t.rotation))
- throw new TypeError(
- "init.rotation, when provided, must be 0, 90, 180, or 270.",
- );
- if (t.flip !== void 0 && typeof t.flip != "boolean")
- throw new TypeError("init.flip, when provided, must be a boolean.");
- if (!Number.isFinite(t.timestamp))
- throw new TypeError("init.timestamp must be a number.");
- if (
- t.duration !== void 0 &&
- (!Number.isFinite(t.duration) || t.duration < 0)
- )
- throw new TypeError(
- "init.duration, when provided, must be a non-negative number.",
- );
- if (
- ((this._data = e),
- e._referenceCount++,
- (this.format = e.getFormat()),
- this.format !== null && !Ba.includes(this.format))
- )
- throw new TypeError(
- "getFormat() must return a VideoSamplePixelFormat or null.",
- );
- if (
- ((this.visibleRect = {
- left: 0,
- top: 0,
- width: e.getCodedWidth(),
- height: e.getCodedHeight(),
- }),
- !Number.isInteger(this.visibleRect.width) ||
- this.visibleRect.width <= 0)
- )
- throw new TypeError("getCodedWidth() must return a positive integer.");
- if (
- !Number.isInteger(this.visibleRect.height) ||
- this.visibleRect.height <= 0
- )
- throw new TypeError("getCodedHeight() must return a positive integer.");
- if (
- ((this.squarePixelWidth = e.getSquarePixelWidth()),
- !Number.isInteger(this.squarePixelWidth) || this.squarePixelWidth <= 0)
- )
- throw new TypeError(
- "getSquarePixelWidth() must return a positive integer.",
- );
- if (
- ((this.squarePixelHeight = e.getSquarePixelHeight()),
- !Number.isInteger(this.squarePixelHeight) ||
- this.squarePixelHeight <= 0)
- )
- throw new TypeError(
- "getSquarePixelHeight() must return a positive integer.",
- );
- ((this.rotation = t.rotation ?? 0),
- (this.flip = t.flip ?? !1),
- (this.timestamp = t.timestamp),
- (this.duration = t.duration ?? 0),
- (this.colorSpace = e.getColorSpace()));
- } else
- throw new TypeError(
- "Invalid data type: Must be a BufferSource, CanvasImageSource, or VideoSampleResource.",
- );
- ((this.encodeOptions = (t == null ? void 0 : t.encodeOptions) ?? {}),
- (this.pixelAspectRatio = ii({
- num: this.squarePixelWidth * this.codedHeight,
- den: this.squarePixelHeight * this.codedWidth,
- })),
- bt == null ||
- bt.register(this, { type: "video", data: this._data }, this));
- }
- clone() {
- if (this._closed) throw new Error("VideoSample is closed.");
- return (
- T(this._data !== null),
- this._data instanceof Mr
- ? new tt(this._data, {
- timestamp: this.timestamp,
- duration: this.duration,
- rotation: this.rotation,
- flip: this.flip,
- encodeOptions: this.encodeOptions,
- })
- : Nn(this._data)
- ? new tt(this._data.clone(), {
- timestamp: this.timestamp,
- duration: this.duration,
- rotation: this.rotation,
- flip: this.flip,
- encodeOptions: this.encodeOptions,
- })
- : this._data instanceof Uint8Array
- ? (T(this._layout),
- new tt(this._data, {
- format: this.format,
- layout: this._layout,
- codedWidth: this.codedWidth,
- codedHeight: this.codedHeight,
- timestamp: this.timestamp,
- duration: this.duration,
- colorSpace: this.colorSpace,
- rotation: this.rotation,
- flip: this.flip,
- visibleRect: this.visibleRect,
- displayWidth: this.displayWidth,
- displayHeight: this.displayHeight,
- encodeOptions: this.encodeOptions,
- _doNotCopy: !0,
- }))
- : new tt(this._data, {
- format: this.format,
- codedWidth: this.codedWidth,
- codedHeight: this.codedHeight,
- timestamp: this.timestamp,
- duration: this.duration,
- colorSpace: this.colorSpace,
- rotation: this.rotation,
- flip: this.flip,
- visibleRect: this.visibleRect,
- displayWidth: this.displayWidth,
- displayHeight: this.displayHeight,
- encodeOptions: this.encodeOptions,
- })
- );
- }
- close() {
- this._closed ||
- (bt == null || bt.unregister(this),
- this._data instanceof Mr
- ? (this._data._referenceCount--,
- this._data._referenceCount === 0 && this._data.close())
- : Nn(this._data)
- ? this._data.close()
- : (this._data = null),
- (this._closed = !0));
- }
- allocationSize(e = {}) {
- if ((Ac(e), this._closed)) throw new Error("VideoSample is closed.");
- if ((e.format ?? this.format) == null)
- throw new Error("Cannot get allocation size when format is null.");
- return Nn(this._data)
- ? this._data.allocationSize(e)
- : Bc(this, e).allocationSize;
- }
- async copyTo(e, t = {}) {
- if (!os(e))
- throw new TypeError(
- "destination must be an ArrayBuffer or an ArrayBuffer view.",
- );
- if ((Ac(t), this._closed)) throw new Error("VideoSample is closed.");
- if ((t.format ?? this.format) == null)
- throw new Error("Cannot copy video sample data when format is null.");
- if ((T(this._data !== null), Nn(this._data)))
- return this._data.copyTo(e, t);
- if (
- t.format &&
- !["RGBA", "RGBX", "BGRA", "BGRX"].includes(this.format) &&
- ["RGBA", "RGBX", "BGRA", "BGRX"].includes(t.format)
- )
- if (this._data instanceof Mr) {
- const u = { stack: [], error: void 0, hasError: !1 };
- try {
- const l = yp(
- u,
- await this._data.toRgbSample(
- {
- timestamp: this.timestamp,
- duration: this.duration,
- rotation: this.rotation,
- flip: this.flip,
- },
- t.colorSpace ?? "srgb",
- ),
- !1,
- );
- if (!(l instanceof tt))
- throw new TypeError("toRgbSample() must return a VideoSample.");
- if (!["RGBA", "RGBX", "BGRA", "BGRX"].includes(l.format))
- throw new Error(
- `Sample returned by toRgbSample was expected to have an RGB format, got '${l.format}' instead.`,
- );
- return await l.copyTo(e, t);
- } catch (l) {
- ((u.error = l), (u.hasError = !0));
- } finally {
- kp(u);
- }
- } else {
- if (typeof VideoFrame > "u")
- throw new Error(
- "For this sample, converting from a non-RGB to an RGB format requires VideoFrame to be defined.",
- );
- const u = this.toVideoFrame(),
- l = await u.copyTo(e, t);
- return (u.close(), l);
- }
- const n = Bc(this, t);
- T(this.format);
- const i = Ze(e);
- if (i.byteLength < n.allocationSize)
- throw new TypeError(
- `Destination buffer too small. Required: ${n.allocationSize}, Available: ${i.byteLength}`,
- );
- const s = gs(this.format);
- let a;
- if (this._data instanceof Mr) {
- let u = this._data.getDataPlanes();
- if (
- (O(u) && (u = await u),
- !Array.isArray(u) ||
- u.some(
- (l) =>
- !(l.data instanceof Uint8Array) ||
- !Number.isInteger(l.stride) ||
- l.stride < 0,
- ))
- )
- throw new TypeError(
- 'getDataPlanes() must return an array of objects with a Uint8Array "data" property and a non-negative integer "stride" property.',
- );
- a = u;
- } else if (this._data instanceof Uint8Array)
- (T(this._layout),
- T(this._layout.length === s.length),
- (a = this._layout.map((u, l) => {
- const d = Math.ceil(this.codedHeight / s[l].heightDivisor);
- return {
- data: this._data.subarray(u.offset, u.offset + u.stride * d),
- stride: u.stride,
- };
- })));
- else {
- const l = this._data.getContext("2d");
- T(l);
- const d = l.getImageData(0, 0, this.codedWidth, this.codedHeight);
- a = [{ data: Ze(d.data), stride: 4 * this.codedWidth }];
- }
- const o = [],
- c = s.length;
- for (let u = 0; u < c; u++) {
- const l = n.computedLayouts[u],
- d = a[u].stride,
- f = a[u].data;
- let h = l.sourceTop * d;
- h += l.sourceLeftBytes;
- let p = l.destinationOffset;
- const m = l.sourceWidthBytes,
- b = { offset: p, stride: l.destinationStride };
- for (let g = 0; g < l.sourceHeight; g++) {
- if (h + m > f.byteLength) throw new Error("Source buffer OOB read.");
- if (p + m > i.byteLength)
- throw new Error("Destination buffer OOB write.");
- const y = f.subarray(h, h + m);
- (i.set(y, p), (h += d), (p += l.destinationStride));
- }
- o.push(b);
- }
- if (t.format !== void 0) {
- const u = this.format.startsWith("RGB") !== t.format.startsWith("RGB"),
- l = this.format.includes("X") && t.format.includes("A");
- if (u || l)
- for (let d = 0; d < n.allocationSize; d += 4) {
- if (u) {
- const f = i[d],
- h = i[d + 2];
- ((i[d] = h), (i[d + 2] = f));
- }
- l && (i[d + 3] = 255);
- }
- }
- return o;
- }
- toVideoFrame() {
- if (this._closed) throw new Error("VideoSample is closed.");
- if ((T(this._data !== null), this._data instanceof Mr)) {
- if (this.format === null)
- throw new Error(
- "Cannot convert a VideoSampleResource-backed VideoSample to VideoFrame if format is null.",
- );
- const e = this._data.getDataPlanes();
- if (O(e))
- throw new Error(
- "Cannot convert a VideoSampleResource-backed VideoSample to VideoFrame if getDataPlanes() returns a promise.",
- );
- const t = e.reduce((a, o) => a + o.data.byteLength, 0),
- n = new Uint8Array(t);
- let i = 0;
- const s = [];
- for (const a of e)
- (n.set(a.data, i), s.push(i), (i += a.data.byteLength));
- return new VideoFrame(n, {
- format: this.format,
- layout: e.map((a, o) => ({ offset: s[o], stride: a.stride })),
- codedWidth: this.codedWidth,
- codedHeight: this.codedHeight,
- timestamp: this.microsecondTimestamp,
- duration: this.microsecondDuration,
- colorSpace: this.colorSpace,
- visibleRect: this.visibleRect,
- displayWidth: this.squarePixelWidth,
- displayHeight: this.squarePixelHeight,
- });
- } else
- return Nn(this._data)
- ? new VideoFrame(this._data, {
- timestamp: this.microsecondTimestamp,
- duration: this.microsecondDuration || void 0,
- })
- : this._data instanceof Uint8Array
- ? (T(this._layout),
- new VideoFrame(this._data, {
- format: this.format,
- codedWidth: this.codedWidth,
- codedHeight: this.codedHeight,
- layout: this._layout,
- timestamp: this.microsecondTimestamp,
- duration: this.microsecondDuration || void 0,
- colorSpace: this.colorSpace,
- visibleRect: this.visibleRect,
- displayWidth: this.squarePixelWidth,
- displayHeight: this.squarePixelHeight,
- }))
- : new VideoFrame(this._data, {
- timestamp: this.microsecondTimestamp,
- duration: this.microsecondDuration || void 0,
- });
- }
- draw(e, t, n, i, s, a, o, c, u) {
- let l = 0,
- d = 0,
- f = this.displayWidth,
- h = this.displayHeight,
- p = 0,
- m = 0,
- b = this.displayWidth,
- g = this.displayHeight;
- if (
- (a !== void 0
- ? ((l = t),
- (d = n),
- (f = i),
- (h = s),
- (p = a),
- (m = o),
- c !== void 0 ? ((b = c), (g = u)) : ((b = f), (g = h)))
- : ((p = t), (m = n), i !== void 0 && ((b = i), (g = s))),
- !(
- (typeof CanvasRenderingContext2D < "u" &&
- e instanceof CanvasRenderingContext2D) ||
- (typeof OffscreenCanvasRenderingContext2D < "u" &&
- e instanceof OffscreenCanvasRenderingContext2D)
- ))
- )
- throw new TypeError(
- "context must be a CanvasRenderingContext2D or OffscreenCanvasRenderingContext2D.",
- );
- if (!Number.isFinite(l)) throw new TypeError("sx must be a number.");
- if (!Number.isFinite(d)) throw new TypeError("sy must be a number.");
- if (!Number.isFinite(f) || f < 0)
- throw new TypeError("sWidth must be a non-negative number.");
- if (!Number.isFinite(h) || h < 0)
- throw new TypeError("sHeight must be a non-negative number.");
- if (!Number.isFinite(p)) throw new TypeError("dx must be a number.");
- if (!Number.isFinite(m)) throw new TypeError("dy must be a number.");
- if (!Number.isFinite(b) || b < 0)
- throw new TypeError("dWidth must be a non-negative number.");
- if (!Number.isFinite(g) || g < 0)
- throw new TypeError("dHeight must be a non-negative number.");
- if (this._closed) throw new Error("VideoSample is closed.");
- ({
- sx: l,
- sy: d,
- sWidth: f,
- sHeight: h,
- } = this._unmapSourceRegion(l, d, f, h, this.rotation, this.flip));
- const y = this.toCanvasImageSource();
- e.save();
- const C = p + b / 2,
- _ = m + g / 2;
- (e.translate(C, _),
- this.flip && e.scale(-1, 1),
- e.rotate((this.rotation * Math.PI) / 180));
- const v = this.rotation % 180 === 0 ? 1 : b / g;
- (e.scale(1 / v, v),
- e.drawImage(y, l, d, f, h, -b / 2, -g / 2, b, g),
- e.restore());
- }
- drawWithFit(e, t) {
- var C, _, v, I;
- if (!(
- (typeof CanvasRenderingContext2D < "u" &&
- e instanceof CanvasRenderingContext2D) ||
- (typeof OffscreenCanvasRenderingContext2D < "u" &&
- e instanceof OffscreenCanvasRenderingContext2D)
- ))
- throw new TypeError(
- "context must be a CanvasRenderingContext2D or OffscreenCanvasRenderingContext2D.",
- );
- if (!t || typeof t != "object")
- throw new TypeError("options must be an object.");
- if (!["fill", "contain", "cover"].includes(t.fit))
- throw new TypeError("options.fit must be 'fill', 'contain', or 'cover'.");
- if (t.rotation !== void 0 && ![0, 90, 180, 270].includes(t.rotation))
- throw new TypeError(
- "options.rotation, when provided, must be 0, 90, 180, or 270.",
- );
- if (t.flip !== void 0 && typeof t.flip != "boolean")
- throw new TypeError("options.flip, when provided, must be a boolean.");
- t.crop !== void 0 && Zi(t.crop, "options.");
- const n = e.canvas.width,
- i = e.canvas.height,
- s = t.rotation ?? this.rotation,
- a = t.flip ?? this.flip,
- [o, c] =
- s % 180 === 0
- ? [this.squarePixelWidth, this.squarePixelHeight]
- : [this.squarePixelHeight, this.squarePixelWidth];
- let u = t.crop;
- u && (u = Fa(u, o, c));
- let l, d, f, h;
- const {
- sx: p,
- sy: m,
- sWidth: b,
- sHeight: g,
- } = this._unmapSourceRegion(
- ((C = t.crop) == null ? void 0 : C.left) ?? 0,
- ((_ = t.crop) == null ? void 0 : _.top) ?? 0,
- ((v = t.crop) == null ? void 0 : v.width) ?? o,
- ((I = t.crop) == null ? void 0 : I.height) ?? c,
- s,
- a,
- );
- if (t.fit === "fill") ((l = 0), (d = 0), (f = n), (h = i));
- else {
- const [w, x] = t.crop ? [t.crop.width, t.crop.height] : [o, c],
- k =
- t.fit === "contain" ? Math.min(n / w, i / x) : Math.max(n / w, i / x);
- ((f = w * k), (h = x * k), (l = (n - f) / 2), (d = (i - h) / 2));
- }
- e.save();
- const y = s % 180 === 0 ? 1 : f / h;
- (e.translate(n / 2, i / 2),
- a && e.scale(-1, 1),
- e.rotate((s * Math.PI) / 180),
- e.scale(1 / y, y),
- e.translate(-n / 2, -i / 2),
- e.drawImage(this.toCanvasImageSource(), p, m, b, g, l, d, f, h),
- e.restore());
- }
- _unmapSourceRegion(e, t, n, i, s, a) {
- return (
- a &&
- (e =
- (s % 180 === 0 ? this.squarePixelWidth : this.squarePixelHeight) -
- e -
- n),
- s === 90
- ? ([e, t, n, i] = [t, this.squarePixelHeight - e - n, i, n])
- : s === 180
- ? ([e, t] = [
- this.squarePixelWidth - e - n,
- this.squarePixelHeight - t - i,
- ])
- : s === 270 &&
- ([e, t, n, i] = [this.squarePixelWidth - t - i, e, i, n]),
- { sx: e, sy: t, sWidth: n, sHeight: i }
- );
- }
- _drawWithFitAndMipmapping(e, t, n) {
- const i = e.width,
- s = e.height,
- [a, o] =
- n.rotation % 180 === 0
- ? [this.squarePixelWidth, this.squarePixelHeight]
- : [this.squarePixelHeight, this.squarePixelWidth],
- c = n.crop ? n.crop.width : a,
- u = n.crop ? n.crop.height : o;
- let l = 0;
- 2 * i < c &&
- 2 * s < u &&
- (l = Math.floor(Math.log2(Math.min(c / i, u / s))));
- const d = i * 2 ** l,
- f = s * 2 ** l,
- {
- canvas: h,
- context: p,
- isNew: m,
- } = l > 0 ? _c(d, f) : { canvas: e, context: t, isNew: n.targetIsFresh };
- ((p.imageSmoothingQuality = "high"),
- n.fillBlack
- ? ((p.fillStyle = "black"), p.fillRect(0, 0, d, f))
- : m || p.clearRect(0, 0, d, f),
- this.drawWithFit(p, {
- fit: n.fit,
- rotation: n.rotation,
- flip: n.flip,
- crop: n.crop,
- }),
- (p.globalCompositeOperation = "copy"));
- for (let b = l; b > 1; b--) {
- const g = i * 2 ** b,
- y = s * 2 ** b;
- p.drawImage(h, 0, 0, g, y, 0, 0, g / 2, y / 2);
- }
- ((p.globalCompositeOperation = "source-over"),
- l > 0 &&
- ((t.imageSmoothingQuality = "high"),
- (t.globalCompositeOperation = "copy"),
- t.drawImage(h, 0, 0, 2 * i, 2 * s, 0, 0, i, s),
- (t.globalCompositeOperation = "source-over")));
- }
- toCanvasImageSource() {
- if (this._closed) throw new Error("VideoSample is closed.");
- if (
- (T(this._data !== null),
- this._data instanceof Mr || this._data instanceof Uint8Array)
- ) {
- const e = this.toVideoFrame();
- return (queueMicrotask(() => e.close()), e);
- } else return this._data;
- }
- async transform(e) {
- if (!e || typeof e != "object")
- throw new TypeError("options must be an object.");
- if (e.width !== void 0 && (!Number.isInteger(e.width) || e.width <= 0))
- throw new TypeError(
- "options.width, when provided, must be a positive integer.",
- );
- if (e.height !== void 0 && (!Number.isInteger(e.height) || e.height <= 0))
- throw new TypeError(
- "options.height, when provided, must be a positive integer.",
- );
- if (
- e.roundDimensionsTo !== void 0 &&
- (!Number.isInteger(e.roundDimensionsTo) || e.roundDimensionsTo <= 0)
- )
- throw new TypeError(
- "options.roundDimensionsTo, when provided, must be a positive integer.",
- );
- if (e.fit !== void 0 && !["fill", "contain", "cover"].includes(e.fit))
- throw new TypeError(
- 'options.fit, when provided, must be one of "fill", "contain", or "cover".',
- );
- if (e.width !== void 0 && e.height !== void 0 && e.fit === void 0)
- throw new TypeError(
- "When both options.width and options.height are provided, options.fit must also be provided.",
- );
- if (e.rotate !== void 0 && ![0, 90, 180, 270].includes(e.rotate))
- throw new TypeError(
- "options.rotate, when provided, must be 0, 90, 180 or 270.",
- );
- if (e.flip !== void 0 && typeof e.flip != "boolean")
- throw new TypeError("options.flip, when provided, must be a boolean.");
- if (
- (e.crop !== void 0 && Zi(e.crop, "options."),
- e.alpha !== void 0 && !["keep", "discard"].includes(e.alpha))
- )
- throw new TypeError(
- "options.alpha, when provided, must be 'keep' or 'discard'.",
- );
- const { rotation: t, flip: n } = Ef(
- this.rotation,
- this.flip,
- e.rotate ?? 0,
- e.flip ?? !1,
- ),
- [i, s] =
- t % 180 === 0
- ? [this.squarePixelWidth, this.squarePixelHeight]
- : [this.squarePixelHeight, this.squarePixelWidth];
- let a = e.crop;
- a && (a = Fa(a, i, s));
- const o = a ? a.width : i,
- c = a ? a.height : s,
- u = o / c;
- let l, d;
- (e.width !== void 0 && e.height === void 0
- ? ((l = e.width), (d = l / u))
- : e.width === void 0 && e.height !== void 0
- ? ((d = e.height), (l = d * u))
- : e.width !== void 0 && e.height !== void 0
- ? ((l = e.width), (d = e.height))
- : ((l = o), (d = c)),
- (l = ga(l, e.roundDimensionsTo ?? 1)),
- (d = ga(d, e.roundDimensionsTo ?? 1)));
- const f = {
- width: l,
- height: d,
- fit: e.fit ?? "fill",
- rotation: t,
- flip: n,
- crop: a ?? { left: 0, top: 0, width: i, height: s },
- alpha: e.alpha ?? "keep",
- };
- for (const b of xp) {
- let g = b(this, f);
- if ((O(g) && (g = await g), g !== null)) return g;
- }
- const { canvas: h, context: p, isNew: m } = _c(f.width, f.height);
- return (
- this._drawWithFitAndMipmapping(h, p, {
- fit: f.fit,
- rotation: f.rotation,
- flip: f.flip,
- crop: f.crop,
- targetIsFresh: m,
- fillBlack: f.alpha === "discard",
- }),
- new tt(h, {
- timestamp: this.timestamp,
- duration: this.duration,
- rotation: 0,
- flip: !1,
- })
- );
- }
- setRotation(e) {
- if (![0, 90, 180, 270].includes(e))
- throw new TypeError("newRotation must be 0, 90, 180, or 270.");
- this.rotation = e;
- }
- setFlip(e) {
- if (typeof e != "boolean")
- throw new TypeError("newFlip must be a boolean.");
- this.flip = e;
- }
- setTimestamp(e) {
- if (!Number.isFinite(e))
- throw new TypeError("newTimestamp must be a number.");
- this.timestamp = e;
- }
- setDuration(e) {
- if (!Number.isFinite(e) || e < 0)
- throw new TypeError("newDuration must be a non-negative number.");
- this.duration = e;
- }
- setEncodeOptions(e) {
- if (!e || typeof e != "object")
- throw new TypeError("newEncodeOptions must be an object.");
- this.encodeOptions = e;
- }
- [Symbol.dispose]() {
- this.close();
- }
-}
-const xp = [],
- Sp = 3,
- Mn = [];
-let Ic = 0;
-const _c = (r, e) => {
- for (const i of Mn)
- if (i.canvas.width === r && i.canvas.height === e)
- return (
- (i.age = Ic++),
- { canvas: i.canvas, context: i.context, isNew: !1 }
- );
- let t;
- if (typeof OffscreenCanvas < "u") t = new OffscreenCanvas(r, e);
- else {
- if (typeof window > "u" || typeof document > "u")
- throw new Error(
- "Cannot transform VideoSamples in this environment. Either run in an environment with OffscreenCanvas or HTMLCanvasElement, or supply a custom VideoSample transformer using registerVideoSampleTransformer().",
- );
- ((t = document.createElement("canvas")), (t.width = r), (t.height = e));
- }
- const n = t.getContext("2d", { alpha: !0, willReadFrequently: !1 });
- if (!n)
- throw new Error(
- "The '2d' canvas context is required to transform VideoSamples. Register a custom transformer using registerVideoSampleTransformer to work around this limitation.",
- );
- return (
- Mn.length >= Sp &&
- Mn.splice(
- Ka(Mn, (i) => i.age),
- 1,
- ),
- Mn.push({ canvas: t, context: n, age: Ic++ }),
- { canvas: t, context: n, isNew: !0 }
- );
-};
-class Hs {
- constructor(e) {
- if (e !== void 0) {
- if (!e || typeof e != "object")
- throw new TypeError(
- "init.colorSpace, when provided, must be an object.",
- );
- const t = Object.keys(xn);
- if (e.primaries != null && !t.includes(e.primaries))
- throw new TypeError(
- `init.colorSpace.primaries, when provided, must be one of ${t.join(", ")}.`,
- );
- const n = Object.keys(Sn);
- if (e.transfer != null && !n.includes(e.transfer))
- throw new TypeError(
- `init.colorSpace.transfer, when provided, must be one of ${n.join(", ")}.`,
- );
- const i = Object.keys(Pn);
- if (e.matrix != null && !i.includes(e.matrix))
- throw new TypeError(
- `init.colorSpace.matrix, when provided, must be one of ${i.join(", ")}.`,
- );
- if (e.fullRange != null && typeof e.fullRange != "boolean")
- throw new TypeError(
- "init.colorSpace.fullRange, when provided, must be a boolean.",
- );
- }
- ((this.primaries = (e == null ? void 0 : e.primaries) ?? null),
- (this.transfer = (e == null ? void 0 : e.transfer) ?? null),
- (this.matrix = (e == null ? void 0 : e.matrix) ?? null),
- (this.fullRange = (e == null ? void 0 : e.fullRange) ?? null));
- }
- toJSON() {
- return {
- primaries: this.primaries,
- transfer: this.transfer,
- matrix: this.matrix,
- fullRange: this.fullRange,
- };
- }
-}
-const Nn = (r) => typeof VideoFrame < "u" && r instanceof VideoFrame,
- Fa = (r, e, t) => {
- const n = Math.min(r.left, e),
- i = Math.min(r.top, t),
- s = Math.min(r.width, e - n),
- a = Math.min(r.height, t - i);
- return (T(s >= 0), T(a >= 0), { left: n, top: i, width: s, height: a });
- },
- Zi = (r, e) => {
- if (!r || typeof r != "object")
- throw new TypeError(e + "crop, when provided, must be an object.");
- if (!Number.isInteger(r.left) || r.left < 0)
- throw new TypeError(e + "crop.left must be a non-negative integer.");
- if (!Number.isInteger(r.top) || r.top < 0)
- throw new TypeError(e + "crop.top must be a non-negative integer.");
- if (!Number.isInteger(r.width) || r.width < 0)
- throw new TypeError(e + "crop.width must be a non-negative integer.");
- if (!Number.isInteger(r.height) || r.height < 0)
- throw new TypeError(e + "crop.height must be a non-negative integer.");
- },
- Ac = (r) => {
- if (!r || typeof r != "object")
- throw new TypeError("options must be an object.");
- if (
- r.colorSpace !== void 0 &&
- !["display-p3", "srgb"].includes(r.colorSpace)
- )
- throw new TypeError(
- "options.colorSpace, when provided, must be 'display-p3' or 'srgb'.",
- );
- if (r.format !== void 0 && typeof r.format != "string")
- throw new TypeError("options.format, when provided, must be a string.");
- if (r.layout !== void 0) {
- if (!Array.isArray(r.layout))
- throw new TypeError("options.layout, when provided, must be an array.");
- for (const e of r.layout) {
- if (!e || typeof e != "object")
- throw new TypeError(
- "Each entry in options.layout must be an object.",
- );
- if (!Number.isInteger(e.offset) || e.offset < 0)
- throw new TypeError("plane.offset must be a non-negative integer.");
- if (!Number.isInteger(e.stride) || e.stride < 0)
- throw new TypeError("plane.stride must be a non-negative integer.");
- }
- }
- if (r.rect !== void 0) {
- if (!r.rect || typeof r.rect != "object")
- throw new TypeError("options.rect, when provided, must be an object.");
- if (r.rect.x !== void 0 && (!Number.isInteger(r.rect.x) || r.rect.x < 0))
- throw new TypeError(
- "options.rect.x, when provided, must be a non-negative integer.",
- );
- if (r.rect.y !== void 0 && (!Number.isInteger(r.rect.y) || r.rect.y < 0))
- throw new TypeError(
- "options.rect.y, when provided, must be a non-negative integer.",
- );
- if (
- r.rect.width !== void 0 &&
- (!Number.isInteger(r.rect.width) || r.rect.width < 0)
- )
- throw new TypeError(
- "options.rect.width, when provided, must be a non-negative integer.",
- );
- if (
- r.rect.height !== void 0 &&
- (!Number.isInteger(r.rect.height) || r.rect.height < 0)
- )
- throw new TypeError(
- "options.rect.height, when provided, must be a non-negative integer.",
- );
- }
- },
- Pp = (r, e, t) => {
- const n = gs(r),
- i = [];
- let s = 0;
- for (const a of n) {
- const o = Math.ceil(e / a.widthDivisor),
- c = Math.ceil(t / a.heightDivisor),
- u = o * a.sampleBytes,
- l = u * c;
- (i.push({ offset: s, stride: u }), (s += l));
- }
- return i;
- },
- gs = (r) => {
- const e = (t, n, i, s, a) => {
- const o = [
- { sampleBytes: t, widthDivisor: 1, heightDivisor: 1 },
- { sampleBytes: n, widthDivisor: i, heightDivisor: s },
- { sampleBytes: n, widthDivisor: i, heightDivisor: s },
- ];
- return (
- a && o.push({ sampleBytes: t, widthDivisor: 1, heightDivisor: 1 }),
- o
- );
- };
- switch (r) {
- case "I420":
- return e(1, 1, 2, 2, !1);
- case "I420P10":
- case "I420P12":
- return e(2, 2, 2, 2, !1);
- case "I420A":
- return e(1, 1, 2, 2, !0);
- case "I420AP10":
- case "I420AP12":
- return e(2, 2, 2, 2, !0);
- case "I422":
- return e(1, 1, 2, 1, !1);
- case "I422P10":
- case "I422P12":
- return e(2, 2, 2, 1, !1);
- case "I422A":
- return e(1, 1, 2, 1, !0);
- case "I422AP10":
- case "I422AP12":
- return e(2, 2, 2, 1, !0);
- case "I444":
- return e(1, 1, 1, 1, !1);
- case "I444P10":
- case "I444P12":
- return e(2, 2, 1, 1, !1);
- case "I444A":
- return e(1, 1, 1, 1, !0);
- case "I444AP10":
- case "I444AP12":
- return e(2, 2, 1, 1, !0);
- case "NV12":
- return [
- { sampleBytes: 1, widthDivisor: 1, heightDivisor: 1 },
- { sampleBytes: 2, widthDivisor: 2, heightDivisor: 2 },
- ];
- case "RGBA":
- case "RGBX":
- case "BGRA":
- case "BGRX":
- return [{ sampleBytes: 4, widthDivisor: 1, heightDivisor: 1 }];
- default:
- (pr(r), T(!1));
- }
- },
- Bc = (r, e) => {
- const t = { left: 0, top: 0, width: r.codedWidth, height: r.codedHeight },
- n = e.rect,
- i = Cp(t, n, r.codedWidth, r.codedHeight, r.format),
- s = e.layout;
- let a;
- if (!e.format || e.format === r.format) a = r.format;
- else if (["RGBA", "RGBX", "BGRA", "BGRX"].includes(e.format)) a = e.format;
- else throw new Error("NotSupportedError: Invalid destination format.");
- return Ep(i, a, s);
- },
- Cp = (r, e, t, n, i) => {
- const s = { ...r };
- if (e !== void 0) {
- if (e.width === 0 || e.height === 0)
- throw new TypeError("visibleRect dimensions cannot be zero.");
- if ((e.x || 0) + (e.width || 0) > t)
- throw new TypeError("visibleRect exceeds codedWidth.");
- if ((e.y || 0) + (e.height || 0) > n)
- throw new TypeError("visibleRect exceeds codedHeight.");
- ((s.x = e.x || 0),
- (s.y = e.y || 0),
- (s.width = e.width || 0),
- (s.height = e.height || 0));
- }
- if (!vp(i, s))
- throw new TypeError("visibleRect alignment is invalid for the format.");
- return s;
- },
- vp = (r, e) => {
- if (r === null) return !0;
- const t = gs(r);
- for (let n = 0; n < t.length; n++) {
- const i = t[n],
- s = i.widthDivisor,
- a = i.heightDivisor;
- if ((e.x || 0) % s !== 0 || (e.y || 0) % a !== 0) return !1;
- }
- return !0;
- },
- Ep = (r, e, t) => {
- const n = gs(e),
- i = n.length;
- if (t !== void 0 && t.length !== i)
- throw new TypeError(`Layout must have ${i} planes.`);
- let s = 0;
- const a = [],
- o = [];
- for (let c = 0; c < i; c++) {
- const u = n[c],
- l = u.sampleBytes,
- d = u.widthDivisor,
- f = u.heightDivisor,
- h = {
- destinationOffset: 0,
- destinationStride: 0,
- sourceTop: 0,
- sourceHeight: 0,
- sourceLeftBytes: 0,
- sourceWidthBytes: 0,
- };
- if (
- ((h.sourceTop = Math.ceil(Math.trunc(r.y || 0) / f)),
- (h.sourceHeight = Math.ceil(Math.trunc(r.height || 0) / f)),
- (h.sourceLeftBytes = Math.floor(Math.trunc(r.x || 0) / d) * l),
- (h.sourceWidthBytes = Math.floor(Math.trunc(r.width || 0) / d) * l),
- t !== void 0)
- ) {
- const b = t[c];
- if (b.stride < h.sourceWidthBytes)
- throw new TypeError(`Stride for plane ${c} is too small.`);
- ((h.destinationOffset = b.offset), (h.destinationStride = b.stride));
- } else
- ((h.destinationOffset = s), (h.destinationStride = h.sourceWidthBytes));
- const m = h.destinationStride * h.sourceHeight + h.destinationOffset;
- if (m > 4294967295) throw new TypeError("Allocation size exceeds limit.");
- (o.push(m), (s = Math.max(s, m)));
- for (let b = 0; b < c; b++) {
- const g = a[b];
- if (!(o[c] <= g.destinationOffset || o[b] <= h.destinationOffset))
- throw new TypeError("Planes overlap.");
- }
- a.push(h);
- }
- return { allocationSize: s, computedLayouts: a };
- },
- vi = new Set([
- "f32",
- "f32-planar",
- "s16",
- "s16-planar",
- "s32",
- "s32-planar",
- "u8",
- "u8-planar",
- ]);
-class On {
- constructor() {
- this._referenceCount = 0;
- }
-}
-class wt {
- get microsecondTimestamp() {
- return Math.trunc(_r * this.timestamp);
- }
- get microsecondDuration() {
- return Math.trunc(_r * this.duration);
- }
- constructor(e) {
- if (((this._closed = !1), Dn(e))) {
- if (e.format === null)
- throw new TypeError("AudioData with null format is not supported.");
- ((this._data = e),
- (this.format = e.format),
- (this.sampleRate = e.sampleRate),
- (this.numberOfFrames = e.numberOfFrames),
- (this.numberOfChannels = e.numberOfChannels),
- (this.timestamp = e.timestamp / 1e6),
- (this.duration = e.numberOfFrames / e.sampleRate));
- } else if (e instanceof On) {
- if (
- ((this._data = e),
- e._referenceCount++,
- (this.format = e.getFormat()),
- !vi.has(this.format))
- )
- throw new TypeError("getFormat() must return an AudioSampleFormat.");
- if (
- ((this.sampleRate = e.getSampleRate()),
- !Number.isInteger(this.sampleRate) || this.sampleRate <= 0)
- )
- throw new TypeError("getSampleRate() must return a positive integer.");
- if (
- ((this.numberOfFrames = e.getNumberOfFrames()),
- !Number.isInteger(this.numberOfFrames) || this.numberOfFrames < 0)
- )
- throw new TypeError(
- "getNumberOfFrames() must return a non-negative integer.",
- );
- if (
- ((this.numberOfChannels = e.getNumberOfChannels()),
- !Number.isInteger(this.numberOfChannels) || this.numberOfChannels <= 0)
- )
- throw new TypeError(
- "getNumberOfChannels() must return a positive integer.",
- );
- if (
- ((this.timestamp = e.getTimestamp()), !Number.isFinite(this.timestamp))
- )
- throw new TypeError("getTimestamp() must return a finite number.");
- this.duration = this.numberOfFrames / this.sampleRate;
- } else {
- if (!e || typeof e != "object")
- throw new TypeError("Invalid AudioDataInit: must be an object.");
- if (!vi.has(e.format))
- throw new TypeError("Invalid AudioDataInit: invalid format.");
- if (!Number.isFinite(e.sampleRate) || e.sampleRate <= 0)
- throw new TypeError("Invalid AudioDataInit: sampleRate must be > 0.");
- if (!Number.isInteger(e.numberOfChannels) || e.numberOfChannels === 0)
- throw new TypeError(
- "Invalid AudioDataInit: numberOfChannels must be an integer > 0.",
- );
- if (!Number.isFinite(e == null ? void 0 : e.timestamp))
- throw new TypeError("init.timestamp must be a number.");
- const t = e.data.byteLength / (vr(e.format) * e.numberOfChannels);
- if (!Number.isInteger(t))
- throw new TypeError(
- "Invalid AudioDataInit: data size is not a multiple of frame size.",
- );
- ((this.format = e.format),
- (this.sampleRate = e.sampleRate),
- (this.numberOfFrames = t),
- (this.numberOfChannels = e.numberOfChannels),
- (this.timestamp = e.timestamp),
- (this.duration = t / e.sampleRate));
- let n;
- if (e.data instanceof ArrayBuffer) n = new Uint8Array(e.data);
- else if (ArrayBuffer.isView(e.data))
- n = new Uint8Array(e.data.buffer, e.data.byteOffset, e.data.byteLength);
- else
- throw new TypeError(
- "Invalid AudioDataInit: data is not a BufferSource.",
- );
- const i = this.numberOfFrames * this.numberOfChannels * vr(this.format);
- if (n.byteLength < i)
- throw new TypeError("Invalid AudioDataInit: insufficient data size.");
- this._data = n;
- }
- bt == null || bt.register(this, { type: "audio", data: this._data }, this);
- }
- allocationSize(e) {
- if (!e || typeof e != "object")
- throw new TypeError("options must be an object.");
- if (!Number.isInteger(e.planeIndex) || e.planeIndex < 0)
- throw new TypeError("planeIndex must be a non-negative integer.");
- if (e.format !== void 0 && !vi.has(e.format))
- throw new TypeError("Invalid format.");
- if (
- e.frameOffset !== void 0 &&
- (!Number.isInteger(e.frameOffset) || e.frameOffset < 0)
- )
- throw new TypeError("frameOffset must be a non-negative integer.");
- if (
- e.frameCount !== void 0 &&
- (!Number.isInteger(e.frameCount) || e.frameCount < 0)
- )
- throw new TypeError("frameCount must be a non-negative integer.");
- if (this._closed) throw new Error("AudioSample is closed.");
- const t = e.format ?? this.format,
- n = e.frameOffset ?? 0;
- if (n >= this.numberOfFrames)
- throw new RangeError("frameOffset out of range");
- const i = e.frameCount !== void 0 ? e.frameCount : this.numberOfFrames - n;
- if (i > this.numberOfFrames - n)
- throw new RangeError("frameCount out of range");
- const s = vr(t),
- a = Wr(t);
- if (a && e.planeIndex >= this.numberOfChannels)
- throw new RangeError("planeIndex out of range");
- if (!a && e.planeIndex !== 0)
- throw new RangeError("planeIndex out of range");
- return (a ? i : i * this.numberOfChannels) * s;
- }
- copyTo(e, t) {
- if (!os(e))
- throw new TypeError(
- "destination must be an ArrayBuffer or an ArrayBuffer view.",
- );
- if (!t || typeof t != "object")
- throw new TypeError("options must be an object.");
- if (!Number.isInteger(t.planeIndex) || t.planeIndex < 0)
- throw new TypeError("planeIndex must be a non-negative integer.");
- if (t.format !== void 0 && !vi.has(t.format))
- throw new TypeError("Invalid format.");
- if (
- t.frameOffset !== void 0 &&
- (!Number.isInteger(t.frameOffset) || t.frameOffset < 0)
- )
- throw new TypeError("frameOffset must be a non-negative integer.");
- if (
- t.frameCount !== void 0 &&
- (!Number.isInteger(t.frameCount) || t.frameCount < 0)
- )
- throw new TypeError("frameCount must be a non-negative integer.");
- if (this._closed) throw new Error("AudioSample is closed.");
- const { format: n, frameCount: i, frameOffset: s } = t;
- let { planeIndex: a } = t,
- o = this.format;
- const c = n ?? this.format;
- if (!c) throw new Error("Destination format not determined");
- const u = this.numberOfFrames,
- l = this.numberOfChannels,
- d = s ?? 0;
- if (d >= u) throw new RangeError("frameOffset out of range");
- const f = i !== void 0 ? i : u - d;
- if (f > u - d) throw new RangeError("frameCount out of range");
- const h = vr(c),
- p = Wr(c);
- if (p && a >= l) throw new RangeError("planeIndex out of range");
- if (!p && a !== 0) throw new RangeError("planeIndex out of range");
- const b = (p ? f : f * l) * h;
- if (e.byteLength < b)
- throw new RangeError("Destination buffer is too small");
- const g = ge(e),
- y = Mu(c);
- if (Dn(this._data))
- if (Fi() && l > 2 && c !== o) {
- _p(this._data, g, o, c, l, a, d, f);
- return;
- } else
- try {
- this._data.copyTo(e, {
- planeIndex: a,
- frameOffset: d,
- frameCount: f,
- format: c,
- });
- return;
- } catch (x) {
- if (c === "f32-planar") throw x;
- o = "f32-planar";
- }
- const C = Ru(o),
- _ = vr(o),
- v = Wr(o);
- let I;
- if (this._data instanceof On) {
- const x = (k) => {
- const S = this._data.getDataPlane(k);
- if (!(S instanceof Uint8Array))
- throw new TypeError("getDataPlane() must return a Uint8Array.");
- const E = u * _ * (v ? 1 : l);
- if (S.byteLength !== E)
- throw new TypeError(
- `Data plane ${k} has invalid size. Expected exactly ${E} bytes, got ${S.byteLength} bytes.`,
- );
- return S;
- };
- if (v)
- if (p) ((I = x(a)), (a = 0));
- else {
- I = new Uint8Array(u * _ * l);
- for (let k = 0; k < l; k++) {
- const S = x(k);
- I.set(S, k * u * _);
- }
- }
- else I = x(0);
- } else if (this._data instanceof Uint8Array) I = this._data;
- else if ((T(o === "f32-planar"), p))
- ((I = new Uint8Array(
- this._data.allocationSize({ format: "f32-planar", planeIndex: a }),
- )),
- this._data.copyTo(I, { format: "f32-planar", planeIndex: a }),
- (a = 0));
- else {
- I = new Uint8Array(
- this._data.allocationSize({ format: "f32-planar", planeIndex: 0 }) * l,
- );
- for (let x = 0; x < l; x++)
- this._data.copyTo(I.subarray(x * u * _, (x + 1) * u * _), {
- format: "f32-planar",
- planeIndex: x,
- });
- }
- const w = ge(I);
- for (let x = 0; x < f; x++)
- if (p) {
- const k = x * h;
- let S;
- v ? (S = (a * u + (x + d)) * _) : (S = ((x + d) * l + a) * _);
- const E = C(w, S);
- y(g, k, E);
- } else
- for (let k = 0; k < l; k++) {
- const E = (x * l + k) * h;
- let B;
- v ? (B = (k * u + (x + d)) * _) : (B = ((x + d) * l + k) * _);
- const R = C(w, B);
- y(g, E, R);
- }
- }
- clone() {
- if (this._closed) throw new Error("AudioSample is closed.");
- if (this._data instanceof On) {
- const e = new wt(this._data);
- return (e.setTimestamp(this.timestamp), e);
- } else if (Dn(this._data)) {
- const e = new wt(this._data.clone());
- return (e.setTimestamp(this.timestamp), e);
- } else
- return new wt({
- format: this.format,
- sampleRate: this.sampleRate,
- numberOfFrames: this.numberOfFrames,
- numberOfChannels: this.numberOfChannels,
- timestamp: this.timestamp,
- data: this._data,
- });
- }
- trim(e, t = this.numberOfFrames) {
- if (!Number.isInteger(e) || e < 0)
- throw new TypeError("startFrame must be a non-negative integer.");
- if (!Number.isInteger(t) || t < 0)
- throw new TypeError("endFrame must be a non-negative integer.");
- if (e > this.numberOfFrames)
- throw new RangeError("startFrame out of range.");
- if (t > this.numberOfFrames) throw new RangeError("endFrame out of range.");
- if (t < e)
- throw new RangeError("endFrame must not be less than startFrame.");
- if (this._closed) throw new Error("AudioSample is closed.");
- const n = t - e,
- i = vr(this.format);
- let s;
- if (Wr(this.format)) {
- const a = n * i;
- if (((s = new Uint8Array(a * this.numberOfChannels)), n > 0))
- for (let o = 0; o < this.numberOfChannels; o++)
- this.copyTo(s.subarray(o * a, (o + 1) * a), {
- planeIndex: o,
- format: this.format,
- frameOffset: e,
- frameCount: n,
- });
- } else
- ((s = new Uint8Array(n * this.numberOfChannels * i)),
- n > 0 &&
- this.copyTo(s, {
- planeIndex: 0,
- format: this.format,
- frameOffset: e,
- frameCount: n,
- }));
- return new wt({
- data: s,
- format: this.format,
- sampleRate: this.sampleRate,
- numberOfChannels: this.numberOfChannels,
- timestamp: this.timestamp + e / this.sampleRate,
- });
- }
- close() {
- this._closed ||
- (bt == null || bt.unregister(this),
- this._data instanceof On
- ? (this._data._referenceCount--,
- this._data._referenceCount === 0 && this._data.close())
- : Dn(this._data)
- ? this._data.close()
- : (this._data = new Uint8Array(0)),
- (this._closed = !0));
- }
- toAudioData() {
- if (this._closed) throw new Error("AudioSample is closed.");
- return this._data instanceof On
- ? this._createAudioDataFromData()
- : Dn(this._data)
- ? this._data.timestamp === this.microsecondTimestamp
- ? this._data.clone()
- : this._createAudioDataFromData()
- : new AudioData({
- format: this.format,
- sampleRate: this.sampleRate,
- numberOfFrames: this.numberOfFrames,
- numberOfChannels: this.numberOfChannels,
- timestamp: this.microsecondTimestamp,
- data:
- this._data.buffer instanceof ArrayBuffer
- ? this._data.buffer
- : this._data.slice(),
- });
- }
- _createAudioDataFromData() {
- if (Wr(this.format)) {
- const e = this.allocationSize({ planeIndex: 0, format: this.format }),
- t = new ArrayBuffer(e * this.numberOfChannels);
- for (let n = 0; n < this.numberOfChannels; n++)
- this.copyTo(new Uint8Array(t, n * e, e), {
- planeIndex: n,
- format: this.format,
- });
- return new AudioData({
- format: this.format,
- sampleRate: this.sampleRate,
- numberOfFrames: this.numberOfFrames,
- numberOfChannels: this.numberOfChannels,
- timestamp: this.microsecondTimestamp,
- data: t,
- });
- } else {
- const e = new ArrayBuffer(
- this.allocationSize({ planeIndex: 0, format: this.format }),
- );
- return (
- this.copyTo(e, { planeIndex: 0, format: this.format }),
- new AudioData({
- format: this.format,
- sampleRate: this.sampleRate,
- numberOfFrames: this.numberOfFrames,
- numberOfChannels: this.numberOfChannels,
- timestamp: this.microsecondTimestamp,
- data: e,
- })
- );
- }
- }
- toAudioBuffer() {
- if (this._closed) throw new Error("AudioSample is closed.");
- const e = new AudioBuffer({
- numberOfChannels: this.numberOfChannels,
- length: this.numberOfFrames,
- sampleRate: this.sampleRate,
- }),
- t = new Float32Array(
- this.allocationSize({ planeIndex: 0, format: "f32-planar" }) / 4,
- );
- for (let n = 0; n < this.numberOfChannels; n++)
- (this.copyTo(t, { planeIndex: n, format: "f32-planar" }),
- e.copyToChannel(t, n));
- return e;
- }
- setTimestamp(e) {
- if (!Number.isFinite(e))
- throw new TypeError("newTimestamp must be a number.");
- this.timestamp = e;
- }
- [Symbol.dispose]() {
- this.close();
- }
- static *_fromAudioBuffer(e, t) {
- if (!(e instanceof AudioBuffer))
- throw new TypeError("audioBuffer must be an AudioBuffer.");
- const n = 48e3 * 5,
- i = e.numberOfChannels,
- s = e.sampleRate,
- a = e.length,
- o = Math.floor(n / i);
- let c = 0,
- u = a;
- for (; u > 0;) {
- const l = Math.min(o, u),
- d = new Float32Array(i * l);
- for (let f = 0; f < i; f++)
- e.copyFromChannel(d.subarray(f * l, (f + 1) * l), f, c);
- (yield new wt({
- format: "f32-planar",
- sampleRate: s,
- numberOfFrames: l,
- numberOfChannels: i,
- timestamp: t + c / s,
- data: d,
- }),
- (c += l),
- (u -= l));
- }
- }
- static fromAudioBuffer(e, t) {
- if (!(e instanceof AudioBuffer))
- throw new TypeError("audioBuffer must be an AudioBuffer.");
- const n = 48e3 * 5,
- i = e.numberOfChannels,
- s = e.sampleRate,
- a = e.length,
- o = Math.floor(n / i);
- let c = 0,
- u = a;
- const l = [];
- for (; u > 0;) {
- const d = Math.min(o, u),
- f = new Float32Array(i * d);
- for (let p = 0; p < i; p++)
- e.copyFromChannel(f.subarray(p * d, (p + 1) * d), p, c);
- const h = new wt({
- format: "f32-planar",
- sampleRate: s,
- numberOfFrames: d,
- numberOfChannels: i,
- timestamp: t + c / s,
- data: f,
- });
- (l.push(h), (c += d), (u -= d));
- }
- return l;
- }
-}
-const vr = (r) => {
- switch (r) {
- case "u8":
- case "u8-planar":
- return 1;
- case "s16":
- case "s16-planar":
- return 2;
- case "s32":
- case "s32-planar":
- return 4;
- case "f32":
- case "f32-planar":
- return 4;
- default:
- throw new Error("Unknown AudioSampleFormat");
- }
- },
- Wr = (r) => {
- switch (r) {
- case "u8-planar":
- case "s16-planar":
- case "s32-planar":
- case "f32-planar":
- return !0;
- default:
- return !1;
- }
- },
- Ru = (r) => {
- switch (r) {
- case "u8":
- case "u8-planar":
- return (e, t) => (e.getUint8(t) - 128) / 128;
- case "s16":
- case "s16-planar":
- return (e, t) => e.getInt16(t, !0) / 32768;
- case "s32":
- case "s32-planar":
- return (e, t) => e.getInt32(t, !0) / 2147483648;
- case "f32":
- case "f32-planar":
- return (e, t) => e.getFloat32(t, !0);
- }
- },
- Mu = (r) => {
- switch (r) {
- case "u8":
- case "u8-planar":
- return (e, t, n) =>
- e.setUint8(t, De(Math.round(n * 128) + 128, 0, 255));
- case "s16":
- case "s16-planar":
- return (e, t, n) =>
- e.setInt16(t, De(Math.round(n * 32768), -32768, 32767), !0);
- case "s32":
- case "s32-planar":
- return (e, t, n) =>
- e.setInt32(
- t,
- De(Math.round(n * 2147483648), -2147483648, 2147483647),
- !0,
- );
- case "f32":
- case "f32-planar":
- return (e, t, n) => e.setFloat32(t, n, !0);
- }
- },
- Dn = (r) => typeof AudioData < "u" && r instanceof AudioData,
- Ip = (r) => {
- switch (r) {
- case "u8-planar":
- return "u8";
- case "s16-planar":
- return "s16";
- case "s32-planar":
- return "s32";
- case "f32-planar":
- return "f32";
- default:
- return r;
- }
- },
- _p = (r, e, t, n, i, s, a, o) => {
- const c = Ru(t),
- u = Mu(n),
- l = vr(t),
- d = vr(n),
- f = Wr(t);
- if (Wr(n))
- if (f) {
- const p = new ArrayBuffer(o * l),
- m = ge(p);
- r.copyTo(p, {
- planeIndex: s,
- frameOffset: a,
- frameCount: o,
- format: t,
- });
- for (let b = 0; b < o; b++) {
- const g = b * l,
- y = b * d,
- C = c(m, g);
- u(e, y, C);
- }
- } else {
- const p = new ArrayBuffer(o * i * l),
- m = ge(p);
- r.copyTo(p, {
- planeIndex: 0,
- frameOffset: a,
- frameCount: o,
- format: t,
- });
- for (let b = 0; b < o; b++) {
- const g = (b * i + s) * l,
- y = b * d,
- C = c(m, g);
- u(e, y, C);
- }
- }
- else if (f) {
- const p = o * l,
- m = new ArrayBuffer(p),
- b = ge(m);
- for (let g = 0; g < i; g++) {
- r.copyTo(m, {
- planeIndex: g,
- frameOffset: a,
- frameCount: o,
- format: t,
- });
- for (let y = 0; y < o; y++) {
- const C = y * l,
- _ = (y * i + g) * d,
- v = c(b, C);
- u(e, _, v);
- }
- }
- } else {
- const p = new ArrayBuffer(o * i * l),
- m = ge(p);
- r.copyTo(p, { planeIndex: 0, frameOffset: a, frameCount: o, format: t });
- for (let b = 0; b < o; b++)
- for (let g = 0; g < i; g++) {
- const y = b * i + g,
- C = y * l,
- _ = y * d,
- v = c(m, C);
- u(e, _, v);
- }
- }
- },
- Ap = (r, e) => {
- const t = r.allocationSize({ format: e, planeIndex: 0 }),
- n = new ArrayBuffer(t);
- return (
- r.copyTo(n, { format: e, planeIndex: 0 }),
- new wt({
- data: n,
- format: e,
- numberOfChannels: r.numberOfChannels,
- sampleRate: r.sampleRate,
- timestamp: r.timestamp,
- duration: r.duration,
- })
- );
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const Ra = new Map(),
- Ma = new Map(),
- Bp = (r) => {
- if (!r || typeof r != "object")
- throw new TypeError("Encoding config must be an object.");
- if (!Rt.includes(r.codec))
- throw new TypeError(
- `Invalid video codec '${r.codec}'. Must be one of: ${Rt.join(", ")}.`,
- );
- const e = r.bitrate;
- if (r.quality === void 0 && e === void 0)
- throw new TypeError("config.quality must be provided.");
- if (r.quality !== void 0 && e !== void 0)
- throw new TypeError(
- "config.quality and config.bitrate cannot both be provided.",
- );
- if (r.quality !== void 0 && !(r.quality instanceof vt))
- throw new TypeError("config.quality, when provided, must be a Quality.");
- if (e !== void 0 && !(e instanceof vt) && (!Number.isInteger(e) || e <= 0))
- throw new TypeError(
- "config.bitrate, when provided, must be a positive integer or a quality.",
- );
- if (
- r.keyFrameInterval !== void 0 &&
- (!Number.isFinite(r.keyFrameInterval) || r.keyFrameInterval < 0)
- )
- throw new TypeError(
- "config.keyFrameInterval, when provided, must be a non-negative number.",
- );
- if (
- r.sizeChangeBehavior !== void 0 &&
- !["deny", "passThrough", "fill", "contain", "cover"].includes(
- r.sizeChangeBehavior,
- )
- )
- throw new TypeError(
- "config.sizeChangeBehavior, when provided, must be 'deny', 'passThrough', 'fill', 'contain' or 'cover'.",
- );
- if (r.transform !== void 0) {
- if (typeof r.transform != "object" || !r.transform)
- throw new TypeError(
- "config.transform, when provided, must be an object.",
- );
- if (
- r.transform.width !== void 0 &&
- (!Number.isInteger(r.transform.width) || r.transform.width <= 0)
- )
- throw new TypeError(
- "config.transform.width, when provided, must be a positive integer.",
- );
- if (
- r.transform.height !== void 0 &&
- (!Number.isInteger(r.transform.height) || r.transform.height <= 0)
- )
- throw new TypeError(
- "config.transform.height, when provided, must be a positive integer.",
- );
- if (
- r.transform.fit !== void 0 &&
- !["fill", "contain", "cover"].includes(r.transform.fit)
- )
- throw new TypeError(
- 'config.transform.fit, when provided, must be one of "fill", "contain", or "cover".',
- );
- if (
- r.transform.width !== void 0 &&
- r.transform.height !== void 0 &&
- r.transform.fit === void 0 &&
- !["fill", "contain", "cover"].includes(r.sizeChangeBehavior)
- )
- throw new TypeError(
- "When both config.transform.width and config.transform.height are provided, config.transform.fit must also be provided.",
- );
- if (
- r.transform.fit !== void 0 &&
- ["fill", "contain", "cover"].includes(r.sizeChangeBehavior) &&
- r.transform.fit !== r.sizeChangeBehavior
- )
- throw new TypeError(
- "config.transform.fit, when provided, cannot differ from config.sizeChangeBehavior when config.sizeChangeBehavior is 'fill', 'contain' or 'cover', as sizeChangeBehavior already determines the fitting algorithm.",
- );
- if (
- r.transform.rotate !== void 0 &&
- ![0, 90, 180, 270].includes(r.transform.rotate)
- )
- throw new TypeError(
- "config.transform.rotate, when provided, must be 0, 90, 180 or 270.",
- );
- if (r.transform.flip !== void 0 && typeof r.transform.flip != "boolean")
- throw new TypeError(
- "config.transform.flip, when provided, must be a boolean.",
- );
- if (
- (r.transform.crop !== void 0 &&
- Zi(r.transform.crop, "config.transform."),
- r.transform.process !== void 0 &&
- typeof r.transform.process != "function")
- )
- throw new TypeError(
- "config.transform.process, when provided, must be a function.",
- );
- if (
- r.transform.frameRate !== void 0 &&
- (!Number.isFinite(r.transform.frameRate) || r.transform.frameRate <= 0)
- )
- throw new TypeError(
- "config.transform.frameRate, when provided, must be a finite positive number.",
- );
- if (r.transform.force !== void 0 && typeof r.transform.force != "boolean")
- throw new TypeError(
- "config.transform.force, when provided, must be a boolean.",
- );
- }
- if (r.onEncodedPacket !== void 0 && typeof r.onEncodedPacket != "function")
- throw new TypeError(
- "config.onEncodedPacket, when provided, must be a function.",
- );
- if (r.onEncoderConfig !== void 0 && typeof r.onEncoderConfig != "function")
- throw new TypeError(
- "config.onEncoderConfig, when provided, must be a function.",
- );
- if (r.onEncodedSample !== void 0 && typeof r.onEncodedSample != "function")
- throw new TypeError(
- "config.onEncodedSample, when provided, must be a function.",
- );
- Nu(r.codec, r);
- },
- Nu = (r, e) => {
- if (!e || typeof e != "object")
- throw new TypeError("Encoding options must be an object.");
- if (e.alpha !== void 0 && !["discard", "keep"].includes(e.alpha))
- throw new TypeError(
- "options.alpha, when provided, must be 'discard' or 'keep'.",
- );
- const t = e.bitrateMode;
- if (t !== void 0 && !["constant", "variable"].includes(t))
- throw new TypeError(
- "bitrateMode, when provided, must be 'constant' or 'variable'.",
- );
- if (
- e.latencyMode !== void 0 &&
- !["quality", "realtime"].includes(e.latencyMode)
- )
- throw new TypeError(
- "latencyMode, when provided, must be 'quality' or 'realtime'.",
- );
- if (e.fullCodecString !== void 0 && typeof e.fullCodecString != "string")
- throw new TypeError("fullCodecString, when provided, must be a string.");
- if (e.fullCodecString !== void 0 && ur(e.fullCodecString) !== r)
- throw new TypeError(
- `fullCodecString, when provided, must be a string that matches the specified codec (${r}).`,
- );
- if (
- e.hardwareAcceleration !== void 0 &&
- !["no-preference", "prefer-hardware", "prefer-software"].includes(
- e.hardwareAcceleration,
- )
- )
- throw new TypeError(
- "hardwareAcceleration, when provided, must be 'no-preference', 'prefer-hardware' or 'prefer-software'.",
- );
- if (e.scalabilityMode !== void 0 && typeof e.scalabilityMode != "string")
- throw new TypeError("scalabilityMode, when provided, must be a string.");
- if (e.contentHint !== void 0 && typeof e.contentHint != "string")
- throw new TypeError("contentHint, when provided, must be a string.");
- },
- Ou = (r) => {
- const e = r.bitrateMode,
- t = r.quality._toVideoRateControl(r.codec, r.width, r.height, e),
- n = (s, a, o) => ({
- codec:
- r.fullCodecString ??
- Ih(r.codec, r.width, r.height, o, r.alpha === "keep"),
- width: r.width,
- height: r.height,
- displayWidth: r.squarePixelWidth,
- displayHeight: r.squarePixelHeight,
- bitrate: s,
- bitrateMode: a,
- alpha: r.alpha ?? "discard",
- framerate: r.framerate,
- latencyMode: r.latencyMode,
- hardwareAcceleration: r.hardwareAcceleration,
- scalabilityMode: r.scalabilityMode,
- contentHint: r.contentHint,
- ...Bh(r.codec),
- }),
- i = [];
- return (
- t.quantizer !== null &&
- i.push({
- config: n(void 0, "quantizer", t.bitrate),
- quantizer: t.quantizer,
- }),
- t.bitrateMode !== "quantizer" &&
- i.push({
- config: n(t.bitrate, t.bitrateMode, t.bitrate),
- quantizer: null,
- }),
- T(i.length > 0),
- i
- );
- },
- Fp = (r) => {
- if (!r || typeof r != "object")
- throw new TypeError("Encoding config must be an object.");
- if (!fr.includes(r.codec))
- throw new TypeError(
- `Invalid audio codec '${r.codec}'. Must be one of: ${fr.join(", ")}.`,
- );
- const e = r.bitrate;
- if (
- r.quality === void 0 &&
- e === void 0 &&
- !(ut.includes(r.codec) || r.codec === "flac")
- )
- throw new TypeError(
- "config.quality must be provided for compressed audio codecs.",
- );
- if (r.quality !== void 0 && e !== void 0)
- throw new TypeError(
- "config.quality and config.bitrate cannot both be provided.",
- );
- if (r.quality !== void 0 && !(r.quality instanceof vt))
- throw new TypeError("config.quality, when provided, must be a Quality.");
- if (e !== void 0 && !(e instanceof vt) && (!Number.isInteger(e) || e <= 0))
- throw new TypeError(
- "config.bitrate, when provided, must be a positive integer or a quality.",
- );
- if (r.transform !== void 0) {
- if (typeof r.transform != "object" || !r.transform)
- throw new TypeError(
- "config.transform, when provided, must be an object.",
- );
- if (
- r.transform.numberOfChannels !== void 0 &&
- (!Number.isInteger(r.transform.numberOfChannels) ||
- r.transform.numberOfChannels <= 0)
- )
- throw new TypeError(
- "config.transform.numberOfChannels, when provided, must be a positive integer.",
- );
- if (
- r.transform.sampleRate !== void 0 &&
- (!Number.isInteger(r.transform.sampleRate) ||
- r.transform.sampleRate <= 0)
- )
- throw new TypeError(
- "config.transform.sampleRate, when provided, must be a positive integer.",
- );
- if (
- r.transform.sampleFormat !== void 0 &&
- !["u8", "s16", "s32", "f32"].includes(r.transform.sampleFormat)
- )
- throw new TypeError(
- "config.transform.sampleFormat, when provided, must be one of: u8, s16, s32, f32.",
- );
- if (
- r.transform.process !== void 0 &&
- typeof r.transform.process != "function"
- )
- throw new TypeError(
- "config.transform.process, when provided, must be a function.",
- );
- }
- if (r.onEncodedPacket !== void 0 && typeof r.onEncodedPacket != "function")
- throw new TypeError(
- "config.onEncodedPacket, when provided, must be a function.",
- );
- if (r.onEncoderConfig !== void 0 && typeof r.onEncoderConfig != "function")
- throw new TypeError(
- "config.onEncoderConfig, when provided, must be a function.",
- );
- if (r.onEncodedSample !== void 0 && typeof r.onEncodedSample != "function")
- throw new TypeError(
- "config.onEncodedSample, when provided, must be a function.",
- );
- Du(r.codec, r);
- },
- Du = (r, e) => {
- if (!e || typeof e != "object")
- throw new TypeError("Encoding options must be an object.");
- const t = e.bitrateMode;
- if (t !== void 0 && !["constant", "variable"].includes(t))
- throw new TypeError(
- "bitrateMode, when provided, must be 'constant' or 'variable'.",
- );
- if (e.fullCodecString !== void 0 && typeof e.fullCodecString != "string")
- throw new TypeError("fullCodecString, when provided, must be a string.");
- if (e.fullCodecString !== void 0 && ur(e.fullCodecString) !== r)
- throw new TypeError(
- `fullCodecString, when provided, must be a string that matches the specified codec (${r}).`,
- );
- },
- zu = (r) => {
- var t, n;
- const e = r.bitrateMode;
- return {
- codec: r.fullCodecString ?? Ah(r.codec, r.numberOfChannels, r.sampleRate),
- numberOfChannels: r.numberOfChannels,
- sampleRate: r.sampleRate,
- bitrate: (t = r.quality) == null ? void 0 : t._toAudioBitrate(r.codec),
- bitrateMode: ((n = r.quality) == null ? void 0 : n._bitrateMode) ?? e,
- ...Fh(r.codec),
- };
- };
-class vt {
- constructor(e) {
- if (
- ((typeof e == "number" || typeof e == "string") && (e = { quality: e }),
- !e || typeof e != "object")
- )
- throw new TypeError("options must be an object.");
- if (
- e.bitrateMode !== void 0 &&
- !["constant", "variable"].includes(e.bitrateMode)
- )
- throw new TypeError(
- "options.bitrateMode, when provided, must be 'constant' or 'variable'.",
- );
- if ("quality" in e) {
- if (
- typeof e.quality == "string"
- ? !(e.quality in Fc)
- : typeof e.quality != "number" || Number.isNaN(e.quality)
- )
- throw new TypeError(
- "options.quality must be a number, or one of 'very-low', 'low', 'medium', 'high' or 'very-high'.",
- );
- if (e.preferBitrate !== void 0 && typeof e.preferBitrate != "boolean")
- throw new TypeError(
- "options.preferBitrate, when provided, must be a boolean.",
- );
- if ("bitrate" in e || "quantizer" in e)
- throw new TypeError(
- "options.quality cannot be combined with options.bitrate or options.quantizer.",
- );
- ((this._quality =
- typeof e.quality == "string" ? Fc[e.quality] : e.quality),
- (this._preferBitrate = e.preferBitrate ?? !1),
- (this._bitrate = void 0),
- (this._quantizer = void 0));
- } else {
- if (
- e.bitrate !== void 0 &&
- (!Number.isInteger(e.bitrate) || e.bitrate <= 0)
- )
- throw new TypeError(
- "options.bitrate, when provided, must be a positive integer.",
- );
- if (
- e.quantizer !== void 0 &&
- (!Number.isInteger(e.quantizer) || e.quantizer < 0)
- )
- throw new TypeError(
- "options.quantizer, when provided, must be a non-negative integer.",
- );
- if (e.bitrate === void 0 && e.quantizer === void 0)
- throw new TypeError(
- "At least one of options.bitrate or options.quantizer must be set.",
- );
- if ("preferBitrate" in e)
- throw new TypeError(
- "options.preferBitrate can only be combined with options.quality.",
- );
- ((this._quality = void 0),
- (this._preferBitrate = !1),
- (this._bitrate = e.bitrate),
- (this._quantizer = e.quantizer));
- }
- this._bitrateMode = e.bitrateMode;
- }
- _toVideoRateControl(e, t, n, i) {
- const s = Rp[e];
- let a = null,
- o = this._bitrateMode ?? i ?? "variable";
- if (this._quantizer !== void 0) {
- if (s)
- if (this._quantizer < s.min || this._quantizer > s.max) {
- if (this._bitrate === void 0)
- throw new Error(
- `Quantizer ${this._quantizer} is out of range for codec '${e}'; must be between ${s.min} and ${s.max}.`,
- );
- } else
- ((a = this._quantizer),
- this._bitrate === void 0 && (o = "quantizer"));
- else if (this._bitrate === void 0)
- throw new Error(
- `Codec '${e}' does not support quantizer-based encoding. Provide a bitrate in the Quality to define a fallback.`,
- );
- } else
- this._bitrate === void 0 &&
- s &&
- !this._preferBitrate &&
- (T(this._quality !== void 0),
- (a = De(Math.round(Of(s.worst, s.best, this._quality)), s.min, s.max)));
- let c;
- if (this._bitrate !== void 0) c = this._bitrate;
- else {
- let u = this._quality;
- (u === void 0 &&
- (T(a !== null && s),
- (u = De((a - s.worst) / (s.best - s.worst), 0, 1))),
- (c = Rc(e, t, n, Vs(u))));
- }
- return { quantizer: a, bitrate: c, bitrateMode: o };
- }
- _toVideoBitrate(e, t, n) {
- return this._bitrate !== void 0
- ? this._bitrate
- : (T(this._quality !== void 0), Rc(e, t, n, Vs(this._quality)));
- }
- _toAudioBitrate(e) {
- if (ut.includes(e) || e === "flac") return;
- if (this._bitrate !== void 0) return this._bitrate;
- if (this._quality === void 0)
- throw new Error(
- "This Quality defines neither a quality level nor a bitrate and therefore cannot be used for audio encoding.",
- );
- const t = Vs(this._quality),
- i = {
- aac: 128e3,
- opus: 64e3,
- mp3: 16e4,
- vorbis: 64e3,
- ac3: 384e3,
- eac3: 192e3,
- dts: 768e3,
- }[e];
- if (!i) throw new Error(`Unhandled codec: ${e}`);
- let s = i * t;
- return (
- e === "aac"
- ? (s = [96e3, 128e3, 16e4, 192e3].reduce((o, c) =>
- Math.abs(c - s) < Math.abs(o - s) ? c : o,
- ))
- : e === "opus" || e === "vorbis"
- ? (s = Math.max(6e3, s))
- : e === "mp3" &&
- (s = [
- 8e3, 16e3, 24e3, 32e3, 4e4, 48e3, 64e3, 8e4, 96e3, 112e3, 128e3,
- 16e4, 192e3, 224e3, 256e3, 32e4,
- ].reduce((o, c) => (Math.abs(c - s) < Math.abs(o - s) ? c : o))),
- Math.round(s / 1e3) * 1e3
- );
- }
-}
-const Fc = {
- "very-low": 0,
- low: 0.25,
- medium: 0.5,
- high: 0.75,
- "very-high": 1,
- },
- Rp = {
- avc: { min: 0, max: 51, worst: 41, best: 16 },
- hevc: { min: 0, max: 51, worst: 41, best: 16 },
- vp9: { min: 0, max: 63, worst: 52, best: 20 },
- av1: { min: 0, max: 255, worst: 208, best: 80 },
- },
- Vs = (r) => 0.3 * Math.exp(2.5538 * r),
- Rc = (r, e, t, n) => {
- const i = e * t,
- s = 1920 * 1080,
- a = 3e6,
- o = Math.pow(i / s, 0.95),
- c = a * o,
- u = { avc: 1, hevc: 0.6, vp9: 0.6, av1: 0.4, vp8: 1.2, prores: 22e7 / a },
- d = c * u[r] * n;
- return Math.ceil(d / 1e3) * 1e3;
- },
- Wu = (r, e) => {
- if (r === "avc") return { avc: { quantizer: e } };
- if (r === "hevc") return { hevc: { quantizer: e } };
- if (r === "vp9") return { vp9: { quantizer: e } };
- if (r === "av1") return { av1: { quantizer: e } };
- T(!1);
- },
- Mp = async (r, e = {}) => {
- const {
- width: t = 1280,
- height: n = 720,
- quality: i,
- bitrate: s,
- frameRate: a,
- ...o
- } = e;
- if (!Rt.includes(r)) return !1;
- if (!Number.isInteger(t) || t <= 0)
- throw new TypeError("width must be a positive integer.");
- if (!Number.isInteger(n) || n <= 0)
- throw new TypeError("height must be a positive integer.");
- if (i !== void 0 && !(i instanceof vt))
- throw new TypeError("quality, when provided, must be a Quality.");
- if (i !== void 0 && s !== void 0)
- throw new TypeError("quality and bitrate cannot both be provided.");
- if (s !== void 0 && !(s instanceof vt) && (!Number.isInteger(s) || s <= 0))
- throw new TypeError("bitrate must be a positive integer or a quality.");
- if (a !== void 0 && (!Number.isFinite(a) || a <= 0))
- throw new TypeError(
- "frameRate, when provided, must be a finite positive number.",
- );
- Nu(r, o);
- const c = bs(i, s) ?? new vt("medium");
- let u;
- try {
- u = Ou({
- codec: r,
- width: t,
- height: n,
- quality: c,
- framerate: a,
- ...o,
- alpha: "discard",
- });
- } catch {
- return !1;
- }
- const l = JSON.stringify(u),
- d = Ra.get(l);
- if (d) return d;
- const f = (async () => {
- for (const { config: p } of u)
- if (Ji.some((m) => m.supports(r, p))) return !0;
- if (
- typeof VideoEncoder > "u" ||
- ((t % 2 === 1 || n % 2 === 1) && r === "avc")
- )
- return !1;
- for (const { config: p, quantizer: m } of u) {
- try {
- if (!(await VideoEncoder.isConfigSupported(p)).supported) continue;
- } catch {
- continue;
- }
- if (
- !Vi() ||
- (await new Promise(async (g) => {
- try {
- const y = new VideoEncoder({
- output: () => {},
- error: () => g(!1),
- });
- y.configure(p);
- const C = new Uint8Array(t * n * 4),
- _ = new VideoFrame(C, {
- format: "RGBA",
- codedWidth: t,
- codedHeight: n,
- timestamp: 0,
- });
- (y.encode(_, m !== null ? Wu(r, m) : void 0),
- _.close(),
- await y.flush(),
- g(!0));
- } catch {
- g(!1);
- }
- }))
- )
- return !0;
- }
- return !1;
- })();
- return (Ra.set(l, f), f);
- },
- Np = async (r, e = {}) => {
- const {
- numberOfChannels: t = 2,
- sampleRate: n = 48e3,
- quality: i,
- bitrate: s,
- ...a
- } = e;
- if (!fr.includes(r)) return !1;
- if (!Number.isInteger(t) || t <= 0)
- throw new TypeError("numberOfChannels must be a positive integer.");
- if (!Number.isInteger(n) || n <= 0)
- throw new TypeError("sampleRate must be a positive integer.");
- if (i !== void 0 && !(i instanceof vt))
- throw new TypeError("quality, when provided, must be a Quality.");
- if (i !== void 0 && s !== void 0)
- throw new TypeError("quality and bitrate cannot both be provided.");
- if (s !== void 0 && !(s instanceof vt) && (!Number.isInteger(s) || s <= 0))
- throw new TypeError("bitrate must be a positive integer.");
- Du(r, a);
- const o = bs(i, s) ?? new vt("medium"),
- c = zu({
- codec: r,
- numberOfChannels: t,
- sampleRate: n,
- quality: o,
- ...a,
- }),
- u = JSON.stringify(c),
- l = Ma.get(u);
- if (l) return l;
- const d = (async () => {
- if (es.some((f) => f.supports(r, c)) || ut.includes(r)) return !0;
- if (typeof AudioEncoder > "u") return !1;
- try {
- return (await AudioEncoder.isConfigSupported(c)).supported === !0;
- } catch {
- return !1;
- }
- })();
- return (Ma.set(u, d), d);
- },
- bs = (r, e) => {
- if (r !== void 0) return r;
- if (e !== void 0) return e instanceof vt ? e : new vt({ bitrate: e });
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class Op {
- static supports(e, t) {
- return !1;
- }
-}
-class Dp {
- static supports(e, t) {
- return !1;
- }
-}
-const Uu = [],
- zp = [],
- Ji = [],
- es = [],
- P1 = (r) => {
- if (r.prototype instanceof Op) {
- const e = r;
- if (Ji.includes(e)) {
- te._warn("Video encoder already registered.");
- return;
- }
- (Ji.push(e), Ra.clear());
- } else if (r.prototype instanceof Dp) {
- const e = r;
- if (es.includes(e)) {
- te._warn("Audio encoder already registered.");
- return;
- }
- (es.push(e), Ma.clear());
- } else
- throw new TypeError(
- "Encoder must be a CustomVideoEncoder or CustomAudioEncoder.",
- );
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const Wp = (r) => {
- let n = r >> 2,
- i = 4096,
- s = 0,
- a = 12,
- o = 0;
- for (
- n < 0 && ((n = -n), (s = 128)), n += 33, n > 8191 && (n = 8191);
- (n & i) !== i && a >= 5;
- )
- ((i >>= 1), a--);
- return ((o = (n >> (a - 4)) & 15), ~(s | ((a - 5) << 4) | o) & 255);
- },
- Up = (r) => {
- let t = 2048,
- n = 0,
- i = 11,
- s = 0,
- a = r >> 3;
- for (
- a < 0 ? (a = -a - 1) : (n = 128), a > 4095 && (a = 4095);
- (a & t) !== t && i >= 5;
- )
- ((t >>= 1), i--);
- return (
- (s = (a >> (i === 4 ? 1 : i - 4)) & 15),
- (n | ((i - 4) << 4) | s) ^ 85
- );
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const Nr = (r) => {
- if (!r || typeof r != "object")
- throw new TypeError("options must be an object.");
- if (r.metadataOnly !== void 0 && typeof r.metadataOnly != "boolean")
- throw new TypeError(
- "options.metadataOnly, when defined, must be a boolean.",
- );
- if (r.verifyKeyPackets !== void 0 && typeof r.verifyKeyPackets != "boolean")
- throw new TypeError(
- "options.verifyKeyPackets, when defined, must be a boolean.",
- );
- if (r.verifyKeyPackets && r.metadataOnly)
- throw new TypeError(
- "options.verifyKeyPackets and options.metadataOnly cannot be enabled together.",
- );
- if (r.skipLiveWait !== void 0 && typeof r.skipLiveWait != "boolean")
- throw new TypeError(
- "options.skipLiveWait, when defined, must be a boolean.",
- );
- },
- Gr = (r) => {
- if (!hi(r)) throw new TypeError("timestamp must be a number.");
- },
- Ls = (r, e, t) =>
- t.verifyKeyPackets
- ? e.then(async (n) => {
- if (!n || n.type === "delta") return n;
- const i = await r.determinePacketType(n);
- return (i && (n.type = i), n);
- })
- : e;
-class lo {
- constructor(e) {
- if (!(e instanceof yi)) throw new TypeError("track must be an InputTrack.");
- this._track = e;
- }
- async getFirstPacket(e = {}) {
- if ((Nr(e), this._track.input._disposed)) throw new rt();
- return Ls(this._track, this._track._backing.getFirstPacket(e), e);
- }
- async getFirstKeyPacket(e = {}) {
- Nr(e);
- const t = await this.getFirstPacket(e);
- return t ? (t.type === "key" ? t : this.getNextKeyPacket(t, e)) : null;
- }
- async getPacket(e, t = {}) {
- if ((Gr(e), Nr(t), this._track.input._disposed)) throw new rt();
- return Ls(this._track, this._track._backing.getPacket(e, t), t);
- }
- async getNextPacket(e, t = {}) {
- if (!(e instanceof Ee))
- throw new TypeError("packet must be an EncodedPacket.");
- if ((Nr(t), this._track.input._disposed)) throw new rt();
- return Ls(this._track, this._track._backing.getNextPacket(e, t), t);
- }
- async getKeyPacket(e, t = {}) {
- if ((Gr(e), Nr(t), this._track.input._disposed)) throw new rt();
- if (!t.verifyKeyPackets) return this._track._backing.getKeyPacket(e, t);
- const n = await this._track._backing.getKeyPacket(e, t);
- return (
- n &&
- (T(n.type === "key"),
- (await this._track.determinePacketType(n)) === "delta"
- ? this.getKeyPacket(
- n.timestamp - 1 / (await this._track.getTimeResolution()),
- t,
- )
- : n)
- );
- }
- async getNextKeyPacket(e, t = {}) {
- if (!(e instanceof Ee))
- throw new TypeError("packet must be an EncodedPacket.");
- if ((Nr(t), this._track.input._disposed)) throw new rt();
- if (!t.verifyKeyPackets) return this._track._backing.getNextKeyPacket(e, t);
- const n = await this._track._backing.getNextKeyPacket(e, t);
- return (
- n &&
- (T(n.type === "key"),
- (await this._track.determinePacketType(n)) === "delta"
- ? this.getNextKeyPacket(n, t)
- : n)
- );
- }
- packets(e, t, n = {}) {
- if (e !== void 0 && !(e instanceof Ee))
- throw new TypeError("startPacket must be an EncodedPacket.");
- if (e !== void 0 && e.isMetadataOnly && !(n != null && n.metadataOnly))
- throw new TypeError(
- "startPacket can only be metadata-only if options.metadataOnly is enabled.",
- );
- if (t !== void 0 && !(t instanceof Ee))
- throw new TypeError("endPacket must be an EncodedPacket.");
- if ((Nr(n), this._track.input._disposed)) throw new rt();
- const i = [];
- let { promise: s, resolve: a } = Ke(),
- { promise: o, resolve: c } = Ke(),
- u = !1,
- l = !1,
- d = null,
- f = !1;
- const h = [],
- p = () => Math.max(2, h.length);
- (async () => {
- let b = e ?? (await this.getFirstPacket(n));
- for (
- ;
- b &&
- !l &&
- !this._track.input._disposed &&
- !(t && b.sequenceNumber >= (t == null ? void 0 : t.sequenceNumber));
- ) {
- if (i.length > p()) {
- (({ promise: o, resolve: c } = Ke()), await o);
- continue;
- }
- (i.push(b),
- a(),
- ({ promise: s, resolve: a } = Ke()),
- (b = await this.getNextPacket(b, n)));
- }
- ((u = !0), a());
- })().catch((b) => {
- f || ((d = b), (f = !0), a());
- });
- const m = this._track;
- return {
- async next() {
- for (;;) {
- if (m.input._disposed) throw new rt();
- if (l) return { value: void 0, done: !0 };
- if (f) throw d;
- if (i.length > 0) {
- const b = i.shift(),
- g = performance.now();
- for (h.push(g); h.length > 0 && g - h[0] >= 1e3;) h.shift();
- return (c(), { value: b, done: !1 });
- } else {
- if (u) return { value: void 0, done: !0 };
- await s;
- }
- }
- },
- async return() {
- return ((l = !0), c(), a(), { value: void 0, done: !0 });
- },
- async throw(b) {
- throw b;
- },
- [Symbol.asyncIterator]() {
- return this;
- },
- };
- }
-}
-class Hp {
- constructor(e, t) {
- ((this.onSample = e), (this.onError = t));
- }
-}
-class Vp {
- mediaSamplesInRange(e = -1 / 0, t = 1 / 0, n) {
- (Gr(e), Gr(t));
- const i = [];
- let s = !1,
- a = null,
- { promise: o, resolve: c } = Ke(),
- { promise: u, resolve: l } = Ke(),
- d = !1,
- f = !1,
- h = !1,
- p = null,
- m = null,
- b = !1;
- const g = { ...n, verifyKeyPackets: !0, metadataOnly: !1 };
- (async () => {
- p = await this._createDecoder(
- (k) => {
- if ((l(), k.timestamp >= t && (f = !0), f)) {
- k.close();
- return;
- }
- (a && (k.timestamp > e ? (i.push(a), (s = !0)) : a.close()),
- k.timestamp >= e && (i.push(k), (s = !0)),
- (a = s ? null : k),
- i.length > 0 && (c(), ({ promise: o, resolve: c } = Ke())));
- },
- (k) => {
- b || ((m = k), (b = !0), c());
- },
- );
- const _ = this._createPacketSink(),
- v = (await _.getKeyPacket(e, g)) ?? (await _.getFirstKeyPacket(g));
- let I = v;
- const x = _.packets(v ?? void 0, void 0, g);
- for (await x.next(); I && !f && !this._track.input._disposed;) {
- const k = Mc(i.length);
- if (i.length + p.getDecodeQueueSize() > k) {
- (({ promise: u, resolve: l } = Ke()), await u);
- continue;
- }
- p.decode(I);
- const S = await x.next();
- if (S.done) break;
- I = S.value;
- }
- (await x.return(),
- !h && !this._track.input._disposed && (await p.flush()),
- !s && a && i.push(a),
- (d = !0),
- c());
- })()
- .catch((_) => {
- b || ((m = _), (b = !0), c());
- })
- .finally(() => {
- p == null || p.close();
- });
- const y = this._track,
- C = () => {
- a == null || a.close();
- for (const _ of i) _.close();
- };
- return {
- async next() {
- for (;;) {
- if (y.input._disposed) throw ((h = !0), (f = !0), C(), new rt());
- if (h) return { value: void 0, done: !0 };
- if (b) throw ((h = !0), (f = !0), C(), m);
- if (i.length > 0) {
- const _ = i.shift();
- return (l(), { value: _, done: !1 });
- } else if (!d) await o;
- else return { value: void 0, done: !0 };
- }
- },
- async return() {
- return ((h = !0), (f = !0), l(), c(), C(), { value: void 0, done: !0 });
- },
- async throw(_) {
- throw _;
- },
- [Symbol.asyncIterator]() {
- return this;
- },
- };
- }
- mediaSamplesAtTimestamps(e, t) {
- Mf(e);
- const n = Rf(e),
- i = [],
- s = [];
- let { promise: a, resolve: o } = Ke(),
- { promise: c, resolve: u } = Ke(),
- l = !1,
- d = !1,
- f = null,
- h = null,
- p = !1;
- const m = (C) => {
- (s.push(C), o(), ({ promise: a, resolve: o } = Ke()));
- },
- b = { ...t, verifyKeyPackets: !0, metadataOnly: !1 };
- (async () => {
- f = await this._createDecoder(
- (k) => {
- if ((u(), d)) {
- k.close();
- return;
- }
- let S = 0;
- for (; i.length > 0 && k.timestamp - i[0] > -1e-10;) (S++, i.shift());
- if (S > 0) for (let E = 0; E < S; E++) m(E < S - 1 ? k.clone() : k);
- else k.close();
- },
- (k) => {
- p || ((h = k), (p = !0), o());
- },
- );
- const C = this._createPacketSink();
- let _ = null,
- v = null,
- I = -1;
- const w = async () => {
- (T(v), T(f));
- let k = v;
- for (f.decode(k); k.sequenceNumber < I;) {
- const S = Mc(s.length);
- for (; s.length + f.getDecodeQueueSize() > S && !d;)
- (({ promise: c, resolve: u } = Ke()), await c);
- if (d) break;
- const E = await C.getNextPacket(k, b);
- (T(E), f.decode(E), (k = E));
- }
- I = -1;
- },
- x = async () => {
- (T(f), await f.flush());
- for (let k = 0; k < i.length; k++) m(null);
- i.length = 0;
- };
- for await (const k of n) {
- if ((Gr(k), d || this._track.input._disposed)) break;
- const S = await C.getPacket(k, b),
- E = S && (await C.getKeyPacket(k, b));
- if (!E) {
- (I !== -1 && (await w(), await x()), m(null), (_ = null));
- continue;
- }
- (_ &&
- (E.sequenceNumber !== v.sequenceNumber ||
- S.timestamp < _.timestamp) &&
- (await w(), await x()),
- i.push(S.timestamp),
- (I = Math.max(S.sequenceNumber, I)),
- (_ = S),
- (v = E));
- }
- (!d &&
- !this._track.input._disposed &&
- (I !== -1 && (await w()), await x()),
- (l = !0),
- o());
- })()
- .catch((C) => {
- p || ((h = C), (p = !0), o());
- })
- .finally(() => {
- f == null || f.close();
- });
- const g = this._track,
- y = () => {
- for (const C of s) C == null || C.close();
- };
- return {
- async next() {
- for (;;) {
- if (g.input._disposed) throw ((d = !0), y(), new rt());
- if (d) return { value: void 0, done: !0 };
- if (p) throw ((d = !0), y(), h);
- if (s.length > 0) {
- const C = s.shift();
- return (T(C !== void 0), u(), { value: C, done: !1 });
- } else if (!l) await a;
- else return { value: void 0, done: !0 };
- }
- },
- async return() {
- return ((d = !0), u(), o(), y(), { value: void 0, done: !0 });
- },
- async throw(C) {
- throw C;
- },
- [Symbol.asyncIterator]() {
- return this;
- },
- };
- }
-}
-const Mc = (r) => (r === 0 ? 40 : 8);
-class Lp extends Hp {
- constructor(e, t, n, i, s, a, o) {
- var u, l, d, f;
- (super(e, t),
- (this.codec = n),
- (this.decoderConfig = i),
- (this.rotation = s),
- (this.flip = a),
- (this.timeResolution = o),
- (this.decoder = null),
- (this.customDecoder = null),
- (this.customDecoderCallSerializer = new ja()),
- (this.customDecoderQueueSize = 0),
- (this.inputTimestamps = []),
- (this.sampleQueue = []),
- (this.currentPacketIndex = 0),
- (this.raslSkipped = !1),
- (this.alphaDecoder = null),
- (this.alphaHadKeyframe = !1),
- (this.colorQueue = []),
- (this.alphaQueue = []),
- (this.merger = null),
- (this.decodedAlphaChunkCount = 0),
- (this.alphaDecoderQueueSize = 0),
- (this.nullAlphaFrameQueue = []),
- (this.currentAlphaPacketIndex = 0),
- (this.alphaRaslSkipped = !1),
- (this.finalSamples = []),
- (this.mergeAlphaPromises = []));
- const c = Uu.find((h) => h.supports(n, i));
- if (c)
- ((this.customDecoder = new c()),
- (this.customDecoder.codec = n),
- (this.customDecoder.config = i),
- (this.customDecoder.onSample = (h) => {
- if (!(h instanceof tt))
- throw new TypeError(
- "The argument passed to onSample must be a VideoSample.",
- );
- this.finalizeAndEmitSample(h);
- }),
- (this.customDecoder.onError = (h) => {
- t(h);
- }),
- this.customDecoderCallSerializer
- .call(() => this.customDecoder.init())
- .catch((h) => t(h)));
- else {
- const h = (m) => {
- if (this.alphaQueue.length > 0) {
- const b = this.alphaQueue.shift();
- (T(b !== void 0), this.mergeAlpha(m, b));
- } else this.colorQueue.push(m);
- };
- if (ya()) {
- if (n === "avc" && this.decoderConfig.description) {
- const m = Ya(Ze(this.decoderConfig.description));
- if (m && m.sequenceParameterSets.length > 0) {
- const b = bn(m.sequenceParameterSets[0]);
- b &&
- (b.frameMbsOnlyFlag === 0 &&
- (this.decoderConfig = {
- ...this.decoderConfig,
- hardwareAcceleration: "prefer-software",
- }),
- b.maxDecFrameBuffering !== 0 &&
- b.bitstreamRestrictionFlag !== 1 &&
- ((m.sequenceParameterSets[0] = Ho(b)),
- (this.decoderConfig = {
- ...this.decoderConfig,
- description: Nl(m),
- })));
- }
- }
- Ha(this.decoderConfig.colorSpace) ||
- (this.decoderConfig = {
- ...this.decoderConfig,
- colorSpace: {
- primaries:
- ((u = this.decoderConfig.colorSpace) == null
- ? void 0
- : u.primaries) ?? "bt709",
- matrix:
- ((l = this.decoderConfig.colorSpace) == null
- ? void 0
- : l.matrix) ?? "bt709",
- transfer:
- ((d = this.decoderConfig.colorSpace) == null
- ? void 0
- : d.transfer) ?? "bt709",
- fullRange:
- ((f = this.decoderConfig.colorSpace) == null
- ? void 0
- : f.fullRange) ?? !1,
- },
- });
- }
- const p = new Error("Decoding error").stack;
- ((this.decoder = new VideoDecoder({
- output: (m) => {
- try {
- h(m);
- } catch (b) {
- this.onError(b);
- }
- },
- error: (m) => {
- ((m.stack = p), this.onError(m));
- },
- })),
- this.decoder.configure(this.decoderConfig));
- }
- }
- getDecodeQueueSize() {
- var e;
- return this.customDecoder
- ? this.customDecoderQueueSize
- : (T(this.decoder),
- Math.max(
- this.decoder.decodeQueueSize,
- ((e = this.alphaDecoder) == null ? void 0 : e.decodeQueueSize) ?? 0,
- ));
- }
- decode(e) {
- if (
- this.codec === "hevc" &&
- this.currentPacketIndex > 0 &&
- !this.raslSkipped
- ) {
- if (this.hasHevcRaslPicture(e.data)) return;
- this.raslSkipped = !0;
- }
- if (this.customDecoder)
- (this.customDecoderQueueSize++,
- this.customDecoderCallSerializer
- .call(() => this.customDecoder.decode(e))
- .catch((t) => this.onError(t))
- .finally(() => this.customDecoderQueueSize--));
- else {
- if (
- (T(this.decoder),
- Fi() || Fo(this.inputTimestamps, e.timestamp, (t) => t),
- ya() && this.currentPacketIndex === 0)
- ) {
- if (this.codec === "avc") {
- const t = [];
- let n = !1;
- for (const s of Rl(e.data, this.decoderConfig)) {
- const a = ai(e.data[s.offset]);
- if ((n || (n = a >= 1 && a <= 5), a === Xe.AUD)) {
- if (n) break;
- t.length = 0;
- }
- (a >= 20 && a <= 31) ||
- t.push(e.data.subarray(s.offset, s.offset + s.length));
- }
- if (!this.decoderConfig.description)
- for (let s = 0; s < t.length; s++) {
- const a = t[s];
- if (ai(a[0]) !== Xe.SPS) continue;
- const o = bn(a);
- o &&
- o.maxDecFrameBuffering !== 0 &&
- o.bitstreamRestrictionFlag !== 1 &&
- (t[s] = Ho(o));
- break;
- }
- const i = Xf(t, this.decoderConfig);
- e = new Ee(i, e.type, e.timestamp, e.duration);
- } else if (this.codec === "hevc") {
- const t = ih(e.data, this.decoderConfig);
- t && (e = new Ee(t, e.type, e.timestamp, e.duration));
- }
- }
- (this.decoder.decode(e.toEncodedVideoChunk()), this.decodeAlphaData(e));
- }
- this.currentPacketIndex++;
- }
- decodeAlphaData(e) {
- if (!e.sideData.alpha) {
- this.pushNullAlphaFrame();
- return;
- }
- if ((this.merger || (this.merger = new qp()), !this.alphaDecoder)) {
- const n = (s) => {
- if (this.colorQueue.length > 0) {
- const a = this.colorQueue.shift();
- (T(a !== void 0), this.mergeAlpha(a, s));
- } else this.alphaQueue.push(s);
- for (
- this.decodedAlphaChunkCount++;
- this.nullAlphaFrameQueue.length > 0 &&
- this.nullAlphaFrameQueue[0] === this.decodedAlphaChunkCount;
- )
- if (
- (this.nullAlphaFrameQueue.shift(), this.colorQueue.length > 0)
- ) {
- const a = this.colorQueue.shift();
- (T(a !== void 0), this.mergeAlpha(a, null));
- } else this.alphaQueue.push(null);
- this.alphaDecoderQueueSize--;
- },
- i = new Error("Decoding error").stack;
- ((this.alphaDecoder = new VideoDecoder({
- output: (s) => {
- try {
- n(s);
- } catch (a) {
- this.onError(a);
- }
- },
- error: (s) => {
- ((s.stack = i), this.onError(s));
- },
- })),
- this.alphaDecoder.configure({
- ...this.decoderConfig,
- colorSpace: {
- fullRange: !0,
- matrix: "bt709",
- primaries: "bt709",
- transfer: "bt709",
- },
- }));
- }
- const t = fs(this.codec, this.decoderConfig, e.sideData.alpha);
- if (
- (this.alphaHadKeyframe || (this.alphaHadKeyframe = t === "key"),
- this.alphaHadKeyframe)
- ) {
- if (
- this.codec === "hevc" &&
- this.currentAlphaPacketIndex > 0 &&
- !this.alphaRaslSkipped
- ) {
- if (this.hasHevcRaslPicture(e.sideData.alpha)) {
- this.pushNullAlphaFrame();
- return;
- }
- this.alphaRaslSkipped = !0;
- }
- (this.currentAlphaPacketIndex++,
- this.alphaDecoder.decode(e.alphaToEncodedVideoChunk(t ?? e.type)),
- this.alphaDecoderQueueSize++);
- } else this.pushNullAlphaFrame();
- }
- pushNullAlphaFrame() {
- this.alphaDecoderQueueSize === 0
- ? this.alphaQueue.push(null)
- : this.nullAlphaFrameQueue.push(
- this.decodedAlphaChunkCount + this.alphaDecoderQueueSize,
- );
- }
- hasHevcRaslPicture(e) {
- for (const t of Li(e, this.decoderConfig)) {
- const n = wn(e[t.offset]);
- if (n === ze.RASL_N || n === ze.RASL_R) return !0;
- }
- return !1;
- }
- sampleHandler(e) {
- if (Fi()) {
- if (
- this.sampleQueue.length > 0 &&
- e.timestamp >= Ae(this.sampleQueue).timestamp
- ) {
- for (const t of this.sampleQueue) this.finalizeAndEmitSample(t);
- this.sampleQueue.length = 0;
- }
- Fo(this.sampleQueue, e, (t) => t.timestamp);
- } else {
- const t = this.inputTimestamps.shift();
- (T(t !== void 0), e.setTimestamp(t), this.finalizeAndEmitSample(e));
- }
- }
- finalizeAndEmitSample(e) {
- (e.setTimestamp(
- Math.round(e.timestamp * this.timeResolution) / this.timeResolution,
- ),
- e.setDuration(
- Math.round(e.duration * this.timeResolution) / this.timeResolution,
- ),
- e.setRotation(this.rotation),
- e.setFlip(this.flip),
- this.onSample(e));
- }
- async mergeAlpha(e, t) {
- const n = Ke();
- this.mergeAlphaPromises.push(n.promise);
- const i = { sample: null };
- this.finalSamples.push(i);
- try {
- if (!t) i.sample = new tt(e);
- else {
- T(this.merger);
- const s = await this.merger.merge(e, t);
- i.sample = new tt(s);
- }
- for (
- ;
- this.finalSamples.length > 0 && this.finalSamples[0].sample !== null;
- ) {
- const s = this.finalSamples.shift();
- this.sampleHandler(s.sample);
- }
- } catch (s) {
- (pa(this.finalSamples, i), this.onError(s));
- } finally {
- (pa(this.mergeAlphaPromises, n.promise), n.resolve());
- }
- }
- async flush() {
- var e;
- if (
- (this.customDecoder
- ? await this.customDecoderCallSerializer.call(() =>
- this.customDecoder.flush(),
- )
- : (T(this.decoder),
- await Promise.all([
- this.decoder.flush(),
- (e = this.alphaDecoder) == null ? void 0 : e.flush(),
- ]),
- await Promise.all(this.mergeAlphaPromises),
- this.colorQueue.forEach((t) => t.close()),
- (this.colorQueue.length = 0),
- this.alphaQueue.forEach((t) => (t == null ? void 0 : t.close())),
- (this.alphaQueue.length = 0),
- (this.alphaHadKeyframe = !1),
- (this.decodedAlphaChunkCount = 0),
- (this.alphaDecoderQueueSize = 0),
- (this.nullAlphaFrameQueue.length = 0),
- (this.currentAlphaPacketIndex = 0),
- (this.alphaRaslSkipped = !1)),
- Fi())
- ) {
- for (const t of this.sampleQueue) this.finalizeAndEmitSample(t);
- this.sampleQueue.length = 0;
- }
- ((this.currentPacketIndex = 0), (this.raslSkipped = !1));
- }
- close() {
- var e;
- this.customDecoder
- ? this.customDecoderCallSerializer.call(() => this.customDecoder.close())
- : (T(this.decoder),
- this.decoder.state !== "closed" && this.decoder.close(),
- this.alphaDecoder &&
- this.alphaDecoder.state !== "closed" &&
- this.alphaDecoder.close(),
- this.colorQueue.forEach((t) => t.close()),
- (this.colorQueue.length = 0),
- this.alphaQueue.forEach((t) => (t == null ? void 0 : t.close())),
- (this.alphaQueue.length = 0),
- (e = this.merger) == null || e.close());
- for (const t of this.sampleQueue) t.close();
- this.sampleQueue.length = 0;
- }
-}
-let qs = null;
-class qp {
- constructor() {
- ((this.workers = []),
- (this.nextWorkerIndex = 0),
- (this.pendingRequests = new Map()),
- (this.nextRequestId = 0));
- }
- merge(e, t) {
- if (this.workers.length === 0) {
- if (!qs) {
- const o = new Blob([`(${jp.toString()})()`], {
- type: "application/javascript",
- });
- qs = URL.createObjectURL(o);
- }
- const a = De(navigator.hardwareConcurrency, 1, 4);
- for (let o = 0; o < a; o++) {
- const c = new Worker(qs);
- (c.addEventListener("message", (u) => {
- const l = u.data,
- d = this.pendingRequests.get(l.id);
- d &&
- (this.pendingRequests.delete(l.id),
- "error" in l ? d.reject(new Error(l.error)) : d.resolve(l.frame));
- }),
- c.addEventListener("error", (u) => {
- const l = new Error(u.message || "Color/alpha merge worker error.");
- for (const d of this.pendingRequests.values()) d.reject(l);
- this.pendingRequests.clear();
- }),
- this.workers.push(c));
- }
- }
- const n = this.nextRequestId++,
- i = Ke();
- this.pendingRequests.set(n, i);
- const s = this.workers[this.nextWorkerIndex];
- return (
- (this.nextWorkerIndex = (this.nextWorkerIndex + 1) % this.workers.length),
- s.postMessage({ id: n, color: e, alpha: t }, { transfer: [e, t] }),
- i.promise
- );
- }
- close() {
- for (const t of this.workers) t.terminate();
- this.workers.length = 0;
- const e = new Error("Color/alpha merger closed.");
- for (const t of this.pendingRequests.values()) t.reject(e);
- this.pendingRequests.clear();
- }
-}
-const jp = () => {
- let r = null,
- e = null,
- t = Promise.resolve();
- self.addEventListener("message", (c) => {
- const { id: u, color: l, alpha: d } = c.data;
- t = t.then(async () => {
- try {
- const f = await n(l, d);
- self.postMessage({ id: u, frame: f }, { transfer: [f] });
- } catch (f) {
- self.postMessage({ id: u, error: f.message });
- } finally {
- (l.close(), d.close());
- }
- });
- });
- const n = async (c, u) => {
- const l = c.format,
- d = u.format;
- if (!l || !d)
- throw new Error(
- "CPU color/alpha merging requires a known VideoFrame format.",
- );
- const f = l.includes("P10"),
- h = l.includes("P12"),
- p = d.includes("P10"),
- m = d.includes("P12");
- if (p !== f || m !== h)
- throw new Error(
- `CPU color/alpha merging requires the alpha frame to have the same bit depth as the color frame (color: '${l}', alpha: '${d}').`,
- );
- if (l === "RGBX" || l === "RGBA" || l === "BGRX" || l === "BGRA")
- return await i(c, u, l);
- if (
- l === "I420" ||
- l === "I420P10" ||
- l === "I420P12" ||
- l === "I422" ||
- l === "I422P10" ||
- l === "I422P12" ||
- l === "I444" ||
- l === "I444P10" ||
- l === "I444P12"
- )
- return await s(c, u, l);
- if (l === "NV12") return await a(c, u);
- throw new Error(
- `CPU color/alpha merging does not support format '${l}'.`,
- );
- },
- i = async (c, u, l) => {
- var y, C;
- const d =
- ((y = c.visibleRect) == null ? void 0 : y.width) ?? c.codedWidth,
- f =
- ((C = c.visibleRect) == null ? void 0 : C.height) ?? c.codedHeight,
- h = d * f,
- p = new Uint8Array(h * 4);
- await c.copyTo(p);
- const m = await o(u, d, f, 1);
- for (let _ = 0, v = 3; _ < h; _++, v += 4) p[v] = m[_];
- const g = {
- format: l === "RGBX" || l === "RGBA" ? "RGBA" : "BGRA",
- codedWidth: d,
- codedHeight: f,
- timestamp: c.timestamp,
- duration: c.duration ?? void 0,
- transfer: [p.buffer],
- };
- return new VideoFrame(p, g);
- },
- s = async (c, u, l) => {
- var R, M;
- const d =
- ((R = c.visibleRect) == null ? void 0 : R.width) ?? c.codedWidth,
- f =
- ((M = c.visibleRect) == null ? void 0 : M.height) ?? c.codedHeight,
- h = l.includes("P10"),
- p = l.includes("P12"),
- m = h || p ? 2 : 1;
- let b, g;
- l.startsWith("I420")
- ? ((b = Math.ceil(d / 2)), (g = Math.ceil(f / 2)))
- : l.startsWith("I422")
- ? ((b = Math.ceil(d / 2)), (g = f))
- : ((b = d), (g = f));
- const y = d * f,
- C = b * g,
- _ = y * m,
- v = C * m,
- I = y * m,
- w = _ + 2 * v + I,
- x = new Uint8Array(w);
- await c.copyTo(x);
- const k = await o(u, d, f, m),
- S = _ + 2 * v;
- x.set(k, S);
- const B = {
- format: l.slice(0, 4) + "A" + l.slice(4),
- codedWidth: d,
- codedHeight: f,
- timestamp: c.timestamp,
- duration: c.duration ?? void 0,
- transfer: [x.buffer],
- };
- return new VideoFrame(x, B);
- },
- a = async (c, u) => {
- var w, x;
- const l =
- ((w = c.visibleRect) == null ? void 0 : w.width) ?? c.codedWidth,
- d =
- ((x = c.visibleRect) == null ? void 0 : x.height) ?? c.codedHeight,
- f = l * d,
- h = Math.ceil(l / 2),
- p = Math.ceil(d / 2),
- m = h * p,
- b = c.allocationSize();
- ((!e || e.byteLength !== b) && (e = new Uint8Array(b)),
- await c.copyTo(e));
- const g = new Uint8Array(f + 2 * m + f);
- g.set(e.subarray(0, f), 0);
- const y = f,
- C = f + m,
- _ = f;
- for (let k = 0; k < m; k++)
- ((g[y + k] = e[_ + k * 2]), (g[C + k] = e[_ + k * 2 + 1]));
- const v = await o(u, l, d, 1);
- g.set(v, f + 2 * m);
- const I = {
- format: "I420A",
- codedWidth: l,
- codedHeight: d,
- timestamp: c.timestamp,
- duration: c.duration ?? void 0,
- transfer: [g.buffer],
- };
- return new VideoFrame(g, I);
- },
- o = async (c, u, l, d) => {
- const f = c.allocationSize();
- ((!r || r.byteLength !== f) && (r = new Uint8Array(f)),
- await c.copyTo(r));
- const h = c.format;
- if (h === "RGBA" || h === "BGRA" || h === "RGBX" || h === "BGRX") {
- const p = h === "RGBA" || h === "RGBX" ? 0 : 2,
- m = u * l;
- for (let b = 0; b < m; b++) r[b] = r[b * 4 + p];
- return r.subarray(0, m);
- } else {
- const p = r.subarray(0, u * l * d);
- if (c.colorSpace.fullRange === !1) {
- const m = h.includes("P12") ? 12 : h.includes("P10") ? 10 : 8,
- b = 16 << (m - 8),
- g = 235 << (m - 8),
- y = (1 << m) - 1,
- C = d === 2 ? new Uint16Array(p.buffer, 0, u * l) : p;
- for (let _ = 0; _ < C.length; _++) {
- const v = Math.round(((C[_] - b) * y) / (g - b));
- C[_] = Math.min(Math.max(v, 0), y);
- }
- }
- return p;
- }
- };
- },
- Hu = (r) => {
- if (!r || typeof r != "object")
- throw new TypeError("decoderOptions must be an object.");
- if (
- r.hardwareAcceleration !== void 0 &&
- !["no-preference", "prefer-hardware", "prefer-software"].includes(
- r.hardwareAcceleration,
- )
- )
- throw new TypeError(
- "decoderOptions.hardwareAcceleration, when provided, must be 'no-preference', 'prefer-hardware' or 'prefer-software'.",
- );
- if (
- r.optimizeForLatency !== void 0 &&
- typeof r.optimizeForLatency != "boolean"
- )
- throw new TypeError(
- "decoderOptions.optimizeForLatency, when provided, must be a boolean.",
- );
- };
-class $p extends Vp {
- constructor(e, t = {}) {
- if (!(e instanceof ws))
- throw new TypeError("videoTrack must be an InputVideoTrack.");
- (Hu(t), super(), (this._track = e), (this._decoderOptions = t));
- }
- async _createDecoder(e, t) {
- if (!(await this._track.canDecode()))
- throw typeof VideoDecoder > "u"
- ? new Error($a("VideoDecoder"))
- : new Error(
- "This video track cannot be decoded in this environment. Make sure to check decodability before using a track.",
- );
- const n = await this._track.getCodec(),
- i = await this._track.getRotation(),
- s = await this._track.getFlip();
- let a = await this._track.getDecoderConfig();
- const o = await this._track.getTimeResolution();
- return (
- T(n && a),
- (a = {
- ...a,
- hardwareAcceleration: this._decoderOptions.hardwareAcceleration,
- optimizeForLatency: this._decoderOptions.optimizeForLatency,
- }),
- new Lp(e, t, n, a, i, s, o)
- );
- }
- _createPacketSink() {
- return new lo(this._track);
- }
- async getSample(e, t = {}) {
- Gr(e);
- for await (const n of this.mediaSamplesAtTimestamps([e], t)) return n;
- throw new Error("Internal error: Iterator returned nothing.");
- }
- samples(e, t, n = {}) {
- return this.mediaSamplesInRange(e, t, n);
- }
- samplesAtTimestamps(e, t = {}) {
- return this.mediaSamplesAtTimestamps(e, t);
- }
-}
-class Gp {
- constructor(e, t = {}) {
- if (
- ((this._rotation = 0),
- (this._flip = !1),
- (this._initPromise = null),
- (this._nextCanvasIndex = 0),
- !(e instanceof ws))
- )
- throw new TypeError("videoTrack must be an InputVideoTrack.");
- if (t && typeof t != "object")
- throw new TypeError("options must be an object.");
- if (t.alpha !== void 0 && typeof t.alpha != "boolean")
- throw new TypeError("options.alpha, when provided, must be a boolean.");
- if (t.width !== void 0 && (!Number.isInteger(t.width) || t.width <= 0))
- throw new TypeError(
- "options.width, when defined, must be a positive integer.",
- );
- if (t.height !== void 0 && (!Number.isInteger(t.height) || t.height <= 0))
- throw new TypeError(
- "options.height, when defined, must be a positive integer.",
- );
- if (t.fit !== void 0 && !["fill", "contain", "cover"].includes(t.fit))
- throw new TypeError(
- 'options.fit, when provided, must be one of "fill", "contain", or "cover".',
- );
- if (t.width !== void 0 && t.height !== void 0 && t.fit === void 0)
- throw new TypeError(
- "When both options.width and options.height are provided, options.fit must also be provided.",
- );
- if (t.rotation !== void 0 && ![0, 90, 180, 270].includes(t.rotation))
- throw new TypeError(
- "options.rotation, when provided, must be 0, 90, 180 or 270.",
- );
- if (t.flip !== void 0 && typeof t.flip != "boolean")
- throw new TypeError("options.flip, when provided, must be a boolean.");
- if (
- (t.crop !== void 0 && Zi(t.crop, "options."),
- t.poolSize !== void 0 &&
- (typeof t.poolSize != "number" ||
- !Number.isInteger(t.poolSize) ||
- t.poolSize < 0))
- )
- throw new TypeError("poolSize must be a non-negative integer.");
- (t.decoderOptions !== void 0 && Hu(t.decoderOptions),
- (this._videoTrack = e),
- (this._alpha = t.alpha ?? !1),
- (this._options = t),
- (this._fit = t.fit ?? "fill"),
- (this._videoSampleSink = new $p(e, t.decoderOptions)),
- (this._canvasPool = Array.from({ length: t.poolSize ?? 0 }, () => null)));
- }
- _ensureInit() {
- return (
- this._initPromise ??
- (this._initPromise = (async () => {
- const e = this._options,
- t = this._videoTrack,
- n = e.rotation ?? (await t.getRotation()),
- i = e.flip ?? (await t.getFlip()),
- s = await t.getSquarePixelWidth(),
- a = await t.getSquarePixelHeight(),
- [o, c] = n % 180 === 0 ? [s, a] : [a, s];
- let u = e.crop;
- u && (u = Fa(u, o, c));
- let [l, d] = u ? [u.width, u.height] : [o, c];
- const f = l / d;
- (e.width !== void 0 && e.height === void 0
- ? ((l = e.width), (d = Math.round(l / f)))
- : e.width === void 0 && e.height !== void 0
- ? ((d = e.height), (l = Math.round(d * f)))
- : e.width !== void 0 &&
- e.height !== void 0 &&
- ((l = e.width), (d = e.height)),
- (this._width = l),
- (this._height = d),
- (this._rotation = n),
- (this._flip = i),
- (this._crop = u));
- })())
- );
- }
- _videoSampleToWrappedCanvas(e) {
- const t = this._width,
- n = this._height;
- let i = this._canvasPool[this._nextCanvasIndex],
- s = !1;
- (i ||
- (typeof document < "u"
- ? ((i = document.createElement("canvas")),
- (i.width = t),
- (i.height = n))
- : (i = new OffscreenCanvas(t, n)),
- this._canvasPool.length > 0 &&
- (this._canvasPool[this._nextCanvasIndex] = i),
- (s = !0)),
- this._canvasPool.length > 0 &&
- (this._nextCanvasIndex =
- (this._nextCanvasIndex + 1) % this._canvasPool.length));
- const a = i.getContext("2d", { alpha: this._alpha || Vi() });
- (T(a),
- e._drawWithFitAndMipmapping(i, a, {
- fit: this._fit,
- rotation: this._rotation,
- flip: this._flip,
- crop: this._crop,
- targetIsFresh: s,
- fillBlack: !this._alpha && Vi(),
- }));
- const o = { canvas: i, timestamp: e.timestamp, duration: e.duration };
- return (e.close(), o);
- }
- async getCanvas(e, t) {
- (Gr(e), await this._ensureInit());
- const n = await this._videoSampleSink.getSample(e, t);
- return n && this._videoSampleToWrappedCanvas(n);
- }
- async *canvases(e, t, n) {
- (await this._ensureInit(),
- yield* Ro(this._videoSampleSink.samples(e, t, n), (i) =>
- this._videoSampleToWrappedCanvas(i),
- ));
- }
- async *canvasesAtTimestamps(e, t) {
- (await this._ensureInit(),
- yield* Ro(
- this._videoSampleSink.samplesAtTimestamps(e, t),
- (n) => n && this._videoSampleToWrappedCanvas(n),
- ));
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class yi {
- constructor(e, t) {
- ((this.input = e), (this._backing = t));
- }
- isVideoTrack() {
- return this instanceof ws;
- }
- isAudioTrack() {
- return this instanceof Vu;
- }
- get id() {
- return this._backing.getId();
- }
- get number() {
- return this._backing.getNumber();
- }
- async getInternalCodecId() {
- return this._backing.getInternalCodecId();
- }
- get internalCodecId() {
- return _e(
- this._backing.getInternalCodecId(),
- "internalCodecId",
- "getInternalCodecId",
- );
- }
- async getLanguageCode() {
- return this._backing.getLanguageCode();
- }
- get languageCode() {
- return _e(
- this._backing.getLanguageCode(),
- "languageCode",
- "getLanguageCode",
- );
- }
- async getName() {
- return this._backing.getName();
- }
- get name() {
- return _e(this._backing.getName(), "name", "getName");
- }
- async getTimeResolution() {
- return this._backing.getTimeResolution();
- }
- get timeResolution() {
- return _e(
- this._backing.getTimeResolution(),
- "timeResolution",
- "getTimeResolution",
- );
- }
- async isRelativeToUnixEpoch() {
- return this._backing.isRelativeToUnixEpoch();
- }
- async getUnixTimeForTimestamp(e) {
- return this._backing.getUnixTimeForTimestamp(e);
- }
- async hasUnixTimeMapping() {
- return (
- (await this._backing.getUnixTimeForTimestamp(
- await this.getFirstTimestamp(),
- )) !== null
- );
- }
- async getDisposition() {
- return this._backing.getDisposition();
- }
- get disposition() {
- return _e(this._backing.getDisposition(), "disposition", "getDisposition");
- }
- async getBitrate() {
- return this._backing.getBitrate();
- }
- async getAverageBitrate() {
- return this._backing.getAverageBitrate();
- }
- async getFirstTimestamp() {
- const e = await this._backing.getFirstPacket({ metadataOnly: !0 });
- return (e == null ? void 0 : e.timestamp) ?? 0;
- }
- async computeDuration(e) {
- const t = await this._backing.getPacket(1 / 0, { metadataOnly: !0, ...e }),
- n =
- ((t == null ? void 0 : t.timestamp) ?? 0) +
- ((t == null ? void 0 : t.duration) ?? 0);
- return Hi(n, await this.getTimeResolution());
- }
- async getDurationFromMetadata(e = {}) {
- return this._backing.getDurationFromMetadata(e);
- }
- async computePacketStats(e = 1 / 0, t) {
- const n = new lo(this);
- let i = 1 / 0,
- s = -1 / 0,
- a = 0,
- o = 0;
- for await (const c of n.packets(void 0, void 0, {
- metadataOnly: !0,
- ...t,
- })) {
- if (a >= e && c.timestamp >= s) break;
- ((i = Math.min(i, c.timestamp)),
- (s = Math.max(s, c.timestamp + c.duration)),
- a++,
- (o += c.byteLength));
- }
- return {
- packetCount: a,
- averagePacketRate: a ? Number((a / (s - i)).toPrecision(16)) : 0,
- averageBitrate: a ? Number(((8 * o) / (s - i)).toPrecision(16)) : 0,
- };
- }
- async isLive() {
- return (await this._backing.getLiveRefreshInterval()) !== null;
- }
- async getLiveRefreshInterval() {
- return this._backing.getLiveRefreshInterval();
- }
- canBePairedWith(e) {
- if (!(e instanceof yi)) throw new TypeError("other must be an InputTrack.");
- return this.input !== e.input || this === e
- ? !1
- : (this._backing.getPairingMask() & e._backing.getPairingMask()) !== 0n;
- }
- async getPairableTracks(e) {
- return this.input.getTracks(
- Ur({ filter: (t) => t.canBePairedWith(this) }, e),
- );
- }
- async getPairableVideoTracks(e) {
- return this.input.getVideoTracks(
- Ur({ filter: (t) => t.canBePairedWith(this) }, e),
- );
- }
- async getPairableAudioTracks(e) {
- return this.input.getAudioTracks(
- Ur({ filter: (t) => t.canBePairedWith(this) }, e),
- );
- }
- async getPrimaryPairableVideoTrack(e) {
- return this.input.getPrimaryVideoTrack(
- Ur({ filter: (t) => t.canBePairedWith(this) }, e),
- );
- }
- async getPrimaryPairableAudioTrack(e) {
- return this.input.getPrimaryAudioTrack(
- Ur({ filter: (t) => t.canBePairedWith(this) }, e),
- );
- }
- async hasPairableTrack(e) {
- e && (e = js(e));
- const t = await this.input.getTracks();
- for (const n of t)
- if (this.canBePairedWith(n) && (!e || (await e(n)))) return !0;
- return !1;
- }
- hasPairableVideoTrack(e) {
- return (
- e && (e = js(e)),
- this.hasPairableTrack(
- async (t) => t.isVideoTrack() && (!e || (await e(t))),
- )
- );
- }
- hasPairableAudioTrack(e) {
- return (
- e && (e = js(e)),
- this.hasPairableTrack(
- async (t) => t.isAudioTrack() && (!e || (await e(t))),
- )
- );
- }
-}
-const _e = (r, e, t) => {
- if (O(r))
- throw new Error(
- `'${e}' is deprecated and not available synchronously for this track. Use the preferred '${t}()' instead.`,
- );
- return r;
- },
- js = (r) => {
- if (r !== void 0 && typeof r != "function")
- throw new TypeError("predicate, when provided, must be a function.");
- return r
- ? (e) => {
- const t = (i) => {
- if (typeof i != "boolean")
- throw new TypeError(
- "predicate must return or resolve to a boolean value.",
- );
- return i;
- },
- n = r(e);
- return O(n) ? n.then(t) : t(n);
- }
- : void 0;
- };
-class ws extends yi {
- constructor(e, t) {
- (super(e, t), (this._pixelAspectRatioCache = null));
- }
- get type() {
- return "video";
- }
- async getCodec() {
- return this._backing.getCodec();
- }
- get codec() {
- return _e(this._backing.getCodec(), "codec", "getCodec");
- }
- async hasOnlyKeyPackets() {
- var e, t;
- return (
- (await ((t = (e = this._backing).getHasOnlyKeyPackets) == null
- ? void 0
- : t.call(e))) ?? (await this._backing.getCodec()) === "prores"
- );
- }
- async getCodedWidth() {
- return this._backing.getCodedWidth();
- }
- get codedWidth() {
- return _e(this._backing.getCodedWidth(), "codedWidth", "getCodedWidth");
- }
- async getCodedHeight() {
- return this._backing.getCodedHeight();
- }
- get codedHeight() {
- return _e(this._backing.getCodedHeight(), "codedHeight", "getCodedHeight");
- }
- async getTransformationMatrix() {
- return this._backing.getTransformationMatrix();
- }
- async getRotation() {
- return Pi(await this._backing.getTransformationMatrix());
- }
- get rotation() {
- return Pi(
- _e(this._backing.getTransformationMatrix(), "rotation", "getRotation"),
- );
- }
- async getFlip() {
- return Tl(await this._backing.getTransformationMatrix());
- }
- async getSquarePixelWidth() {
- return this._backing.getSquarePixelWidth();
- }
- get squarePixelWidth() {
- return _e(
- this._backing.getSquarePixelWidth(),
- "squarePixelWidth",
- "getSquarePixelWidth",
- );
- }
- async getSquarePixelHeight() {
- return this._backing.getSquarePixelHeight();
- }
- get squarePixelHeight() {
- return _e(
- this._backing.getSquarePixelHeight(),
- "squarePixelHeight",
- "getSquarePixelHeight",
- );
- }
- async getPixelAspectRatio() {
- return (
- this._pixelAspectRatioCache ??
- (this._pixelAspectRatioCache = ii({
- num: (await this.getSquarePixelWidth()) * (await this.getCodedHeight()),
- den: (await this.getSquarePixelHeight()) * (await this.getCodedWidth()),
- }))
- );
- }
- get pixelAspectRatio() {
- return (
- this._pixelAspectRatioCache ??
- (this._pixelAspectRatioCache = ii({
- num:
- _e(
- this._backing.getSquarePixelWidth(),
- "pixelAspectRatio",
- "getPixelAspectRatio",
- ) *
- _e(
- this._backing.getCodedHeight(),
- "pixelAspectRatio",
- "getPixelAspectRatio",
- ),
- den:
- _e(
- this._backing.getSquarePixelHeight(),
- "pixelAspectRatio",
- "getPixelAspectRatio",
- ) *
- _e(
- this._backing.getCodedWidth(),
- "pixelAspectRatio",
- "getPixelAspectRatio",
- ),
- }))
- );
- }
- async getDisplayWidth() {
- var n, i;
- const e = await ((i = (n = this._backing).getMetadataDisplayWidth) == null
- ? void 0
- : i.call(n));
- return (
- e ??
- ((await this.getRotation()) % 180 === 0
- ? this.getSquarePixelWidth()
- : this.getSquarePixelHeight())
- );
- }
- get displayWidth() {
- var i, s;
- const e =
- (s = (i = this._backing).getMetadataDisplayWidth) == null
- ? void 0
- : s.call(i);
- if (e !== void 0) {
- const a = _e(e, "displayWidth", "getDisplayWidth");
- if (a !== null) return a;
- }
- const n =
- Pi(
- _e(
- this._backing.getTransformationMatrix(),
- "displayWidth",
- "getDisplayWidth",
- ),
- ) %
- 180 ===
- 0
- ? this._backing.getSquarePixelWidth()
- : this._backing.getSquarePixelHeight();
- return _e(n, "displayWidth", "getDisplayWidth");
- }
- async getDisplayHeight() {
- var n, i;
- const e = await ((i = (n = this._backing).getMetadataDisplayHeight) == null
- ? void 0
- : i.call(n));
- return (
- e ??
- ((await this.getRotation()) % 180 === 0
- ? this.getSquarePixelHeight()
- : this.getSquarePixelWidth())
- );
- }
- get displayHeight() {
- var i, s;
- const e =
- (s = (i = this._backing).getMetadataDisplayHeight) == null
- ? void 0
- : s.call(i);
- if (e !== void 0) {
- const a = _e(e, "displayHeight", "getDisplayHeight");
- if (a !== null) return a;
- }
- const n =
- Pi(
- _e(
- this._backing.getTransformationMatrix(),
- "displayHeight",
- "getDisplayHeight",
- ),
- ) %
- 180 ===
- 0
- ? this._backing.getSquarePixelHeight()
- : this._backing.getSquarePixelWidth();
- return _e(n, "displayHeight", "getDisplayHeight");
- }
- async getColorSpace() {
- return this._backing.getColorSpace();
- }
- async hasHighDynamicRange() {
- const e = await this._backing.getColorSpace();
- return (
- e.primaries === "bt2020" ||
- e.primaries === "smpte432" ||
- e.transfer === "pq" ||
- e.transfer === "hlg" ||
- e.matrix === "bt2020-ncl"
- );
- }
- async canBeTransparent() {
- return this._backing.canBeTransparent();
- }
- async getDecoderConfig() {
- return this._backing.getDecoderConfig();
- }
- async getCodecParameterString() {
- var n, i;
- const e = await ((i = (n = this._backing)
- .getMetadataCodecParameterString) == null
- ? void 0
- : i.call(n));
- if (e != null) return e;
- const t = await this._backing.getDecoderConfig();
- return (t == null ? void 0 : t.codec) ?? null;
- }
- async canDecode() {
- try {
- const e = await this._backing.getDecoderConfig();
- if (!e) return !1;
- const t = await this._backing.getCodec();
- return (
- T(t !== null),
- Uu.some((i) => i.supports(t, e))
- ? !0
- : typeof VideoDecoder > "u"
- ? !1
- : (await VideoDecoder.isConfigSupported(e)).supported === !0
- );
- } catch (e) {
- return (te._error("Error during decodability check:", e), !1);
- }
- }
- async determinePacketType(e) {
- if (!(e instanceof Ee))
- throw new TypeError("packet must be an EncodedPacket.");
- if (e.isMetadataOnly)
- throw new TypeError(
- "packet must not be metadata-only to determine its type.",
- );
- const t = await this.getCodec();
- if (t === null) return null;
- const n = await this.getDecoderConfig();
- return (T(n), fs(t, n, e.data));
- }
- async computeFrameRateMetrics(e = {}) {
- if (!e || typeof e != "object")
- throw new TypeError("options must be an object.");
- if (
- e.targetPacketCount !== void 0 &&
- (!hi(e.targetPacketCount) || e.targetPacketCount < 0)
- )
- throw new TypeError(
- "options.targetPacketCount must be a non-negative number.",
- );
- const t = await this.getTimeResolution(),
- n = e.targetPacketCount ?? 256,
- i = new lo(this),
- s = [];
- let a = -1 / 0,
- o = 0;
- for await (const S of i.packets(void 0, void 0, { metadataOnly: !0 })) {
- if (s.length >= n && S.timestamp >= a) break;
- (s.push(S.timestamp), (a = Math.max(a, S.timestamp)), o++);
- }
- const c = new Float64Array(s.length);
- for (let S = 0; S < s.length; S++) c[S] = Math.round(s[S] * t);
- c.sort();
- let u = 1;
- for (let S = 1; S < c.length; S++) c[S] !== c[u - 1] && (c[u++] = c[S]);
- if (u < 2)
- return {
- underlyingFrameRate: null,
- bestGuessFrameRate: t,
- minFrameRate: t,
- maxFrameRate: t,
- averageFrameRate: t,
- medianFrameRate: t,
- frameRateIsConstant: !0,
- probedPacketCount: o,
- };
- const l = c.subarray(0, u),
- d = Kp(l, t),
- f = d ?? t,
- h = d !== null ? t / d : null,
- p = new Map();
- let m = 1 / 0,
- b = -1 / 0,
- g = 0;
- for (let S = 1; S < u; S++) {
- const E = l[S] - l[S - 1],
- B = h !== null ? Math.max(1, Math.round(E / h)) : E;
- (p.set(B, (p.get(B) ?? 0) + 1),
- (m = Math.min(m, B)),
- (b = Math.max(b, B)),
- (g += B));
- }
- const y = u - 1,
- C = [...p.keys()].sort((S, E) => S - E),
- _ = (y - 1) >> 1,
- v = y >> 1;
- let I = 0,
- w = 0,
- x = 0;
- for (const S of C)
- if (((x += p.get(S)), I === 0 && x > _ && (I = S), x > v)) {
- w = S;
- break;
- }
- const k = (f / I + f / w) / 2;
- return {
- underlyingFrameRate: d,
- bestGuessFrameRate: d !== null ? d : Xp(k),
- minFrameRate: f / b,
- maxFrameRate: f / m,
- averageFrameRate: (f * y) / g,
- medianFrameRate: k,
- frameRateIsConstant: d !== null && m === 1 && b === 1,
- probedPacketCount: o,
- };
- }
-}
-class Vu extends yi {
- constructor(e, t) {
- super(e, t);
- }
- get type() {
- return "audio";
- }
- async getCodec() {
- return this._backing.getCodec();
- }
- get codec() {
- return _e(this._backing.getCodec(), "codec", "getCodec");
- }
- async hasOnlyKeyPackets() {
- var e, t;
- return (
- (await ((t = (e = this._backing).getHasOnlyKeyPackets) == null
- ? void 0
- : t.call(e))) ?? !0
- );
- }
- async getNumberOfChannels() {
- return this._backing.getNumberOfChannels();
- }
- get numberOfChannels() {
- return _e(
- this._backing.getNumberOfChannels(),
- "numberOfChannels",
- "getNumberOfChannels",
- );
- }
- async getSampleRate() {
- return this._backing.getSampleRate();
- }
- get sampleRate() {
- return _e(this._backing.getSampleRate(), "sampleRate", "getSampleRate");
- }
- async getDecoderConfig() {
- return this._backing.getDecoderConfig();
- }
- async getCodecParameterString() {
- var n, i;
- const e = await ((i = (n = this._backing)
- .getMetadataCodecParameterString) == null
- ? void 0
- : i.call(n));
- if (e != null) return e;
- const t = await this._backing.getDecoderConfig();
- return (t == null ? void 0 : t.codec) ?? null;
- }
- async canDecode() {
- try {
- const e = await this._backing.getDecoderConfig();
- if (!e) return !1;
- const t = await this._backing.getCodec();
- return (
- T(t !== null),
- zp.some((n) => n.supports(t, e)) || ut.includes(e.codec)
- ? !0
- : typeof AudioDecoder > "u"
- ? !1
- : (await AudioDecoder.isConfigSupported(e)).supported === !0
- );
- } catch (e) {
- return (te._error("Error during decodability check:", e), !1);
- }
- }
- async determinePacketType(e) {
- if (!(e instanceof Ee))
- throw new TypeError("packet must be an EncodedPacket.");
- return (await this.getCodec()) === null ? null : "key";
- }
-}
-const Nc = (r) => -(r ?? -1 / 0),
- zn = (r) => -r,
- Wn = (r) => {
- if (typeof r != "object" || !r)
- throw new TypeError("query must be an object.");
- if (r.filter !== void 0 && typeof r.filter != "function")
- throw new TypeError("query.filter, when provided, must be a function.");
- if (r.sortBy !== void 0 && typeof r.sortBy != "function")
- throw new TypeError("query.sortBy, when provided, must be a function.");
- return {
- filter: r.filter
- ? (e) => {
- const t = (i) => {
- if (typeof i != "boolean")
- throw new TypeError(
- "query.filter must return or resolve to a boolean.",
- );
- return i;
- },
- n = r.filter(e);
- return O(n) ? n.then(t) : t(n);
- }
- : void 0,
- sortBy: r.sortBy
- ? (e) => {
- const t = (i) => {
- if (
- typeof i != "number" &&
- (!Array.isArray(i) || !i.every((s) => typeof s == "number"))
- )
- throw new TypeError(
- "query.sortBy must return or resolve to a number or an array of numbers.",
- );
- return i;
- },
- n = r.sortBy(e);
- return O(n) ? n.then(t) : t(n);
- }
- : void 0,
- };
- },
- Ur = (r, e) => ({
- filter:
- (r != null && r.filter) || (e != null && e.filter)
- ? (t) => {
- var s;
- const n =
- ((s = r == null ? void 0 : r.filter) == null
- ? void 0
- : s.call(r, t)) ?? !0,
- i = (a) => {
- var o;
- return a === !1
- ? !1
- : (((o = e == null ? void 0 : e.filter) == null
- ? void 0
- : o.call(e, t)) ?? !0);
- };
- return O(n) ? n.then(i) : i(n);
- }
- : void 0,
- sortBy:
- (r != null && r.sortBy) || (e != null && e.sortBy)
- ? (t) => {
- var a, o;
- const n =
- ((a = r == null ? void 0 : r.sortBy) == null
- ? void 0
- : a.call(r, t)) ?? [],
- i =
- ((o = e == null ? void 0 : e.sortBy) == null
- ? void 0
- : o.call(e, t)) ?? [],
- s = (c, u) => [
- ...(Array.isArray(c) ? c : [c]),
- ...(Array.isArray(u) ? u : [u]),
- ];
- return O(n) || O(i)
- ? Promise.all([n, i]).then(([c, u]) => s(c, u))
- : s(n, i);
- }
- : void 0,
- }),
- $s = async (r, e) => {
- let t = r;
- if (e != null && e.filter) {
- const a = r.map((c) => e.filter(c));
- if (a.some((c) => O(c))) {
- const c = await Promise.all(a);
- t = r.filter((u, l) => c[l]);
- } else t = r.filter((c, u) => a[u]);
- }
- if (!(e != null && e.sortBy)) return t;
- const n = t.map((a) => e.sortBy(a)),
- s = n.some((a) => O(a)) ? await Promise.all(n) : n;
- return t
- .map((a, o) => ({ track: a, sortValue: s[o] }))
- .sort((a, o) => {
- const c = Array.isArray(a.sortValue) ? a.sortValue : [a.sortValue],
- u = Array.isArray(o.sortValue) ? o.sortValue : [o.sortValue],
- l = Math.max(c.length, u.length);
- for (let d = 0; d < l; d++) {
- const f = c[d] ?? 0,
- h = u[d] ?? 0;
- if (f !== h) return f - h;
- }
- return 0;
- })
- .map((a) => a.track);
- },
- Kp = (r, e) => {
- const i = 1.000000001,
- s = 1e3,
- a = [
- 12,
- 15,
- 20,
- 24e3 / 1001,
- 24,
- 25,
- 3e4 / 1001,
- 30,
- 48,
- 50,
- 6e4 / 1001,
- 60,
- 100,
- 12e4 / 1001,
- 120,
- 144,
- 240,
- ];
- if (r.length < 2) return null;
- const o = new Float64Array(r.length - 1);
- for (let w = 1; w < r.length; w++) {
- const x = r[w] - r[w - 1];
- if (!(x > 0)) return null;
- o[w - 1] = x;
- }
- const c = o.slice();
- c.sort();
- let u = c[Math.floor(c.length * 0.05)];
- for (let w = 0; w < 6; w++) {
- let x = 0,
- k = 0;
- for (const E of o) {
- const B = Math.max(1, Math.round(E / u));
- Math.abs(E - B * u) >= i || ((x += E), (k += B));
- }
- if (k === 0) return null;
- const S = x / k;
- if (Math.abs(S - u) <= 1e-12 * Math.max(1, u)) {
- u = S;
- break;
- }
- u = S;
- }
- let l = 0,
- d = 0,
- f = 0;
- for (const w of o) {
- const x = Math.max(1, Math.round(w / u));
- Math.abs(w - x * u) >= i || (l++, (d += w), (f += x));
- }
- if (l / o.length < 0.98) return null;
- u = d / f;
- const h = 1 / Math.min(f, s),
- p = Math.max(Number.EPSILON, u - h),
- m = u + h,
- b = e / m,
- g = e / p,
- y = e / u;
- let C = null,
- _ = 1 / 0;
- for (const w of a) {
- if (w < b || w > g) continue;
- const x = Math.abs(w / y - 1);
- x < _ && ((C = w), (_ = x));
- }
- if (C === null) {
- const w = Oc(p, m, 1e6),
- x = Oc(b, g, 1e6);
- if (x && (!w || x.den < w.den || (x.den === w.den && x.num <= w.num)))
- C = x.num / x.den;
- else if (w) C = (e * w.den) / w.num;
- else return null;
- }
- const v = e / C;
- let I = 0;
- for (const w of o) {
- const x = Math.max(1, Math.round(w / v));
- Math.abs(w - x * v) < i && I++;
- }
- return I / o.length < 0.98 ? null : C;
- },
- Oc = (r, e, t) => {
- for (let n = 1; n <= t; n++) {
- const i = Math.floor(r * n) + 1;
- if (i / n < e) return ii({ num: i, den: n });
- }
- return null;
- },
- Xp = (r) => {
- const e = [
- 23.976023976023978, 29.970029970029973, 59.940059940059946,
- 119.88011988011989,
- ],
- t = [12, 15, 20, 24, 25, 30, 48, 50, 60, 100, 120, 144, 240],
- n = 5e-4,
- i = 0.025;
- for (const o of e) if (Math.abs(o / r - 1) <= n) return o;
- let s = r,
- a = 1 / 0;
- for (const o of t) {
- const c = Math.abs(o / r - 1);
- c <= i && c < a && ((s = o), (a = c));
- }
- return s;
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ Ga();
-const Qp = 1,
- Yp = 2;
-class ys extends mi {
- get disposed() {
- return this._disposed;
- }
- constructor(e) {
- if (
- (super(),
- (this._demuxerPromise = null),
- (this._format = null),
- (this._trackBackingsCache = null),
- (this._backingToTrack = new Map()),
- (this._disposed = !1),
- (this._nextSourceCacheAge = 0),
- (this._sourceRefs = []),
- (this._sourceCache = []),
- (this._sourceCachePromises = []),
- (this._onFormatDetermined = null),
- !e || typeof e != "object")
- )
- throw new TypeError("options must be an object.");
- if (!Array.isArray(e.formats) || e.formats.some((t) => !(t instanceof Kt)))
- throw new TypeError("options.formats must be an array of InputFormat.");
- if (!(e.source instanceof dr || e.source instanceof oo))
- throw new TypeError("options.source must be a Source or SourceRef.");
- if (e.source instanceof dr && e.source._disposed)
- throw new TypeError("options.source must not be a disposed Source.");
- if (e.initInput !== void 0 && !(e.initInput instanceof ys))
- throw new TypeError(
- "options.initInput, when provided, must be an Input.",
- );
- (e.formatOptions !== void 0 && wp(e.formatOptions, "formatOptions"),
- (this._formats = e.formats),
- (this._initInput = e.initInput ?? null),
- (this._formatOptions = e.formatOptions ?? {}),
- e.source instanceof dr
- ? (this._rootRef = e.source.ref())
- : (this._rootRef = e.source),
- this._sourceRefs.push(this._rootRef));
- }
- get _rootSource() {
- return this._rootRef.source;
- }
- async _getSourceUncached(e) {
- T(this._rootSource instanceof vn);
- const t = await this._rootSource._resolveRequest(e);
- return (
- this._emit("source", { source: t.source, request: e, isRoot: e.isRoot }),
- t
- );
- }
- _getSourceCached(e, t = Qp) {
- const n = this._sourceCache.find(
- (a) => a.cacheGroup === t && yc(a.request, e),
- );
- if (n) return (n.age++, Promise.resolve(n.sourceRef.source.ref()));
- const i = this._sourceCachePromises.find(
- (a) => a.cacheGroup === t && yc(a.request, e),
- );
- if (i) return i.promise.then((a) => a.sourceRef.source.ref());
- const s = (async () => {
- const a = await this._getSourceUncached(e);
- if (
- qn(
- this._sourceCache,
- (d) => d.cacheGroup === t && d.sourceRef.source._refCount === 1,
- ) >= 4
- ) {
- const d = Ka(this._sourceCache, (h) =>
- h.cacheGroup === t && h.sourceRef.source._refCount === 1
- ? h.age
- : 1 / 0,
- );
- T(d !== -1);
- const f = this._sourceCache[d];
- (this._sourceCache.splice(d, 1),
- f.sourceRef.free(),
- pa(this._sourceRefs, f.sourceRef));
- }
- this._sourceRefs.push(a);
- const u = this._sourceCachePromises.findIndex((d) => d.request === e);
- return (
- T(u !== -1),
- this._sourceCachePromises.splice(u, 1),
- {
- request: e,
- sourceRef: a,
- age: this._nextSourceCacheAge++,
- cacheGroup: t,
- }
- );
- })();
- return (
- this._sourceCachePromises.push({ request: e, cacheGroup: t, promise: s }),
- s.then((a) => {
- const o = a.sourceRef.source.ref();
- return (this._sourceCache.push(a), o);
- })
- );
- }
- _getDemuxer() {
- return (
- this._demuxerPromise ??
- (this._demuxerPromise = (async () => {
- var e;
- ((this._reader = new Oi(this._rootSource)),
- this._emit("source", {
- source: this._rootSource,
- request: null,
- isRoot: !0,
- }));
- for (const t of this._formats)
- if (await t._canReadInput(this))
- return (
- (this._format = t),
- (e = this._onFormatDetermined) == null || e.call(this, t),
- t._createDemuxer(this)
- );
- throw new Dc();
- })())
- );
- }
- get source() {
- return this._rootSource;
- }
- async getFormat() {
- return (await this._getDemuxer(), T(this._format), this._format);
- }
- async canRead() {
- try {
- return (await this._getDemuxer(), !0);
- } catch (e) {
- if (e instanceof Dc) return !1;
- throw e;
- }
- }
- async getFirstTimestamp(e) {
- e ?? (e = await this.getTracks());
- const t = e.filter((s) => s !== null);
- if (t.length === 0) return 0;
- const n = await Promise.all(
- t.map((s) => s._backing.getFirstPacket({ metadataOnly: !0 })),
- ),
- i = Math.min(
- ...n.map((s) => (s == null ? void 0 : s.timestamp) ?? 1 / 0),
- );
- return i === 1 / 0 ? 0 : i;
- }
- async computeDuration(e, t) {
- e ?? (e = await this.getTracks());
- const n = e.filter((s) => s !== null);
- if (n.length === 0) return 0;
- const i = await Promise.all(n.map((s) => s.computeDuration(t)));
- return Math.max(...i);
- }
- async getDurationFromMetadata(e, t) {
- e ?? (e = await this.getTracks());
- const n = e.filter((a) => a !== null),
- s = (
- await Promise.all(n.map((a) => a.getDurationFromMetadata(t)))
- ).filter((a) => a !== null);
- return s.length === 0 ? null : Math.max(...s);
- }
- async getTracks(e) {
- e && (e = Wn(e));
- const n = (await this._getTrackBackings()).map((i) =>
- this._wrapBackingAsTrack(i),
- );
- return $s(n, e);
- }
- async getVideoTracks(e) {
- e && (e = Wn(e));
- const n = (await this.getTracks()).filter((i) => i.isVideoTrack());
- return $s(n, e);
- }
- async getAudioTracks(e) {
- e && (e = Wn(e));
- const n = (await this.getTracks()).filter((i) => i.isAudioTrack());
- return $s(n, e);
- }
- async getPrimaryVideoTrack(e) {
- e && (e = Wn(e));
- const t = Ur(e, {
- sortBy: async (i) => [
- zn((await i.getDisposition()).default),
- zn(await i.hasPairableAudioTrack()),
- zn(!(await i.hasOnlyKeyPackets())),
- Nc(await i.getBitrate()),
- ],
- });
- return (await this.getVideoTracks(t))[0] ?? null;
- }
- async getPrimaryAudioTrack(e) {
- e && (e = Wn(e));
- const t = await this.getPrimaryVideoTrack(),
- n = Ur(e, {
- sortBy: async (s) => [
- zn(!t || s.canBePairedWith(t)),
- zn((await s.getDisposition()).default),
- Nc(await s.getBitrate()),
- ],
- });
- return (await this.getAudioTracks(n))[0] ?? null;
- }
- async _getTrackBackings() {
- const e = await this._getDemuxer();
- return (
- this._trackBackingsCache ??
- (this._trackBackingsCache = await e.getTrackBackings())
- );
- }
- _wrapBackingAsTrack(e) {
- const t = this._backingToTrack.get(e);
- if (t) return t;
- const i = e.getType() === "video" ? new ws(this, e) : new Vu(this, e);
- return (this._backingToTrack.set(e, i), i);
- }
- async getMimeType() {
- return (await this._getDemuxer()).getMimeType();
- }
- async getMetadataTags() {
- return (await this._getDemuxer()).getMetadataTags();
- }
- dispose() {
- if (!this._disposed) {
- this._disposed = !0;
- for (const e of this._sourceRefs) e.free();
- ((this._sourceRefs.length = 0),
- this._demuxerPromise &&
- this._demuxerPromise.then((e) => e.dispose()).catch(() => {}));
- }
- }
- [Symbol.dispose]() {
- this.dispose();
- }
-}
-class Dc extends Error {
- constructor(e = "Input has an unsupported or unrecognizable format.") {
- (super(e), (this.name = "UnsupportedInputFormatError"));
- }
-}
-class rt extends Error {
- constructor(e = "Input has been disposed.") {
- (super(e), (this.name = "InputDisposedError"));
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class Oi {
- constructor(e) {
- this.source = e;
- }
- get fileSize() {
- const e = this.source._getFileSize();
- if (e === void 0)
- throw new Error("Reading file size too early; read required first.");
- return e;
- }
- get fileSizeNonStrict() {
- return this.source._getFileSize() ?? null;
- }
- requestSlice(e, t) {
- if (this.source._disposed) throw new rt();
- if (
- e < 0 ||
- (this.fileSizeNonStrict !== null && e + t > this.fileSizeNonStrict)
- )
- return null;
- if (t === 0) {
- const s = new Uint8Array(0);
- return new yt(s, ge(s), 0, e, e);
- }
- const n = e + t,
- i = this.source._read(e, n, Pu, Cu);
- return O(i)
- ? i.then((s) => (s ? new yt(s.bytes, s.view, s.offset, e, n) : null))
- : i
- ? new yt(i.bytes, i.view, i.offset, e, n)
- : null;
- }
- requestSliceRange(e, t, n) {
- if (this.source._disposed) throw new rt();
- if (e < 0) return null;
- if (this.fileSizeNonStrict !== null)
- return this.requestSlice(e, De(this.fileSizeNonStrict - e, t, n));
- {
- const i = this.requestSlice(e, n),
- s = (a) =>
- a ||
- (T(this.fileSizeNonStrict !== null),
- this.requestSlice(e, De(this.fileSizeNonStrict - e, t, n)));
- return O(i) ? i.then(s) : s(i);
- }
- }
- requestEntireFile() {
- if (this.fileSizeNonStrict !== null)
- return this.requestSlice(0, this.fileSizeNonStrict);
- const e = 1024;
- return (async () => {
- const t = [];
- let n = 0;
- for (;;) {
- if (t.length === 1 && this.fileSizeNonStrict !== null)
- return this.requestSlice(0, this.fileSizeNonStrict);
- let a = this.requestSliceRange(n, 0, e);
- if ((O(a) && (a = await a), !a || a.length === 0)) break;
- const o = Z(a, a.length);
- (t.push(o), (n += a.length));
- }
- const i = new Uint8Array(n);
- let s = 0;
- for (const a of t) (i.set(a, s), (s += a.length));
- return new yt(i, ge(i), 0, 0, n);
- })();
- }
-}
-class yt {
- constructor(e, t, n, i, s) {
- ((this.bytes = e),
- (this.view = t),
- (this.offset = n),
- (this.start = i),
- (this.end = s),
- (this.bufferPos = i - n));
- }
- static tempFromBytes(e) {
- return new yt(e, ge(e), 0, 0, e.length);
- }
- get length() {
- return this.end - this.start;
- }
- get filePos() {
- return this.offset + this.bufferPos;
- }
- set filePos(e) {
- this.bufferPos = e - this.offset;
- }
- get remainingLength() {
- return Math.max(this.end - this.filePos, 0);
- }
- skip(e) {
- this.bufferPos += e;
- }
- slice(e, t = this.end - e) {
- if (e < this.start || e + t > this.end)
- throw new RangeError("Slicing outside of original slice.");
- return new yt(this.bytes, this.view, this.offset, e, e + t);
- }
-}
-const dt = (r, e) => {
- if (r.filePos < r.start || r.filePos + e > r.end)
- throw new RangeError(
- `Tried reading [${r.filePos}, ${r.filePos + e}), but slice is [${r.start}, ${r.end}). This is likely an internal error, please report it alongside the file that caused it.`,
- );
- },
- Z = (r, e) => {
- dt(r, e);
- const t = r.bytes.subarray(r.bufferPos, r.bufferPos + e);
- return ((r.bufferPos += e), t);
- },
- Y = (r) => (dt(r, 1), r.view.getUint8(r.bufferPos++)),
- Un = (r, e) => {
- dt(r, 2);
- const t = r.view.getUint16(r.bufferPos, e);
- return ((r.bufferPos += 2), t);
- },
- Ve = (r) => {
- dt(r, 2);
- const e = r.view.getUint16(r.bufferPos, !1);
- return ((r.bufferPos += 2), e);
- },
- Zt = (r) => {
- dt(r, 3);
- const e = vl(r.view, r.bufferPos);
- return ((r.bufferPos += 3), e);
- },
- Na = (r) => {
- dt(r, 2);
- const e = r.view.getInt16(r.bufferPos, !1);
- return ((r.bufferPos += 2), e);
- },
- Br = (r, e) => {
- dt(r, 4);
- const t = r.view.getUint32(r.bufferPos, e);
- return ((r.bufferPos += 4), t);
- },
- L = (r) => {
- dt(r, 4);
- const e = r.view.getUint32(r.bufferPos, !1);
- return ((r.bufferPos += 4), e);
- },
- ln = (r) => {
- dt(r, 4);
- const e = r.view.getUint32(r.bufferPos, !0);
- return ((r.bufferPos += 4), e);
- },
- Vr = (r) => {
- dt(r, 4);
- const e = r.view.getInt32(r.bufferPos, !1);
- return ((r.bufferPos += 4), e);
- },
- Zp = (r) => {
- dt(r, 4);
- const e = r.view.getInt32(r.bufferPos, !0);
- return ((r.bufferPos += 4), e);
- },
- zc = (r, e) => {
- let t, n;
- return (
- e
- ? ((t = Br(r, !0)), (n = Br(r, !0)))
- : ((n = Br(r, !1)), (t = Br(r, !1))),
- n * 4294967296 + t
- );
- },
- ft = (r) => {
- const e = L(r),
- t = L(r);
- return e * 4294967296 + t;
- },
- Jp = (r) => {
- const e = Vr(r),
- t = L(r);
- return e * 4294967296 + t;
- },
- e0 = (r) => {
- const e = ln(r);
- return Zp(r) * 4294967296 + e;
- },
- t0 = (r) => {
- dt(r, 4);
- const e = r.view.getFloat32(r.bufferPos, !1);
- return ((r.bufferPos += 4), e);
- },
- Lu = (r) => {
- dt(r, 8);
- const e = r.view.getFloat64(r.bufferPos, !1);
- return ((r.bufferPos += 8), e);
- },
- Ne = (r, e) => {
- dt(r, e);
- let t = "";
- for (let n = 0; n < e; n++)
- t += String.fromCharCode(r.bytes[r.bufferPos++]);
- return t;
- },
- qu = (r, e, t) =>
- ot
- .decode(Z(r, e))
- .split(
- `
-`,
- )
- .map((s) => s.trim())
- .filter((s) => {
- var a;
- return (
- s.length > 0 &&
- !((a = t == null ? void 0 : t.ignore) != null && a.call(t, s))
- );
- });
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ var Lr;
-(function (r) {
- ((r[(r.Unsynchronisation = 128)] = "Unsynchronisation"),
- (r[(r.ExtendedHeader = 64)] = "ExtendedHeader"),
- (r[(r.ExperimentalIndicator = 32)] = "ExperimentalIndicator"),
- (r[(r.Footer = 16)] = "Footer"));
-})(Lr || (Lr = {}));
-var un;
-(function (r) {
- ((r[(r.ISO_8859_1 = 0)] = "ISO_8859_1"),
- (r[(r.UTF_16_WITH_BOM = 1)] = "UTF_16_WITH_BOM"),
- (r[(r.UTF_16_BE_NO_BOM = 2)] = "UTF_16_BE_NO_BOM"),
- (r[(r.UTF_8 = 3)] = "UTF_8"));
-})(un || (un = {}));
-const Di = 128,
- Et = 10,
- dn = [
- "Blues",
- "Classic rock",
- "Country",
- "Dance",
- "Disco",
- "Funk",
- "Grunge",
- "Hip-hop",
- "Jazz",
- "Metal",
- "New age",
- "Oldies",
- "Other",
- "Pop",
- "Rhythm and blues",
- "Rap",
- "Reggae",
- "Rock",
- "Techno",
- "Industrial",
- "Alternative",
- "Ska",
- "Death metal",
- "Pranks",
- "Soundtrack",
- "Euro-techno",
- "Ambient",
- "Trip-hop",
- "Vocal",
- "Jazz & funk",
- "Fusion",
- "Trance",
- "Classical",
- "Instrumental",
- "Acid",
- "House",
- "Game",
- "Sound clip",
- "Gospel",
- "Noise",
- "Alternative rock",
- "Bass",
- "Soul",
- "Punk",
- "Space",
- "Meditative",
- "Instrumental pop",
- "Instrumental rock",
- "Ethnic",
- "Gothic",
- "Darkwave",
- "Techno-industrial",
- "Electronic",
- "Pop-folk",
- "Eurodance",
- "Dream",
- "Southern rock",
- "Comedy",
- "Cult",
- "Gangsta",
- "Top 40",
- "Christian rap",
- "Pop/funk",
- "Jungle music",
- "Native US",
- "Cabaret",
- "New wave",
- "Psychedelic",
- "Rave",
- "Showtunes",
- "Trailer",
- "Lo-fi",
- "Tribal",
- "Acid punk",
- "Acid jazz",
- "Polka",
- "Retro",
- "Musical",
- "Rock 'n' roll",
- "Hard rock",
- "Folk",
- "Folk rock",
- "National folk",
- "Swing",
- "Fast fusion",
- "Bebop",
- "Latin",
- "Revival",
- "Celtic",
- "Bluegrass",
- "Avantgarde",
- "Gothic rock",
- "Progressive rock",
- "Psychedelic rock",
- "Symphonic rock",
- "Slow rock",
- "Big band",
- "Chorus",
- "Easy listening",
- "Acoustic",
- "Humour",
- "Speech",
- "Chanson",
- "Opera",
- "Chamber music",
- "Sonata",
- "Symphony",
- "Booty bass",
- "Primus",
- "Porn groove",
- "Satire",
- "Slow jam",
- "Club",
- "Tango",
- "Samba",
- "Folklore",
- "Ballad",
- "Power ballad",
- "Rhythmic Soul",
- "Freestyle",
- "Duet",
- "Punk rock",
- "Drum solo",
- "A cappella",
- "Euro-house",
- "Dance hall",
- "Goa music",
- "Drum & bass",
- "Club-house",
- "Hardcore techno",
- "Terror",
- "Indie",
- "Britpop",
- "Negerpunk",
- "Polsk punk",
- "Beat",
- "Christian gangsta rap",
- "Heavy metal",
- "Black metal",
- "Crossover",
- "Contemporary Christian",
- "Christian rock",
- "Merengue",
- "Salsa",
- "Thrash metal",
- "Anime",
- "Jpop",
- "Synthpop",
- "Christmas",
- "Art rock",
- "Baroque",
- "Bhangra",
- "Big beat",
- "Breakbeat",
- "Chillout",
- "Downtempo",
- "Dub",
- "EBM",
- "Eclectic",
- "Electro",
- "Electroclash",
- "Emo",
- "Experimental",
- "Garage",
- "Global",
- "IDM",
- "Illbient",
- "Industro-Goth",
- "Jam Band",
- "Krautrock",
- "Leftfield",
- "Lounge",
- "Math rock",
- "New romantic",
- "Nu-breakz",
- "Post-punk",
- "Post-rock",
- "Psytrance",
- "Shoegaze",
- "Space rock",
- "Trop rock",
- "World music",
- "Neoclassical",
- "Audiobook",
- "Audio theatre",
- "Neue Deutsche Welle",
- "Podcast",
- "Indie rock",
- "G-Funk",
- "Dubstep",
- "Garage rock",
- "Psybient",
- ],
- r0 = (r, e) => {
- var d;
- const t = r.filePos;
- (e.raw ?? (e.raw = {}),
- (d = e.raw).TAG ?? (d.TAG = Z(r, Di - 3)),
- (r.filePos = t));
- const n = Jr(r, 30);
- n && (e.title ?? (e.title = n));
- const i = Jr(r, 30);
- i && (e.artist ?? (e.artist = i));
- const s = Jr(r, 30);
- s && (e.album ?? (e.album = s));
- const a = Jr(r, 4),
- o = Number.parseInt(a, 10);
- Number.isInteger(o) && o > 0 && (e.date ?? (e.date = new Date(String(o))));
- const c = Z(r, 30);
- let u;
- if (c[28] === 0 && c[29] !== 0) {
- const f = c[29];
- (f > 0 && (e.trackNumber ?? (e.trackNumber = f)),
- r.skip(-30),
- (u = Jr(r, 28)),
- r.skip(2));
- } else (r.skip(-30), (u = Jr(r, 30)));
- u && (e.comment ?? (e.comment = u));
- const l = Y(r);
- l < dn.length && (e.genre ?? (e.genre = dn[l]));
- },
- Jr = (r, e) => {
- const t = Z(r, e),
- n = en(t.indexOf(0), t.length),
- i = t.subarray(0, n);
- let s = "";
- for (let a = 0; a < i.length; a++) s += String.fromCharCode(i[a]);
- return s.trimEnd();
- },
- hr = (r) => {
- const e = r.filePos,
- t = Ne(r, 3),
- n = Y(r),
- i = Y(r),
- s = Y(r),
- a = L(r);
- if (t !== "ID3" || n === 255 || i === 255 || (a & 2155905152) !== 0)
- return ((r.filePos = e), null);
- let o = Pa(a);
- return (
- s & Lr.Footer && (o += Et),
- { majorVersion: n, revision: i, flags: s, size: o }
- );
- },
- ks = (r, e, t) => {
- var a, o, c, u, l;
- if (![2, 3, 4].includes(e.majorVersion)) {
- te._warn(`Unsupported ID3v2 major version: ${e.majorVersion}`);
- return;
- }
- const n = e.flags & Lr.Footer ? e.size - Et : e.size,
- i = Z(r, n),
- s = new n0(e, i);
- if (
- (e.flags & Lr.Unsynchronisation &&
- e.majorVersion === 3 &&
- s.ununsynchronizeAll(),
- e.flags & Lr.ExtendedHeader)
- ) {
- const d = s.readU32();
- e.majorVersion === 3 ? (s.pos += d) : (s.pos += d - 4);
- }
- for (; s.pos <= s.bytes.length - s.frameHeaderSize();) {
- const d = s.readId3V2Frame();
- if (!d) break;
- const f = s.pos,
- h = s.pos + d.size;
- let p = !1,
- m = !1,
- b = !1;
- if (
- (e.majorVersion === 3
- ? ((p = !!(d.flags & 64)), (m = !!(d.flags & 128)))
- : e.majorVersion === 4 &&
- ((p = !!(d.flags & 4)),
- (m = !!(d.flags & 8)),
- (b = !!(d.flags & 2) || !!(e.flags & Lr.Unsynchronisation))),
- p)
- ) {
- (te._warn(`Skipping encrypted ID3v2 frame ${d.id}`), (s.pos = h));
- continue;
- }
- if (m) {
- (te._warn(`Skipping compressed ID3v2 frame ${d.id}`), (s.pos = h));
- continue;
- }
- if (
- (b && s.ununsynchronizeRegion(s.pos, h),
- t.raw ?? (t.raw = {}),
- d.id === "TXXX")
- ) {
- const g = (a = t.raw).TXXX ?? (a.TXXX = {}),
- y = s.readId3V2TextEncoding(),
- C = s.readId3V2Text(y, h),
- _ = s.readId3V2Text(y, h);
- g[C] ?? (g[C] = _);
- } else
- d.id[0] === "T"
- ? ((o = t.raw)[(c = d.id)] ?? (o[c] = s.readId3V2EncodingAndText(h)))
- : ((u = t.raw)[(l = d.id)] ?? (u[l] = s.readBytes(d.size)));
- switch (((s.pos = f), d.id)) {
- case "TIT2":
- case "TT2":
- t.title ?? (t.title = s.readId3V2EncodingAndText(h));
- break;
- case "TIT3":
- case "TT3":
- t.description ?? (t.description = s.readId3V2EncodingAndText(h));
- break;
- case "TPE1":
- case "TP1":
- t.artist ?? (t.artist = s.readId3V2EncodingAndText(h));
- break;
- case "TALB":
- case "TAL":
- t.album ?? (t.album = s.readId3V2EncodingAndText(h));
- break;
- case "TPE2":
- case "TP2":
- t.albumArtist ?? (t.albumArtist = s.readId3V2EncodingAndText(h));
- break;
- case "TRCK":
- case "TRK":
- {
- const y = s.readId3V2EncodingAndText(h).split("/"),
- C = Number.parseInt(y[0], 10),
- _ = y[1] && Number.parseInt(y[1], 10);
- (Number.isInteger(C) &&
- C > 0 &&
- (t.trackNumber ?? (t.trackNumber = C)),
- _ &&
- Number.isInteger(_) &&
- _ > 0 &&
- (t.tracksTotal ?? (t.tracksTotal = _)));
- }
- break;
- case "TPOS":
- case "TPA":
- {
- const y = s.readId3V2EncodingAndText(h).split("/"),
- C = Number.parseInt(y[0], 10),
- _ = y[1] && Number.parseInt(y[1], 10);
- (Number.isInteger(C) &&
- C > 0 &&
- (t.discNumber ?? (t.discNumber = C)),
- _ &&
- Number.isInteger(_) &&
- _ > 0 &&
- (t.discsTotal ?? (t.discsTotal = _)));
- }
- break;
- case "TCON":
- case "TCO":
- {
- const g = s.readId3V2EncodingAndText(h);
- let y = /^\((\d+)\)/.exec(g);
- if (y) {
- const C = Number.parseInt(y[1]);
- if (dn[C] !== void 0) {
- t.genre ?? (t.genre = dn[C]);
- break;
- }
- }
- if (((y = /^\d+$/.exec(g)), y)) {
- const C = Number.parseInt(y[0]);
- if (dn[C] !== void 0) {
- t.genre ?? (t.genre = dn[C]);
- break;
- }
- }
- t.genre ?? (t.genre = g);
- }
- break;
- case "TDRC":
- case "TDAT":
- {
- const g = s.readId3V2EncodingAndText(h),
- y = new Date(g);
- Number.isNaN(y.getTime()) || (t.date ?? (t.date = y));
- }
- break;
- case "TYER":
- case "TYE":
- {
- const g = s.readId3V2EncodingAndText(h),
- y = Number.parseInt(g, 10);
- Number.isInteger(y) && (t.date ?? (t.date = new Date(String(y))));
- }
- break;
- case "TBPM":
- case "TBP":
- {
- const g = s.readId3V2EncodingAndText(h),
- y = Number.parseInt(g, 10);
- Number.isInteger(y) && (t.beatsPerMinute ?? (t.beatsPerMinute = y));
- }
- break;
- case "USLT":
- case "ULT":
- {
- const g = s.readU8();
- ((s.pos += 3),
- s.readId3V2Text(g, h),
- t.lyrics ?? (t.lyrics = s.readId3V2Text(g, h)));
- }
- break;
- case "COMM":
- case "COM":
- {
- const g = s.readU8();
- ((s.pos += 3),
- s.readId3V2Text(g, h),
- t.comment ?? (t.comment = s.readId3V2Text(g, h)));
- }
- break;
- case "APIC":
- case "PIC":
- {
- const g = s.readId3V2TextEncoding();
- let y;
- if (e.majorVersion === 2) {
- const I = s.readAscii(3);
- y =
- I === "PNG"
- ? "image/png"
- : I === "JPG"
- ? "image/jpeg"
- : "image/*";
- } else y = s.readId3V2Text(g, h);
- const C = s.readU8(),
- _ = s.readId3V2Text(g, h).trimEnd(),
- v = h - s.pos;
- if (v >= 0) {
- const I = s.readBytes(v);
- (t.images || (t.images = []),
- t.images.push({
- data: I,
- mimeType: y,
- kind:
- C === 3 ? "coverFront" : C === 4 ? "coverBack" : "unknown",
- description: _,
- }));
- }
- }
- break;
- default:
- s.pos += d.size;
- break;
- }
- s.pos = h;
- }
- };
-class n0 {
- constructor(e, t) {
- ((this.header = e),
- (this.bytes = t),
- (this.pos = 0),
- (this.view = new DataView(t.buffer, t.byteOffset, t.byteLength)));
- }
- frameHeaderSize() {
- return this.header.majorVersion === 2 ? 6 : 10;
- }
- ununsynchronizeAll() {
- const e = [];
- for (let t = 0; t < this.bytes.length; t++) {
- const n = this.bytes[t];
- (e.push(n),
- n === 255 && t !== this.bytes.length - 1 && this.bytes[t] === 0 && t++);
- }
- ((this.bytes = new Uint8Array(e)),
- (this.view = new DataView(this.bytes.buffer)));
- }
- ununsynchronizeRegion(e, t) {
- const n = [];
- for (let a = e; a < t; a++) {
- const o = this.bytes[a];
- (n.push(o), o === 255 && a !== t - 1 && this.bytes[a + 1] === 0 && a++);
- }
- const i = this.bytes.subarray(0, e),
- s = this.bytes.subarray(t);
- ((this.bytes = new Uint8Array(i.length + n.length + s.length)),
- this.bytes.set(i, 0),
- this.bytes.set(n, i.length),
- this.bytes.set(s, i.length + n.length),
- (this.view = new DataView(this.bytes.buffer)));
- }
- readBytes(e) {
- const t = this.bytes.subarray(this.pos, this.pos + e);
- return ((this.pos += e), t);
- }
- readU8() {
- const e = this.view.getUint8(this.pos);
- return ((this.pos += 1), e);
- }
- readU16() {
- const e = this.view.getUint16(this.pos, !1);
- return ((this.pos += 2), e);
- }
- readU24() {
- const e = this.view.getUint16(this.pos, !1),
- t = this.view.getUint8(this.pos + 2);
- return ((this.pos += 3), e * 256 + t);
- }
- readU32() {
- const e = this.view.getUint32(this.pos, !1);
- return ((this.pos += 4), e);
- }
- readAscii(e) {
- let t = "";
- for (let n = 0; n < e; n++)
- t += String.fromCharCode(this.view.getUint8(this.pos + n));
- return ((this.pos += e), t);
- }
- readId3V2Frame() {
- if (this.header.majorVersion === 2) {
- const e = this.readAscii(3);
- if (e === "\0\0\0") return null;
- const t = this.readU24();
- return { id: e, size: t, flags: 0 };
- } else {
- const e = this.readAscii(4);
- if (e === "\0\0\0\0") return null;
- const t = this.readU32();
- let n = this.header.majorVersion === 4 ? Pa(t) : t;
- const i = this.readU16(),
- s = this.pos,
- a = (o) => {
- const c = this.pos + o;
- if (c > this.bytes.length) return !1;
- if (c <= this.bytes.length - this.frameHeaderSize()) {
- this.pos += o;
- const u = this.readAscii(4);
- if (u !== "\0\0\0\0" && !/[0-9A-Z]{4}/.test(u)) return !1;
- }
- return !0;
- };
- if (!a(n)) {
- const o = this.header.majorVersion === 4 ? t : Pa(t);
- a(o) && (n = o);
- }
- return ((this.pos = s), { id: e, size: n, flags: i });
- }
- }
- readId3V2TextEncoding() {
- const e = this.readU8();
- if (e > 3) throw new Error(`Unsupported text encoding: ${e}`);
- return e;
- }
- readId3V2Text(e, t) {
- const n = this.pos,
- i = this.readBytes(t - this.pos);
- switch (e) {
- case un.ISO_8859_1: {
- let s = "";
- for (let a = 0; a < i.length; a++) {
- const o = i[a];
- if (o === 0) {
- this.pos = n + a + 1;
- break;
- }
- s += String.fromCharCode(o);
- }
- return s;
- }
- case un.UTF_16_WITH_BOM:
- if (i[0] === 255 && i[1] === 254) {
- const s = new Kn("utf-16le"),
- a = en(
- i.findIndex((o, c) => o === 0 && i[c + 1] === 0 && c % 2 === 0),
- i.length,
- );
- return (
- (this.pos = n + Math.min(a + 2, i.length)),
- s.decode(i.subarray(2, a))
- );
- } else if (i[0] === 254 && i[1] === 255) {
- const s = new Kn("utf-16be"),
- a = en(
- i.findIndex((o, c) => o === 0 && i[c + 1] === 0 && c % 2 === 0),
- i.length,
- );
- return (
- (this.pos = n + Math.min(a + 2, i.length)),
- s.decode(i.subarray(2, a))
- );
- } else {
- const s = en(
- i.findIndex((a) => a === 0),
- i.length,
- );
- return (
- (this.pos = n + Math.min(s + 1, i.length)),
- ot.decode(i.subarray(0, s))
- );
- }
- case un.UTF_16_BE_NO_BOM: {
- const s = new Kn("utf-16be"),
- a = en(
- i.findIndex((o, c) => o === 0 && i[c + 1] === 0 && c % 2 === 0),
- i.length,
- );
- return (
- (this.pos = n + Math.min(a + 2, i.length)),
- s.decode(i.subarray(0, a))
- );
- }
- case un.UTF_8: {
- const s = en(
- i.findIndex((a) => a === 0),
- i.length,
- );
- return (
- (this.pos = n + Math.min(s + 1, i.length)),
- ot.decode(i.subarray(0, s))
- );
- }
- }
- }
- readId3V2EncodingAndText(e) {
- if (this.pos >= e) return "";
- const t = this.readId3V2TextEncoding();
- return this.readId3V2Text(t, e);
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class i0 {
- constructor(e) {
- ((this.mutex = new Cn()),
- (this.trackTimestampInfo = new WeakMap()),
- (this.output = e));
- }
- onTrackClose(e) {}
- validateTimestamp(e, t, n) {
- let i = this.trackTimestampInfo.get(e);
- if (i) {
- if (
- (n && (i.maxTimestampBeforeLastKeyPacket = i.maxTimestamp),
- i.maxTimestampBeforeLastKeyPacket !== null &&
- t < i.maxTimestampBeforeLastKeyPacket)
- )
- throw new Error(
- `Timestamps cannot be smaller than the largest timestamp of the previous GOP (a GOP begins with a key packet and ends right before the next key packet). Got ${t}s, but largest timestamp is ${i.maxTimestampBeforeLastKeyPacket}s.`,
- );
- i.maxTimestamp = Math.max(i.maxTimestamp, t);
- } else {
- if (!n) throw new Error("First packet must be a key packet.");
- ((i = { maxTimestamp: t, maxTimestampBeforeLastKeyPacket: null }),
- this.trackTimestampInfo.set(e, i));
- }
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const Wc = /<(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})>/g,
- s0 = (r) => {
- const e = Math.floor(r / 36e5),
- t = Math.floor((r % (3600 * 1e3)) / (60 * 1e3)),
- n = Math.floor((r % (60 * 1e3)) / 1e3),
- i = r % 1e3;
- return (
- e.toString().padStart(2, "0") +
- ":" +
- t.toString().padStart(2, "0") +
- ":" +
- n.toString().padStart(2, "0") +
- "." +
- i.toString().padStart(3, "0")
- );
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class Ei {
- constructor(e) {
- ((this.writer = e),
- (this.helper = new Uint8Array(8)),
- (this.helperView = new DataView(this.helper.buffer)),
- (this.offsets = new WeakMap()));
- }
- writeU32(e) {
- (this.helperView.setUint32(0, e, !1),
- this.writer.write(this.helper.subarray(0, 4)));
- }
- writeU64(e) {
- (this.helperView.setUint32(0, Math.floor(e / 2 ** 32), !1),
- this.helperView.setUint32(4, e, !1),
- this.writer.write(this.helper.subarray(0, 8)));
- }
- writeAscii(e) {
- for (let t = 0; t < e.length; t++)
- (this.helperView.setUint8(t % 8, e.charCodeAt(t)),
- t % 8 === 7 && this.writer.write(this.helper));
- e.length % 8 !== 0 &&
- this.writer.write(this.helper.subarray(0, e.length % 8));
- }
- writeBox(e) {
- if ((this.offsets.set(e, this.writer.getPos()), e.contents && !e.children))
- (this.writeBoxHeader(e, e.size ?? e.contents.byteLength + 8),
- this.writer.write(e.contents));
- else {
- const t = this.writer.getPos();
- if (
- (this.writeBoxHeader(e, 0),
- e.contents && this.writer.write(e.contents),
- e.children)
- )
- for (const s of e.children) s && this.writeBox(s);
- const n = this.writer.getPos(),
- i = e.size ?? n - t;
- (this.writer.seek(t), this.writeBoxHeader(e, i), this.writer.seek(n));
- }
- }
- writeBoxHeader(e, t) {
- (this.writeU32(e.largeSize ? 1 : t),
- this.writeAscii(e.type),
- e.largeSize && this.writeU64(t));
- }
- measureBoxHeader(e) {
- return 8 + (e.largeSize ? 8 : 0);
- }
- patchBox(e) {
- const t = this.offsets.get(e);
- T(t !== void 0);
- const n = this.writer.getPos();
- (this.writer.seek(t), this.writeBox(e), this.writer.seek(n));
- }
- measureBox(e) {
- if (e.contents && !e.children)
- return this.measureBoxHeader(e) + e.contents.byteLength;
- {
- let t = this.measureBoxHeader(e);
- if ((e.contents && (t += e.contents.byteLength), e.children))
- for (const n of e.children) n && (t += this.measureBox(n));
- return t;
- }
- }
-}
-const de = new Uint8Array(8),
- It = new DataView(de.buffer),
- Me = (r) => [((r % 256) + 256) % 256],
- ne = (r) => (It.setUint16(0, r, !1), [de[0], de[1]]),
- uo = (r) => (It.setInt16(0, r, !1), [de[0], de[1]]),
- ju = (r) => (It.setUint32(0, r, !1), [de[1], de[2], de[3]]),
- H = (r) => (It.setUint32(0, r, !1), [de[0], de[1], de[2], de[3]]),
- qt = (r) => (It.setInt32(0, r, !1), [de[0], de[1], de[2], de[3]]),
- Mt = (r) => (
- It.setUint32(0, Math.floor(r / 2 ** 32), !1),
- It.setUint32(4, r, !1),
- [de[0], de[1], de[2], de[3], de[4], de[5], de[6], de[7]]
- ),
- Uc = (r) => (
- It.setInt32(0, Math.floor(r / 2 ** 32), !1),
- It.setUint32(4, r, !1),
- [de[0], de[1], de[2], de[3], de[4], de[5], de[6], de[7]]
- ),
- $u = (r) => (It.setInt16(0, 2 ** 8 * r, !1), [de[0], de[1]]),
- Ct = (r) => (It.setInt32(0, 2 ** 16 * r, !1), [de[0], de[1], de[2], de[3]]),
- Gs = (r) => (It.setInt32(0, 2 ** 30 * r, !1), [de[0], de[1], de[2], de[3]]),
- Ks = (r, e) => {
- const t = [];
- let n = r;
- do {
- let i = n & 127;
- ((n >>= 7), t.length > 0 && (i |= 128), t.push(i));
- } while (n > 0 || e);
- return t.reverse();
- },
- Pe = (r, e = !1) => {
- const t = Array(r.length)
- .fill(null)
- .map((n, i) => r.charCodeAt(i));
- return (e && t.push(0), t);
- },
- Gu = (r) => [
- Ct(r[0]),
- Ct(r[1]),
- Gs(r[2]),
- Ct(r[3]),
- Ct(r[4]),
- Gs(r[5]),
- Ct(r[6]),
- Ct(r[7]),
- Gs(r[8]),
- ],
- ee = (r, e, t) => ({
- type: r,
- contents: e && new Uint8Array(e.flat(10)),
- children: t,
- }),
- Te = (r, e, t, n, i) => ee(r, [Me(e), ju(t), n ?? []], i),
- a0 = (r) =>
- r.isQuickTime
- ? ee("ftyp", [Pe("qt "), H(512), Pe("qt ")])
- : r.fragmented
- ? r.cmaf
- ? ee("ftyp", [
- Pe("iso5"),
- H(512),
- Pe("iso5"),
- Pe("iso6"),
- Pe("mp41"),
- Pe("cmfc"),
- Pe("dash"),
- ])
- : ee("ftyp", [Pe("iso5"), H(512), Pe("iso5"), Pe("iso6"), Pe("mp41")])
- : ee("ftyp", [
- Pe("isom"),
- H(512),
- Pe("isom"),
- r.holdsAvc ? Pe("avc1") : [],
- Pe("mp41"),
- ]),
- Hc = () =>
- ee("styp", [
- Pe("iso5"),
- H(0),
- Pe("iso5"),
- Pe("iso6"),
- Pe("mp41"),
- Pe("cmfc"),
- Pe("dash"),
- ]),
- Vc = (r, e) => {
- const t = Math.max(0, r.minWrittenTimestamp);
- let n = Math.max(0, r.maxWrittenEndTimestamp - t);
- return (
- Number.isFinite(n) || (n = 0),
- Te("sidx", 1, 0, [
- H(1),
- H(kt),
- Mt(ve(t, kt)),
- Mt(0),
- ne(0),
- ne(1),
- H(e & 2147483647),
- H(ve(n, kt)),
- H(0),
- ])
- );
- },
- Ii = (r) => ({ type: "mdat", largeSize: r }),
- o0 = (r) => ({ type: "free", size: r }),
- Hn = (r) =>
- ee("moov", void 0, [
- c0(r.creationTime, r.trackDatas),
- ...r.trackDatas.map((e) => l0(e, r.creationTime)),
- r.isFragmented ? X0(r.trackDatas) : null,
- cg(r),
- ]),
- c0 = (r, e) => {
- const t = Math.max(
- 0,
- ...e.map((a) =>
- Math.max(0, ve(yn(a), kt) + ve(a.startTimestampOffset ?? 0, kt)),
- ),
- ),
- n = Math.max(0, ...e.map((a) => a.track.id)) + 1,
- i = !lr(r) || !lr(t),
- s = i ? Mt : H;
- return Te("mvhd", +i, 0, [
- s(r),
- s(r),
- H(kt),
- s(t),
- Ct(1),
- $u(1),
- Array(10).fill(0),
- Gu(ei),
- Array(24).fill(0),
- H(n),
- ]);
- },
- l0 = (r, e) => {
- const t = wg(r),
- n = r.startTimestampOffset !== null && r.startTimestampOffset !== 0;
- return ee("trak", void 0, [
- u0(r, e),
- n ? d0(r) : null,
- f0(r, e),
- t.name !== void 0
- ? ee("udta", void 0, [ee("name", [...jt.encode(t.name)])])
- : null,
- ]);
- },
- u0 = (r, e) => {
- var c;
- const t = Math.max(0, ve(yn(r), kt) + ve(r.startTimestampOffset ?? 0, kt)),
- n = !lr(e) || !lr(t),
- i = n ? Mt : H;
- let s;
- if (r.type === "video" && r.track.metadata.transformationMatrix)
- s = r.track.metadata.transformationMatrix;
- else if (r.type === "video") {
- const { rotation: u, flip: l } = r.track.metadata,
- d = ti(xl(u ?? 0), Sl(l ? -1 : 1, 1));
- s = kl(d, r.info.width, r.info.height);
- } else s = ei;
- let a = 2;
- ((c = r.track.metadata.disposition) == null ? void 0 : c.default) !== !1 &&
- (a |= 1);
- const o =
- r.type === "video"
- ? 0
- : r.type === "audio"
- ? 1
- : r.type === "subtitle"
- ? 2
- : pr(r);
- return Te("tkhd", +n, a, [
- i(e),
- i(e),
- H(r.track.id),
- H(0),
- i(t),
- Array(8).fill(0),
- ne(0),
- ne(o),
- $u(r.type === "audio" ? 1 : 0),
- ne(0),
- Gu(s),
- Ct(r.type === "video" ? r.info.width : 0),
- Ct(r.type === "video" ? r.info.height : 0),
- ]);
- },
- d0 = (r) => {
- const e = r.startTimestampOffset;
- if ((T(e !== null), e > 0)) {
- const t = ve(e, kt),
- n = ve(yn(r), kt),
- i = !lr(t) || !lr(n),
- s = i ? Mt : H,
- a = i ? Uc : qt;
- return ee("edts", void 0, [
- Te("elst", i ? 1 : 0, 0, [H(2), s(t), a(-1), Ct(1), s(n), a(0), Ct(1)]),
- ]);
- } else {
- const t = ve(-e, r.timescale),
- n = Math.max(0, ve(yn(r), kt) + ve(e, kt)),
- i = !If(t) || !lr(n),
- s = i ? Mt : H,
- a = i ? Uc : qt;
- return ee("edts", void 0, [
- Te("elst", i ? 1 : 0, 0, [H(1), s(n), a(t), Ct(1)]),
- ]);
- }
- },
- f0 = (r, e) =>
- ee("mdia", void 0, [h0(r, e), fo(!0, m0[r.type], p0[r.type]), g0(r)]),
- h0 = (r, e) => {
- const t = ve(yn(r), r.timescale),
- n = !lr(e) || !lr(t),
- i = n ? Mt : H;
- return Te("mdhd", +n, 0, [
- i(e),
- i(e),
- H(r.timescale),
- i(t),
- ne(Yu(r.track.metadata.languageCode ?? nt)),
- ne(0),
- ]);
- },
- m0 = { video: "vide", audio: "soun", subtitle: "text" },
- p0 = {
- video: "MediabunnyVideoHandler",
- audio: "MediabunnySoundHandler",
- subtitle: "MediabunnyTextHandler",
- },
- fo = (r, e, t, n = "\0\0\0\0") =>
- Te("hdlr", 0, 0, [
- r ? Pe("mhlr") : H(0),
- Pe(e),
- Pe(n),
- H(0),
- H(0),
- Pe(t, !0),
- ]),
- g0 = (r) => ee("minf", void 0, [k0[r.type](), T0(), P0(r)]),
- b0 = () => Te("vmhd", 0, 1, [ne(0), ne(0), ne(0), ne(0)]),
- w0 = () => Te("smhd", 0, 0, [ne(0), ne(0)]),
- y0 = () => Te("nmhd", 0, 0),
- k0 = { video: b0, audio: w0, subtitle: y0 },
- T0 = () => ee("dinf", void 0, [x0()]),
- x0 = () => Te("dref", 0, 0, [H(1)], [S0()]),
- S0 = () => Te("url ", 0, 1),
- P0 = (r) => {
- const e =
- r.compositionTimeOffsetTable.length > 1 ||
- r.compositionTimeOffsetTable.some(
- (t) => t.sampleCompositionTimeOffset !== 0,
- );
- return ee("stbl", void 0, [
- C0(r),
- V0(r),
- e ? G0(r) : null,
- e ? K0(r) : null,
- q0(r),
- j0(r),
- $0(r),
- L0(r),
- ]);
- },
- C0 = (r) => {
- let e;
- if (r.type === "video")
- e = v0(fg(r.track.source._codec, r.info.decoderConfig.codec), r);
- else if (r.type === "audio") {
- const t = Qu(
- r.track.source._codec,
- r.info.decoderConfig.codec,
- r.muxer.isQuickTime,
- );
- (T(t), (e = F0(t, r)));
- } else r.type === "subtitle" && (e = U0(mg[r.track.source._codec], r));
- return (T(e), Te("stsd", 0, 0, [H(1)], [e]));
- },
- v0 = (r, e) => {
- var t;
- return ee(
- r,
- [
- Array(6).fill(0),
- ne(1),
- ne(0),
- ne(0),
- Array(12).fill(0),
- ne(e.info.width),
- ne(e.info.height),
- H(4718592),
- H(4718592),
- H(0),
- ne(1),
- Me(Rs.length),
- Pe(Rs),
- Array(31 - Rs.length).fill(0),
- ne(e.info.hasAlphaChannel ? 32 : 24),
- uo(65535),
- ],
- [
- ((t = Qs[e.track.source._codec]) == null ? void 0 : t.call(Qs, e)) ??
- null,
- E0(e),
- Af(e.info.decoderConfig.colorSpace) ? null : I0(e),
- ho(e),
- ],
- );
- },
- ho = (r) =>
- r.avgBitrate === 0 && r.maxBitrate === 0
- ? null
- : ee("btrt", [H(0), H(r.maxBitrate), H(r.avgBitrate)]),
- E0 = (r) =>
- r.info.pixelAspectRatio.num === r.info.pixelAspectRatio.den
- ? null
- : ee("pasp", [
- H(r.info.pixelAspectRatio.num),
- H(r.info.pixelAspectRatio.den),
- ]),
- I0 = (r) => {
- const e = r.info.decoderConfig.colorSpace;
- return ee("colr", [
- Pe(r.muxer.isQuickTime ? "nclc" : "nclx"),
- ne((e == null ? void 0 : e.primaries) != null ? xn[e.primaries] : 2),
- ne((e == null ? void 0 : e.transfer) != null ? Sn[e.transfer] : 2),
- ne((e == null ? void 0 : e.matrix) != null ? Pn[e.matrix] : 2),
- r.muxer.isQuickTime ? [] : Me((e != null && e.fullRange ? 1 : 0) << 7),
- ]);
- },
- _0 = (r) =>
- r.info.decoderConfig &&
- ee("avcC", [...Ze(r.info.decoderConfig.description)]),
- A0 = (r) =>
- r.info.decoderConfig &&
- ee("hvcC", [...Ze(r.info.decoderConfig.description)]),
- Lc = (r) => {
- var f, h, p, m;
- if (!r.info.decoderConfig) return null;
- const e = r.info.decoderConfig,
- t = e.codec.split("."),
- n = Number(t[1]),
- i = Number(t[2]),
- s = Number(t[3]),
- a = t[4] ? Number(t[4]) : 1,
- o = t[8]
- ? Number(t[8])
- : Number(((f = e.colorSpace) == null ? void 0 : f.fullRange) ?? 0),
- c = (s << 4) + (a << 1) + o,
- u = t[5]
- ? Number(t[5])
- : (h = e.colorSpace) != null && h.primaries
- ? xn[e.colorSpace.primaries]
- : 1,
- l = t[6]
- ? Number(t[6])
- : (p = e.colorSpace) != null && p.transfer
- ? Sn[e.colorSpace.transfer]
- : 1,
- d = t[7]
- ? Number(t[7])
- : (m = e.colorSpace) != null && m.matrix
- ? Pn[e.colorSpace.matrix]
- : 1;
- return Te("vpcC", 1, 0, [Me(n), Me(i), Me(c), Me(u), Me(l), Me(d), ne(0)]);
- },
- B0 = (r) => ee("av1C", _h(r.info.decoderConfig.codec)),
- F0 = (r, e) => {
- var a;
- let t = 0,
- n,
- i = 16;
- const s = ut.includes(e.track.source._codec);
- if (s) {
- const o = e.track.source._codec,
- { sampleSize: c } = Rr(o);
- ((i = 8 * c), i > 16 && (t = 1));
- }
- if ((e.muxer.isQuickTime && (t = 1), t === 0))
- n = [
- Array(6).fill(0),
- ne(1),
- ne(t),
- ne(0),
- H(0),
- ne(e.info.numberOfChannels),
- ne(i),
- ne(0),
- ne(0),
- ne(e.info.sampleRate < 2 ** 16 ? e.info.sampleRate : 0),
- ne(0),
- ];
- else {
- const o = s ? 0 : -2;
- n = [
- Array(6).fill(0),
- ne(1),
- ne(t),
- ne(0),
- H(0),
- ne(e.info.numberOfChannels),
- ne(Math.min(i, 16)),
- uo(o),
- ne(0),
- ne(e.info.sampleRate < 2 ** 16 ? e.info.sampleRate : 0),
- ne(0),
- s
- ? [H(1), H(i / 8), H((e.info.numberOfChannels * i) / 8)]
- : [H(0), H(0), H(0)],
- H(2),
- ];
- }
- return ee(r, n, [
- ((a = hg(e.track.source._codec, e.muxer.isQuickTime)) == null
- ? void 0
- : a(e)) ?? null,
- ho(e),
- ]);
- },
- Xs = (r) => {
- let e;
- switch (r.track.source._codec) {
- case "aac":
- e = 64;
- break;
- case "mp3":
- e = 107;
- break;
- case "vorbis":
- e = 221;
- break;
- default:
- throw new Error(`Unhandled audio codec: ${r.track.source._codec}`);
- }
- let t = [
- ...Me(e),
- ...Me(21),
- ...ju(0),
- ...H(r.maxBitrate),
- ...H(r.avgBitrate),
- ];
- if (r.info.decoderConfig.description) {
- const n = Ze(r.info.decoderConfig.description);
- t = [...t, ...Me(5), ...Ks(n.byteLength), ...n];
- }
- return (
- (t = [
- ...ne(1),
- ...Me(0),
- ...Me(4),
- ...Ks(t.length),
- ...t,
- ...Me(6),
- ...Me(1),
- ...Me(2),
- ]),
- (t = [...Me(3), ...Ks(t.length), ...t]),
- Te("esds", 0, 0, t)
- );
- },
- Sr = (r) => ee("wave", void 0, [R0(r), M0(r), ee("\0\0\0\0")]),
- R0 = (r) =>
- ee("frma", [
- Pe(
- Qu(
- r.track.source._codec,
- r.info.decoderConfig.codec,
- r.muxer.isQuickTime,
- ),
- ),
- ]),
- M0 = (r) => {
- const { littleEndian: e } = Rr(r.track.source._codec);
- return ee("enda", [ne(+e)]);
- },
- N0 = (r) => {
- var c;
- let e = r.info.numberOfChannels,
- t = 3840,
- n = r.info.sampleRate,
- i = 0,
- s = 0,
- a = new Uint8Array(0);
- const o = (c = r.info.decoderConfig) == null ? void 0 : c.description;
- if (o) {
- T(o.byteLength >= 18);
- const u = Ze(o),
- l = Hl(u);
- ((e = l.outputChannelCount),
- (t = l.preSkip),
- (n = l.inputSampleRate),
- (i = l.outputGain),
- (s = l.channelMappingFamily),
- l.channelMappingTable && (a = l.channelMappingTable));
- }
- return ee("dOps", [Me(0), Me(e), ne(t), H(n), uo(i), Me(s), ...a]);
- },
- O0 = (r) => {
- var n;
- const e = (n = r.info.decoderConfig) == null ? void 0 : n.description;
- T(e);
- const t = Ze(e);
- return Te("dfLa", 0, 0, [...t.subarray(4)]);
- },
- zt = (r) => {
- const { littleEndian: e, sampleSize: t } = Rr(r.track.source._codec),
- n = +e;
- return Te("pcmC", 0, 0, [Me(n), Me(8 * t)]);
- },
- D0 = (r) => {
- T(r.info.primingPacket);
- const e = Vl(r.info.primingPacket.data);
- if (!e)
- throw new Error(
- "Couldn't extract AC-3 frame info from the audio packet. Ensure the packets contain valid AC-3 sync frames (as specified in ETSI TS 102 366).",
- );
- const t = new Uint8Array(3),
- n = new pe(t);
- return (
- n.writeBits(2, e.fscod),
- n.writeBits(5, e.bsid),
- n.writeBits(3, e.bsmod),
- n.writeBits(3, e.acmod),
- n.writeBits(1, e.lfeon),
- n.writeBits(5, e.bitRateCode),
- n.writeBits(5, 0),
- ee("dac3", [...t])
- );
- },
- z0 = (r) => {
- T(r.info.primingPacket);
- const e = ql(r.info.primingPacket.data);
- if (!e)
- throw new Error(
- "Couldn't extract E-AC-3 frame info from the audio packet. Ensure the packets contain valid E-AC-3 sync frames (as specified in ETSI TS 102 366).",
- );
- let t = 16;
- for (const a of e.substreams)
- ((t += 23), a.numDepSub > 0 ? (t += 9) : (t += 1));
- const n = Math.ceil(t / 8),
- i = new Uint8Array(n),
- s = new pe(i);
- (s.writeBits(13, e.dataRate), s.writeBits(3, e.substreams.length - 1));
- for (const a of e.substreams)
- (s.writeBits(2, a.fscod),
- s.writeBits(5, a.bsid),
- s.writeBits(1, 0),
- s.writeBits(1, 0),
- s.writeBits(3, a.bsmod),
- s.writeBits(3, a.acmod),
- s.writeBits(1, a.lfeon),
- s.writeBits(3, 0),
- s.writeBits(4, a.numDepSub),
- a.numDepSub > 0 ? s.writeBits(9, a.chanLoc) : s.writeBits(1, 0));
- return ee("dec3", [...i]);
- },
- W0 = (r) => {
- T(r.info.primingPacket);
- const e = to(r.info.primingPacket.data);
- if (!e)
- throw new Error(
- "Couldn't extract DTS frame info from the audio packet. Ensure the packets contain valid DTS frames as specified in ETSI TS 102 114.",
- );
- return ee("ddts", [...Ch(e)]);
- },
- U0 = (r, e) =>
- ee(r, [Array(6).fill(0), ne(1)], [pg[e.track.source._codec](e), ho(e)]),
- H0 = (r) => ee("vttC", [...jt.encode(r.info.config.description)]),
- V0 = (r) =>
- Te("stts", 0, 0, [
- H(r.timeToSampleTable.length),
- r.timeToSampleTable.map((e) => [H(e.sampleCount), H(e.sampleDelta)]),
- ]),
- L0 = (r) => {
- if (r.samples.every((t) => t.type === "key")) return null;
- const e = [...r.samples.entries()].filter(([, t]) => t.type === "key");
- return Te("stss", 0, 0, [H(e.length), e.map(([t]) => H(t + 1))]);
- },
- q0 = (r) =>
- Te("stsc", 0, 0, [
- H(r.compactlyCodedChunkTable.length),
- r.compactlyCodedChunkTable.map((e) => [
- H(e.firstChunk),
- H(e.samplesPerChunk),
- H(1),
- ]),
- ]),
- j0 = (r) => {
- if (r.type === "audio" && r.info.requiresPcmTransformation) {
- const { sampleSize: e } = Rr(r.track.source._codec);
- return Te("stsz", 0, 0, [
- H(e * r.info.numberOfChannels),
- H(r.samples.reduce((t, n) => t + ve(n.duration, r.timescale), 0)),
- ]);
- }
- return Te("stsz", 0, 0, [
- H(0),
- H(r.samples.length),
- r.samples.map((e) => H(e.size)),
- ]);
- },
- $0 = (r) =>
- r.finalizedChunks.length > 0 && Ae(r.finalizedChunks).offset >= 2 ** 32
- ? Te("co64", 0, 0, [
- H(r.finalizedChunks.length),
- r.finalizedChunks.map((e) => Mt(e.offset)),
- ])
- : Te("stco", 0, 0, [
- H(r.finalizedChunks.length),
- r.finalizedChunks.map((e) => H(e.offset)),
- ]),
- G0 = (r) =>
- Te("ctts", 1, 0, [
- H(r.compositionTimeOffsetTable.length),
- r.compositionTimeOffsetTable.map((e) => [
- H(e.sampleCount),
- qt(e.sampleCompositionTimeOffset),
- ]),
- ]),
- K0 = (r) => {
- let e = 1 / 0,
- t = -1 / 0,
- n = 1 / 0,
- i = -1 / 0;
- (T(r.compositionTimeOffsetTable.length > 0), T(r.samples.length > 0));
- for (let a = 0; a < r.compositionTimeOffsetTable.length; a++) {
- const o = r.compositionTimeOffsetTable[a];
- ((e = Math.min(e, o.sampleCompositionTimeOffset)),
- (t = Math.max(t, o.sampleCompositionTimeOffset)));
- }
- for (let a = 0; a < r.samples.length; a++) {
- const o = r.samples[a];
- ((n = Math.min(n, ve(o.timestamp, r.timescale))),
- (i = Math.max(i, ve(o.timestamp + o.duration, r.timescale))));
- }
- const s = Math.max(-e, 0);
- return i >= 2 ** 31
- ? null
- : Te("cslg", 0, 0, [qt(s), qt(e), qt(t), qt(n), qt(i)]);
- },
- X0 = (r) => ee("mvex", void 0, r.map(Q0)),
- Q0 = (r) => Te("trex", 0, 0, [H(r.track.id), H(1), H(0), H(0), H(0)]),
- qc = (r, e) => ee("moof", void 0, [Y0(r), ...e.map(Z0)]),
- Y0 = (r) => Te("mfhd", 0, 0, [H(r)]),
- Ku = (r) => {
- let e = 0,
- t = 0;
- const n = 0,
- i = 0,
- s = r.type === "delta";
- return (
- (t |= +s),
- s ? (e |= 1) : (e |= 2),
- (e << 24) | (t << 16) | (n << 8) | i
- );
- },
- Z0 = (r) => ee("traf", void 0, [J0(r), eg(r), tg(r)]),
- J0 = (r) => {
- T(r.currentChunk);
- let e = 0;
- ((e |= 8), (e |= 16), (e |= 32), (e |= 131072));
- const t = r.currentChunk.samples[1] ?? r.currentChunk.samples[0],
- n = {
- duration: t.timescaleUnitsToNextSample,
- size: t.size,
- flags: Ku(t),
- };
- return Te("tfhd", 0, e, [
- H(r.track.id),
- H(n.duration),
- H(n.size),
- H(n.flags),
- ]);
- },
- eg = (r) => (
- T(r.currentChunk),
- Te("tfdt", 1, 0, [Mt(ve(r.currentChunk.startTimestamp, r.timescale))])
- ),
- tg = (r) => {
- T(r.currentChunk);
- const e = r.currentChunk.samples.map((m) => m.timescaleUnitsToNextSample),
- t = r.currentChunk.samples.map((m) => m.size),
- n = r.currentChunk.samples.map(Ku),
- i = r.currentChunk.samples.map((m) =>
- ve(m.timestamp - m.decodeTimestamp, r.timescale),
- ),
- s = new Set(e),
- a = new Set(t),
- o = new Set(n),
- c = new Set(i),
- u = o.size === 2 && n[0] !== n[1],
- l = s.size > 1,
- d = a.size > 1,
- f = !u && o.size > 1,
- h = c.size > 1 || [...c].some((m) => m !== 0);
- let p = 0;
- return (
- (p |= 1),
- (p |= 4 * +u),
- (p |= 256 * +l),
- (p |= 512 * +d),
- (p |= 1024 * +f),
- (p |= 2048 * +h),
- Te("trun", 1, p, [
- H(r.currentChunk.samples.length),
- H(r.currentChunk.offset - r.currentChunk.moofOffset || 0),
- u ? H(n[0]) : [],
- r.currentChunk.samples.map((m, b) => [
- l ? H(e[b]) : [],
- d ? H(t[b]) : [],
- f ? H(n[b]) : [],
- h ? qt(i[b]) : [],
- ]),
- ])
- );
- },
- rg = (r) => ee("mfra", void 0, [...r.map(ng), ig()]),
- ng = (r) =>
- Te("tfra", 1, 0, [
- H(r.track.id),
- H(63),
- H(r.finalizedChunks.length),
- r.finalizedChunks.map((t) => [
- Mt(ve(t.samples[0].timestamp, r.timescale)),
- Mt(t.moofOffset),
- H(t.trafIndex + 1),
- H(1),
- H(1),
- ]),
- ]),
- ig = () => Te("mfro", 0, 0, [H(0)]),
- sg = () => ee("vtte"),
- ag = (r, e, t, n, i) =>
- ee("vttc", void 0, [
- i !== null ? ee("vsid", [qt(i)]) : null,
- t !== null ? ee("iden", [...jt.encode(t)]) : null,
- e !== null ? ee("ctim", [...jt.encode(s0(e))]) : null,
- n !== null ? ee("sttg", [...jt.encode(n)]) : null,
- ee("payl", [...jt.encode(r)]),
- ]),
- og = (r) => ee("vtta", [...jt.encode(r)]),
- cg = (r) => {
- const e = [],
- t = r.format._options.metadataFormat ?? "auto",
- n = r.output._metadataTags;
- if (t === "mdir" || (t === "auto" && !r.isQuickTime)) {
- const i = ug(n);
- i && e.push(i);
- } else if (t === "mdta") {
- const i = dg(n);
- i && e.push(i);
- } else
- (t === "udta" || (t === "auto" && r.isQuickTime)) &&
- lg(e, r.output._metadataTags);
- return e.length === 0 ? null : ee("udta", void 0, e);
- },
- lg = (r, e) => {
- for (const { key: t, value: n } of El(e))
- switch (t) {
- case "title":
- r.push(Wt("©nam", n));
- break;
- case "description":
- r.push(Wt("©des", n));
- break;
- case "artist":
- r.push(Wt("©ART", n));
- break;
- case "album":
- r.push(Wt("©alb", n));
- break;
- case "albumArtist":
- r.push(Wt("albr", n));
- break;
- case "genre":
- r.push(Wt("©gen", n));
- break;
- case "date":
- r.push(Wt("©day", n.toISOString().slice(0, 10)));
- break;
- case "comment":
- r.push(Wt("©cmt", n));
- break;
- case "lyrics":
- r.push(Wt("©lyr", n));
- break;
- case "raw":
- break;
- case "discNumber":
- case "discsTotal":
- case "trackNumber":
- case "tracksTotal":
- case "beatsPerMinute":
- case "images":
- break;
- default:
- pr(t);
- }
- if (e.raw)
- for (const t in e.raw) {
- const n = e.raw[t];
- n == null ||
- t.length !== 4 ||
- r.some((i) => i.type === t) ||
- (typeof n == "string"
- ? r.push(Wt(t, n))
- : n instanceof Uint8Array && r.push(ee(t, Array.from(n))));
- }
- },
- Wt = (r, e) => {
- const t = jt.encode(e);
- return ee(r, [ne(t.length), ne(Yu("und")), Array.from(t)]);
- },
- jc = { "image/jpeg": 13, "image/png": 14, "image/bmp": 27 },
- Xu = (r, e) => {
- const t = [];
- for (const { key: n, value: i } of El(r))
- switch (n) {
- case "title":
- t.push({ key: e ? "title" : "©nam", value: Bt(i) });
- break;
- case "description":
- t.push({ key: e ? "description" : "©des", value: Bt(i) });
- break;
- case "artist":
- t.push({ key: e ? "artist" : "©ART", value: Bt(i) });
- break;
- case "album":
- t.push({ key: e ? "album" : "©alb", value: Bt(i) });
- break;
- case "albumArtist":
- t.push({ key: e ? "album_artist" : "aART", value: Bt(i) });
- break;
- case "comment":
- t.push({ key: e ? "comment" : "©cmt", value: Bt(i) });
- break;
- case "genre":
- t.push({ key: e ? "genre" : "©gen", value: Bt(i) });
- break;
- case "beatsPerMinute":
- e || t.push({ key: "tmpo", value: ee("data", [H(21), H(0), ne(i)]) });
- break;
- case "lyrics":
- t.push({ key: e ? "lyrics" : "©lyr", value: Bt(i) });
- break;
- case "date":
- t.push({
- key: e ? "date" : "©day",
- value: Bt(i.toISOString().slice(0, 10)),
- });
- break;
- case "images":
- for (const s of i)
- s.kind === "coverFront" &&
- t.push({
- key: "covr",
- value: ee("data", [
- H(jc[s.mimeType] ?? 0),
- H(0),
- Array.from(s.data),
- ]),
- });
- break;
- case "trackNumber":
- if (e) {
- const s =
- r.tracksTotal !== void 0 ? `${i}/${r.tracksTotal}` : i.toString();
- t.push({ key: "track", value: Bt(s) });
- } else
- t.push({
- key: "trkn",
- value: ee("data", [
- H(0),
- H(0),
- ne(0),
- ne(i),
- ne(r.tracksTotal ?? 0),
- ne(0),
- ]),
- });
- break;
- case "discNumber":
- e ||
- t.push({
- key: "disc",
- value: ee("data", [
- H(0),
- H(0),
- ne(0),
- ne(i),
- ne(r.discsTotal ?? 0),
- ne(0),
- ]),
- });
- break;
- case "tracksTotal":
- case "discsTotal":
- break;
- case "raw":
- break;
- default:
- pr(n);
- }
- if (r.raw)
- for (const n in r.raw) {
- const i = r.raw[n];
- i == null ||
- (!e && n.length !== 4) ||
- t.some((s) => s.key === n) ||
- (typeof i == "string"
- ? t.push({ key: n, value: Bt(i) })
- : i instanceof Uint8Array
- ? t.push({
- key: n,
- value: ee("data", [H(0), H(0), Array.from(i)]),
- })
- : i instanceof fn &&
- t.push({
- key: n,
- value: ee("data", [
- H(jc[i.mimeType] ?? 0),
- H(0),
- Array.from(i.data),
- ]),
- }));
- }
- return t;
- },
- ug = (r) => {
- const e = Xu(r, !1);
- return e.length === 0
- ? null
- : Te("meta", 0, 0, void 0, [
- fo(!1, "mdir", "", "appl"),
- ee(
- "ilst",
- void 0,
- e.map((t) => ee(t.key, void 0, [t.value])),
- ),
- ]);
- },
- dg = (r) => {
- const e = Xu(r, !0);
- return e.length === 0
- ? null
- : ee("meta", void 0, [
- fo(!1, "mdta", ""),
- Te(
- "keys",
- 0,
- 0,
- [H(e.length)],
- e.map((t) => ee("mdta", [...jt.encode(t.key)])),
- ),
- ee(
- "ilst",
- void 0,
- e.map((t, n) => {
- const i = String.fromCharCode(...H(n + 1));
- return ee(i, void 0, [t.value]);
- }),
- ),
- ]);
- },
- Bt = (r) => ee("data", [H(1), H(0), ...jt.encode(r)]),
- fg = (r, e) => {
- switch (r) {
- case "avc":
- return e.startsWith("avc3") ? "avc3" : "avc1";
- case "hevc":
- return "hvc1";
- case "vp8":
- return "vp08";
- case "vp9":
- return "vp09";
- case "av1":
- return "av01";
- case "prores":
- return e;
- }
- },
- Qs = { avc: _0, hevc: A0, vp8: Lc, vp9: Lc, av1: B0, prores: null },
- Qu = (r, e, t) => {
- switch (r) {
- case "aac":
- return "mp4a";
- case "mp3":
- return "mp4a";
- case "opus":
- return "Opus";
- case "vorbis":
- return "mp4a";
- case "flac":
- return "fLaC";
- case "ulaw":
- return "ulaw";
- case "alaw":
- return "alaw";
- case "pcm-u8":
- return "raw ";
- case "pcm-s8":
- return "sowt";
- case "ac3":
- return "ac-3";
- case "eac3":
- return "ec-3";
- case "dts":
- return e;
- }
- if (t)
- switch (r) {
- case "pcm-s16":
- return "sowt";
- case "pcm-s16be":
- return "twos";
- case "pcm-s24":
- return "in24";
- case "pcm-s24be":
- return "in24";
- case "pcm-s32":
- return "in32";
- case "pcm-s32be":
- return "in32";
- case "pcm-f32":
- return "fl32";
- case "pcm-f32be":
- return "fl32";
- case "pcm-f64":
- return "fl64";
- case "pcm-f64be":
- return "fl64";
- }
- else
- switch (r) {
- case "pcm-s16":
- return "ipcm";
- case "pcm-s16be":
- return "ipcm";
- case "pcm-s24":
- return "ipcm";
- case "pcm-s24be":
- return "ipcm";
- case "pcm-s32":
- return "ipcm";
- case "pcm-s32be":
- return "ipcm";
- case "pcm-f32":
- return "fpcm";
- case "pcm-f32be":
- return "fpcm";
- case "pcm-f64":
- return "fpcm";
- case "pcm-f64be":
- return "fpcm";
- }
- },
- hg = (r, e) => {
- switch (r) {
- case "aac":
- return Xs;
- case "mp3":
- return Xs;
- case "opus":
- return N0;
- case "vorbis":
- return Xs;
- case "flac":
- return O0;
- case "ac3":
- return D0;
- case "eac3":
- return z0;
- case "dts":
- return W0;
- }
- if (e)
- switch (r) {
- case "pcm-s24":
- return Sr;
- case "pcm-s24be":
- return Sr;
- case "pcm-s32":
- return Sr;
- case "pcm-s32be":
- return Sr;
- case "pcm-f32":
- return Sr;
- case "pcm-f32be":
- return Sr;
- case "pcm-f64":
- return Sr;
- case "pcm-f64be":
- return Sr;
- }
- else
- switch (r) {
- case "pcm-s16":
- return zt;
- case "pcm-s16be":
- return zt;
- case "pcm-s24":
- return zt;
- case "pcm-s24be":
- return zt;
- case "pcm-s32":
- return zt;
- case "pcm-s32be":
- return zt;
- case "pcm-f32":
- return zt;
- case "pcm-f32be":
- return zt;
- case "pcm-f64":
- return zt;
- case "pcm-f64be":
- return zt;
- }
- return null;
- },
- mg = { webvtt: "wvtt" },
- pg = { webvtt: H0 },
- Yu = (r) => {
- T(r.length === 3);
- let e = 0;
- for (let t = 0; t < 3; t++) ((e <<= 5), (e += r.charCodeAt(t) - 96));
- return e;
- };
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class Oa {
- constructor(e, t) {
- if (
- ((this.finalized = !1),
- (this.started = !1),
- (this.pos = 0),
- (this.trackedWrites = null),
- (this.trackedStart = -1),
- (this.trackedEnd = -1),
- e._writerAcquired)
- )
- throw new Error("Can't have multiple Writers for the same Target.");
- ((this.target = e), e._setMonotonicity(t), (e._writerAcquired = !0));
- }
- start() {
- (T(!this.started), this.target._start(), (this.started = !0));
- }
- write(e) {
- (T(this.started && !this.finalized),
- this.maybeTrackWrites(e),
- this.target._write(e, this.pos),
- (this.pos += e.byteLength));
- }
- seek(e) {
- this.pos = e;
- }
- getPos() {
- return this.pos;
- }
- async flush() {
- return (T(this.started && !this.finalized), this.target._flush());
- }
- async finalize() {
- (T(this.started && !this.finalized),
- await this.target._finalize(),
- (this.finalized = !0));
- }
- maybeTrackWrites(e) {
- if (!this.trackedWrites) return;
- let t = this.getPos();
- if (t < this.trackedStart) {
- if (t + e.byteLength <= this.trackedStart) return;
- ((e = e.subarray(this.trackedStart - t)), (t = 0));
- }
- const n = t + e.byteLength - this.trackedStart;
- let i = this.trackedWrites.byteLength;
- for (; i < n;) i *= 2;
- if (i !== this.trackedWrites.byteLength) {
- const s = new Uint8Array(i);
- (s.set(this.trackedWrites, 0), (this.trackedWrites = s));
- }
- (this.trackedWrites.set(e, t - this.trackedStart),
- (this.trackedEnd = Math.max(this.trackedEnd, t + e.byteLength)));
- }
- startTrackingWrites() {
- ((this.trackedWrites = new Uint8Array(2 ** 10)),
- (this.trackedStart = this.getPos()),
- (this.trackedEnd = this.trackedStart));
- }
- stopTrackingWrites() {
- if (!this.trackedWrites)
- throw new Error(
- "Internal error: Can't get tracked writes since nothing was tracked.",
- );
- const t = {
- data: this.trackedWrites.subarray(0, this.trackedEnd - this.trackedStart),
- start: this.trackedStart,
- end: this.trackedEnd,
- };
- return ((this.trackedWrites = null), t);
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class er extends mi {
- constructor() {
- (super(...arguments),
- (this._writerAcquired = !1),
- (this._monotonicity = null),
- (this.onwrite = null));
- }
- _setMonotonicity(e) {
- this._monotonicity !== !1 && (this._monotonicity = e);
- }
- _dispatchWrite(e, t) {
- var n;
- ((n = this.onwrite) == null || n.call(this, e, t),
- this._emit("write", { start: e, end: t }));
- }
- slice(e) {
- if (!Number.isInteger(e) || e < 0)
- throw new TypeError("offset must be a non-negative integer.");
- return new gg(this, e);
- }
-}
-const Ys = 2 ** 16,
- Zs = 2 ** 32;
-class zi extends er {
- constructor(e = {}) {
- if (
- (super(),
- (this.buffer = null),
- (this._maxPos = 0),
- !e || typeof e != "object")
- )
- throw new TypeError(
- "BufferTarget options, when provided, must be an object.",
- );
- if (e.onFinalize !== void 0 && typeof e.onFinalize != "function")
- throw new TypeError(
- "options.onFinalize, when provided, must be a function.",
- );
- if (
- ((this._options = e),
- (this._supportsResize = "resize" in new ArrayBuffer(0)),
- this._supportsResize)
- )
- try {
- this._buffer = new ArrayBuffer(Ys, { maxByteLength: Zs });
- } catch {
- ((this._buffer = new ArrayBuffer(Ys)), (this._supportsResize = !1));
- }
- else this._buffer = new ArrayBuffer(Ys);
- this._bytes = new Uint8Array(this._buffer);
- }
- _ensureSize(e) {
- let t = this._buffer.byteLength;
- for (; t < e;) t *= 2;
- if (t !== this._buffer.byteLength) {
- if (t > Zs)
- throw new Error(
- `ArrayBuffer exceeded maximum size of ${Zs} bytes. Please consider using another target.`,
- );
- if (this._supportsResize) this._buffer.resize(t);
- else {
- const n = new ArrayBuffer(t),
- i = new Uint8Array(n);
- (i.set(this._bytes, 0), (this._buffer = n), (this._bytes = i));
- }
- }
- }
- _start() {}
- _write(e, t) {
- (this._ensureSize(t + e.byteLength),
- this._bytes.set(e, t),
- (this._maxPos = Math.max(this._maxPos, t + e.byteLength)),
- this._dispatchWrite(t, t + e.byteLength));
- }
- async _flush() {}
- async _finalize() {
- ((this.buffer = this._buffer.slice(0, this._maxPos)),
- this._options.onFinalize && (await this._options.onFinalize(this.buffer)),
- this._emit("finalized"));
- }
- async _close() {}
- _getSlice(e, t) {
- return this._bytes.slice(e, t);
- }
-}
-class gg extends er {
- constructor(e, t) {
- (super(), (this._baseTarget = e), (this._offset = t));
- }
- _start() {}
- _write(e, t) {
- (this._baseTarget._write(e, this._offset + t),
- this._dispatchWrite(t, t + e.byteLength));
- }
- _flush() {
- return this._baseTarget._flush();
- }
- async _finalize() {
- this._emit("finalized");
- }
- async _close() {}
- _setMonotonicity(e) {
- (super._setMonotonicity(e), this._baseTarget._setMonotonicity(e));
- }
-}
-class Js {
- constructor(e, t) {
- if (((this.rootPath = e), (this.getTarget = t), typeof e != "string"))
- throw new TypeError("rootPath must be a string.");
- if (typeof t != "function")
- throw new TypeError("getTarget must be a function.");
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const kt = 57600,
- bg = 2082844800,
- wg = (r) => {
- const e = {},
- t = r.track;
- return (t.metadata.name !== void 0 && (e.name = t.metadata.name), e);
- },
- ve = (r, e, t = !0) => {
- const n = r * e;
- return t ? Math.round(n) : n;
- },
- yn = (r) => {
- if (r.samples.length === 0) return 0;
- let e = 1 / 0,
- t = -1 / 0;
- for (let n = 0; n < r.samples.length; n++) {
- const i = r.samples[n];
- (i.timestamp < e && (e = i.timestamp),
- i.timestamp + i.duration > t && (t = i.timestamp + i.duration));
- }
- return e === 1 / 0 ? 0 : t - e;
- };
-class yg extends i0 {
- constructor(e, t) {
- (super(e),
- (this.writer = null),
- (this.boxWriter = null),
- (this.initWriter = null),
- (this.initBoxWriter = null),
- (this.auxTarget = new zi()),
- (this.auxWriter = new Oa(this.auxTarget, !1)),
- (this.auxBoxWriter = new Ei(this.auxWriter)),
- (this.mdat = null),
- (this.ftypSize = null),
- (this.trackDatas = []),
- (this.allTracksKnown = Ke()),
- (this.creationTime = Math.floor(Date.now() / 1e3) + bg),
- (this.finalizedChunks = []),
- (this.wroteFragmentedHeader = !1),
- (this.nextFragmentNumber = 1),
- (this.maxWrittenTimestamp = -1 / 0),
- (this.minWrittenTimestamp = 1 / 0),
- (this.maxWrittenEndTimestamp = -1 / 0),
- (this.segmentHeaderSize = null),
- (this.format = t),
- (this.formatOptions = { ...t._options }),
- (this.isQuickTime = t instanceof rd),
- (this.isCmaf = t instanceof Gc),
- (this.minimumFragmentDuration =
- this.formatOptions.minimumFragmentDuration ??
- (t instanceof Gc ? 1 / 0 : 1)),
- this.auxWriter.start());
- }
- async start() {
- var n;
- const e = await this.mutex.acquire();
- if (
- (this.isCmaf
- ? ((this.fastStart = "fragmented"), (this.isFragmented = !0))
- : ((this.writer = await this.output._getRootWriter((i) =>
- this.formatOptions.fastStart !== void 0
- ? this.formatOptions.fastStart === "fragmented"
- : i instanceof zi,
- )),
- (this.boxWriter = new Ei(this.writer)),
- (this.fastStart =
- this.formatOptions.fastStart ??
- (this.writer.target instanceof zi ? "in-memory" : !1)),
- (this.isFragmented = this.fastStart === "fragmented")),
- this.isCmaf)
- ) {
- if (!this.output._hasInitTarget())
- throw new Error(
- "CMAF outputs require the initTarget field in OutputOptions to be set; the init segment will be written to it.",
- );
- const i = await this.output._getInitTarget(),
- s = new Oa(i, !0);
- (s.start(), (this.initWriter = s), (this.initBoxWriter = new Ei(s)));
- }
- const t = this.output.tracks.some(
- (i) => i.isVideoTrack() && i.source._codec === "avc",
- );
- {
- const i = this.initBoxWriter ?? this.boxWriter;
- if (
- (T(i),
- this.formatOptions.onFtyp && i.writer.startTrackingWrites(),
- i.writeBox(
- a0({
- isQuickTime: this.isQuickTime,
- holdsAvc: t,
- fragmented: this.isFragmented,
- cmaf: this.isCmaf,
- }),
- ),
- this.formatOptions.onFtyp)
- ) {
- const { data: s, start: a } = i.writer.stopTrackingWrites();
- this.formatOptions.onFtyp(s, a);
- }
- ((this.ftypSize = i.writer.getPos()),
- this.isCmaf && (await this.initWriter.flush()));
- }
- if (this.fastStart !== "in-memory")
- if (this.fastStart === "reserve") {
- for (const i of this.output.tracks)
- if (i.metadata.maximumPacketCount === void 0)
- throw new Error(
- "All tracks must specify maximumPacketCount in their metadata when using fastStart: 'reserve'.",
- );
- } else
- this.isFragmented ||
- (T(this.writer),
- T(this.boxWriter),
- this.formatOptions.onMdat && this.writer.startTrackingWrites(),
- (this.mdat = Ii(!0)),
- this.boxWriter.writeBox(this.mdat));
- await ((n = this.writer) == null ? void 0 : n.flush());
- for (const i of this.output.tracks)
- i.isVideoTrack() && i.metadata.decoderConfig
- ? this.getVideoTrackData(i, i.metadata.primingPacket ?? null, {
- decoderConfig: i.metadata.decoderConfig,
- })
- : i.isAudioTrack() &&
- i.metadata.decoderConfig &&
- this.getAudioTrackData(i, i.metadata.primingPacket ?? null, {
- decoderConfig: i.metadata.decoderConfig,
- });
- e();
- }
- allTracksAreKnown() {
- for (const e of this.output.tracks)
- if (!e.source._closed && !this.trackDatas.some((t) => t.track === e))
- return !1;
- return !0;
- }
- async getMimeType() {
- await this.allTracksKnown.promise;
- const e = this.trackDatas.map((t) =>
- t.type === "video" || t.type === "audio"
- ? t.info.decoderConfig.codec
- : { webvtt: "wvtt" }[t.track.source._codec],
- );
- return nu({
- isQuickTime: this.isQuickTime,
- hasVideo: this.trackDatas.some((t) => t.type === "video"),
- hasAudio: this.trackDatas.some((t) => t.type === "audio"),
- codecStrings: e,
- });
- }
- getVideoTrackData(e, t, n) {
- const i = this.trackDatas.find((h) => h.track === e);
- if (i) return i;
- (Zl(n, e.source._codec), T(n), T(n.decoderConfig));
- const s = { ...n.decoderConfig };
- (T(s.codedWidth !== void 0), T(s.codedHeight !== void 0));
- let a = !1;
- if (e.source._codec === "avc" && !s.description) {
- if (!t)
- throw new Error(
- "No AVC description provided; you must therefore provide a priming packet.",
- );
- const h = bi(t.data);
- if (!h)
- throw new Error(
- "Couldn't extract an AVCDecoderConfigurationRecord from the AVC packet. Make sure the packets are in Annex B format (as specified in ITU-T-REC-H.264) when not providing a description, or provide a description (must be an AVCDecoderConfigurationRecord as specified in ISO 14496-15) and ensure the packets are in AVCC format.",
- );
- ((s.description = Nl(h)), (a = !0));
- } else if (e.source._codec === "hevc" && !s.description) {
- if (!t)
- throw new Error(
- "No HEVC description provided; you must therefore provide a priming packet.",
- );
- const h = wi(t.data);
- if (!h)
- throw new Error(
- "Couldn't extract an HEVCDecoderConfigurationRecord from the HEVC packet. Make sure the packets are in Annex B format (as specified in ITU-T-REC-H.265) when not providing a description, or provide a description (must be an HEVCDecoderConfigurationRecord as specified in ISO 14496-15) and ensure the packets are in HEVC format.",
- );
- ((s.description = nh(h)), (a = !0));
- }
- const o = Wf(1 / (e.metadata.frameRate ?? kt), 1e6).den,
- c = s.displayAspectWidth,
- u = s.displayAspectHeight,
- l =
- c === void 0 || u === void 0
- ? { num: 1, den: 1 }
- : ii({ num: c * s.codedHeight, den: u * s.codedWidth }),
- d = s.codec === "ap4h" || s.codec === "ap4x",
- f = {
- muxer: this,
- track: e,
- type: "video",
- info: {
- width: s.codedWidth,
- height: s.codedHeight,
- pixelAspectRatio: l,
- decoderConfig: s,
- requiresAnnexBTransformation: a,
- hasAlphaChannel: d,
- },
- timescale: o,
- samples: [],
- sampleQueue: [],
- timestampProcessingQueue: [],
- timeToSampleTable: [],
- compositionTimeOffsetTable: [],
- lastTimescaleUnits: null,
- lastSample: null,
- startTimestampOffset: null,
- finalizedChunks: [],
- currentChunk: null,
- compactlyCodedChunkTable: [],
- closed: !1,
- avgBitrate: e.source._nominalBitrate ?? e.metadata.averageBitrate ?? 0,
- maxBitrate: e.source._nominalBitrate ?? e.metadata.bitrate ?? 0,
- };
- return (
- this.trackDatas.push(f),
- this.trackDatas.sort((h, p) => h.track.id - p.track.id),
- this.allTracksAreKnown() && this.allTracksKnown.resolve(),
- f
- );
- }
- getAudioTrackData(e, t, n) {
- const i = this.trackDatas.find((c) => c.track === e);
- if (i) return i;
- (Jl(n, e.source._codec), T(n), T(n.decoderConfig));
- const s = { ...n.decoderConfig };
- let a = !1;
- if (e.source._codec === "aac" && !s.description) {
- if (!t)
- throw new Error(
- "No AAC description provided; you must therefore provide a priming packet.",
- );
- const c = Xr(yt.tempFromBytes(t.data));
- if (!c)
- throw new Error(
- "Couldn't parse ADTS header from the AAC packet. Make sure the packets are in ADTS format (as specified in ISO 13818-7) when not providing a description, or provide a description (must be an AudioSpecificConfig as specified in ISO 14496-3) and ensure the packets are raw AAC data.",
- );
- const u = Kr[c.samplingFrequencyIndex],
- l = pi[c.channelConfiguration];
- if (u === void 0 || l === void 0)
- throw new Error("Invalid ADTS frame header.");
- ((s.description = Al({
- objectType: c.objectType,
- outputSampleRate: u,
- outputNumberOfChannels: l,
- })),
- (a = !0));
- }
- if (!t) {
- if (e.source._codec === "ac3" || e.source._codec === "eac3")
- throw new Error("AC-3/E-AC-3 require a priming packet.");
- if (e.source._codec === "dts")
- throw new Error("DTS requires a priming packet.");
- }
- const o = {
- muxer: this,
- track: e,
- type: "audio",
- info: {
- numberOfChannels: n.decoderConfig.numberOfChannels,
- sampleRate: n.decoderConfig.sampleRate,
- decoderConfig: s,
- requiresPcmTransformation:
- !this.isFragmented && ut.includes(e.source._codec),
- expectedNextPcmPacketTimestamp: null,
- requiresAdtsStripping: a,
- primingPacket: t,
- },
- timescale: s.sampleRate,
- samples: [],
- sampleQueue: [],
- timestampProcessingQueue: [],
- timeToSampleTable: [],
- compositionTimeOffsetTable: [],
- lastTimescaleUnits: null,
- lastSample: null,
- startTimestampOffset: null,
- finalizedChunks: [],
- currentChunk: null,
- compactlyCodedChunkTable: [],
- closed: !1,
- avgBitrate: e.source._nominalBitrate ?? e.metadata.averageBitrate ?? 0,
- maxBitrate: e.source._nominalBitrate ?? e.metadata.bitrate ?? 0,
- };
- return (
- this.trackDatas.push(o),
- this.trackDatas.sort((c, u) => c.track.id - u.track.id),
- this.allTracksAreKnown() && this.allTracksKnown.resolve(),
- o
- );
- }
- getSubtitleTrackData(e, t) {
- const n = this.trackDatas.find((s) => s.track === e);
- if (n) return n;
- (Wh(t), T(t), T(t.config));
- const i = {
- muxer: this,
- track: e,
- type: "subtitle",
- info: { config: t.config },
- timescale: 1e3,
- samples: [],
- sampleQueue: [],
- timestampProcessingQueue: [],
- timeToSampleTable: [],
- compositionTimeOffsetTable: [],
- lastTimescaleUnits: null,
- lastSample: null,
- startTimestampOffset: null,
- finalizedChunks: [],
- currentChunk: null,
- compactlyCodedChunkTable: [],
- closed: !1,
- avgBitrate: e.source._nominalBitrate ?? e.metadata.averageBitrate ?? 0,
- maxBitrate: e.source._nominalBitrate ?? e.metadata.bitrate ?? 0,
- lastCueEndTimestamp: null,
- cueQueue: [],
- nextSourceId: 0,
- cueToSourceId: new WeakMap(),
- };
- return (
- this.trackDatas.push(i),
- this.trackDatas.sort((s, a) => s.track.id - a.track.id),
- this.allTracksAreKnown() && this.allTracksKnown.resolve(),
- i
- );
- }
- async addEncodedVideoPacket(e, t, n) {
- const i = await this.mutex.acquire();
- try {
- const s = this.getVideoTrackData(e, t, n);
- let a = t.data;
- if (s.info.requiresAnnexBTransformation) {
- const c = [...gi(a)].map((u) =>
- a.subarray(u.offset, u.offset + u.length),
- );
- if (c.length === 0)
- throw new Error(
- "Failed to transform packet data. Make sure all packets are provided in Annex B format, as specified in ITU-T-REC-H.264 and ITU-T-REC-H.265.",
- );
- a = Qa(c, 4);
- }
- this.validateTimestamp(s.track, t.timestamp, t.type === "key");
- const o = this.createSampleForTrack(
- s,
- a,
- t.timestamp,
- t.duration,
- t.type,
- );
- await this.registerSample(s, o);
- } finally {
- i();
- }
- }
- async addEncodedAudioPacket(e, t, n) {
- const i = await this.mutex.acquire();
- try {
- const s = this.getAudioTrackData(e, t, n);
- let a = t.data;
- if (s.info.requiresAdtsStripping) {
- const l = Xr(yt.tempFromBytes(a));
- if (!l) throw new Error("Expected ADTS frame, didn't get one.");
- const d = l.crcCheck === null ? Xi : $r;
- a = a.subarray(d);
- }
- this.validateTimestamp(s.track, t.timestamp, t.type === "key");
- let o = t.timestamp,
- c = t.duration;
- if (s.info.requiresPcmTransformation) {
- const d =
- Rr(s.info.decoderConfig.codec).sampleSize * s.info.numberOfChannels;
- if (
- ((c = a.byteLength / d / s.info.sampleRate),
- s.info.expectedNextPcmPacketTimestamp !== null)
- ) {
- const f = o - s.info.expectedNextPcmPacketTimestamp;
- if (f < 0.01) o = s.info.expectedNextPcmPacketTimestamp;
- else {
- const h = await this.padWithSilence(
- s,
- s.info.expectedNextPcmPacketTimestamp,
- f,
- );
- o = s.info.expectedNextPcmPacketTimestamp + h;
- }
- }
- s.info.expectedNextPcmPacketTimestamp = o + c;
- }
- const u = this.createSampleForTrack(s, a, o, c, t.type);
- await this.registerSample(s, u);
- } finally {
- i();
- }
- }
- async padWithSilence(e, t, n) {
- const i = ve(n, e.timescale);
- if (((n = i / e.timescale), i > 0)) {
- const { sampleSize: s, silentValue: a } = Rr(e.info.decoderConfig.codec),
- o = i * e.info.numberOfChannels,
- c = new Uint8Array(s * o).fill(a),
- u = this.createSampleForTrack(e, new Uint8Array(c.buffer), t, n, "key");
- await this.registerSample(e, u);
- }
- return n;
- }
- async addSubtitleCue(e, t, n) {
- const i = await this.mutex.acquire();
- try {
- const s = this.getSubtitleTrackData(e, n);
- (this.validateTimestamp(s.track, t.timestamp, !0),
- e.source._codec === "webvtt" &&
- (s.cueQueue.push(t), await this.processWebVTTCues(s, t.timestamp)));
- } finally {
- i();
- }
- }
- async processWebVTTCues(e, t) {
- for (; e.cueQueue.length > 0;) {
- e.lastCueEndTimestamp ??
- (e.lastCueEndTimestamp = Math.min(0, e.cueQueue[0].timestamp));
- const n = new Set([]);
- for (const u of e.cueQueue)
- (T(u.timestamp <= t),
- T(e.lastCueEndTimestamp <= u.timestamp + u.duration),
- n.add(Math.max(u.timestamp, e.lastCueEndTimestamp)),
- n.add(u.timestamp + u.duration));
- const i = [...n].sort((u, l) => u - l),
- s = i[0],
- a = i[1] ?? s;
- if (t < a) break;
- if (e.lastCueEndTimestamp < s) {
- this.auxWriter.seek(0);
- const u = sg();
- this.auxBoxWriter.writeBox(u);
- const l = this.auxTarget._getSlice(0, this.auxWriter.getPos()),
- d = this.createSampleForTrack(
- e,
- l,
- e.lastCueEndTimestamp,
- s - e.lastCueEndTimestamp,
- "key",
- );
- (await this.registerSample(e, d), (e.lastCueEndTimestamp = s));
- }
- this.auxWriter.seek(0);
- for (let u = 0; u < e.cueQueue.length; u++) {
- const l = e.cueQueue[u];
- if (l.timestamp >= a) break;
- Wc.lastIndex = 0;
- const d = Wc.test(l.text),
- f = l.timestamp + l.duration;
- let h = e.cueToSourceId.get(l);
- if (
- (h === void 0 &&
- a < f &&
- ((h = e.nextSourceId++), e.cueToSourceId.set(l, h)),
- l.notes)
- ) {
- const m = og(l.notes);
- this.auxBoxWriter.writeBox(m);
- }
- const p = ag(
- l.text,
- d ? s : null,
- l.identifier ?? null,
- l.settings ?? null,
- h ?? null,
- );
- (this.auxBoxWriter.writeBox(p), f === a && e.cueQueue.splice(u--, 1));
- }
- const o = this.auxTarget._getSlice(0, this.auxWriter.getPos()),
- c = this.createSampleForTrack(e, o, s, a - s, "key");
- (await this.registerSample(e, c), (e.lastCueEndTimestamp = a));
- }
- }
- createSampleForTrack(e, t, n, i, s) {
- return {
- timestamp: n,
- decodeTimestamp: n,
- duration: i,
- data: t,
- size: t.byteLength,
- type: s,
- timescaleUnitsToNextSample: ve(i, e.timescale),
- };
- }
- processTimestamps(e, t) {
- if (e.timestampProcessingQueue.length === 0) return;
- if (e.type === "audio" && e.info.requiresPcmTransformation) {
- (T(!this.isFragmented),
- e.startTimestampOffset ??
- (e.startTimestampOffset = e.timestampProcessingQueue[0].timestamp));
- let i = 0;
- for (let s = 0; s < e.timestampProcessingQueue.length; s++) {
- const a = e.timestampProcessingQueue[s],
- o = ve(a.duration, e.timescale);
- i += o;
- }
- if (e.timeToSampleTable.length === 0)
- e.timeToSampleTable.push({ sampleCount: i, sampleDelta: 1 });
- else {
- const s = Ae(e.timeToSampleTable);
- s.sampleCount += i;
- }
- e.timestampProcessingQueue.length = 0;
- return;
- }
- const n = e.timestampProcessingQueue
- .map((i) => i.timestamp)
- .sort((i, s) => i - s);
- this.isFragmented
- ? (e.startTimestampOffset ?? (e.startTimestampOffset = Math.min(n[0], 0)))
- : (e.startTimestampOffset ?? (e.startTimestampOffset = n[0]));
- for (let i = 0; i < e.timestampProcessingQueue.length; i++) {
- const s = e.timestampProcessingQueue[i];
- s.decodeTimestamp = n[i];
- const a = ve(s.timestamp - s.decodeTimestamp, e.timescale),
- o = ve(s.duration, e.timescale);
- if (e.lastTimescaleUnits !== null) {
- T(e.lastSample);
- const c = ve(s.decodeTimestamp, e.timescale, !1),
- u = Math.round(c - e.lastTimescaleUnits);
- if (
- (T(u >= 0),
- (e.lastTimescaleUnits += u),
- (e.lastSample.timescaleUnitsToNextSample = u),
- !this.isFragmented)
- ) {
- let l = Ae(e.timeToSampleTable);
- if ((T(l), l.sampleCount === 1)) {
- l.sampleDelta = u;
- const f = e.timeToSampleTable[e.timeToSampleTable.length - 2];
- f &&
- f.sampleDelta === u &&
- (f.sampleCount++, e.timeToSampleTable.pop(), (l = f));
- } else
- l.sampleDelta !== u &&
- (l.sampleCount--,
- e.timeToSampleTable.push(
- (l = { sampleCount: 1, sampleDelta: u }),
- ));
- l.sampleDelta === o
- ? l.sampleCount++
- : e.timeToSampleTable.push({ sampleCount: 1, sampleDelta: o });
- const d = Ae(e.compositionTimeOffsetTable);
- (T(d),
- d.sampleCompositionTimeOffset === a
- ? d.sampleCount++
- : e.compositionTimeOffsetTable.push({
- sampleCount: 1,
- sampleCompositionTimeOffset: a,
- }));
- }
- } else
- ((e.lastTimescaleUnits = ve(s.decodeTimestamp, e.timescale, !1)),
- this.isFragmented ||
- (e.timeToSampleTable.push({ sampleCount: 1, sampleDelta: o }),
- e.compositionTimeOffsetTable.push({
- sampleCount: 1,
- sampleCompositionTimeOffset: a,
- })));
- e.lastSample = s;
- }
- if (
- ((e.timestampProcessingQueue.length = 0),
- T(e.lastSample),
- T(e.lastTimescaleUnits !== null),
- t !== void 0 && e.lastSample.timescaleUnitsToNextSample === 0)
- ) {
- T(t.type === "key");
- const i = ve(t.timestamp, e.timescale, !1),
- s = Math.round(i - e.lastTimescaleUnits);
- e.lastSample.timescaleUnitsToNextSample = s;
- }
- }
- async registerSample(e, t) {
- (t.type === "key" && this.processTimestamps(e, t),
- e.timestampProcessingQueue.push(t),
- this.isFragmented
- ? (e.sampleQueue.push(t), await this.interleaveSamples())
- : this.fastStart === "reserve"
- ? await this.registerSampleFastStartReserve(e, t)
- : await this.addSampleToTrack(e, t));
- }
- async addSampleToTrack(e, t) {
- if (
- !this.isFragmented &&
- (e.samples.push(t), this.fastStart === "reserve")
- ) {
- const i = e.track.metadata.maximumPacketCount;
- if ((T(i !== void 0), e.samples.length > i))
- throw new Error(
- `Track #${e.track.id} has already reached the maximum packet count (${i}). Either add less packets or increase the maximum packet count.`,
- );
- }
- let n = !1;
- if (!e.currentChunk) n = !0;
- else {
- e.currentChunk.startTimestamp = Math.min(
- e.currentChunk.startTimestamp,
- t.timestamp,
- );
- const i = t.timestamp - e.currentChunk.startTimestamp;
- if (this.isFragmented) {
- const s = this.trackDatas.every((a) => {
- if (e === a) return t.type === "key";
- const o = a.sampleQueue[0];
- return o ? o.type === "key" : a.closed;
- });
- i >= this.minimumFragmentDuration &&
- s &&
- t.timestamp > this.maxWrittenTimestamp &&
- ((n = !0), await this.finalizeFragment());
- } else n = i >= 0.5;
- }
- (n &&
- (e.currentChunk && (await this.finalizeCurrentChunk(e)),
- (e.currentChunk = {
- startTimestamp: t.timestamp,
- samples: [],
- offset: null,
- moofOffset: null,
- trafIndex: null,
- })),
- T(e.currentChunk),
- e.currentChunk.samples.push(t),
- this.isFragmented &&
- ((this.maxWrittenTimestamp = Math.max(
- this.maxWrittenTimestamp,
- t.timestamp,
- )),
- (this.maxWrittenEndTimestamp = Math.max(
- this.maxWrittenEndTimestamp,
- t.timestamp + t.duration,
- )),
- (this.minWrittenTimestamp = Math.min(
- this.minWrittenTimestamp,
- t.timestamp,
- ))));
- }
- async finalizeCurrentChunk(e) {
- if ((T(!this.isFragmented), T(this.writer), !e.currentChunk)) return;
- (e.finalizedChunks.push(e.currentChunk),
- this.finalizedChunks.push(e.currentChunk));
- let t = e.currentChunk.samples.length;
- if (
- (e.type === "audio" &&
- e.info.requiresPcmTransformation &&
- (t = e.currentChunk.samples.reduce(
- (n, i) => n + ve(i.duration, e.timescale),
- 0,
- )),
- (e.compactlyCodedChunkTable.length === 0 ||
- Ae(e.compactlyCodedChunkTable).samplesPerChunk !== t) &&
- e.compactlyCodedChunkTable.push({
- firstChunk: e.finalizedChunks.length,
- samplesPerChunk: t,
- }),
- this.fastStart === "in-memory")
- ) {
- e.currentChunk.offset = 0;
- return;
- }
- e.currentChunk.offset = this.writer.getPos();
- for (const n of e.currentChunk.samples)
- (T(n.data), this.writer.write(n.data), (n.data = null));
- await this.writer.flush();
- }
- async interleaveSamples(e = !1) {
- if ((T(this.isFragmented), !(!e && !this.allTracksAreKnown())))
- e: for (;;) {
- let t = null,
- n = 1 / 0;
- for (const s of this.trackDatas) {
- if (!e && s.sampleQueue.length === 0 && !s.closed) break e;
- s.sampleQueue.length > 0 &&
- s.sampleQueue[0].timestamp < n &&
- ((t = s), (n = s.sampleQueue[0].timestamp));
- }
- if (!t) break;
- const i = t.sampleQueue.shift();
- await this.addSampleToTrack(t, i);
- }
- }
- async finalizeFragment(e = !this.isCmaf) {
- if ((T(this.isFragmented), !this.wroteFragmentedHeader)) {
- this.wroteFragmentedHeader = !0;
- const h = this.initBoxWriter ?? this.boxWriter;
- (T(h),
- this.formatOptions.onMoov && h.writer.startTrackingWrites(),
- this.ensureOneEnabledTrack());
- const p = Hn(this);
- if ((h.writeBox(p), this.formatOptions.onMoov)) {
- const { data: m, start: b } = h.writer.stopTrackingWrites();
- this.formatOptions.onMoov(m, b);
- }
- if (this.isCmaf) {
- (T(this.initWriter),
- await this.initWriter.flush(),
- await this.initWriter.finalize(),
- (this.writer = await this.output._getRootWriter(!0)),
- (this.boxWriter = new Ei(this.writer)));
- const m = this.boxWriter.measureBox(Hc()),
- b = this.boxWriter.measureBox(Vc(this, 0));
- ((this.segmentHeaderSize = m + b),
- this.writer.seek(this.segmentHeaderSize));
- }
- }
- (T(this.writer), T(this.boxWriter));
- const t = this.trackDatas.filter((h) => h.currentChunk);
- if (t.length === 0) {
- e && (await this.writer.flush());
- return;
- }
- const n = this.nextFragmentNumber++,
- i = qc(n, t),
- s = this.writer.getPos(),
- a = s + this.boxWriter.measureBox(i);
- let o = a + sr,
- c = 1 / 0;
- for (let h = 0; h < t.length; h++) {
- const p = t[h];
- (T(p.currentChunk),
- T(p.startTimestampOffset !== null),
- (p.currentChunk.offset = o),
- (p.currentChunk.moofOffset = s),
- (p.currentChunk.trafIndex = h),
- (p.currentChunk.startTimestamp -= p.startTimestampOffset));
- for (const m of p.currentChunk.samples)
- ((o += m.size),
- (m.timestamp -= p.startTimestampOffset),
- (m.decodeTimestamp -= p.startTimestampOffset));
- c = Math.min(c, p.currentChunk.startTimestamp);
- }
- const u = o - a,
- l = u >= 2 ** 32;
- if (l) for (const h of t) h.currentChunk.offset += Hr - sr;
- this.formatOptions.onMoof && this.writer.startTrackingWrites();
- const d = qc(n, t);
- if ((this.boxWriter.writeBox(d), this.formatOptions.onMoof)) {
- const { data: h, start: p } = this.writer.stopTrackingWrites();
- this.formatOptions.onMoof(h, p, c);
- }
- (T(this.writer.getPos() === a),
- this.formatOptions.onMdat && this.writer.startTrackingWrites());
- const f = Ii(l);
- ((f.size = u),
- this.boxWriter.writeBox(f),
- this.writer.seek(a + (l ? Hr : sr)));
- for (const h of t)
- for (const p of h.currentChunk.samples)
- (this.writer.write(p.data), (p.data = null));
- if (this.formatOptions.onMdat) {
- const { data: h, start: p } = this.writer.stopTrackingWrites();
- this.formatOptions.onMdat(h, p);
- }
- for (const h of t)
- (h.finalizedChunks.push(h.currentChunk),
- this.finalizedChunks.push(h.currentChunk),
- (h.currentChunk = null));
- e && (await this.writer.flush());
- }
- async registerSampleFastStartReserve(e, t) {
- this.allTracksAreKnown()
- ? (this.mdat || (await this.createFastStartReserveMdat()),
- await this.addSampleToTrack(e, t))
- : e.sampleQueue.push(t);
- }
- async createFastStartReserveMdat() {
- (T(this.writer), T(this.boxWriter), this.ensureOneEnabledTrack());
- const e = Hn(this),
- n =
- this.boxWriter.measureBox(e) +
- this.computeSampleTableSizeUpperBound() +
- 4096;
- (T(this.ftypSize !== null),
- this.writer.seek(this.ftypSize + n),
- this.formatOptions.onMdat && this.writer.startTrackingWrites(),
- (this.mdat = Ii(!0)),
- this.boxWriter.writeBox(this.mdat));
- for (const i of this.trackDatas) {
- for (const s of i.sampleQueue) await this.addSampleToTrack(i, s);
- i.sampleQueue.length = 0;
- }
- }
- computeSampleTableSizeUpperBound() {
- T(this.fastStart === "reserve");
- let e = 0;
- for (const t of this.trackDatas) {
- const n = t.track.metadata.maximumPacketCount;
- (T(n !== void 0),
- (e += 8 * Math.ceil((2 / 3) * n)),
- (e += 4 * n),
- (e += 8 * Math.ceil((2 / 3) * n)),
- (e += 12 * Math.ceil((2 / 3) * n)),
- (e += 4 * n),
- (e += 8 * n));
- }
- return e;
- }
- async onTrackClose(e) {
- const t = await this.mutex.acquire(),
- n = this.trackDatas.find((i) => i.track === e);
- (n &&
- ((n.closed = !0),
- n.type === "subtitle" &&
- e.source._codec === "webvtt" &&
- (await this.processWebVTTCues(n, 1 / 0)),
- this.processTimestamps(n)),
- this.allTracksAreKnown() && this.allTracksKnown.resolve(),
- this.isFragmented && (await this.interleaveSamples()),
- t());
- }
- ensureOneEnabledTrack() {
- for (const e of ["video", "audio", "subtitle"]) {
- const t = this.trackDatas.filter((i) => i.type === e);
- if (t.length === 0) continue;
- if (
- !t.some((i) => {
- var s;
- return (
- ((s = i.track.metadata.disposition) == null
- ? void 0
- : s.default) !== !1
- );
- })
- ) {
- const i = t[0];
- i.track.metadata.disposition = {
- ...i.track.metadata.disposition,
- default: !0,
- };
- }
- }
- }
- async forceFragmentFinalization() {
- T(this.isFragmented);
- const e = await this.mutex.acquire();
- try {
- for (const t of this.trackDatas)
- (t.type === "subtitle" &&
- t.track.source._codec === "webvtt" &&
- (await this.processWebVTTCues(t, 1 / 0)),
- this.processTimestamps(t));
- (await this.interleaveSamples(!0), await this.finalizeFragment());
- } finally {
- e();
- }
- }
- async finalize() {
- const e = await this.mutex.acquire();
- (this.allTracksKnown.resolve(),
- this.ensureOneEnabledTrack(),
- !this.mdat &&
- this.fastStart === "reserve" &&
- (await this.createFastStartReserveMdat()));
- for (const t of this.trackDatas)
- ((t.closed = !0),
- t.type === "subtitle" &&
- t.track.source._codec === "webvtt" &&
- (await this.processWebVTTCues(t, 1 / 0)),
- this.processTimestamps(t));
- if (this.isFragmented)
- (await this.interleaveSamples(!0), await this.finalizeFragment(!1));
- else
- for (const t of this.trackDatas) {
- await this.finalizeCurrentChunk(t);
- const n = yn(t);
- if (n > 0) {
- let o = 0;
- for (const c of t.samples) o += c.size;
- t.avgBitrate = Math.round((8 * o) / n);
- } else t.avgBitrate = 0;
- let i = 0,
- s = 0,
- a = 0;
- for (let o = 0; o < t.samples.length; o++) {
- const c = t.samples[o];
- for (
- s += c.size;
- c.decodeTimestamp - t.samples[i].decodeTimestamp >= 1;
- )
- ((s -= t.samples[i].size), i++);
- a = Math.max(a, s);
- }
- if (((t.maxBitrate = 8 * a), t.startTimestampOffset !== null))
- for (let o = 0; o < t.samples.length; o++) {
- const c = t.samples[o];
- ((c.timestamp -= t.startTimestampOffset),
- (c.decodeTimestamp -= t.startTimestampOffset));
- }
- }
- if ((T(this.writer), T(this.boxWriter), this.fastStart === "in-memory")) {
- this.mdat = Ii(!1);
- let t;
- for (let i = 0; i < 2; i++) {
- const s = Hn(this),
- a = this.boxWriter.measureBox(s);
- t = this.boxWriter.measureBox(this.mdat);
- let o = this.writer.getPos() + a + t;
- for (const c of this.finalizedChunks) {
- c.offset = o;
- for (const { data: u } of c.samples)
- (T(u), (o += u.byteLength), (t += u.byteLength));
- }
- if (o < 2 ** 32) break;
- t >= 2 ** 32 && (this.mdat.largeSize = !0);
- }
- this.formatOptions.onMoov && this.writer.startTrackingWrites();
- const n = Hn(this);
- if ((this.boxWriter.writeBox(n), this.formatOptions.onMoov)) {
- const { data: i, start: s } = this.writer.stopTrackingWrites();
- this.formatOptions.onMoov(i, s);
- }
- (this.formatOptions.onMdat && this.writer.startTrackingWrites(),
- (this.mdat.size = t),
- this.boxWriter.writeBox(this.mdat));
- for (const i of this.finalizedChunks)
- for (const s of i.samples)
- (T(s.data), this.writer.write(s.data), (s.data = null));
- if (this.formatOptions.onMdat) {
- const { data: i, start: s } = this.writer.stopTrackingWrites();
- this.formatOptions.onMdat(i, s);
- }
- } else if (this.isFragmented)
- if (this.isCmaf) {
- const t =
- this.segmentHeaderSize !== null
- ? this.writer.getPos() - this.segmentHeaderSize
- : 0;
- (this.writer.seek(0),
- this.boxWriter.writeBox(Hc()),
- this.boxWriter.writeBox(Vc(this, t)));
- } else {
- const t = this.writer.getPos(),
- n = rg(this.trackDatas);
- this.boxWriter.writeBox(n);
- const i = this.writer.getPos() - t;
- (this.writer.seek(this.writer.getPos() - 4),
- this.boxWriter.writeU32(i));
- }
- else {
- T(this.mdat);
- const t = this.boxWriter.offsets.get(this.mdat);
- T(t !== void 0);
- const n = this.writer.getPos() - t;
- if (
- ((this.mdat.size = n),
- (this.mdat.largeSize = n >= 2 ** 32),
- this.boxWriter.patchBox(this.mdat),
- this.formatOptions.onMdat)
- ) {
- const { data: s, start: a } = this.writer.stopTrackingWrites();
- this.formatOptions.onMdat(s, a);
- }
- const i = Hn(this);
- if (this.fastStart === "reserve") {
- (T(this.ftypSize !== null),
- this.writer.seek(this.ftypSize),
- this.formatOptions.onMoov && this.writer.startTrackingWrites(),
- this.boxWriter.writeBox(i));
- const s = this.boxWriter.offsets.get(this.mdat) - this.writer.getPos();
- this.boxWriter.writeBox(o0(s));
- } else
- (this.formatOptions.onMoov && this.writer.startTrackingWrites(),
- this.boxWriter.writeBox(i));
- if (this.formatOptions.onMoov) {
- const { data: s, start: a } = this.writer.stopTrackingWrites();
- this.formatOptions.onMoov(s, a);
- }
- }
- e();
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class kg {
- constructor(e) {
- ((this.sourceSampleRate = null),
- (this.sourceNumberOfChannels = null),
- (this.startTime = null),
- (this.bufferStartFrame = 0),
- (this.maxWrittenFrame = null),
- (this.targetSampleRate = e.targetSampleRate),
- (this.targetNumberOfChannels = e.targetNumberOfChannels),
- (this.onSample = e.onSample),
- (this.bufferSizeInFrames = Math.floor(this.targetSampleRate * 5)),
- (this.bufferSizeInSamples =
- this.bufferSizeInFrames * this.targetNumberOfChannels));
- }
- doChannelMixerSetup() {
- T(this.sourceNumberOfChannels !== null);
- const e = this.sourceNumberOfChannels,
- t = this.targetNumberOfChannels;
- e === 1 && t === 2
- ? (this.channelMixer = (n, i) => n[i * e])
- : e === 1 && t === 4
- ? (this.channelMixer = (n, i, s) => n[i * e] * +(s < 2))
- : e === 1 && t === 6
- ? (this.channelMixer = (n, i, s) => n[i * e] * +(s === 2))
- : e === 2 && t === 1
- ? (this.channelMixer = (n, i) => {
- const s = i * e;
- return 0.5 * (n[s] + n[s + 1]);
- })
- : e === 2 && t === 4
- ? (this.channelMixer = (n, i, s) => (s < 2 ? n[i * e + s] : 0))
- : e === 2 && t === 6
- ? (this.channelMixer = (n, i, s) => (s < 2 ? n[i * e + s] : 0))
- : e === 4 && t === 1
- ? (this.channelMixer = (n, i) => {
- const s = i * e;
- return 0.25 * (n[s] + n[s + 1] + n[s + 2] + n[s + 3]);
- })
- : e === 4 && t === 2
- ? (this.channelMixer = (n, i, s) => {
- const a = i * e;
- return 0.5 * (n[a + s] + n[a + s + 2]);
- })
- : e === 4 && t === 6
- ? (this.channelMixer = (n, i, s) => {
- const a = i * e;
- return s < 2
- ? n[a + s]
- : s === 2 || s === 3
- ? 0
- : n[a + s - 2];
- })
- : e === 6 && t === 1
- ? (this.channelMixer = (n, i) => {
- const s = i * e;
- return (
- Math.SQRT1_2 * (n[s] + n[s + 1]) +
- n[s + 2] +
- 0.5 * (n[s + 4] + n[s + 5])
- );
- })
- : e === 6 && t === 2
- ? (this.channelMixer = (n, i, s) => {
- const a = i * e;
- return (
- n[a + s] +
- Math.SQRT1_2 * (n[a + 2] + n[a + s + 4])
- );
- })
- : e === 6 && t === 4
- ? (this.channelMixer = (n, i, s) => {
- const a = i * e;
- return s < 2
- ? n[a + s] + Math.SQRT1_2 * n[a + 2]
- : n[a + s + 2];
- })
- : (this.channelMixer = (n, i, s) =>
- s < e ? n[i * e + s] : 0);
- }
- ensureTempBufferSize(e) {
- let t = this.tempSourceBuffer.length;
- for (; t < e;) t *= 2;
- if (t !== this.tempSourceBuffer.length) {
- const n = new Float32Array(t);
- (n.set(this.tempSourceBuffer), (this.tempSourceBuffer = n));
- }
- }
- async add(e) {
- if (this.sourceSampleRate === null) {
- ((this.sourceSampleRate = e.sampleRate),
- (this.sourceNumberOfChannels = e.numberOfChannels),
- (this.startTime = e.timestamp));
- const u = Math.ceil(this.targetSampleRate / this.sourceSampleRate);
- ((this.bufferCapacityInFrames = this.bufferSizeInFrames + u),
- (this.outputBuffer = new Float32Array(
- this.bufferCapacityInFrames * this.targetNumberOfChannels,
- )),
- (this.tempSourceBuffer = new Float32Array(
- this.sourceSampleRate * this.sourceNumberOfChannels,
- )),
- this.doChannelMixerSetup());
- }
- T(this.startTime !== null);
- const t = e.numberOfFrames * e.numberOfChannels;
- this.ensureTempBufferSize(t);
- const n = e.allocationSize({ planeIndex: 0, format: "f32" }),
- i = new Float32Array(this.tempSourceBuffer.buffer, 0, n / 4);
- e.copyTo(i, { planeIndex: 0, format: "f32" });
- const s = e.timestamp - this.startTime,
- a = s + e.duration,
- o =
- Math.floor((s - 1 / this.sourceSampleRate) * this.targetSampleRate) + 1,
- c = Math.ceil(a * this.targetSampleRate);
- for (let u = o; u < c; u++) {
- if (u < this.bufferStartFrame) continue;
- for (; u >= this.bufferStartFrame + this.bufferCapacityInFrames;)
- (await this.finalizeCurrentBuffer(),
- (this.bufferStartFrame += this.bufferSizeInFrames));
- const l = u - this.bufferStartFrame;
- T(l < this.bufferCapacityInFrames);
- const h = (u / this.targetSampleRate - s) * this.sourceSampleRate,
- p = Math.floor(h),
- m = Math.ceil(h),
- b = h - p;
- for (let g = 0; g < this.targetNumberOfChannels; g++) {
- let y = 0,
- C = 0;
- (p >= 0 && p < e.numberOfFrames && (y = this.channelMixer(i, p, g)),
- m >= 0 && m < e.numberOfFrames && (C = this.channelMixer(i, m, g)));
- const _ = y + b * (C - y),
- v = l * this.targetNumberOfChannels + g;
- this.outputBuffer[v] += _;
- }
- this.maxWrittenFrame === null
- ? (this.maxWrittenFrame = l)
- : (this.maxWrittenFrame = Math.max(this.maxWrittenFrame, l));
- }
- }
- async finalizeCurrentBuffer() {
- if (this.maxWrittenFrame === null) return;
- T(this.startTime !== null);
- const e =
- Math.min(this.maxWrittenFrame + 1, this.bufferSizeInFrames) *
- this.targetNumberOfChannels,
- t = new Float32Array(e);
- t.set(this.outputBuffer.subarray(0, e));
- const n = new wt({
- format: "f32",
- sampleRate: this.targetSampleRate,
- numberOfChannels: this.targetNumberOfChannels,
- timestamp: this.startTime + this.bufferStartFrame / this.targetSampleRate,
- data: t,
- });
- (await this.onSample(n),
- this.outputBuffer.copyWithin(0, this.bufferSizeInSamples),
- this.outputBuffer.fill(
- 0,
- this.outputBuffer.length - this.bufferSizeInSamples,
- ),
- (this.maxWrittenFrame =
- this.maxWrittenFrame >= this.bufferSizeInFrames
- ? this.maxWrittenFrame - this.bufferSizeInFrames
- : null));
- }
- async finalize() {
- for (; this.maxWrittenFrame !== null;)
- (await this.finalizeCurrentBuffer(),
- (this.bufferStartFrame += this.bufferSizeInFrames));
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ var Tg = function (r, e, t) {
- if (e != null) {
- if (typeof e != "object" && typeof e != "function")
- throw new TypeError("Object expected.");
- var n, i;
- if (t) {
- if (!Symbol.asyncDispose)
- throw new TypeError("Symbol.asyncDispose is not defined.");
- n = e[Symbol.asyncDispose];
- }
- if (n === void 0) {
- if (!Symbol.dispose)
- throw new TypeError("Symbol.dispose is not defined.");
- ((n = e[Symbol.dispose]), t && (i = n));
- }
- if (typeof n != "function") throw new TypeError("Object not disposable.");
- (i &&
- (n = function () {
- try {
- i.call(this);
- } catch (s) {
- return Promise.reject(s);
- }
- }),
- r.stack.push({ value: e, dispose: n, async: t }));
- } else t && r.stack.push({ async: !0 });
- return e;
- },
- xg = (function (r) {
- return function (e) {
- function t(a) {
- ((e.error = e.hasError
- ? new r(a, e.error, "An error was suppressed during disposal.")
- : a),
- (e.hasError = !0));
- }
- var n,
- i = 0;
- function s() {
- for (; (n = e.stack.pop());)
- try {
- if (!n.async && i === 1)
- return ((i = 0), e.stack.push(n), Promise.resolve().then(s));
- if (n.dispose) {
- var a = n.dispose.call(n.value);
- if (n.async)
- return (
- (i |= 2),
- Promise.resolve(a).then(s, function (o) {
- return (t(o), s());
- })
- );
- } else i |= 1;
- } catch (o) {
- t(o);
- }
- if (i === 1)
- return e.hasError ? Promise.reject(e.error) : Promise.resolve();
- if (e.hasError) throw e.error;
- }
- return s();
- };
- })(
- typeof SuppressedError == "function"
- ? SuppressedError
- : function (r, e, t) {
- var n = new Error(t);
- return (
- (n.name = "SuppressedError"),
- (n.error = r),
- (n.suppressed = e),
- n
- );
- },
- );
-class mo {
- constructor() {
- ((this._connectedTrack = null),
- (this._closingPromise = null),
- (this._closed = !1),
- (this._nominalBitrate = null));
- }
- _ensureValidAdd() {
- if (!this._connectedTrack)
- throw new Error("Source is not connected to an output track.");
- if (this._connectedTrack.output.state === "canceled")
- throw new Error("Output has been canceled.");
- if (
- this._connectedTrack.output.state === "finalizing" ||
- this._connectedTrack.output.state === "finalized"
- )
- throw new Error("Output has been finalized.");
- if (this._connectedTrack.output.state === "pending")
- throw new Error("Output has not started.");
- if (this._closed) throw new Error("Source is closed.");
- }
- async _start() {}
- async _flushAndClose(e) {}
- close() {
- if (this._closingPromise) return;
- const e = this._connectedTrack;
- if (!e)
- throw new Error(
- "Cannot call close without connecting the source to an output track.",
- );
- if (e.output.state === "pending")
- throw new Error("Cannot call close before output has been started.");
- this._closingPromise = (async () => {
- (await this._flushAndClose(!1),
- (this._closed = !0),
- !(e.output.state === "finalizing" || e.output.state === "finalized") &&
- e.output._muxer.onTrackClose(e));
- })();
- }
- async _flushOrWaitForOngoingClose(e) {
- return (
- this._closingPromise ??
- (this._closingPromise = (async () => {
- (await this._flushAndClose(e), (this._closed = !0));
- })())
- );
- }
-}
-class Zu extends mo {
- constructor(e) {
- if ((super(), !Rt.includes(e)))
- throw new TypeError(
- `Invalid video codec '${e}'. Must be one of: ${Rt.join(", ")}.`,
- );
- this._codec = e;
- }
-}
-const $c = (r, e) => {
- if (r.metadata.hasOnlyKeyPackets && e.type !== "key")
- throw new Error(
- "Cannot add non-key packets to a hasOnlyKeyPackets video track.",
- );
-};
-class Sg {
- setError(e) {
- this.errorSet || ((this.error = e), (this.errorSet = !0));
- }
- constructor(e, t) {
- ((this.source = e),
- (this.encodingConfig = t),
- (this.ensureEncoderPromise = null),
- (this.encoderInitialized = !1),
- (this.encoder = null),
- (this.encoderConfig = null),
- (this.encodersReclaimed = !1),
- (this.muxer = null),
- (this.lastMultipleOfKeyFrameInterval = -1),
- (this.emittedEncoderPackets = 0),
- (this.codedWidth = null),
- (this.codedHeight = null),
- (this.outputWidth = null),
- (this.outputHeight = null),
- (this.frameRateLastSample = null),
- (this.frameRateLastTimestamp = null),
- (this.frameRateLastEndTimestamp = null),
- (this.preciseTimings = []),
- (this.customEncoder = null),
- (this.customEncoderCallSerializer = new ja()),
- (this.customEncoderQueueSize = 0),
- (this.defaultEncodeOptions = {}),
- (this.alphaEncoder = null),
- (this.splitter = null),
- (this.splitterCreationFailed = !1),
- (this.alphaFrameQueue = []),
- (this.error = null),
- (this.errorSet = !1),
- (this.lastMuxerPromise = Promise.resolve()),
- (this.closed = !1));
- }
- async add(e, t, n) {
- var s, a, o, c, u, l, d, f, h, p, m, b, g, y;
- const i = e;
- try {
- (this.checkForEncoderError(), this.source._ensureValidAdd());
- const C = this.encodingConfig,
- _ = C.sizeChangeBehavior ?? "deny";
- let v = !1;
- if (this.codedWidth !== null && this.codedHeight !== null) {
- if (
- (e.codedWidth !== this.codedWidth ||
- e.codedHeight !== this.codedHeight) &&
- ((v = !0), _ === "deny")
- )
- throw new Error(
- `Video sample size must remain constant. Expected ${this.codedWidth}x${this.codedHeight}, got ${e.codedWidth}x${e.codedHeight}. To allow the sample size to change over time, set \`sizeChangeBehavior\` to a value other than 'deny' in the encoding options.`,
- );
- } else
- ((this.codedWidth = e.codedWidth), (this.codedHeight = e.codedHeight));
- if (
- ((s = C.transform) == null ? void 0 : s.width) !== void 0 ||
- ((a = C.transform) == null ? void 0 : a.height) !== void 0 ||
- ((o = C.transform) == null ? void 0 : o.rotate) !== void 0 ||
- ((c = C.transform) == null ? void 0 : c.flip) !== void 0 ||
- ((u = C.transform) == null ? void 0 : u.crop) !== void 0 ||
- ((l = C.transform) == null ? void 0 : l.force) === !0 ||
- (v && _ !== "passThrough")
- ) {
- let k = (d = C.transform) == null ? void 0 : d.width,
- S = (f = C.transform) == null ? void 0 : f.height,
- E = ((h = C.transform) == null ? void 0 : h.fit) ?? "fill";
- v &&
- _ !== "passThrough" &&
- (T(this.outputWidth),
- T(this.outputHeight),
- T(_ !== "deny"),
- (k = this.outputWidth),
- (S = this.outputHeight),
- (E = _));
- const B = await e.transform({
- width: k,
- height: S,
- roundDimensionsTo: 2,
- crop: (p = C.transform) == null ? void 0 : p.crop,
- rotate: (m = C.transform) == null ? void 0 : m.rotate,
- flip: (b = C.transform) == null ? void 0 : b.flip,
- fit: E,
- alpha: C.alpha,
- });
- ((this.outputWidth === null || this.outputHeight === null) &&
- ((this.outputWidth = B.displayWidth),
- (this.outputHeight = B.displayHeight)),
- t && e.close(),
- (e = B),
- (t = !0));
- } else
- (this.outputWidth === null || this.outputHeight === null) &&
- ((this.outputWidth = e.codedWidth),
- (this.outputHeight = e.codedHeight));
- const x = (g = C.transform) == null ? void 0 : g.frameRate;
- if (x !== void 0) {
- const k = e.timestamp + e.duration,
- S = Mo(e.timestamp, x);
- if (this.frameRateLastSample !== null)
- if (S <= this.frameRateLastTimestamp) {
- (this.frameRateLastSample.close(),
- (this.frameRateLastSample = e.clone()),
- (this.frameRateLastEndTimestamp = k));
- return;
- } else await this.padFrameRate(S, n);
- (e === i && ((e = e.clone()), (t = !0)),
- e.setTimestamp(S),
- e.setDuration(1 / x),
- (y = this.frameRateLastSample) == null || y.close(),
- (this.frameRateLastSample = e.clone()),
- (this.frameRateLastTimestamp = S),
- (this.frameRateLastEndTimestamp = k));
- }
- await this.processAndEncode(e, n);
- } finally {
- t && e.close();
- }
- }
- async processAndEncode(e, t) {
- var s, a, o;
- const n = this.encodingConfig;
- let i;
- if ((s = n.transform) != null && s.process) {
- let c = n.transform.process(e);
- if ((O(c) && (c = await c), c === null)) return;
- Array.isArray(c) || (c = [c]);
- const u = [];
- try {
- for (const l of c)
- l instanceof tt
- ? u.push(l)
- : typeof VideoFrame < "u" && l instanceof VideoFrame
- ? u.push(new tt(l))
- : u.push(
- new tt(l, { timestamp: e.timestamp, duration: e.duration }),
- );
- } catch (l) {
- for (const d of u) d !== e && d.close();
- for (const d of c)
- ((d instanceof tt && d !== e) ||
- (typeof VideoFrame < "u" && d instanceof VideoFrame)) &&
- d.close();
- throw l;
- }
- i = u;
- } else i = [e];
- try {
- for (const c of i) {
- if (
- (this.encoderInitialized ||
- (this.ensureEncoderPromise || this.ensureEncoder(c),
- this.encoderInitialized || (await this.ensureEncoderPromise)),
- T(this.encoderInitialized),
- this.closed)
- )
- break;
- this.encodersReclaimed && this.recreateWebCodecsEncoders();
- const u = this.encodingConfig.keyFrameInterval ?? 2,
- l = Math.floor(c.timestamp / u),
- d = { ...this.defaultEncodeOptions, ...c.encodeOptions, ...t },
- f = {
- ...d,
- keyFrame:
- d.keyFrame !== void 0
- ? d.keyFrame
- : u === 0 || l !== this.lastMultipleOfKeyFrameInterval,
- };
- if (
- ((this.lastMultipleOfKeyFrameInterval = l),
- (o = (a = this.encodingConfig).onEncodedSample) == null ||
- o.call(a, c),
- this.customEncoder)
- ) {
- this.customEncoderQueueSize++;
- const h = c.clone(),
- p = this.customEncoderCallSerializer
- .call(() => this.customEncoder.encode(h, f))
- .catch((m) => this.setError(m))
- .finally(() => {
- (this.customEncoderQueueSize--, h.close());
- });
- this.customEncoderQueueSize >= 4 && (await p);
- } else {
- T(this.encoder);
- const h = c.toVideoFrame(),
- p = ke(
- this.preciseTimings,
- h.timestamp,
- (b) => b.microsecondTimestamp,
- ),
- m = p !== -1 ? this.preciseTimings[p] : null;
- if (
- (m && m.microsecondTimestamp === h.timestamp
- ? (m.timestamp !== c.timestamp && (m.timestampIsValid = !1),
- m.duration !== c.duration && (m.durationIsValid = !1))
- : (this.preciseTimings.splice(p + 1, 0, {
- microsecondTimestamp: h.timestamp,
- timestamp: c.timestamp,
- duration: c.duration,
- timestampIsValid: !0,
- durationIsValid: !0,
- }),
- this.preciseTimings.length > 128 &&
- this.preciseTimings.shift()),
- this.alphaEncoder)
- )
- if (
- (!!h.format && !h.format.includes("A")) ||
- this.splitterCreationFailed
- ) {
- this.alphaFrameQueue.push(null);
- try {
- this.encoder.encode(h, f);
- } finally {
- h.close();
- }
- } else {
- this.splitter || (this.splitter = new Pg());
- const { colorFrame: g, alphaFrame: y } =
- await this.splitter.split(h);
- this.alphaFrameQueue.push(y);
- try {
- this.encoder.encode(g, f);
- } finally {
- g.close();
- }
- }
- else
- try {
- this.encoder.encode(h, f);
- } finally {
- h.close();
- }
- this.encoder.encodeQueueSize >= 4 &&
- (await new Promise((b) =>
- this.encoder.addEventListener("dequeue", b, { once: !0 }),
- ));
- }
- await this.lastMuxerPromise;
- }
- } finally {
- for (const c of i) c !== e && c.close();
- }
- }
- async padFrameRate(e, t) {
- const n = this.encodingConfig.transform.frameRate;
- T(this.frameRateLastSample);
- const i = Math.round((e - this.frameRateLastTimestamp) * n);
- for (let s = 1; s < i; s++) {
- const a = { stack: [], error: void 0, hasError: !1 };
- try {
- const o = Tg(a, this.frameRateLastSample.clone(), !1);
- (o.setTimestamp(this.frameRateLastTimestamp + s / n),
- o.setDuration(1 / n),
- await this.processAndEncode(o, t));
- } catch (o) {
- ((a.error = o), (a.hasError = !0));
- } finally {
- xg(a);
- }
- }
- }
- ensureEncoder(e) {
- this.ensureEncoderPromise = (async () => {
- var o, c, u;
- const t = bs(this.encodingConfig.quality, this.encodingConfig.bitrate);
- T(t !== void 0);
- const n = Ou({
- ...this.encodingConfig,
- quality: t,
- width: e.codedWidth,
- height: e.codedHeight,
- squarePixelWidth: e.squarePixelWidth,
- squarePixelHeight: e.squarePixelHeight,
- framerate:
- (o = this.source._connectedTrack) == null
- ? void 0
- : o.metadata.frameRate,
- });
- let i = null,
- s;
- for (const l of n) {
- const d = l.config;
- if (
- ((u = (c = this.encodingConfig).onEncoderConfig) == null ||
- u.call(c, d),
- (s = Ji.find((h) => h.supports(this.encodingConfig.codec, d))),
- s)
- ) {
- i = l;
- break;
- }
- if (typeof VideoEncoder > "u") continue;
- if (
- ((d.alpha = "discard"),
- this.encodingConfig.alpha === "keep" && (d.latencyMode = "quality"),
- (d.width % 2 === 1 || d.height % 2 === 1) &&
- (this.encodingConfig.codec === "avc" ||
- this.encodingConfig.codec === "hevc"))
- )
- throw new Error(
- `The dimensions ${d.width}x${d.height} are not supported for codec '${this.encodingConfig.codec}'; both width and height must be even numbers. Make sure to round your dimensions to the nearest even number.`,
- );
- try {
- if ((await VideoEncoder.isConfigSupported(d)).supported) {
- i = l;
- break;
- }
- } catch {}
- }
- if (!i) {
- if (typeof VideoEncoder > "u") throw new Error($a("VideoEncoder"));
- const l = n[0].config,
- d = n.map(({ config: f, quantizer: h }) =>
- h !== null ? `quantizer ${h}` : `${f.bitrate} bps`,
- );
- throw new Error(
- `This specific encoder configuration (${l.codec}, ${d.join(" / ")}, ${l.width}x${l.height}, hardware acceleration: ${l.hardwareAcceleration ?? "no-preference"}) is not supported in this environment. Consider using another codec or changing your video parameters.`,
- );
- }
- const a = i.config;
- (i.quantizer !== null
- ? (this.defaultEncodeOptions = Wu(
- this.encodingConfig.codec,
- i.quantizer,
- ))
- : (this.source._nominalBitrate = a.bitrate ?? null),
- s
- ? ((this.customEncoder = new s()),
- (this.customEncoder.codec = this.encodingConfig.codec),
- (this.customEncoder.config = a),
- (this.customEncoder.onPacket = (l, d) => {
- var f, h;
- if (!(l instanceof Ee))
- throw new TypeError(
- "The first argument passed to onPacket must be an EncodedPacket.",
- );
- if (d !== void 0 && (!d || typeof d != "object"))
- throw new TypeError(
- "The second argument passed to onPacket must be an object or undefined.",
- );
- ($c(this.source._connectedTrack, l),
- (h = (f = this.encodingConfig).onEncodedPacket) == null ||
- h.call(f, l, d),
- (this.lastMuxerPromise = this.muxer
- .addEncodedVideoPacket(this.source._connectedTrack, l, d)
- .catch((p) => {
- this.setError(p);
- })));
- }),
- (this.customEncoder.onError = (l) => {
- this.setError(l);
- }),
- await this.customEncoder.init())
- : ((this.encoderConfig = a), this.createWebCodecsEncoders()),
- T(this.source._connectedTrack),
- (this.muxer = this.source._connectedTrack.output._muxer),
- (this.encoderInitialized = !0));
- })();
- }
- createWebCodecsEncoders() {
- const e = this.encoderConfig;
- T(e);
- const t = [],
- n = [];
- let i = 0,
- s = 0;
- const a = (c, u) => {
- if (Uf(c)) {
- this.encodersReclaimed = !0;
- return;
- }
- ((c.stack = u), this.setError(c));
- },
- o = new Error("Encoding error").stack;
- if (
- ((this.encoder = new VideoEncoder({
- output: (c, u) => {
- if (!this.alphaEncoder) {
- this.addPacket(c, null, u);
- return;
- }
- const l = this.alphaFrameQueue.shift();
- (T(l !== void 0),
- l
- ? (this.alphaEncoder.encode(l, {
- ...this.defaultEncodeOptions,
- keyFrame: c.type === "key",
- }),
- s++,
- l.close(),
- t.push({ chunk: c, meta: u }))
- : s === 0
- ? this.addPacket(c, null, u)
- : (n.push(i + s), t.push({ chunk: c, meta: u })));
- },
- error: (c) => a(c, o),
- })),
- this.encoder.configure(e),
- this.encodingConfig.alpha === "keep")
- ) {
- const c = new Error("Encoding error").stack;
- ((this.alphaEncoder = new VideoEncoder({
- output: (u, l) => {
- s--;
- const d = t.shift();
- for (
- T(d !== void 0), this.addPacket(d.chunk, u, d.meta), i++;
- n.length > 0 && n[0] === i;
- ) {
- n.shift();
- const f = t.shift();
- (T(f !== void 0), this.addPacket(f.chunk, null, f.meta));
- }
- },
- error: (u) => a(u, c),
- })),
- this.alphaEncoder.configure(e));
- }
- }
- addPacket(e, t, n) {
- var l, d;
- const i = {};
- if (t) {
- const f = new Uint8Array(t.byteLength);
- (t.copyTo(f), (i.alpha = f));
- }
- let s = Ee.fromEncodedChunk(e, i);
- const a = this.encoderConfig;
- (T(a),
- n != null &&
- n.decoderConfig &&
- (n.decoderConfig.codec = hs({
- width: a.width,
- height: a.height,
- codec: this.encodingConfig.codec,
- codecDescription: n.decoderConfig.description
- ? Ze(n.decoderConfig.description)
- : null,
- colorSpace: n.decoderConfig.colorSpace ?? null,
- avcType: a.codec.includes("avc1.")
- ? 1
- : a.codec.includes("avc3.")
- ? 3
- : null,
- avcCodecInfo:
- this.encodingConfig.codec === "avc" && !n.decoderConfig.description
- ? bi(s.data)
- : null,
- hevcCodecInfo:
- this.encodingConfig.codec === "hevc" && !n.decoderConfig.description
- ? wi(s.data)
- : null,
- vp9CodecInfo: this.encodingConfig.codec === "vp9" ? Za(s.data) : null,
- av1CodecInfo: this.encodingConfig.codec === "av1" ? ds(s.data) : null,
- proresFormat: null,
- })));
- const o = ke(
- this.preciseTimings,
- e.timestamp,
- (f) => f.microsecondTimestamp,
- ),
- c = o !== -1 ? this.preciseTimings[o] : null;
- let u = null;
- (this.emittedEncoderPackets === 0 &&
- s.type === "delta" &&
- n != null &&
- n.decoderConfig &&
- (u = fs(this.encodingConfig.codec, n.decoderConfig, s.data)),
- ((c && c.microsecondTimestamp === e.timestamp) || u !== null) &&
- (s = s.clone({
- timestamp: c != null && c.timestampIsValid ? c.timestamp : void 0,
- duration: c != null && c.durationIsValid ? c.duration : void 0,
- type: u ?? void 0,
- })),
- $c(this.source._connectedTrack, s),
- (d = (l = this.encodingConfig).onEncodedPacket) == null ||
- d.call(l, s, n),
- (this.lastMuxerPromise = this.muxer
- .addEncodedVideoPacket(this.source._connectedTrack, s, n)
- .catch((f) => {
- this.setError(f);
- })),
- this.emittedEncoderPackets++);
- }
- recreateWebCodecsEncoders() {
- (T(this.encoder),
- this.encoder.state !== "closed" && this.encoder.close(),
- this.alphaEncoder &&
- this.alphaEncoder.state !== "closed" &&
- this.alphaEncoder.close(),
- this.alphaFrameQueue.forEach((e) => (e == null ? void 0 : e.close())),
- (this.alphaFrameQueue.length = 0),
- (this.encodersReclaimed = !1),
- (this.lastMultipleOfKeyFrameInterval = -1),
- this.createWebCodecsEncoders());
- }
- async flushAndClose(e) {
- var t, n, i;
- try {
- if (!e && (this.checkForEncoderError(), this.frameRateLastSample)) {
- const s = this.encodingConfig.transform.frameRate,
- a = Mo(this.frameRateLastEndTimestamp, s);
- await this.padFrameRate(a);
- }
- ((this.closed = !0),
- e ||
- (this.customEncoder
- ? this.customEncoderCallSerializer.call(() =>
- this.customEncoder.flush(),
- )
- : this.encoder &&
- !this.encodersReclaimed &&
- (await this.encoder.flush(),
- await ((t = this.alphaEncoder) == null ? void 0 : t.flush()),
- await si(25))));
- } finally {
- ((this.closed = !0),
- (n = this.frameRateLastSample) == null || n.close(),
- (this.frameRateLastSample = null),
- this.customEncoder
- ? await this.customEncoderCallSerializer
- .call(() => this.customEncoder.close())
- .catch((s) => this.setError(s))
- : this.encoder &&
- (this.encoder.state !== "closed" && this.encoder.close(),
- this.alphaEncoder &&
- this.alphaEncoder.state !== "closed" &&
- this.alphaEncoder.close(),
- this.alphaFrameQueue.forEach((s) =>
- s == null ? void 0 : s.close(),
- ),
- (this.alphaFrameQueue.length = 0),
- (i = this.splitter) == null || i.close()));
- }
- e || this.checkForEncoderError();
- }
- getQueueSize() {
- var e;
- return this.customEncoder
- ? this.customEncoderQueueSize
- : (((e = this.encoder) == null ? void 0 : e.encodeQueueSize) ?? 0);
- }
- checkForEncoderError() {
- if (this.errorSet) throw this.error;
- }
-}
-let ea = null;
-class Pg {
- constructor() {
- ((this.worker = null),
- (this.pendingRequests = new Map()),
- (this.nextRequestId = 0));
- }
- split(e) {
- if (!this.worker) {
- if (!ea) {
- const i = new Blob([`(${Cg.toString()})()`], {
- type: "application/javascript",
- });
- ea = URL.createObjectURL(i);
- }
- ((this.worker = new Worker(ea)),
- this.worker.addEventListener("message", (i) => {
- const s = i.data,
- a = this.pendingRequests.get(s.id);
- a &&
- (this.pendingRequests.delete(s.id),
- "error" in s
- ? a.reject(new Error(s.error))
- : a.resolve({
- colorFrame: s.colorFrame,
- alphaFrame: s.alphaFrame,
- }));
- }),
- this.worker.addEventListener("error", (i) => {
- const s = new Error(
- i.message || "Color/alpha splitter worker error.",
- );
- for (const a of this.pendingRequests.values()) a.reject(s);
- this.pendingRequests.clear();
- }));
- }
- const t = this.nextRequestId++,
- n = Ke();
- return (
- this.pendingRequests.set(t, n),
- this.worker.postMessage({ id: t, sourceFrame: e }, { transfer: [e] }),
- n.promise
- );
- }
- close() {
- var t;
- ((t = this.worker) == null || t.terminate(), (this.worker = null));
- const e = new Error("Color/alpha splitter closed.");
- for (const n of this.pendingRequests.values()) n.reject(e);
- this.pendingRequests.clear();
- }
-}
-const Cg = () => {
- let r = null,
- e = Promise.resolve();
- self.addEventListener("message", (s) => {
- const { id: a, sourceFrame: o } = s.data;
- e = e.then(async () => {
- try {
- const { colorFrame: c, alphaFrame: u } = await t(o);
- self.postMessage(
- { id: a, colorFrame: c, alphaFrame: u },
- { transfer: [c, u] },
- );
- } catch (c) {
- self.postMessage({ id: a, error: c.message });
- } finally {
- o.close();
- }
- });
- });
- const t = async (s) => {
- const a = s.format;
- if (!a)
- throw new Error(
- "CPU color/alpha splitting requires a known VideoFrame format.",
- );
- const o = s.allocationSize();
- if (
- ((!r || r.byteLength !== o) && (r = new Uint8Array(o)),
- await s.copyTo(r),
- a === "RGBA" || a === "BGRA")
- )
- return n(r, a, s);
- if (
- a === "I420A" ||
- a === "I420AP10" ||
- a === "I420AP12" ||
- a === "I422A" ||
- a === "I422AP10" ||
- a === "I422AP12" ||
- a === "I444A" ||
- a === "I444AP10" ||
- a === "I444AP12"
- )
- return i(r, a, s);
- throw new Error(
- `CPU color/alpha splitting does not support format '${a}'.`,
- );
- },
- n = (s, a, o) => {
- var y, C;
- const c =
- ((y = o.visibleRect) == null ? void 0 : y.width) ?? o.codedWidth,
- u = ((C = o.visibleRect) == null ? void 0 : C.height) ?? o.codedHeight,
- l = c * u,
- d = Math.ceil(c / 2),
- f = Math.ceil(u / 2),
- h = l + d * f * 2,
- p = new Uint8Array(h);
- for (let _ = 0, v = 3; _ < l; _++, v += 4) p[_] = s[v];
- p.fill(128, l);
- const m = new VideoFrame(s, {
- format: a === "RGBA" ? "RGBX" : "BGRX",
- codedWidth: c,
- codedHeight: u,
- timestamp: o.timestamp,
- duration: o.duration ?? void 0,
- }),
- b = {
- format: "I420",
- codedWidth: c,
- codedHeight: u,
- timestamp: o.timestamp,
- duration: o.duration ?? void 0,
- colorSpace: {
- fullRange: !0,
- matrix: "bt709",
- primaries: "bt709",
- transfer: "bt709",
- },
- transfer: [p.buffer],
- },
- g = new VideoFrame(p, b);
- return { colorFrame: m, alphaFrame: g };
- },
- i = (s, a, o) => {
- var le, ue;
- const c =
- ((le = o.visibleRect) == null ? void 0 : le.width) ?? o.codedWidth,
- u =
- ((ue = o.visibleRect) == null ? void 0 : ue.height) ?? o.codedHeight,
- l = a.includes("P10"),
- d = a.includes("P12"),
- f = l || d ? 2 : 1;
- let h, p;
- a.startsWith("I420")
- ? ((h = Math.ceil(c / 2)), (p = Math.ceil(u / 2)))
- : a.startsWith("I422")
- ? ((h = Math.ceil(c / 2)), (p = u))
- : ((h = c), (p = u));
- const m = c * u,
- b = h * p,
- g = m * f,
- y = b * f,
- C = m * f,
- _ = g + y * 2,
- v = a.replace("A", ""),
- I = Math.ceil(c / 2),
- w = Math.ceil(u / 2),
- x = I * w,
- k = x * f,
- S = C + 2 * k,
- E = new Uint8Array(S),
- B = _;
- E.set(s.subarray(B, B + C), 0);
- const R = C,
- M = l ? 512 : d ? 2048 : 128;
- f === 1 ? E.fill(M, R) : new Uint16Array(E.buffer, R, 2 * x).fill(M);
- const z = l ? "I420P10" : d ? "I420P12" : "I420",
- q = new VideoFrame(s.subarray(0, _), {
- format: v,
- codedWidth: c,
- codedHeight: u,
- timestamp: o.timestamp,
- duration: o.duration ?? void 0,
- }),
- j = {
- format: z,
- codedWidth: c,
- codedHeight: u,
- timestamp: o.timestamp,
- duration: o.duration ?? void 0,
- colorSpace: {
- fullRange: !0,
- matrix: "bt709",
- primaries: "bt709",
- transfer: "bt709",
- },
- transfer: [E.buffer],
- },
- se = new VideoFrame(E, j);
- return { colorFrame: q, alphaFrame: se };
- };
-};
-class vg extends Zu {
- constructor(e, t) {
- if (
- !(typeof HTMLCanvasElement < "u" && e instanceof HTMLCanvasElement) &&
- !(typeof OffscreenCanvas < "u" && e instanceof OffscreenCanvas)
- )
- throw new TypeError(
- "canvas must be an HTMLCanvasElement or OffscreenCanvas.",
- );
- (Bp(t),
- super(t.codec),
- (this._encoder = new Sg(this, t)),
- (this._canvas = e));
- }
- add(e, t = 0, n) {
- if (!Number.isFinite(e))
- throw new TypeError("timestamp must be a finite number.");
- if (!Number.isFinite(t) || t < 0)
- throw new TypeError("duration must be a non-negative number.");
- const i = new tt(this._canvas, { timestamp: e, duration: t });
- return this._encoder.add(i, !0, n);
- }
- _flushAndClose(e) {
- return this._encoder.flushAndClose(e);
- }
-}
-class Ju extends mo {
- constructor(e) {
- if ((super(), !fr.includes(e)))
- throw new TypeError(
- `Invalid audio codec '${e}'. Must be one of: ${fr.join(", ")}.`,
- );
- this._codec = e;
- }
-}
-class Eg {
- setError(e) {
- this.errorSet || ((this.error = e), (this.errorSet = !0));
- }
- constructor(e, t) {
- ((this.source = e),
- (this.encodingConfig = t),
- (this.ensureEncoderPromise = null),
- (this.encoderInitialized = !1),
- (this.encoder = null),
- (this.muxer = null),
- (this.lastNumberOfChannels = null),
- (this.lastSampleRate = null),
- (this.isPcmEncoder = !1),
- (this.outputSampleSize = null),
- (this.writeOutputValue = null),
- (this.customEncoder = null),
- (this.customEncoderCallSerializer = new ja()),
- (this.customEncoderQueueSize = 0),
- (this.lastEndSampleIndex = null),
- (this.resampler = null),
- (this.error = null),
- (this.errorSet = !1),
- (this.lastMuxerPromise = Promise.resolve()),
- (this.closed = !1));
- }
- async add(e, t) {
- var n, i;
- try {
- if (
- (this.checkForEncoderError(),
- this.source._ensureValidAdd(),
- this.lastNumberOfChannels !== null && this.lastSampleRate !== null)
- ) {
- if (
- e.numberOfChannels !== this.lastNumberOfChannels ||
- e.sampleRate !== this.lastSampleRate
- )
- throw new Error(
- `Audio parameters must remain constant. Expected ${this.lastNumberOfChannels} channels at ${this.lastSampleRate} Hz, got ${e.numberOfChannels} channels at ${e.sampleRate} Hz.`,
- );
- } else
- ((this.lastNumberOfChannels = e.numberOfChannels),
- (this.lastSampleRate = e.sampleRate));
- const s = this.encodingConfig;
- ((n = s.transform) == null ? void 0 : n.numberOfChannels) !== void 0 ||
- ((i = s.transform) == null ? void 0 : i.sampleRate) !== void 0
- ? (this.resampler ||
- (this.resampler = new kg({
- targetNumberOfChannels:
- s.transform.numberOfChannels ?? e.numberOfChannels,
- targetSampleRate: s.transform.sampleRate ?? e.sampleRate,
- onSample: async (o) => {
- await this.processAndEncode(o, !0);
- },
- })),
- await this.resampler.add(e))
- : await this.processAndEncode(e, t);
- } finally {
- t && e.close();
- }
- }
- async processAndEncode(e, t) {
- var i, s;
- const n = this.encodingConfig;
- if (
- ((i = n.transform) == null ? void 0 : i.sampleFormat) !== void 0 &&
- Ip(e.format) !== n.transform.sampleFormat
- ) {
- const a = Ap(e, n.transform.sampleFormat);
- (t && e.close(), (e = a), (t = !0));
- }
- if ((s = n.transform) != null && s.process)
- try {
- let a = n.transform.process(e);
- if ((O(a) && (a = await a), a === null)) return;
- Array.isArray(a) || (a = [a]);
- try {
- for (const o of a)
- if (!(o instanceof wt))
- throw new TypeError(
- "The audio process function must return an AudioSample, null, or an array of AudioSamples.",
- );
- for (const o of a) await this.encodeSample(o, !0);
- } finally {
- for (const o of a) o instanceof wt && o.close();
- }
- } finally {
- t && e.close();
- }
- else await this.encodeSample(e, t);
- }
- async encodeSample(e, t) {
- var n, i;
- try {
- if (
- (this.encoderInitialized ||
- (this.ensureEncoderPromise || this.ensureEncoder(e),
- this.encoderInitialized || (await this.ensureEncoderPromise)),
- T(this.encoderInitialized),
- this.closed)
- )
- return;
- {
- const s = Math.round(e.timestamp * e.sampleRate),
- a = Math.round((e.timestamp + e.duration) * e.sampleRate);
- if (this.lastEndSampleIndex === null) this.lastEndSampleIndex = a;
- else {
- const o = s - this.lastEndSampleIndex;
- if (o >= 64) {
- const c = new wt({
- data: new Float32Array(o * e.numberOfChannels),
- format: "f32-planar",
- sampleRate: e.sampleRate,
- numberOfChannels: e.numberOfChannels,
- numberOfFrames: o,
- timestamp: this.lastEndSampleIndex / e.sampleRate,
- });
- await this.encodeSample(c, !0);
- }
- this.lastEndSampleIndex += e.numberOfFrames;
- }
- }
- if (
- ((i = (n = this.encodingConfig).onEncodedSample) == null ||
- i.call(n, e),
- this.customEncoder)
- ) {
- this.customEncoderQueueSize++;
- const s = e.clone(),
- a = this.customEncoderCallSerializer
- .call(() => this.customEncoder.encode(s))
- .catch((o) => this.setError(o))
- .finally(() => {
- (this.customEncoderQueueSize--, s.close());
- });
- (this.customEncoderQueueSize >= 4 && (await a),
- await this.lastMuxerPromise);
- } else if (this.isPcmEncoder) await this.doPcmEncoding(e, t);
- else {
- T(this.encoder);
- const s = e.toAudioData();
- (this.encoder.encode(s),
- s.close(),
- t && e.close(),
- this.encoder.encodeQueueSize >= 4 &&
- (await new Promise((a) =>
- this.encoder.addEventListener("dequeue", a, { once: !0 }),
- )),
- await this.lastMuxerPromise);
- }
- } finally {
- t && e.close();
- }
- }
- async doPcmEncoding(e, t) {
- var m, b;
- (T(this.outputSampleSize), T(this.writeOutputValue));
- const {
- numberOfChannels: n,
- numberOfFrames: i,
- sampleRate: s,
- timestamp: a,
- } = e,
- o = 2048,
- c = [];
- for (let g = 0; g < i; g += o) {
- const y = Math.min(o, e.numberOfFrames - g),
- C = y * n * this.outputSampleSize,
- _ = new ArrayBuffer(C),
- v = new DataView(_);
- c.push({ frameCount: y, view: v });
- }
- const u = e.format === "s32" || e.format === "s32-planar",
- l = u ? "s32-planar" : "f32-planar",
- d = u ? 1 / 2147483648 : 1,
- f = e.allocationSize({ planeIndex: 0, format: l }),
- h = u ? new Int32Array(f / 4) : new Float32Array(f / 4);
- for (let g = 0; g < n; g++) {
- e.copyTo(h, { planeIndex: g, format: l });
- for (let y = 0; y < c.length; y++) {
- const { frameCount: C, view: _ } = c[y];
- for (let v = 0; v < C; v++)
- this.writeOutputValue(
- _,
- (v * n + g) * this.outputSampleSize,
- h[y * o + v] * d,
- );
- }
- }
- t && e.close();
- const p = {
- decoderConfig: {
- codec: this.encodingConfig.codec,
- numberOfChannels: n,
- sampleRate: s,
- },
- };
- for (let g = 0; g < c.length; g++) {
- const { frameCount: y, view: C } = c[g],
- _ = C.buffer,
- v = g * o,
- I = new Ee(new Uint8Array(_), "key", a + v / s, y / s);
- ((b = (m = this.encodingConfig).onEncodedPacket) == null ||
- b.call(m, I, p),
- await this.muxer.addEncodedAudioPacket(
- this.source._connectedTrack,
- I,
- p,
- ));
- }
- }
- ensureEncoder(e) {
- this.ensureEncoderPromise = (async () => {
- var o, c;
- const { numberOfChannels: t, sampleRate: n } = e,
- i = bs(this.encodingConfig.quality, this.encodingConfig.bitrate),
- s = zu({
- numberOfChannels: t,
- sampleRate: n,
- ...this.encodingConfig,
- quality: i,
- });
- ((c = (o = this.encodingConfig).onEncoderConfig) == null || c.call(o, s),
- (this.source._nominalBitrate = s.bitrate ?? null));
- const a = es.find((u) => u.supports(this.encodingConfig.codec, s));
- if (a)
- ((this.customEncoder = new a()),
- (this.customEncoder.codec = this.encodingConfig.codec),
- (this.customEncoder.config = s),
- (this.customEncoder.onPacket = (u, l) => {
- var d, f;
- if (!(u instanceof Ee))
- throw new TypeError(
- "The first argument passed to onPacket must be an EncodedPacket.",
- );
- if (l !== void 0 && (!l || typeof l != "object"))
- throw new TypeError(
- "The second argument passed to onPacket must be an object or undefined.",
- );
- ((f = (d = this.encodingConfig).onEncodedPacket) == null ||
- f.call(d, u, l),
- (this.lastMuxerPromise = this.muxer
- .addEncodedAudioPacket(this.source._connectedTrack, u, l)
- .catch((h) => {
- this.setError(h);
- })));
- }),
- (this.customEncoder.onError = (u) => {
- this.setError(u);
- }),
- await this.customEncoder.init());
- else if (ut.includes(this.encodingConfig.codec)) this.initPcmEncoder();
- else {
- if (typeof AudioEncoder > "u") throw new Error($a("AudioEncoder"));
- let u;
- try {
- u = (await AudioEncoder.isConfigSupported(s)).supported ?? !1;
- } catch {
- u = !1;
- }
- if (!u)
- throw new Error(
- `This specific encoder configuration (${s.codec}, ${s.bitrate} bps, ${s.numberOfChannels} channels, ${s.sampleRate} Hz) is not supported in this environment. Consider using another codec or changing your audio parameters.`,
- );
- const l = new Error("Encoding error").stack;
- ((this.encoder = new AudioEncoder({
- output: (d, f) => {
- var p, m;
- if (
- this.encodingConfig.codec === "aac" &&
- f != null &&
- f.decoderConfig
- ) {
- let b = !1;
- if (
- (!f.decoderConfig.description ||
- f.decoderConfig.description.byteLength < 2
- ? (b = !0)
- : (b = Xa(Ze(f.decoderConfig.description)).objectType === 0),
- b)
- ) {
- const g = Number(Ae(s.codec.split(".")));
- f.decoderConfig.description = Al({
- objectType: g,
- outputNumberOfChannels: f.decoderConfig.numberOfChannels,
- outputSampleRate: f.decoderConfig.sampleRate,
- });
- }
- }
- let h = Ee.fromEncodedChunk(d);
- ((h = h.clone({
- timestamp: Hi(h.timestamp, s.sampleRate),
- duration:
- d.duration != null ? Hi(h.duration, s.sampleRate) : void 0,
- })),
- (m = (p = this.encodingConfig).onEncodedPacket) == null ||
- m.call(p, h, f),
- (this.lastMuxerPromise = this.muxer
- .addEncodedAudioPacket(this.source._connectedTrack, h, f)
- .catch((b) => {
- this.setError(b);
- })));
- },
- error: (d) => {
- ((d.stack = l), this.setError(d));
- },
- })),
- this.encoder.configure(s));
- }
- (T(this.source._connectedTrack),
- (this.muxer = this.source._connectedTrack.output._muxer),
- (this.encoderInitialized = !0));
- })();
- }
- initPcmEncoder() {
- this.isPcmEncoder = !0;
- const e = this.encodingConfig.codec,
- { dataType: t, sampleSize: n, littleEndian: i } = Rr(e);
- switch (((this.outputSampleSize = n), n)) {
- case 1:
- t === "unsigned"
- ? (this.writeOutputValue = (s, a, o) =>
- s.setUint8(a, De(Math.round(o * 128) + 128, 0, 255)))
- : t === "signed"
- ? (this.writeOutputValue = (s, a, o) => {
- s.setInt8(a, De(Math.round(o * 128), -128, 127));
- })
- : t === "ulaw"
- ? (this.writeOutputValue = (s, a, o) => {
- const c = De(Math.round(o * 32768), -32768, 32767);
- s.setUint8(a, Wp(c));
- })
- : t === "alaw"
- ? (this.writeOutputValue = (s, a, o) => {
- const c = De(Math.round(o * 32768), -32768, 32767);
- s.setUint8(a, Up(c));
- })
- : T(!1);
- break;
- case 2:
- t === "unsigned"
- ? (this.writeOutputValue = (s, a, o) =>
- s.setUint16(a, De(Math.round(o * 32768) + 32768, 0, 65535), i))
- : t === "signed"
- ? (this.writeOutputValue = (s, a, o) =>
- s.setInt16(a, De(Math.round(o * 32768), -32768, 32767), i))
- : T(!1);
- break;
- case 3:
- t === "unsigned"
- ? (this.writeOutputValue = (s, a, o) =>
- La(s, a, De(Math.round(o * 8388608) + 8388608, 0, 16777215), i))
- : t === "signed"
- ? (this.writeOutputValue = (s, a, o) =>
- Nf(s, a, De(Math.round(o * 8388608), -8388608, 8388607), i))
- : T(!1);
- break;
- case 4:
- t === "unsigned"
- ? (this.writeOutputValue = (s, a, o) =>
- s.setUint32(
- a,
- De(Math.round(o * 2147483648) + 2147483648, 0, 4294967295),
- i,
- ))
- : t === "signed"
- ? (this.writeOutputValue = (s, a, o) =>
- s.setInt32(
- a,
- De(Math.round(o * 2147483648), -2147483648, 2147483647),
- i,
- ))
- : t === "float"
- ? (this.writeOutputValue = (s, a, o) => s.setFloat32(a, o, i))
- : T(!1);
- break;
- case 8:
- t === "float"
- ? (this.writeOutputValue = (s, a, o) => s.setFloat64(a, o, i))
- : T(!1);
- break;
- default:
- (pr(n), T(!1));
- }
- }
- async flushAndClose(e) {
- try {
- (e ||
- (this.checkForEncoderError(),
- this.resampler && (await this.resampler.finalize())),
- (this.closed = !0),
- e ||
- (this.customEncoder
- ? this.customEncoderCallSerializer.call(() =>
- this.customEncoder.flush(),
- )
- : this.encoder && (await this.encoder.flush())));
- } finally {
- ((this.closed = !0),
- (this.resampler = null),
- this.customEncoder
- ? await this.customEncoderCallSerializer
- .call(() => this.customEncoder.close())
- .catch((t) => this.setError(t))
- : this.encoder &&
- this.encoder.state !== "closed" &&
- this.encoder.close());
- }
- e || this.checkForEncoderError();
- }
- getQueueSize() {
- var e;
- return this.customEncoder
- ? this.customEncoderQueueSize
- : this.isPcmEncoder
- ? 0
- : (((e = this.encoder) == null ? void 0 : e.encodeQueueSize) ?? 0);
- }
- checkForEncoderError() {
- if (this.errorSet) throw this.error;
- }
-}
-class Ig extends Ju {
- constructor(e, t = {}) {
- if ((Fp(e), typeof t != "object" || !t))
- throw new TypeError("options must be an object.");
- if (t.startTimestamp !== void 0 && !Number.isFinite(t.startTimestamp))
- throw new TypeError(
- "options.startTimestamp, when provided, must be a finite number.",
- );
- (super(e.codec),
- (this._encoder = new Eg(this, e)),
- (this._accumulatedTime = t.startTimestamp ?? 0));
- }
- async add(e) {
- if (!(e instanceof AudioBuffer))
- throw new TypeError("audioBuffer must be an AudioBuffer.");
- const t = wt._fromAudioBuffer(e, this._accumulatedTime);
- this._accumulatedTime += e.duration;
- for (const n of t) await this._encoder.add(n, !0);
- }
- _flushAndClose(e) {
- return this._encoder.flushAndClose(e);
- }
-}
-class _g extends mo {
- constructor(e) {
- if ((super(), !oi.includes(e)))
- throw new TypeError(
- `Invalid subtitle codec '${e}'. Must be one of: ${oi.join(", ")}.`,
- );
- this._codec = e;
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ class ed {
- get supportsVideoRotationMetadata() {
- return this.supportsVideoTransformationMetadata;
- }
- getSupportedVideoCodecs() {
- return this.getSupportedCodecs().filter((e) => Rt.includes(e));
- }
- getSupportedAudioCodecs() {
- return this.getSupportedCodecs().filter((e) => fr.includes(e));
- }
- getSupportedSubtitleCodecs() {
- return this.getSupportedCodecs().filter((e) => oi.includes(e));
- }
- _codecUnsupportedHint(e) {
- return "";
- }
- _isFragmentedIsobmff() {
- return !1;
- }
-}
-class po extends ed {
- constructor(e = {}) {
- if (!e || typeof e != "object")
- throw new TypeError("options must be an object.");
- if (
- e.fastStart !== void 0 &&
- ![!1, "in-memory", "reserve", "fragmented"].includes(e.fastStart)
- )
- throw new TypeError(
- "options.fastStart, when provided, must be false, 'in-memory', 'reserve', or 'fragmented'.",
- );
- if (
- e.minimumFragmentDuration !== void 0 &&
- (!hi(e.minimumFragmentDuration) || e.minimumFragmentDuration < 0)
- )
- throw new TypeError(
- "options.minimumFragmentDuration, when provided, must be a non-negative number.",
- );
- if (e.onFtyp !== void 0 && typeof e.onFtyp != "function")
- throw new TypeError("options.onFtyp, when provided, must be a function.");
- if (e.onMoov !== void 0 && typeof e.onMoov != "function")
- throw new TypeError("options.onMoov, when provided, must be a function.");
- if (e.onMdat !== void 0 && typeof e.onMdat != "function")
- throw new TypeError("options.onMdat, when provided, must be a function.");
- if (e.onMoof !== void 0 && typeof e.onMoof != "function")
- throw new TypeError("options.onMoof, when provided, must be a function.");
- if (
- e.metadataFormat !== void 0 &&
- !["mdir", "mdta", "udta", "auto"].includes(e.metadataFormat)
- )
- throw new TypeError(
- "options.metadataFormat, when provided, must be either 'auto', 'mdir', 'mdta', or 'udta'.",
- );
- (super(), (this._options = e));
- }
- getSupportedTrackCounts() {
- return {
- video: { min: 0, max: 4294967295 },
- audio: { min: 0, max: 4294967295 },
- subtitle: { min: 0, max: 4294967295 },
- total: { min: 0, max: 4294967295 },
- };
- }
- get supportsVideoTransformationMetadata() {
- return !0;
- }
- get supportsTimestampedMediaData() {
- return !0;
- }
- get negativeTimestampSupport() {
- return "full";
- }
- _createMuxer(e) {
- return new yg(e, this);
- }
- _isFragmentedIsobmff() {
- return this._options.fastStart === "fragmented";
- }
-}
-class td extends po {
- constructor(e) {
- super(e);
- }
- get _name() {
- return "MP4";
- }
- get fileExtension() {
- return ".mp4";
- }
- get mimeType() {
- return "video/mp4";
- }
- getSupportedCodecs() {
- return [
- ...Rt,
- ...ro,
- "pcm-s16",
- "pcm-s16be",
- "pcm-s24",
- "pcm-s24be",
- "pcm-s32",
- "pcm-s32be",
- "pcm-f32",
- "pcm-f32be",
- "pcm-f64",
- "pcm-f64be",
- ...oi,
- ];
- }
- _codecUnsupportedHint(e) {
- return new rd().getSupportedCodecs().includes(e)
- ? " Switching to MOV will grant support for this codec."
- : "";
- }
-}
-class Gc extends po {
- constructor(e) {
- super(e);
- }
- get _name() {
- return "CMAF";
- }
- get fileExtension() {
- return ".m4s";
- }
- get mimeType() {
- return "video/mp4";
- }
- getSupportedCodecs() {
- return [
- ...Rt,
- ...ro,
- "pcm-s16",
- "pcm-s16be",
- "pcm-s24",
- "pcm-s24be",
- "pcm-s32",
- "pcm-s32be",
- "pcm-f32",
- "pcm-f32be",
- "pcm-f64",
- "pcm-f64be",
- ...oi,
- ];
- }
-}
-class rd extends po {
- constructor(e) {
- super(e);
- }
- get _name() {
- return "MOV";
- }
- get fileExtension() {
- return ".mov";
- }
- get mimeType() {
- return "video/quicktime";
- }
- getSupportedCodecs() {
- return [...Rt, ...fr];
- }
- _codecUnsupportedHint(e) {
- return new td().getSupportedCodecs().includes(e)
- ? " Switching to MP4 will grant support for this codec."
- : "";
- }
-}
-/*!
- * Copyright (c) 2026-present, Vanilagy and contributors
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */ const Kc = ["video", "audio", "subtitle"];
-class ki {
- constructor(e, t, n, i, s) {
- ((this.id = e),
- (this.output = t),
- (this.type = n),
- (this.source = i),
- (this.metadata = s));
- }
- isVideoTrack() {
- return this.type === "video";
- }
- isAudioTrack() {
- return this.type === "audio";
- }
- isSubtitleTrack() {
- return this.type === "subtitle";
- }
- canBePairedWith(e) {
- if (!(e instanceof ki))
- throw new TypeError("other must be an OutputTrack.");
- if (this === e) return !1;
- const t = Do(this.metadata.group),
- n = Do(e.metadata.group);
- for (const i of t)
- if (
- (this.type !== e.type && n.some((o) => i === o)) ||
- n.some((o) => i._pairedGroups.has(o))
- )
- return !0;
- return !1;
- }
-}
-class Ag extends ki {
- constructor(e, t, n, i) {
- super(e, t, "video", n, i);
- }
-}
-class Bg extends ki {
- constructor(e, t, n, i) {
- super(e, t, "audio", n, i);
- }
-}
-class Fg extends ki {
- constructor(e, t, n, i) {
- super(e, t, "subtitle", n, i);
- }
-}
-class ui {
- constructor() {
- this._pairedGroups = new Set();
- }
- pairWith(e) {
- if (!(e instanceof ui))
- throw new TypeError("other must be an OutputTrackGroup.");
- if (this === e) throw new TypeError("Cannot pair a group with itself.");
- (this._pairedGroups.add(e), e._pairedGroups.add(this));
- }
-}
-const ta = (r) => {
- if (!r || typeof r != "object")
- throw new TypeError("metadata must be an object.");
- if (r.languageCode !== void 0 && !qa(r.languageCode))
- throw new TypeError(
- "metadata.languageCode, when provided, must be a three-letter, ISO 639-2/T language code.",
- );
- if (r.name !== void 0 && typeof r.name != "string")
- throw new TypeError("metadata.name, when provided, must be a string.");
- if (
- (r.disposition !== void 0 && $f(r.disposition),
- r.maximumPacketCount !== void 0 &&
- (!Number.isInteger(r.maximumPacketCount) || r.maximumPacketCount < 0))
- )
- throw new TypeError(
- "metadata.maximumPacketCount, when provided, must be a non-negative integer.",
- );
- if (r.bitrate !== void 0 && (!Number.isFinite(r.bitrate) || r.bitrate < 0))
- throw new TypeError(
- "metadata.bitrate, when provided, must be a non-negative number.",
- );
- if (
- r.averageBitrate !== void 0 &&
- (!Number.isFinite(r.averageBitrate) || r.averageBitrate < 0)
- )
- throw new TypeError(
- "metadata.averageBitrate, when provided, must be a non-negative number.",
- );
- if (
- r.group !== void 0 &&
- !(r.group instanceof ui) &&
- (!Array.isArray(r.group) || r.group.some((e) => !(e instanceof ui)))
- )
- throw new TypeError(
- "metadata.group, when provided, must be an OutputTrackGroup instance or an array of OutputTrackGroup instances.",
- );
-};
-class Rg extends mi {
- get target() {
- const e =
- "Output.target cannot be used when using PathedTarget with an async callback. Use the 'target' event instead.";
- if (this._rootTargetPromise) throw new TypeError(e);
- const t = this._getRootTarget();
- if (O(t)) throw new TypeError(e);
- return t;
- }
- constructor(e) {
- if (
- (super(),
- (this.state = "pending"),
- (this.defaultTrackGroup = new ui()),
- (this.tracks = []),
- (this._onFinalize = null),
- (this._unfinalizedTargets = new Set()),
- (this._rootWriterPromise = null),
- (this._startPromise = null),
- (this._cancelPromise = null),
- (this._finalizePromise = null),
- (this._mutex = new Cn()),
- (this._metadataTags = {}),
- (this._rootTarget = null),
- (this._rootTargetPromise = null),
- (this._firstMediaStreamTimestamp = null),
- !e || typeof e != "object")
- )
- throw new TypeError("options must be an object.");
- if (!(e.format instanceof ed))
- throw new TypeError("options.format must be an OutputFormat.");
- if (!(e.target instanceof er || e.target instanceof Js))
- throw new TypeError("options.target must be a Target or a PathedTarget.");
- if (
- (e.target instanceof er && this._rememberTarget(e.target),
- e.initTarget !== void 0 &&
- !(e.initTarget instanceof er) &&
- typeof e.initTarget != "function")
- )
- throw new Error(
- "options.initTarget, when provided, must be a Target or a function that returns or resolves to a Target.",
- );
- if (e.onFinalize !== void 0 && typeof e.onFinalize != "function")
- throw new TypeError(
- "options.onFinalize, when provided, must be a function.",
- );
- ((this.format = e.format),
- (this._target = e.target),
- (this._onFinalize = e.onFinalize ?? null),
- (this._initTarget = e.initTarget ?? null),
- this._initTarget instanceof er && this._rememberTarget(this._initTarget),
- (this._muxer = e.format._createMuxer(this)));
- }
- _getTargetValidated(e) {
- T(this._target instanceof Js);
- const t = this._target.getTarget(e),
- n = (i) => {
- if (!(i instanceof er))
- throw new TypeError("getTarget must return a Target.");
- return i;
- };
- return O(t) ? t.then(n) : n(t);
- }
- async _getTarget(e) {
- T(this._target instanceof Js);
- const t = await this._getTargetValidated(e);
- return (
- this._emit("target", { target: t, request: e, isRoot: e.isRoot }),
- this.state === "canceled" ? await t._close() : this._rememberTarget(t),
- t
- );
- }
- _rememberTarget(e) {
- (this._unfinalizedTargets.add(e),
- e.on("finalized", () => this._unfinalizedTargets.delete(e), {
- once: !0,
- }));
- }
- async _getInitTarget() {
- if ((T(this._initTarget !== null), this._initTarget instanceof er))
- return this._initTarget;
- const e = await this._initTarget();
- return (
- this.state === "canceled" ? await e._close() : this._rememberTarget(e),
- e
- );
- }
- _hasInitTarget() {
- return this._initTarget !== null;
- }
- _getRootTarget() {
- if (this._rootTarget) return this._rootTarget;
- if (this._rootTargetPromise) return this._rootTargetPromise;
- if (this._target instanceof er)
- return (
- this._emit("target", {
- target: this._target,
- request: null,
- isRoot: !0,
- }),
- (this._rootTarget = this._target),
- this._target
- );
- const e = {
- path: this._target.rootPath,
- isRoot: !0,
- mimeType: this.format.mimeType,
- },
- t = this._getTargetValidated(e),
- n = (i) => (
- this.state === "canceled" ? i._close() : this._rememberTarget(i),
- this._emit("target", { target: i, request: e, isRoot: !0 }),
- (this._rootTarget = i),
- i
- );
- return O(t) ? (this._rootTargetPromise = t.then(n)) : n(t);
- }
- _getRootWriter(e) {
- return (
- this._rootWriterPromise ??
- (this._rootWriterPromise = (async () => {
- const t = await this._getRootTarget(),
- n = new Oa(t, typeof e == "boolean" ? e : e(t));
- return (n.start(), n);
- })())
- );
- }
- addVideoTrack(e, t = {}) {
- if (!(e instanceof Zu))
- throw new TypeError("source must be a VideoSource.");
- if (
- (ta(t), t.rotation !== void 0 && ![0, 90, 180, 270].includes(t.rotation))
- )
- throw new TypeError(
- `Invalid video rotation: ${t.rotation}. Has to be 0, 90, 180 or 270.`,
- );
- if (t.flip !== void 0 && typeof t.flip != "boolean")
- throw new TypeError("metadata.flip, when provided, must be a boolean.");
- if (
- t.transformationMatrix !== void 0 &&
- (!Array.isArray(t.transformationMatrix) ||
- t.transformationMatrix.length !== 9 ||
- !t.transformationMatrix.every((i) => Number.isFinite(i)))
- )
- throw new TypeError(
- "metadata.transformationMatrix, when provided, must be an array of 9 finite numbers.",
- );
- if (
- t.frameRate !== void 0 &&
- (!Number.isFinite(t.frameRate) || t.frameRate <= 0)
- )
- throw new TypeError(
- `Invalid video frame rate: ${t.frameRate}. Must be a positive number.`,
- );
- if (
- t.hasOnlyKeyPackets !== void 0 &&
- typeof t.hasOnlyKeyPackets != "boolean"
- )
- throw new TypeError(
- "metadata.hasOnlyKeyPackets, when provided, must be a boolean.",
- );
- if (t.canBeTransparent !== void 0 && typeof t.canBeTransparent != "boolean")
- throw new TypeError(
- "metadata.canBeTransparent, when provided, must be a boolean.",
- );
- if (
- (t.decoderConfig !== void 0 &&
- Zl({ decoderConfig: t.decoderConfig }, e._codec),
- t.primingPacket !== void 0)
- ) {
- if (!(t.primingPacket instanceof Ee))
- throw new TypeError(
- "metadata.primingPacket, when provided, must be an EncodedPacket.",
- );
- if (t.decoderConfig === void 0)
- throw new TypeError(
- "metadata.primingPacket can only be provided alongside metadata.decoderConfig.",
- );
- }
- const n = { ...t };
- return (
- n.group ?? (n.group = this.defaultTrackGroup),
- this._addTrack(new Ag(this.tracks.length + 1, this, e, n))
- );
- }
- addAudioTrack(e, t = {}) {
- if (!(e instanceof Ju))
- throw new TypeError("source must be an AudioSource.");
- if (
- (ta(t),
- t.decoderConfig !== void 0 &&
- Jl({ decoderConfig: t.decoderConfig }, e._codec),
- t.primingPacket !== void 0)
- ) {
- if (!(t.primingPacket instanceof Ee))
- throw new TypeError(
- "metadata.primingPacket, when provided, must be an EncodedPacket.",
- );
- if (t.decoderConfig === void 0)
- throw new TypeError(
- "metadata.primingPacket can only be provided alongside metadata.decoderConfig.",
- );
- }
- const n = { ...t };
- return (
- n.group ?? (n.group = this.defaultTrackGroup),
- this._addTrack(new Bg(this.tracks.length + 1, this, e, n))
- );
- }
- addSubtitleTrack(e, t = {}) {
- if (!(e instanceof _g))
- throw new TypeError("source must be a SubtitleSource.");
- ta(t);
- const n = { ...t };
- return (
- n.group ?? (n.group = this.defaultTrackGroup),
- this._addTrack(new Fg(this.tracks.length + 1, this, e, n))
- );
- }
- setMetadataTags(e) {
- if ((jf(e), this.state !== "pending"))
- throw new Error(
- "Cannot set metadata tags after output has been started or canceled.",
- );
- this._metadataTags = e;
- }
- _addTrack(e) {
- if (this.state !== "pending")
- throw new Error(
- "Cannot add track after output has been started or canceled.",
- );
- if (e.source._connectedTrack)
- throw new Error("Source is already used for a track.");
- const t = this.format.getSupportedTrackCounts(),
- n = this.tracks.reduce((a, o) => a + (o.type === e.type ? 1 : 0), 0),
- i = t[e.type].max;
- if (n === i)
- throw new Error(
- i === 0
- ? `${this.format._name} does not support ${e.type} tracks.`
- : `${this.format._name} does not support more than ${i} ${e.type} track${i === 1 ? "" : "s"}.`,
- );
- const s = t.total.max;
- if (this.tracks.length === s)
- throw new Error(
- `${this.format._name} does not support more than ${s} tracks${s === 1 ? "" : "s"} in total.`,
- );
- if (e.isVideoTrack()) {
- const a = this.format.getSupportedVideoCodecs();
- if (a.length === 0)
- throw new Error(
- `${this.format._name} does not support video tracks.` +
- this.format._codecUnsupportedHint(e.source._codec),
- );
- if (!a.includes(e.source._codec))
- throw new Error(
- `Codec '${e.source._codec}' cannot be contained within ${this.format._name}. Supported video codecs are: ${a.map((o) => `'${o}'`).join(", ")}.` +
- this.format._codecUnsupportedHint(e.source._codec),
- );
- } else if (e.isAudioTrack()) {
- const a = this.format.getSupportedAudioCodecs();
- if (a.length === 0)
- throw new Error(
- `${this.format._name} does not support audio tracks.` +
- this.format._codecUnsupportedHint(e.source._codec),
- );
- if (!a.includes(e.source._codec))
- throw new Error(
- `Codec '${e.source._codec}' cannot be contained within ${this.format._name}. Supported audio codecs are: ${a.map((o) => `'${o}'`).join(", ")}.` +
- this.format._codecUnsupportedHint(e.source._codec),
- );
- } else if (e.isSubtitleTrack()) {
- const a = this.format.getSupportedSubtitleCodecs();
- if (a.length === 0)
- throw new Error(
- `${this.format._name} does not support subtitle tracks.` +
- this.format._codecUnsupportedHint(e.source._codec),
- );
- if (!a.includes(e.source._codec))
- throw new Error(
- `Codec '${e.source._codec}' cannot be contained within ${this.format._name}. Supported subtitle codecs are: ${a.map((o) => `'${o}'`).join(", ")}.` +
- this.format._codecUnsupportedHint(e.source._codec),
- );
- }
- return (this.tracks.push(e), (e.source._connectedTrack = e), e);
- }
- hasEnoughTracks() {
- const e = this.format.getSupportedTrackCounts();
- for (const n of Kc) {
- const i = this.tracks.reduce((a, o) => a + (o.type === n ? 1 : 0), 0),
- s = e[n].min;
- if (i < s) return !1;
- }
- const t = e.total.min;
- return !(this.tracks.length < t);
- }
- async start() {
- const e = this.format.getSupportedTrackCounts();
- for (const n of Kc) {
- const i = this.tracks.reduce((a, o) => a + (o.type === n ? 1 : 0), 0),
- s = e[n].min;
- if (i < s)
- throw new Error(
- s === e[n].max
- ? `${this.format._name} requires exactly ${s} ${n} track${s === 1 ? "" : "s"}.`
- : `${this.format._name} requires at least ${s} ${n} track${s === 1 ? "" : "s"}.`,
- );
- }
- const t = e.total.min;
- if (this.tracks.length < t)
- throw new Error(
- t === e.total.max
- ? `${this.format._name} requires exactly ${t} track${t === 1 ? "" : "s"}.`
- : `${this.format._name} requires at least ${t} track${t === 1 ? "" : "s"}.`,
- );
- if (this.state === "canceled") throw new Error("Output has been canceled.");
- return this._startPromise
- ? (te._warn("Output has already been started."), this._startPromise)
- : (this._startPromise = (async () => {
- this.state = "started";
- const n = this._mutex.acquire();
- try {
- await this._muxer.start();
- const i = this.tracks.map((s) => s.source._start());
- await Promise.all(i);
- } finally {
- (await n)();
- }
- })());
- }
- getMimeType() {
- return this._muxer.getMimeType();
- }
- async cancel() {
- if (this.state === "canceled") return this._cancelPromise ?? void 0;
- if (this.state === "finalizing" || this.state === "finalized") {
- this.state === "finalized" &&
- te._warn("Output has already been finalized.");
- return;
- }
- return (this._cancelPromise = (async () => {
- this.state = "canceled";
- const e = await this._mutex.acquire();
- try {
- const t = this.tracks.map((n) =>
- n.source._flushOrWaitForOngoingClose(!0),
- );
- (await Promise.all(t),
- await Promise.all(
- [...this._unfinalizedTargets].map((n) => n._close()),
- ),
- this._unfinalizedTargets.clear());
- } finally {
- e();
- }
- })());
- }
- async finalize() {
- if (this.state === "pending")
- throw new Error("Cannot finalize before starting.");
- if (this.state === "canceled")
- throw new Error("Cannot finalize after canceling.");
- return this._finalizePromise
- ? (te._warn("Output has already been finalized."), this._finalizePromise)
- : (this._finalizePromise = (async () => {
- this.state = "finalizing";
- const e = await this._mutex.acquire();
- try {
- const t = this.tracks.map((n) =>
- n.source._flushOrWaitForOngoingClose(!1),
- );
- if (
- (await Promise.all(t),
- await this._muxer.finalize(),
- this._rootWriterPromise)
- ) {
- const n = await this._rootWriterPromise;
- n.finalized || (await n.flush(), await n.finalize());
- }
- (this._onFinalize && (await this._onFinalize()),
- (this.state = "finalized"));
- } catch (t) {
- throw ((this.state = "canceled"), t);
- } finally {
- (await Promise.all(
- [...this._unfinalizedTargets].map((t) =>
- t._close().catch(() => {}),
- ),
- ),
- this._unfinalizedTargets.clear(),
- e());
- }
- })());
- }
-}
-const J = (r, e, t = 0) => {
- var i;
- const n = r.s.cues[e];
- return n ? n.start + (((i = n.chunks[t]) == null ? void 0 : i.t0) ?? 0) : 0;
- },
- nd = (r, e) => {
- var t;
- return ((t = r.s.cues[e]) == null ? void 0 : t.end) ?? 0;
- };
-function kn(r, e, t = {}) {
- const { c: n, L: i } = r;
- if (i.P)
- return (
- (n.fillStyle = "#000"),
- n.fillRect(0, 0, i.W, i.H),
- e &&
- Qr(n, e.img, e.w, e.h, 0, 0, i.W, i.H, t.zoom ?? 1, 0.5, t.fy ?? 0.5),
- yl(n, i, 0.6, 0.5),
- { x: 0, y: 0, w: i.W, h: i.H }
- );
- gn(n, i, e, 0.5);
- const s = i.H * 0.86,
- a = e ? Math.min(s * (e.w / e.h), i.W * 0.5) : s * 0.5625,
- o = (t.cx ?? i.W * 0.69) - a / 2,
- c = (i.H - s) / 2;
- return (
- za(n, e, o, c, a, s, { zoom: t.zoom, fy: t.fy }),
- Pf(n, i, 0.35),
- { x: o, y: c, w: a, h: s }
- );
-}
-function $t(r, e, t = {}) {
- const { c: n, L: i, lt: s } = r,
- a = i.P,
- o = t.align ?? (a ? "center" : "left"),
- c = t.x ?? (a ? (i.safe.l + i.W - i.safe.r) / 2 + 20 : 150);
- let u = t.y ?? (a ? i.safe.t + 90 : i.H * 0.36);
- const l = a ? 92 : 104,
- d = t.dark ? X.ink : "#fff";
- if (t.chip) {
- const f = fe(V(s, t.chipAt ?? 0, (t.chipAt ?? 0) + 0.4));
- (Ue(n, t.chip, c, u - (a ? 10 : 30) + (1 - f) * 20, {
- size: a ? 32 : 34,
- align: o === "center" ? "center" : "left",
- alpha: f,
- bg: t.dark ? X.teal : "rgba(255,255,255,0.18)",
- }),
- (u += a ? 110 : 120));
- }
- for (const f of e) {
- const h = f.size ?? l;
- (We(n, f.s, c, u, V(s, f.at, f.at + 0.9), {
- size: h,
- color: f.color ?? d,
- align: o,
- shadow: t.dark ? 0 : 24,
- }),
- (u += h * 1.25));
- }
-}
-function ra(r, e, t, n, i, s, a = 0) {
- const o = i / e.n;
- (r.save(),
- (r.fillStyle = "#fff"),
- r.beginPath(),
- r.roundRect(t - o * 0.6, n - o * 0.6, i + o * 1.2, i + o * 1.2, 14),
- r.fill());
- for (let c = 0; c < e.n; c++)
- for (let u = 0; u < e.n; u++) {
- const l = c * e.n + u,
- d = e.cells[l];
- ((r.fillStyle = d.hex),
- a
- ? (r.beginPath(),
- r.roundRect(t + u * o + 0.5, n + c * o + 0.5, o - 1, o - 1, o * a),
- r.fill())
- : r.fillRect(t + u * o, n + c * o, o + 0.5, o + 0.5));
- }
- r.restore();
-}
-// —— 开场极简图标(v3):全部预渲染进离屏 canvas,逐帧只做 drawImage,避免卡顿 ——
-const Hk = new Map();
-function hkRR(c, x, y, w, h, r) {
- (c.beginPath(), c.roundRect(x, y, w, h, r));
-}
-function hkFinder(c, x, y, s, ink, bg) {
- ((c.fillStyle = ink), hkRR(c, x, y, s, s, s * 0.28), c.fill());
- ((c.fillStyle = bg), hkRR(c, x + s * 0.17, y + s * 0.17, s * 0.66, s * 0.66, s * 0.2), c.fill());
- ((c.fillStyle = ink), hkRR(c, x + s * 0.32, y + s * 0.32, s * 0.36, s * 0.36, s * 0.12), c.fill());
-}
-function hkSpark(c, x, y, s, col) {
- (c.save(), c.translate(x, y), (c.fillStyle = col), c.beginPath());
- for (let k = 0; k < 4; k++) {
- const a = (k * Math.PI) / 2;
- (c.lineTo(Math.cos(a) * s, Math.sin(a) * s),
- c.quadraticCurveTo(0, 0, Math.cos(a + Math.PI / 4) * s * 0.18, Math.sin(a + Math.PI / 4) * s * 0.18),
- c.quadraticCurveTo(0, 0, Math.cos(a + Math.PI / 2) * s, Math.sin(a + Math.PI / 2) * s));
- }
- (c.closePath(), c.fill(), c.restore());
-}
-function hkIcon(kind, m) {
- const key = kind + ":" + Math.round(m);
- let cv = Hk.get(key);
- if (cv) return cv;
- const S = 2,
- pad = m * 0.25,
- W = Math.ceil((m + pad * 2) * S);
- ((cv = document.createElement("canvas")), (cv.width = cv.height = W));
- const c = cv.getContext("2d");
- (c.scale(S, S), c.translate(pad, pad));
- const r = m * 0.24;
- // 柔和投影
- (c.save(),
- (c.shadowColor = "rgba(40,32,18,0.18)"),
- (c.shadowBlur = m * 0.12),
- (c.shadowOffsetY = m * 0.05),
- (c.fillStyle = kind === "ai" ? "#0f766e" : "#ffffff"),
- hkRR(c, 0, 0, m, m, r),
- c.fill(),
- c.restore());
- if (kind === "ai") {
- const g = c.createLinearGradient(0, 0, m, m);
- (g.addColorStop(0, "#2dd4bf"), g.addColorStop(1, "#0f5f73"), (c.fillStyle = g), hkRR(c, 0, 0, m, m, r), c.fill());
- ((c.font = Jn(m * 0.4, 900)), (c.textAlign = "center"), (c.textBaseline = "middle"), (c.fillStyle = "#ffffff"));
- c.fillText("AI", m * 0.47, m * 0.55);
- (hkSpark(c, m * 0.76, m * 0.25, m * 0.11, "#ffffff"), hkSpark(c, m * 0.86, m * 0.4, m * 0.05, "rgba(255,255,255,0.75)"));
- } else if (kind === "qr" || kind === "art") {
- const art = kind === "art";
- if (art) {
- const g = c.createLinearGradient(0, 0, m, m);
- (g.addColorStop(0, "#ffd6a5"), g.addColorStop(0.5, "#fdb4c8"), g.addColorStop(1, "#a5e3f0"), (c.fillStyle = g), hkRR(c, 0, 0, m, m, r), c.fill());
- } else ((c.strokeStyle = "rgba(22,32,31,0.10)"), (c.lineWidth = m * 0.012), hkRR(c, 0, 0, m, m, r), c.stroke());
- const ink = art ? "#ffffff" : X.ink,
- bg = art ? "rgba(255,255,255,0)" : "#ffffff",
- p = m * 0.17,
- f = m * 0.27;
- if (art) {
- // 艺术二维码:定位角变成白色圆角框,中间留给“画”
- for (const [x, y] of [[p, p], [m - p - f, p], [p, m - p - f]]) {
- ((c.strokeStyle = "#ffffff"), (c.lineWidth = f * 0.16), hkRR(c, x + f * 0.08, y + f * 0.08, f * 0.84, f * 0.84, f * 0.26), c.stroke());
- ((c.fillStyle = "#ffffff"), hkRR(c, x + f * 0.32, y + f * 0.32, f * 0.36, f * 0.36, f * 0.12), c.fill());
- }
- // 一笔画出的“画”:柔和曲线 + 星光
- (c.save(), (c.strokeStyle = "#ffffff"), (c.lineWidth = m * 0.045), (c.lineCap = "round"), c.beginPath());
- (c.moveTo(m * 0.56, m * 0.8), c.bezierCurveTo(m * 0.62, m * 0.56, m * 0.74, m * 0.9, m * 0.83, m * 0.6), c.stroke(), c.restore());
- (hkSpark(c, m * 0.66, m * 0.58, m * 0.075, "#ffffff"), hkSpark(c, m * 0.83, m * 0.82, m * 0.045, "rgba(255,255,255,0.85)"));
- } else {
- for (const [x, y] of [[p, p], [m - p - f, p], [p, m - p - f]]) hkFinder(c, x, y, f, ink, bg);
- // 右下角:极简示意点阵(非真实编码)
- const d = m * 0.085,
- g0 = m - p - f + f * 0.06;
- for (const [i, j] of [[0, 0], [2, 0], [1, 1], [0, 2], [2, 2]]) ((c.fillStyle = ink), hkRR(c, g0 + i * d * 1.25, g0 + j * d * 1.25, d, d, d * 0.3), c.fill());
- for (const [x, y] of [[0.5, 0.2], [0.5, 0.36], [0.2, 0.5], [0.36, 0.5]]) ((c.fillStyle = ink), hkRR(c, m * x - d / 2, m * y - d / 2, d, d, d * 0.3), c.fill());
- }
- } else if (kind === "ask") {
- ((c.fillStyle = X.ink), hkRR(c, 0, 0, m, m, r), c.fill());
- ((c.font = Jn(m * 0.6, 900)), (c.textAlign = "center"), (c.textBaseline = "middle"), (c.fillStyle = "#ffbb27"));
- c.fillText("?", m / 2, m * 0.54);
- }
- return (Hk.set(key, cv), cv);
-}
-function hkDraw(e, kind, cx, cy, m, k, a = 1) {
- if (k <= 0 || a <= 0) return;
- const cv = hkIcon(kind, m),
- s = (m * 1.5) / m;
- (e.save(), (e.globalAlpha *= a), e.translate(cx, cy), e.scale(k, k), e.drawImage(cv, (-m * s) / 2, (-m * s) / 2, m * s, m * s), e.restore());
-}
-function Mg(r) {
- const { c: e, L: t, lt: i } = r,
- s = t.P;
- Gt(e, t);
- const a = J(r, "l1", 0),
- o = J(r, "l1", 1),
- c = J(r, "l1", 2),
- u = J(r, "l1", 3),
- l = J(r, "l1", 4),
- d = s ? (t.safe.l + t.W - t.safe.r) / 2 : t.W / 2,
- E1 = i > l - 0.1 ? tr(V(i, l - 0.1, l + 0.9)) : 0,
- m = s ? 190 : 230,
- b = s ? 72 : 110,
- g = m * 3 + b * 2,
- y = d - g / 2,
- C = [y, y + m + b, y + (m + b) * 2],
- v = s ? 920 : 640;
- if (!(E1 >= 1 && !s)) {
- // 标题:固定字号 + 变换缩放,避免逐帧改字号造成的抖动
- const f = tr(V(i, o - 0.35, o + 0.1)),
- h = pt(1, 64 / (s ? 110 : 128), f),
- p = pt(s ? 900 : t.H / 2 + 40, s ? t.safe.t + 90 : 150, f);
- (e.save(),
- e.translate(d, p),
- e.scale(h, h),
- We(e, "有没有一种可能?", 0, 0, V(i, a - 0.05, a + 0.9), { size: s ? 110 : 128, color: X.ink, align: "center" }),
- e.restore());
- const rowK = tr(V(i, u - 0.3, u + 0.2)),
- _ = pt(s ? 560 : 330, s ? 440 : 250, rowK),
- I = 1 - 0.55 * rowK,
- w = (E, B, R, M, z = X.sub) => be(e, E, B, R, { size: s ? 34 : 36, weight: 700, color: z, align: "center", alpha: M }),
- x = (E, B, R, M) => be(e, E, B, R + (s ? 26 : 32), { size: s ? 84 : 100, color: X.teal, align: "center", alpha: M }),
- k = (E) => lt(V(i, E, E + 0.4)),
- S = (E) => fe(V(i, E, E + 0.3)),
- cy = _ + m / 2;
- if (i > o - 0.1) {
- (e.save(), (e.globalAlpha = I));
- (hkDraw(e, "ai", C[0] + m / 2, cy, m, k(o)),
- w("AI", C[0] + m / 2, _ + m + 56, S(o + 0.1)),
- x("+", (C[0] + m + C[1]) / 2, cy, S(o + 0.25)),
- hkDraw(e, "qr", C[1] + m / 2, cy, m, k(o + 0.45)),
- w("二维码", C[1] + m / 2, _ + m + 56, S(o + 0.55)),
- x("=", (C[1] + m + C[2]) / 2, cy, S(c - 0.1)),
- hkDraw(e, "art", C[2] + m / 2, cy, m, k(c)),
- w("艺术二维码", C[2] + m / 2, _ + m + 56, S(c + 0.1), X.teal),
- e.restore());
- }
- if (i > u - 0.1) {
- const E = k(u),
- vy = v + m / 2;
- (e.save(), e.translate(C[0] + m / 2, vy), e.scale(E, E));
- const B = m / 3.3;
- ([[-1, -1], [0, -1], [1, -1], [-1, 0], [0, 0], [1, 0], [-1, 1], [0, 1], [1, 1]].forEach(([j, se], le) => {
- const ue = lt(V(i, u + le * 0.04, u + le * 0.04 + 0.3));
- mr(e, j * B * 1.02, se * B * 1.02, B * ue, ct[le % ct.length]);
- }),
- e.restore(),
- w("拼豆", C[0] + m / 2, v + m + 56, S(u + 0.1)),
- x("+", (C[0] + m + C[1]) / 2, vy, S(u + 0.3)),
- hkDraw(e, "qr", C[1] + m / 2, vy, m, k(u + 0.6)),
- w("二维码", C[1] + m / 2, v + m + 56, S(u + 0.7)),
- x("=", (C[1] + m + C[2]) / 2, vy, S(u + 1)));
- const z = k(u + 1.15),
- q = tr(V(i, l - 0.1, l + 0.5));
- z > 0 && q < 1 && hkDraw(e, "ask", C[2] + m / 2, vy, m, z * (1 - q));
- }
- }
- if (i > l - 0.1) {
- const E = E1,
- B = pt(C[2], 0, E),
- R = pt(v, 0, E),
- M = pt(m, t.W, E),
- z = pt(m, t.H, E),
- q = r.f("show_finished");
- ((t.P || E < 1) &&
- (e.save(),
- e.beginPath(),
- e.roundRect(B, R, M, z, 28 * (1 - E)),
- e.clip(),
- t.P && ((e.fillStyle = "#000"), e.fillRect(B, R, M, z)),
- q && Qr(e, q.img, q.w, q.h, B, R, M, z, 1.06),
- e.restore()),
- !t.P &&
- E > 0 &&
- (e.save(), (e.globalAlpha = E), kn(r, q, { zoom: 1.06 }), e.restore()),
- t.P && E >= 1 && yl(e, t, 0.6, 0.5),
- $t(r, [
- { s: "可以扫码的", at: l + 0.6 },
- { s: "拼豆作品", at: l + 0.85, color: "#7dffb6" },
- ]));
- }
-}
-function Ng(r) {
- const { c: e, L: t, lt: n } = r,
- i = nd(r, "l2") - 0.15;
- if (n < i) {
- const l = kn(r, r.f("show_finished"), { zoom: 1.06 + 0.04 * (n / i) }),
- d = t.P ? 170 : 60,
- f = l.w - d * 2,
- h = Math.min(f, l.h - d * 2);
- (as(e, l.x + d, l.y + (l.h - h) / 2, f, h, n, fe(V(n, 0.1, 0.5))),
- $t(
- r,
- [
- { s: "打开微信", at: J(r, "l2", 1) },
- { s: "扫一扫", at: J(r, "l2", 1) + 0.45, color: "#7dffb6" },
- ],
- { chip: "拼好之后", chipAt: J(r, "l2", 0) },
- ));
- return;
- }
- const s = n - i;
- gn(e, t, r.f("show_finished"), 0.55);
- const a = t.P ? 1080 : 900,
- o = t.P ? t.W / 2 - 30 : t.W * 0.68,
- c = t.P ? 380 + a / 2 : t.H / 2,
- u = fe(V(s, 0, 0.45));
- (di(e, r.f("scan_final"), o, c + (1 - u) * 120, a, { alpha: u }),
- Wa(e, o, c, V(s, 0.68, 1.9), t.P ? 1.1 : 1),
- t.P
- ? We(
- e,
- "它会开口说话",
- t.W / 2 - 30,
- t.safe.t + 100,
- V(n, J(r, "l3", 0), J(r, "l3", 0) + 0.9),
- { size: 90, align: "center", shadow: 20 },
- )
- : $t(
- r,
- [
- { s: "它会", at: J(r, "l3", 0) },
- { s: "开口说话。", at: J(r, "l3", 0) + 0.25, color: "#7dffb6" },
- ],
- { chip: "藏在里面的话", chipAt: J(r, "l3", 0) },
- ));
-}
-function ts(r, e, t, n, i, s) {
- const { c: a, A: o } = r,
- c = o.images.icon,
- u = Fr(a, "豆维", i),
- l = i * 0.95,
- d = l + i * 0.25 + u,
- f = s === "center" ? e - d / 2 : e;
- (a.save(), (a.globalAlpha *= Be(n * 1.5)));
- const h = lt(n);
- (a.save(),
- a.translate(f + l / 2, t - i * 0.36),
- a.scale(h, h),
- a.beginPath(),
- a.roundRect(-l / 2, -l / 2, l, l, l * 0.24),
- a.clip(),
- a.drawImage(c, -l / 2, -l / 2, l, l),
- a.restore(),
- a.restore(),
- We(a, "豆维", f + l + i * 0.25, t, n, { size: i, color: X.ink }));
-}
-function Og(r) {
- const { c: e, L: t, A: n, lt: i } = r;
- Gt(e, t);
- const s = t.P,
- a = s ? 600 : 620,
- o = s ? t.W / 2 - 15 - a / 2 : t.W * 0.29 - a / 2,
- c = s ? 370 : (t.H - a) / 2,
- u = o + a / 2,
- l = c + a / 2,
- d = 0;
- const h = lt(V(i, 0.2, 0.75));
- if (h > 0) {
- const b = n.images.mpcode;
- (e.save(),
- e.translate(u, l),
- e.scale(h, h),
- e.rotate((1 - Math.min(1, h)) * -0.3),
- (e.shadowColor = "rgba(20,40,30,0.25)"),
- (e.shadowBlur = 50),
- (e.shadowOffsetY = 16),
- (e.fillStyle = "#fff"),
- e.beginPath(),
- e.roundRect(-a / 2, -a / 2, a, a, a * 0.12),
- e.fill(),
- (e.shadowColor = "transparent"));
- const g = a * 0.86;
- (e.beginPath(),
- e.roundRect(-g / 2, -g / 2, g, g, g * 0.06),
- e.clip(),
- e.drawImage(b, -g / 2, -g / 2, g, g),
- e.restore());
- const y = fe(V(i, 0.9, 1.3));
- Ue(e, "微信扫码 · 打开豆维", u, c + a + (s ? 90 : 72), {
- size: s ? 32 : 30,
- bg: X.green,
- align: "center",
- alpha: y,
- });
- }
- const p = J(r, "l4", 0),
- m = J(r, "l4", 1);
- if (s)
- (ts(r, t.W / 2 - 15, 1200, V(i, p - 0.1, p + 0.6), 150, "center"),
- We(e, "可扫码的拼豆", t.W / 2 - 15, 1310, V(i, m, m + 0.8), {
- size: 64,
- color: X.teal,
- align: "center",
- }));
- else {
- const b = t.W * 0.56;
- (ts(r, b, 520, V(i, p - 0.1, p + 0.6), 190, "left"),
- We(e, "可扫码的拼豆", b + 6, 650, V(i, m, m + 0.8), {
- size: 76,
- color: X.teal,
- }));
- const g = V(i, m + 0.5, m + 1.1);
- Ue(e, "MARD 拼豆图纸生成器", b + 6, 750, { size: 30, alpha: g, bg: X.ink });
- }
-}
-function Dg(r) {
- const { c: e, L: t, lt: n } = r,
- i = J(r, "l6", 0);
- if (n < i) {
- (kn(r, r.f("show_normal"), { zoom: 1.04 + (0.03 * n) / i }),
- $t(r, [{ s: "只能用来看。", at: J(r, "l5", 1) }], {
- chip: "普通拼豆",
- chipAt: J(r, "l5", 0),
- }));
- return;
- }
- const s = n - i;
- gn(e, t, r.f("scan_fail"), 0.6);
- const a = t.P ? 1060 : 900,
- o = t.P ? t.W / 2 - 30 : t.W * 0.68,
- c = t.P ? 390 + a / 2 : t.H / 2,
- u = fe(V(s, 0, 0.4)),
- l = di(e, r.f("scan_fail"), o, c + (1 - u) * 100, a, { alpha: u });
- as(
- e,
- l.sx + l.sw * 0.12,
- l.sy + l.sh * 0.3,
- l.sw * 0.76,
- l.sw * 0.76,
- s,
- u * 0.9,
- );
- const d = J(r, "l6", 1),
- f = J(r, "l6", 2),
- h = J(r, "l6", 3);
- if (t.P) {
- We(e, "想拼一个二维码?", t.W / 2 - 30, t.safe.t + 100, V(n, i, i + 0.9), {
- size: 80,
- align: "center",
- shadow: 20,
- });
- const m = l.sy + l.sh * 0.78,
- b = fe(V(n, d, d + 0.3)),
- g = fe(V(n, f, f + 0.3));
- (Ue(e, "✕ 颜色差一点", o - 150, m + (1 - b) * 30, {
- size: 36,
- bg: X.red,
- align: "center",
- alpha: b,
- }),
- Ue(e, "✕ 格子错一格", o + 150, m + 90 + (1 - g) * 30, {
- size: 36,
- bg: X.red,
- align: "center",
- alpha: g,
- }));
- } else {
- $t(r, [
- { s: "想拼一个", at: i },
- { s: "二维码?", at: i + 0.3 },
- ]);
- const m = fe(V(n, d, d + 0.3)),
- b = fe(V(n, f, f + 0.3));
- (Ue(e, "✕ 颜色差一点", 150 + (1 - m) * -40, 760, {
- size: 40,
- bg: X.red,
- alpha: m,
- }),
- Ue(e, "✕ 格子错一格", 150 + (1 - b) * -40, 860, {
- size: 40,
- bg: X.red,
- alpha: b,
- }));
- }
- const p = V(n, h, h + 0.3);
- if (p > 0) {
- (e.save(), e.translate(o, c), e.rotate(-0.16));
- const m = 1 + (1 - fe(p)) * 1.4;
- (e.scale(m, m),
- (e.globalAlpha = fe(p)),
- (e.strokeStyle = X.red),
- (e.lineWidth = 10));
- const b = t.P ? 560 : 520,
- g = 170;
- ((e.fillStyle = "rgba(255,255,255,0.88)"),
- e.beginPath(),
- e.roundRect(-b / 2, -g / 2, b, g, 24),
- e.fill(),
- e.stroke(),
- be(e, "扫不出来", 0, 34, { size: 96, color: X.red, align: "center" }),
- e.restore());
- }
-}
-function zg(r) {
- const { c: e, L: t, lt: n } = r;
- Gt(e, t);
- const i = t.P,
- s = i ? 900 : 920,
- a = i ? t.W / 2 - 30 : t.W * 0.7,
- o = i ? 470 + s / 2 : t.H / 2 + 10,
- c = fe(V(n, 0.05, 0.6));
- if (
- (di(e, r.f("app_demo"), a, o + (1 - c) * 160, s, {
- alpha: c,
- rot: (1 - c) * 0.08,
- }),
- i)
- )
- (We(
- e,
- "把最难的部分",
- t.W / 2 - 30,
- t.safe.t + 80,
- V(n, J(r, "l7", 1), J(r, "l7", 1) + 0.7),
- { size: 78, color: X.ink, align: "center" },
- ),
- We(
- e,
- "交给算法",
- t.W / 2 - 30,
- t.safe.t + 180,
- V(n, J(r, "l7", 1) + 0.35, J(r, "l7", 1) + 1.1),
- { size: 96, color: X.teal, align: "center" },
- ));
- else {
- $t(
- r,
- [
- { s: "把最难的部分", at: J(r, "l7", 1), color: X.ink, size: 92 },
- { s: "交给算法", at: J(r, "l7", 1) + 0.35, color: X.teal, size: 128 },
- ],
- { chip: "豆维 · 微信小程序", chipAt: 0.1, dark: !0, y: 330 },
- );
- const u = ["写一句话", "选张照片", "导出图纸"];
- let l = 150;
- u.forEach((d, f) => {
- const h = fe(V(n, 1.6 + f * 0.25, 2 + f * 0.25)),
- p = Ue(e, `${f + 1} ${d}`, l, 810 + (1 - h) * 20, {
- size: 32,
- bg: "#fff",
- color: X.ink,
- alpha: h,
- });
- l += p + 18;
- });
- }
-}
-const Xc = new Map();
-function Wg(r) {
- let e = Xc.get(r);
- return (e || ((e = ll(ol(r, "Q"))), Xc.set(r, e)), e);
-}
-function go(r, e, t, n, i) {
- const s = e.P,
- a = s ? e.safe.l + 10 : 150,
- o = s ? e.safe.t + 70 : 180;
- (r.save(),
- (r.globalAlpha = i),
- be(r, `0${t}`, a, o + 20 + (1 - i) * 30, {
- size: s ? 120 : 150,
- color: "rgba(15,118,110,0.16)",
- font: wl,
- }),
- Ue(r, `STEP ${t}`, a + (s ? 150 : 190), o - 30, { size: 28, bg: X.teal }),
- be(r, n, a + (s ? 150 : 190), o + 40, { size: s ? 60 : 64, color: X.ink }),
- r.restore());
-}
-function Ug(r) {
- const { c: e, L: t, lt: n } = r;
- Gt(e, t);
- const i = t.P;
- go(e, t, 1, "写一句话", fe(V(n, 0, 0.5)));
- const s = J(r, "l8", 1),
- a = Be(Math.floor((n - s) / ua) + 1, 0, [...Wi].length),
- o = [...Wi].slice(0, n < s ? 0 : a).join(""),
- c = i ? 860 : 760,
- u = 330,
- l = i ? t.safe.l + 10 : 150,
- d = i ? 410 : 330,
- f = fe(V(n, 0.15, 0.6));
- (e.save(),
- (e.globalAlpha = f),
- e.translate(0, (1 - f) * 40),
- (e.shadowColor = "rgba(40,30,10,0.18)"),
- (e.shadowBlur = 40),
- (e.shadowOffsetY = 12),
- (e.fillStyle = "#fff"),
- e.beginPath(),
- e.roundRect(l, d, c, u, 32),
- e.fill(),
- (e.shadowColor = "transparent"),
- (e.fillStyle = X.teal),
- e.beginPath(),
- e.arc(l + 60, d + 62, 26, 0, Math.PI * 2),
- e.fill(),
- be(e, "1", l + 60, d + 74, { size: 32, align: "center" }),
- be(e, "扫码后要看到什么?", l + 104, d + 72, {
- size: 38,
- color: X.ink,
- weight: 800,
- }),
- be(e, "一句祝福、一个网址,或者你的名字", l + 104, d + 114, {
- size: 26,
- color: X.sub,
- weight: 500,
- }),
- (e.fillStyle = "#f6f5f1"),
- e.beginPath(),
- e.roundRect(l + 34, d + 150, c - 68, 140, 20),
- e.fill(),
- (e.strokeStyle = o ? X.teal : "#e3e0d8"),
- (e.lineWidth = 3),
- e.stroke());
- const h = i ? 44 : 40;
- if (
- (be(e, o || "Happy Birthday!", l + 60, d + 220, {
- size: h,
- color: o ? X.ink : "#b8b4aa",
- weight: 700,
- }),
- Math.floor(n * 2.2) % 2 === 0 || (o && n < s + a * ua + 0.3))
- ) {
- const _ = o ? Fr(e, o, h, 700) : 0;
- ((e.fillStyle = X.teal), e.fillRect(l + 62 + _, d + 182, 4, 50));
- }
- (be(e, `${[...o].length}/300`, l + c - 60, d + 272, {
- size: 22,
- color: "#a19d93",
- weight: 500,
- align: "right",
- }),
- e.restore());
- const p = Wg(o || "Happy Birthday!"),
- m = i ? 560 : 600,
- b = i ? t.W / 2 - 30 - m / 2 : t.W * 0.73 - m / 2,
- g = i ? 830 : (t.H - m) / 2 + 20,
- y = fe(V(n, 0.4, 0.9));
- (e.save(),
- (e.globalAlpha = y * (o ? 1 : 0.4)),
- ss(e, p, b, g, m),
- e.restore());
- const C = o ? `实时生成 · ${p.n}×${p.n} 格` : "示例二维码";
- if (
- (Ue(e, C, b + m / 2, g + m + 70, {
- size: 28,
- align: "center",
- bg: o ? X.teal : "#9a958a",
- alpha: y,
- }),
- !i)
- ) {
- const _ = J(r, "l8", 2);
- ["祝福", "网址", "名字"].forEach((I, w) => {
- const x = fe(V(n, _ + w * 0.3, _ + w * 0.3 + 0.35));
- Ue(e, I, 150 + w * 150, 760 + (1 - x) * 20, {
- size: 34,
- bg: "#fff",
- color: X.teal,
- alpha: x,
- });
- });
- }
-}
-const Hg = { hook: Mg, scan: Ng, title: Og, problem: Dg, algo: zg, step1: Ug };
-function Vg(r) {
- const { c: e, L: t, A: n, lt: i } = r;
- Gt(e, t);
- const s = t.P;
- go(e, t, 2, "选一张照片", fe(V(i, 0, 0.5)));
- const a = s ? 800 : 760,
- o = s ? t.W / 2 - 30 - a / 2 : t.W * 0.66 - a / 2,
- c = s ? 420 : (t.H - a) / 2 + 10,
- u = J(r, "l9", 1) - 0.1,
- l = J(r, "l9", 2),
- d = fe(V(i, u, u + 0.5)),
- f = n.photo,
- h = n.fused,
- p = a / h.n,
- m = pt(-0.1, 1.15, tr(V(i, l, l + 2.2)));
- if (
- (e.save(),
- (e.globalAlpha = d),
- e.translate(0, (1 - d) * 60),
- (e.shadowColor = "rgba(40,30,10,0.25)"),
- (e.shadowBlur = 40),
- (e.shadowOffsetY = 14),
- (e.fillStyle = "#fff"),
- e.fillRect(o - 24, c - 24, a + 48, a + 48),
- (e.shadowColor = "transparent"),
- Qr(e, f, f.width, f.height, o, c, a, a),
- m > -0.1)
- ) {
- e.fillStyle = "#fbfaf6";
- const y = o + Be(m) * a;
- e.fillRect(o, c, y - o, a);
- for (let C = 0; C < h.n; C++)
- for (let _ = 0; _ < h.n; _++) {
- const v = (_ + 0.5) / h.n,
- I = lt(V(m - v, 0, 0.08));
- I > 0 &&
- mr(
- e,
- o + (_ + 0.5) * p,
- c + (C + 0.5) * p,
- p * I,
- h.cells[C * h.n + _].hex,
- );
- }
- if (m < 1.05) {
- const C = o + Be(m) * a,
- _ = e.createLinearGradient(C - 60, 0, C + 10, 0);
- (_.addColorStop(0, "rgba(20,184,166,0)"),
- _.addColorStop(1, "rgba(20,184,166,0.6)"),
- (e.fillStyle = _),
- e.fillRect(C - 60, c, 70, a),
- (e.fillStyle = "#5eead4"),
- e.fillRect(C - 2, c - 10, 5, a + 20));
- }
- }
- e.restore();
- const b = V(i, u, u + 0.25);
- b > 0 &&
- b < 1 &&
- ((e.fillStyle = `rgba(255,255,255,${(1 - b) * 0.7})`),
- e.fillRect(0, 0, t.W, t.H));
- const g = fe(V(i, l + 1.6, l + 2.1));
- s
- ? Ue(e, "二维码 · 融进照片", t.W / 2 - 30, c + a + 90, {
- size: 34,
- align: "center",
- alpha: g,
- })
- : (We(e, "二维码", 150, 560, V(i, l, l + 0.8), { size: 96, color: X.ink }),
- We(e, "悄悄融进画面", 150, 690, V(i, l + 0.3, l + 1.1), {
- size: 96,
- color: X.teal,
- }),
- Ue(e, "不选照片 = 纯二维码", 150, 800, {
- size: 30,
- bg: "#fff",
- color: X.sub,
- alpha: g,
- }));
-}
-const Lg = new Map(Ln.map((r, e) => [r.id, e]));
-function qg(r) {
- const { c: e, L: t, A: n, lt: i, s } = r;
- Gt(e, t);
- const a = t.P,
- o = n.fused,
- c = a ? 600 : 700,
- u = a ? t.W / 2 - 30 - c / 2 : 150,
- l = a ? t.safe.t + 60 : (t.H - c) / 2;
- ss(e, o, u, l, c);
- const d = a ? 21 : 17,
- f = a ? 42 : 46,
- h = Math.ceil(Ln.length / d),
- p = a ? (t.W - 30 - d * f) / 2 : 1e3,
- m = a ? l + c + 120 : 300,
- b = (w) =>
- fe(V(i, 0.2 + (w / Ln.length) * 1.4, 0.5 + (w / Ln.length) * 1.4)),
- g = 0.42,
- y = Math.floor(Math.max(0, i - 0.6) / g),
- C = o.cells
- .map((w, x) => ({ cl: w, i: x }))
- .filter((w) => w.cl.id !== "H2" || w.cl.dark),
- _ = i > 0.6 && i < s.dur - 0.2 ? C[Math.floor(Ye(y + 5) * C.length)] : null,
- v = _ ? (Lg.get(_.cl.id) ?? -1) : -1;
- Ln.forEach((w, x) => {
- const k = b(x);
- if (k <= 0) return;
- const S = Math.floor(x / d),
- E = x % d,
- B = p + E * f + f / 2,
- R = m + S * f + f / 2;
- ((e.fillStyle = w.hex),
- (e.globalAlpha = k * (v >= 0 && v !== x ? 0.75 : 1)),
- e.beginPath(),
- e.roundRect(
- B - f * 0.42 * k,
- R - f * 0.42 * k,
- f * 0.84 * k,
- f * 0.84 * k,
- 8,
- ),
- e.fill(),
- (e.globalAlpha = 1));
- });
- const I = Math.round(221 * fe(V(i, 0.2, 1.8)));
- if (
- (a
- ? (be(e, `${I}`, p, m - 30, { size: 72, color: X.teal }),
- be(e, "MARD 标准色", p + 150, m - 36, {
- size: 34,
- color: X.ink,
- weight: 800,
- }))
- : (be(e, `${I}`, p, m - 50, { size: 120, color: X.teal }),
- be(e, "种 MARD 标准色", p + 230, m - 62, {
- size: 44,
- color: X.ink,
- weight: 800,
- }),
- We(
- e,
- "每一格:最像,又最好扫",
- p,
- m + h * f + 90,
- V(i, J(r, "l10", 1), J(r, "l10", 1) + 1),
- { size: 50, color: X.ink },
- )),
- _ && v >= 0)
- ) {
- const w = c / o.n,
- x = Math.floor(_.i / o.n),
- k = _.i % o.n,
- S = u + (k + 0.5) * w,
- E = l + (x + 0.5) * w,
- B = Math.floor(v / d),
- R = v % d,
- M = p + R * f + f / 2,
- z = m + B * f + f / 2,
- q = fe(V((i - 0.6) % g, 0, 0.18));
- (e.save(),
- (e.strokeStyle = X.ink),
- (e.lineWidth = 4),
- e.setLineDash([10, 8]),
- e.beginPath(),
- e.moveTo(S, E),
- e.lineTo(pt(S, M, q), pt(E, z, q)),
- e.stroke(),
- e.setLineDash([]),
- (e.lineWidth = 5),
- e.beginPath(),
- e.arc(S, E, w * 0.9, 0, Math.PI * 2),
- e.stroke(),
- q > 0.95 &&
- ((e.fillStyle = _.cl.hex),
- (e.shadowColor = "rgba(0,0,0,0.3)"),
- (e.shadowBlur = 20),
- e.beginPath(),
- e.roundRect(M - 46, z - 46, 92, 92, 16),
- e.fill(),
- (e.shadowColor = "transparent"),
- (e.strokeStyle = "#fff"),
- (e.lineWidth = 5),
- e.stroke(),
- Ue(e, _.cl.id, M, z - 84, { size: 30, align: "center", bg: X.ink })),
- e.restore());
- }
-}
-function na(r, e, t, n, i, s, a, o) {
- Ue(r, e, t, n + (1 - a) * 20, {
- size: o,
- align: "center",
- bg: s,
- color: i,
- alpha: a,
- weight: 800,
- });
-}
-function jg(r) {
- const { c: e, L: t, A: n, lt: i } = r;
- Gt(e, t);
- const s = t.P,
- a = J(r, "l11", 0),
- o = J(r, "l11", 1),
- c = J(r, "l11", 2),
- u = J(r, "l11", 3),
- l = s ? 700 : 720,
- d = s ? t.W / 2 - 30 - l / 2 : t.W * 0.33 - l / 2,
- f = s ? t.safe.t + 50 : (t.H - l) / 2,
- h = V(i, u + 0.15, u + 0.75),
- p = n.fused,
- m = n.weak,
- b = (p.n - 1) / 2;
- ss(e, p, d, f, l, {
- k: (I, w, x) => {
- const k = Math.hypot(I - b, w - b) / Math.hypot(b, b),
- S = lt(V(i, a + k * 0.5, a + k * 0.5 + 0.3)),
- B =
- m.cells[x].hex !== p.cells[x].hex && h > 0 && h < 1
- ? 1 + Math.sin(h * Math.PI) * 0.35
- : 1;
- return S * B;
- },
- hex: (I) => (h < 0.5 ? m.cells[I].hex : p.cells[I].hex),
- });
- const g = i > o && i < c + 0.2;
- as(e, d - 30, f - 30, l + 60, l + 60, i - o, g ? 1 : 0);
- const y = s ? t.W / 2 - 30 : t.W * 0.74,
- C = s ? f + l + 130 : t.H * 0.42,
- _ = s ? 36 : 40;
- (i > o &&
- i < c &&
- na(e, "正在检查能否扫出…", y, C, X.ink, "#fff", fe(V(i, o, o + 0.3)), _),
- i >= c &&
- i < u + 0.55 &&
- na(
- e,
- "! 自检未扫出,建议优化",
- y,
- C,
- "#fff",
- X.orange,
- fe(V(i, c, c + 0.3)),
- _,
- ),
- i >= u + 0.55 &&
- na(
- e,
- "✓ 自检通过,可以扫出内容",
- y,
- C,
- "#fff",
- X.teal,
- lt(V(i, u + 0.55, u + 0.9)),
- _,
- ));
- const v = fe(V(i, c + 0.2, c + 0.5));
- if (v > 0) {
- const I = i > u + 0.1 && i < u + 0.3 ? 0.92 : 1;
- (e.save(),
- e.translate(y, C + (s ? 120 : 140)),
- e.scale(I, I),
- (e.globalAlpha = v * (i > u + 0.9 ? 0.4 : 1)),
- (e.fillStyle = X.orange),
- e.beginPath(),
- e.roundRect(-150, -42, 300, 84, 42),
- e.fill(),
- be(e, "一键优化", 0, 15, { size: 40, align: "center" }),
- e.restore());
- const w = V(i, u - 0.3, u + 0.1);
- w > 0 &&
- i < u + 0.6 &&
- (e.save(),
- (e.globalAlpha = Be(1.6 - (i - u) * 2.5)),
- (e.fillStyle = "rgba(15,118,110,0.35)"),
- e.beginPath(),
- e.arc(
- y + 40,
- C + (s ? 120 : 140) + pt(120, 10, fe(w)),
- 34,
- 0,
- Math.PI * 2,
- ),
- e.fill(),
- e.restore());
- }
- (Wa(e, d + l / 2, f + l / 2, V(i, u + 0.55, u + 1.6), 1),
- s ||
- We(e, "手机先替你扫一遍", y, t.H * 0.27, V(i, o, o + 0.9), {
- size: 64,
- color: X.ink,
- align: "center",
- }));
-}
-function Qc(r, e, t, n, i, s, a) {
- const o = i * (e.naturalWidth / e.naturalHeight);
- return (
- r.save(),
- (r.globalAlpha = a),
- r.translate(t, n),
- r.rotate(s),
- (r.shadowColor = "rgba(40,30,10,0.3)"),
- (r.shadowBlur = 50),
- (r.shadowOffsetY = 20),
- (r.fillStyle = "#fff"),
- r.fillRect(-o / 2 - 18, -i / 2 - 18, o + 36, i + 36),
- (r.shadowColor = "transparent"),
- r.drawImage(e, -o / 2, -i / 2, o, i),
- r.restore(),
- o
- );
-}
-function $g(r) {
- const { c: e, L: t, A: n, lt: i } = r;
- Gt(e, t, "#ece6d9");
- const s = t.P;
- go(e, t, 3, "导出图纸", fe(V(i, 0, 0.5)));
- const a = J(r, "l12", 1),
- o = J(r, "l12", 2),
- c = J(r, "l12", 3),
- u = n.images.chart,
- l = n.images.usage,
- d = fe(V(i, a - 0.1, a + 0.5)),
- f = 760,
- h = s ? t.W / 2 - 40 : t.W * 0.36,
- p = s ? 420 + f / 2 : t.H / 2 + 50;
- Qc(e, u, h + (1 - d) * -300, p + (1 - d) * 200, f, pt(-0.25, -0.03, d), d);
- const m = fe(V(i, o, o + 0.4));
- if (m > 0 && i < c + 0.6) {
- const g = (s ? 190 : 200) * m,
- y = h + f * 0.12,
- C = p - f * 0.08,
- _ = 5;
- (e.save(),
- (e.globalAlpha = Be((c + 0.6 - i) * 3)),
- e.beginPath(),
- e.arc(y, C, g, 0, Math.PI * 2),
- (e.shadowColor = "rgba(0,0,0,0.35)"),
- (e.shadowBlur = 30),
- (e.fillStyle = "#fff"),
- e.fill(),
- (e.shadowColor = "transparent"),
- e.clip());
- const v = ((y - h) / f + 0.5) * u.naturalWidth,
- I = ((C - p) / f + 0.5) * u.naturalHeight,
- w = (((g * 2) / f) * u.naturalWidth) / _;
- (e.drawImage(u, v - w / 2, I - w / 2, w, w, y - g, C - g, g * 2, g * 2),
- e.restore(),
- e.save(),
- (e.globalAlpha = Be((c + 0.6 - i) * 3)),
- (e.strokeStyle = X.ink),
- (e.lineWidth = 12),
- e.beginPath(),
- e.arc(y, C, g, 0, Math.PI * 2),
- e.stroke(),
- (e.lineCap = "round"),
- (e.lineWidth = 26),
- e.beginPath(),
- e.moveTo(y + g * 0.72, C + g * 0.72),
- e.lineTo(y + g * 1.15, C + g * 1.15),
- e.stroke(),
- e.restore());
- }
- const b = fe(V(i, c - 0.1, c + 0.5));
- if (b > 0) {
- const g = s ? 700 : 820,
- y = s ? t.W * 0.6 : t.W * 0.72,
- C = s ? 980 : t.H / 2 + 30;
- Qc(e, l, y + (1 - b) * 400, C, g, pt(0.3, 0.05, b), b);
- }
- if (!s) {
- const g = fe(V(i, a + 0.2, a + 0.6));
- Ue(e, "A4 矢量 PDF", 150, 330, { size: 32, alpha: g, bg: X.ink });
- const y = fe(V(i, o, o + 0.4));
- Ue(e, "每格印色号", 150, 410, { size: 32, alpha: y });
- const C = fe(V(i, c, c + 0.4));
- Ue(e, "用豆清单", 150, 490, { size: 32, alpha: C, bg: X.orange });
- }
-}
-function Gg(r) {
- const { c: e, L: t, lt: n } = r,
- i = ["p_half1", "p_half2", "p_almost"],
- s = ["一颗", "一颗", "再一颗"],
- a = [J(r, "l14", 0), J(r, "l14", 1), J(r, "l14", 2)],
- o = 0.32,
- c = J(r, "l13", 1);
- if (t.P) {
- let d = -1;
- for (let y = 0; y < 3; y++) n >= a[y] - o - 0.15 && (d = y);
- if (((e.fillStyle = "#000"), e.fillRect(0, 0, t.W, t.H), d < 0)) {
- (gn(e, t, r.im("p_half1"), 0.45),
- We(
- e,
- "剩下的",
- t.W / 2 - 45,
- 820,
- V(n, J(r, "l13", 0), J(r, "l13", 0) + 0.6),
- { size: 80, align: "center", shadow: 24 },
- ),
- We(e, "交给双手", t.W / 2 - 45, 960, V(n, c, c + 0.7), {
- size: 120,
- align: "center",
- shadow: 24,
- color: "#7dffb6",
- }));
- return;
- }
- const f = a[d] - o - 0.15,
- h = r.im(i[d]);
- h &&
- Qr(e, h.img, h.w, h.h, 0, 0, t.W, t.H, 1.08 + (n - f) * 0.05, 0.5, 0.5);
- const p = e.createLinearGradient(0, 0, 0, 600);
- (p.addColorStop(0, "rgba(0,0,0,0.5)"),
- p.addColorStop(1, "rgba(0,0,0,0)"),
- (e.fillStyle = p),
- e.fillRect(0, 0, t.W, 600));
- const m = t.W - t.safe.r - 90,
- b = t.safe.t + 120;
- for (let y = 0; y <= d; y++) {
- const C = y === d ? n - (a[y] - o) : 10;
- ha(e, m - y * 120, b, 104, ct[[0, 2, 1][y]], C, 360);
- }
- const g = lt(V(n, a[d], a[d] + 0.3));
- be(e, s[d], t.safe.l + 30, t.safe.t + 160, {
- size: 96 * Math.max(0.3, g),
- alpha: Be(g),
- shadow: 20,
- });
- return;
- }
- (gn(e, t, r.im("p_almost"), 0.55),
- We(
- e,
- "剩下的,交给双手",
- t.W / 2,
- 140,
- V(n, J(r, "l13", 0), J(r, "l13", 0) + 0.9),
- { size: 72, align: "center", shadow: 24 },
- ));
- const u = 480,
- l = 640;
- i.forEach((d, f) => {
- const h = a[f] - o - 0.35,
- p = fe(V(n, h, h + 0.35));
- if (p <= 0) return;
- const m = t.W / 2 + (f - 1) * (u + 60) - u / 2,
- b = 250 + (1 - p) * 120;
- (za(e, r.im(d), m, b, u, l, {
- alpha: p,
- zoom: 1.05 + (n - h) * 0.02,
- border: n >= a[f] ? "#fff" : void 0,
- }),
- ha(e, m + u - 46, b + 46, 96, ct[[0, 2, 1][f]], n - (a[f] - o), 300));
- const g = fe(V(n, a[f], a[f] + 0.3));
- Ue(e, s[f], m + u / 2, b + l - 56, {
- size: 40,
- align: "center",
- alpha: g,
- bg: X.teal,
- weight: 900,
- });
- });
-}
-function Kg(r) {
- const { c: e, L: t, lt: n } = r,
- i = J(r, "l15", 1) - 0.1,
- s = J(r, "l15", 2) - 0.1;
- let a, o, c;
- n < i
- ? ((a = r.im("p_last")), (o = "最后一颗"), (c = 0.2))
- : n < s
- ? ((a = r.f("cover_paper")), (o = "盖上烫纸"), (c = i))
- : ((a = r.f("ironing")), (o = "慢慢熨平"), (c = s));
- const u = n - c,
- l = kn(r, a, { zoom: n < i ? 1.18 - 0.05 * n : 1.02 + 0.02 * u });
- if (n < i + 0.3) {
- const d = J(r, "l15", 0) + 0.5,
- f = t.P ? t.W - t.safe.r - 110 : l.x + l.w - 80,
- h = t.P ? t.safe.t + 330 : l.y + 90;
- (e.save(),
- (e.globalAlpha = 1 - V(n, i, i + 0.3)),
- ha(e, f, h, t.P ? 130 : 120, "#ffbb27", n - (d - 0.32), 420),
- e.restore());
- }
- $t(r, [{ s: o, at: c }], {});
-}
-function Xg(r) {
- const { c: e, L: t, lt: n } = r,
- i = nd(r, "l16") + 0.3;
- gn(e, t, r.f("scan_paper"), 0.6);
- const s = t.P,
- a = s ? 1060 : 920,
- o = s ? t.W / 2 - 30 : t.W * 0.66,
- c = s ? 400 + a / 2 : t.H / 2,
- u = fe(V(n, 0, 0.4)),
- l = di(e, r.f("scan_paper"), o, c + (1 - u) * 100, a, { alpha: u });
- if (
- (n < i &&
- as(
- e,
- l.sx + l.sw * 0.12,
- l.sy + l.sh * 0.3,
- l.sw * 0.76,
- l.sw * 0.76,
- n,
- u * 0.9,
- ),
- Wa(e, o, c, V(n, i, i + 1.3), s ? 1.15 : 1.1),
- Cf(e, o, c, V(n, i, i + 1.6), 46, s ? 560 : 640, 7),
- s)
- ) {
- We(
- e,
- "揭开之前,先扫一下",
- t.W / 2 - 30,
- t.safe.t + 100,
- V(n, J(r, "l16", 0), J(r, "l16", 0) + 1),
- { size: 72, align: "center", shadow: 20 },
- );
- const d = lt(V(n, i + 0.05, i + 0.45));
- d > 0 &&
- (e.save(),
- e.translate(o, l.sy + l.sh * 0.82),
- e.scale(d, d),
- be(e, "扫出来了!", 0, 0, {
- size: 120,
- align: "center",
- color: "#7dffb6",
- stroke: "rgba(0,0,0,0.55)",
- strokeW: 14,
- }),
- e.restore());
- } else {
- $t(
- r,
- [
- { s: "揭开之前", at: J(r, "l16", 0) },
- { s: "先扫一下", at: J(r, "l16", 1) },
- ],
- { chip: "烫纸还盖着", chipAt: 0.2 },
- );
- const d = lt(V(n, i + 0.05, i + 0.45));
- d > 0 &&
- (e.save(),
- e.translate(150, 840),
- e.scale(d, d),
- be(e, "扫出来了!", 0, 0, {
- size: 130,
- color: "#7dffb6",
- stroke: "rgba(0,0,0,0.4)",
- strokeW: 12,
- }),
- e.restore());
- }
-}
-function Qg(r) {
- const { c: e, L: t, lt: n } = r,
- i = 2.9;
- if (n < i) kn(r, r.f("peel"), { zoom: 1.04 + n * 0.02 });
- else {
- const s = n - i;
- kn(r, r.im("p_hold"), { zoom: 1.12 - s * 0.03 });
- const a = V(s, 0, 0.3);
- a < 1 &&
- ((e.fillStyle = `rgba(255,255,255,${(1 - a) * 0.6})`),
- e.fillRect(0, 0, t.W, t.H));
- }
- $t(r, [
- { s: "一件会说话的", at: J(r, "l18", 1) },
- {
- s: "礼物",
- at: J(r, "l18", 1) + 0.35,
- color: "#ffd67d",
- size: t.P ? 130 : 150,
- },
- ]);
-}
-const Yc = [
- "const qr = makeQR(text)",
- "fuseGrid(qr, photo, MARD_221)",
- "oklab(r, g, b)",
- "scanCheck(grid) // ✓",
- "exportPDF(A4, codes)",
- "palette.nearest(lab)",
- "wx.scanCode()",
- "msgSecCheck(text)",
-];
-function Yg(r) {
- const { c: e, L: t, lt: n } = r,
- i = e.createLinearGradient(0, 0, t.W, t.H);
- (i.addColorStop(0, "#081614"),
- i.addColorStop(1, "#0d1f2d"),
- (e.fillStyle = i),
- e.fillRect(0, 0, t.W, t.H),
- e.save());
- for (let h = 0; h < 26; h++) {
- const p = Ye(h) * t.W,
- m = ((Ye(h + 50) * t.H + n * (30 + Ye(h + 9) * 50)) % (t.H + 100)) - 50;
- be(e, Yc[h % Yc.length], p, m, {
- size: 24 + Ye(h + 3) * 10,
- weight: 500,
- font: Sf,
- color: `rgba(94,234,212,${0.08 + Ye(h + 7) * 0.12})`,
- });
- }
- e.restore();
- const s = t.P,
- a = s ? 1e3 : 900,
- o = s ? t.W / 2 - 30 : t.W * 0.7,
- c = s ? 440 + a / 2 : t.H / 2,
- u = fe(V(n, 0.05, 0.5)),
- l = e.createRadialGradient(o, c, 0, o, c, a * 0.7);
- (l.addColorStop(0, "rgba(20,184,166,0.35)"),
- l.addColorStop(1, "rgba(20,184,166,0)"),
- (e.fillStyle = l),
- e.fillRect(0, 0, t.W, t.H),
- di(e, r.f("ai_fast"), o, c + (1 - u) * 100, a, { alpha: u }));
- const d = J(r, "l19", 1) + 0.35,
- f = lt(V(n, d, d + 0.4));
- if (f > 0) {
- (e.save(),
- e.translate(o + (s ? 200 : 260), c - a / 2 + 60),
- e.scale(f, f),
- e.rotate(0.12),
- (e.shadowColor = "rgba(94,234,212,0.8)"),
- (e.shadowBlur = 40));
- const h = xi(),
- p = Math.max(180, Fr(e, h, 64) + 70);
- ((e.fillStyle = "#14b8a6"),
- e.beginPath(),
- e.roundRect(-p / 2, -55, p, 110, 30),
- e.fill(),
- (e.shadowColor = "transparent"),
- be(e, h, 0, 24, {
- size: h.length > 3 ? 56 : 72,
- align: "center",
- color: "#04201d",
- }),
- e.restore());
- }
- const q = J(r, "l19", 2);
- s
- ? (We(e, `和 ${xi()} 一起写代码`, t.W / 2 - 30, t.safe.t + 100, V(n, d - 0.2, d + 0.8), {
- size: xi().length > 4 ? 64 : 72,
- align: "center",
- color: "#e6fffb",
- }),
- Ue(e, "想法 → 小程序", t.W / 2 - 30, t.safe.t + 190, {
- size: 34,
- align: "center",
- bg: "#14b8a6",
- color: "#04201d",
- alpha: fe(V(n, q, q + 0.4)),
- }))
- : $t(
- r,
- [
- { s: `我和 ${xi()}`, at: J(r, "l19", 1), color: "#5eead4" },
- { s: "一起写代码", at: J(r, "l19", 1) + 0.5, size: 80 },
- { s: "做出了小程序", at: q, size: 80 },
- ],
- { chip: "为了实现这个想法", chipAt: 0.2, y: 300 },
- );
-}
-function Zg(r) {
- const { c: e, L: t, A: n, lt: i, s } = r;
- Gt(e, t);
- for (let p = 0; p < 34; p++) {
- const m = Ye(p * 3) * t.W,
- b = ((Ye(p * 5) * t.H + i * (40 + Ye(p) * 60)) % (t.H + 100)) - 50;
- (e.save(),
- (e.globalAlpha = 0.5),
- mr(e, m, b, 26 + Ye(p * 2) * 26, ct[p % ct.length]),
- e.restore());
- }
- const a = t.P,
- o = J(r, "l20", 0),
- c = J(r, "l20", 1),
- u = J(r, "l20", 2),
- l = J(r, "l21", 0),
- d = lt(V(i, l - 0.6, l - 0.1)),
- f = n.images.mpcode;
- if (a) {
- const p = t.W / 2 - 30;
- (ts(r, p, t.safe.t + 200, V(i, o - 0.2, o + 0.5), 140, "center"),
- We(e, "可扫码的拼豆", p, t.safe.t + 310, V(i, c, c + 0.8), {
- size: 60,
- color: X.teal,
- align: "center",
- }),
- We(e, "把想说的话,拼给重要的人", p, t.safe.t + 440, V(i, u, u + 1.2), {
- size: 54,
- color: X.ink,
- align: "center",
- weight: 800,
- }),
- d > 0 &&
- (e.save(),
- e.translate(p, 1060),
- e.scale(d, d),
- (e.shadowColor = "rgba(40,30,10,0.25)"),
- (e.shadowBlur = 40),
- (e.shadowOffsetY = 14),
- (e.fillStyle = "#fff"),
- e.beginPath(),
- e.roundRect(-400 / 2 - 40, -400 / 2 - 40, 480, 550, 40),
- e.fill(),
- (e.shadowColor = "transparent"),
- e.drawImage(f, -400 / 2, -400 / 2, 400, 400),
- be(e, "微信扫码 · 立即体验", 0, 400 / 2 + 70, {
- size: 38,
- color: X.teal,
- align: "center",
- }),
- e.restore()));
- } else
- (ts(r, 170, 450, V(i, o - 0.2, o + 0.5), 200, "left"),
- We(e, "可扫码的拼豆", 176, 580, V(i, c, c + 0.8), {
- size: 80,
- color: X.teal,
- }),
- We(e, "把想说的话,拼给重要的人", 176, 720, V(i, u, u + 1.2), {
- size: 60,
- color: X.ink,
- weight: 800,
- }),
- d > 0 &&
- (e.save(),
- e.translate(t.W * 0.76, t.H / 2 - 30),
- e.scale(d, d),
- (e.shadowColor = "rgba(40,30,10,0.25)"),
- (e.shadowBlur = 40),
- (e.shadowOffsetY = 14),
- (e.fillStyle = "#fff"),
- e.beginPath(),
- e.roundRect(-430 / 2 - 40, -430 / 2 - 40, 510, 590, 40),
- e.fill(),
- (e.shadowColor = "transparent"),
- e.drawImage(f, -430 / 2, -430 / 2, 430, 430),
- be(e, "微信扫码 · 立即体验", 0, 430 / 2 + 76, {
- size: 40,
- color: X.teal,
- align: "center",
- }),
- e.restore()));
- const h = V(i, s.dur - 0.7, s.dur);
- h > 0 &&
- ((e.fillStyle = `rgba(244,241,234,${h * 0})`), e.fillRect(0, 0, t.W, t.H));
-}
-const Jg = {
- step2: Vg,
- palette: qg,
- check: jg,
- step3: $g,
- hands: Gg,
- iron: Kg,
- scan2: Xg,
- peel: Qg,
- ai: Yg,
- end: Zg,
- },
- ia = { ...Hg, ...Jg };
-let Or = null;
-function e1(r) {
- return (
- Or || (Or = document.createElement("canvas")),
- (Or.width !== r.W || Or.height !== r.H) &&
- ((Or.width = r.W), (Or.height = r.H)),
- Or
- );
-}
-function sa(r, e, t, n, i, s) {
- var o;
- const a = (c) => {
- const u = t.images[c];
- return u ? { img: u, w: u.naturalWidth, h: u.naturalHeight } : null;
- };
- (r.save(),
- (o = ia[i.id]) == null ||
- o.call(ia, { c: r, L: e, A: t, f: n, im: a, lt: s, s: i }),
- r.restore());
-}
-function t1(r, e, t) {
- const n = e.P ? 9 : 16,
- i = e.W / n,
- s = Math.ceil(e.H / i) + 1;
- for (let a = 0; a < s; a++)
- for (let o = 0; o < n + 1; o++) {
- const u = ((o / n + a / s) / 2) * 0.55 + Ye(a * 31 + o) * 0.08,
- l = t < 0 ? Be((t + 1) * 1.6 - u) : 1 - Be(t * 1.6 - u);
- l <= 0 ||
- mr(
- r,
- o * i + i / 2,
- a * i + i / 2,
- i * 1.45 * tr(l),
- ct[(a * 3 + o) % ct.length],
- );
- }
-}
-function r1(r, e, t) {
- const n = hl.find((d) => t >= d.t0 && t < d.t1);
- if (!n) return;
- const i = Be((t - n.t0) / 0.12) * Be((n.t1 - t) / 0.1);
- let s = e.P ? 50 : 46;
- const a = e.P ? e.W - e.safe.l - e.safe.r - 80 : e.W - 400;
- (r.save(), (r.font = Jn(s, 800)));
- const o = r.measureText(n.text).width;
- (r.restore(), o > a && (s = Math.floor((s * a) / o)));
- const c = e.P ? (e.safe.l + e.W - e.safe.r) / 2 + 20 : e.W / 2,
- u = e.P ? e.H - e.safe.b - 40 : e.H - e.safe.b - 10;
- (r.save(), (r.font = Jn(s, 800)));
- const l = r.measureText(n.text).width;
- ((r.globalAlpha = i),
- (r.fillStyle = "rgba(12,14,14,0.62)"),
- r.beginPath(),
- r.roundRect(c - l / 2 - 28, u - s * 1.02, l + 56, s * 1.5, 18),
- r.fill(),
- be(r, n.text, c, u, {
- size: s,
- weight: 800,
- color: "#fff",
- align: "center",
- }),
- r.restore());
-}
-function id(r, e, t, n, i, s = {}) {
- const { scene: a, index: o } = dl(i),
- c = i - a.start;
- if (
- (r.save(),
- (r.imageSmoothingEnabled = !0),
- (r.imageSmoothingQuality = "high"),
- o > 0 && a.trans === "fade" && c < Ui)
- ) {
- const f = qe[o - 1];
- sa(r, e, t, n, f, f.dur + c);
- const h = e1(e),
- p = h.getContext("2d");
- (p.clearRect(0, 0, e.W, e.H),
- sa(p, e, t, n, a, c),
- (r.globalAlpha = tr(c / Ui)),
- r.drawImage(h, 0, 0),
- (r.globalAlpha = 1));
- } else sa(r, e, t, n, a, c);
- (a.trans === "black" &&
- c < 0.7 &&
- ((r.fillStyle = `rgba(0,0,0,${1 - tr(c / 0.7)})`),
- r.fillRect(0, 0, e.W, e.H)),
- a.trans === "flash" &&
- c < 0.4 &&
- ((r.fillStyle = `rgba(255,255,255,${Math.pow(1 - c / 0.4, 2)})`),
- r.fillRect(0, 0, e.W, e.H)));
- const u = 0.42;
- for (let f = 1; f < qe.length; f++) {
- const h = qe[f];
- if (h.trans !== "bead") continue;
- const p = (i - h.start) / u;
- p > -1 && p < 1 && t1(r, e, p);
- }
- const l = qe[qe.length - 1],
- d = l.start + l.dur;
- (i > d - 0.5 &&
- ((r.fillStyle = `rgba(0,0,0,${Be((i - (d - 0.5)) / 0.5)})`),
- r.fillRect(0, 0, e.W, e.H)),
- s.subs !== !1 && r1(r, e, i),
- s.safe && n1(r, e),
- r.restore());
-}
-function n1(r, e) {
- (r.save(), (r.fillStyle = "rgba(255,40,80,0.16)"));
- const { t, b: n, l: i, r: s } = e.safe;
- (r.fillRect(0, 0, e.W, t),
- r.fillRect(0, e.H - n, e.W, n),
- e.P &&
- (r.fillRect(e.W - s, t + 380, s, e.H - n - t - 380),
- r.fillRect(0, t, i, e.H - t - n)),
- (r.strokeStyle = "rgba(255,40,80,0.8)"),
- (r.lineWidth = 3),
- r.setLineDash([16, 10]),
- r.strokeRect(i, t, e.W - i - s, e.H - t - n),
- r.setLineDash([]));
- const a = (o, c, u) =>
- be(r, o, c, u, {
- size: 26,
- weight: 700,
- color: "rgba(255,255,255,0.9)",
- stroke: "rgba(0,0,0,0.6)",
- strokeW: 5,
- });
- (e.P
- ? (a("状态栏 / 刘海 / 顶部标签", 30, 60),
- a("作者名 / 文案 / 音乐 / 底部导航", 30, e.H - n + 60),
- a("互动按钮", e.W - s + 6, t + 420))
- : (a("弹幕/标题区", 30, 40), a("进度条 / 控制栏", 30, e.H - 30)),
- r.restore());
-}
-class bo {
- constructor(e, t, n) {
- Bn(this, "sink");
- Bn(this, "it", null);
- Bn(this, "cur", null);
- Bn(this, "next", null);
- ((this.input = e),
- (this.track = t),
- (this.dur = n),
- (this.sink = new Gp(t, { poolSize: 0 })));
- }
- static async open(e) {
- const t = new ys({ source: new co(da(`${e}.mp4`)), formats: bp }),
- n = await t.getPrimaryVideoTrack();
- if (!n) throw new Error("素材无视频轨 " + e);
- const i = await n.computeDuration();
- return new bo(t, n, i);
- }
- async restart(e) {
- var t;
- (await ((t = this.it) == null ? void 0 : t.return()),
- (this.it = this.sink.canvases(e)),
- (this.cur = (await this.it.next()).value ?? null),
- (this.next = this.cur ? ((await this.it.next()).value ?? null) : null),
- this.cur || (this.cur = await this.sink.getCanvas(e)));
- }
- async get(e) {
- for (
- e = Math.min(Math.max(0, e), Math.max(0, this.dur - 0.05)),
- (!this.it ||
- !this.cur ||
- e < this.cur.timestamp - 0.002 ||
- e > this.cur.timestamp + 1.5) &&
- (await this.restart(e));
- this.next && this.next.timestamp <= e + 5e-4;
- )
- ((this.cur = this.next),
- (this.next = (await this.it.next()).value ?? null));
- if (!this.cur) return null;
- const t = this.cur.canvas;
- return { img: t, w: t.width, h: t.height };
- }
- async close() {
- var e, t, n;
- try {
- await ((e = this.it) == null ? void 0 : e.return());
- } catch {}
- (n = (t = this.input).dispose) == null || n.call(t);
- }
-}
-async function i1(r, e) {
- const t = is(e.fmt);
- if (!("VideoEncoder" in window))
- throw new Error(
- "当前浏览器不支持 WebCodecs,请使用最新版 Chrome / Edge 导出",
- );
- if (!(await Mp("avc", { width: t.W, height: t.H })))
- throw new Error("当前浏览器无法编码 H.264,请使用最新版 Chrome / Edge");
- if (!(await Np("aac"))) {
- const { registerAacEncoder: d } = await cd(
- async () => {
- const { registerAacEncoder: f } =
- await import("./mediabunny-aac-encoder-v3b174138.js");
- return { registerAacEncoder: f };
- },
- __vite__mapDeps([0, 1, 2, 3, 4, 5]),
- import.meta.url,
- );
- d();
- }
- e.onProgress(0, "正在混音…");
- const n = await fa(),
- i = document.createElement("canvas");
- ((i.width = t.W), (i.height = t.H));
- const s = i.getContext("2d", { alpha: !1 }),
- a = new Rg({
- format: new td({ fastStart: "in-memory" }),
- target: new zi(),
- }),
- o = Math.round(1e7 * Math.sqrt(e.fps / 30)),
- c = new vg(i, { codec: "avc", bitrate: o, keyFrameInterval: 2 }),
- u = new Ig({ codec: "aac", bitrate: 192e3 });
- (a.addVideoTrack(c, { frameRate: e.fps }),
- a.addAudioTrack(u),
- await a.start());
- const l = {};
- try {
- const d = Number(window.__EXPORT_LIMIT) || Le,
- f = Math.ceil(Math.min(Le, d) * e.fps),
- h = f / e.fps,
- p = Math.min(n.length, Math.round(h * n.sampleRate)),
- m = new AudioBuffer({
- length: p,
- numberOfChannels: n.numberOfChannels,
- sampleRate: n.sampleRate,
- });
- for (let y = 0; y < n.numberOfChannels; y++)
- m.copyToChannel(n.getChannelData(y).subarray(0, p), y);
- (await u.add(m), u.close());
- const b = performance.now();
- for (let y = 0; y < f; y++) {
- if (e.signal.aborted) throw new DOMException("已取消", "AbortError");
- const C = y / e.fps,
- _ = Bi(C),
- v = {};
- for (const I of _)
- (l[I.id] || (l[I.id] = await bo.open(I.id)),
- (v[I.id] = await l[I.id].get(I.time)));
- if (
- (id(s, t, r, (I) => v[I] ?? null, C, { safe: !1, subs: !0 }),
- await c.add(C, 1 / e.fps),
- y % 6 === 0)
- ) {
- const I = (performance.now() - b) / 1e3,
- w = (y + 1) / f,
- x = I / w - I;
- e.onProgress(
- w * 0.98,
- `渲染第 ${y + 1}/${f} 帧 · 剩余约 ${Math.ceil(x)} 秒`,
- );
- }
- }
- (c.close(),
- e.onProgress(0.99, "正在封装 MP4…"),
- await a.finalize(),
- e.onProgress(1, "完成"));
- const g = a.target.buffer;
- return new Blob([g], { type: "video/mp4" });
- } catch (d) {
- try {
- await a.cancel();
- } catch {}
- throw d;
- } finally {
- await Promise.all(Object.values(l).map((d) => d.close()));
- }
-}
-function s1(r, e) {
- const t = URL.createObjectURL(r),
- n = document.createElement("a");
- ((n.href = t),
- (n.download = e),
- document.body.appendChild(n),
- n.click(),
- n.remove(),
- setTimeout(() => URL.revokeObjectURL(t), 6e4));
-}
-const a1 = {
- hook: "开场 · 有没有一种可能",
- scan: "微信扫一扫",
- title: "豆维登场",
- problem: "普通拼豆的难题",
- algo: "交给算法",
- step1: "第一步 · 写一句话",
- step2: "第二步 · 选一张照片",
- palette: "MARD 221 色配色",
- check: "生成即自检",
- step3: "第三步 · 导出图纸",
- hands: "动手拼豆",
- iron: "盖纸熨烫",
- scan2: "揭开前先扫一下",
- peel: "完成",
- ai: "用 AI 实现想法",
- end: "片尾",
- },
- wo = (r, e) => (r === "ai" ? `和 ${cr[e ?? "ai"].label} 一起把想法写成小程序` : a1[r]),
- rs = (r) => {
- const e = Math.max(0, Math.floor(r));
- return `${String(Math.floor(e / 60)).padStart(2, "0")}:${String(e % 60).padStart(2, "0")}`;
- },
- o1 = [
- "hook",
- "problem",
- "step1",
- "step2",
- "palette",
- "check",
- "step3",
- "hands",
- "scan2",
- "ai",
- "end",
- ];
-function c1(r) {
- const e = cr[r].label,
- t =
- r === "doubao"
- ? "#豆包 #豆包AI"
- : r === "workbuddy"
- ? "#WorkBuddy"
- : "#AI",
- n = r === "doubao" ? "豆包,豆包AI" : r === "workbuddy" ? "WorkBuddy" : "AI",
- i = qe
- .filter((s) => o1.includes(s.id))
- .map((s) => `${rs(s.start)} ${wo(s.id, r)}`).join(`
-`);
- return {
- douyin: {
- name: "抖音",
- fields: [
- { label: "标题", text: "拼豆也能扫码?这幅画会把悄悄话读给你听" },
- {
- label: "描述",
- text: `有没有一种可能:AI + 二维码 = 艺术二维码,那拼豆 + 二维码 = ?
-为了实现这个想法,我和 ${e} 一起写代码,做出了「豆维」小程序~
-一句话 + 一张照片,「豆维」把二维码悄悄藏进拼豆画里🫘
-✅ MARD 221 色自动配色
-✅ 生成后先替你扫一遍,扫不出一键优化
-✅ 导出带色号的图纸和用豆清单
-拼完用微信一扫,就能读出你想说的话。生日、表白、纪念日送礼都合适~
-👉 微信搜索「豆维」小程序,现在就试试`,
- },
- {
- label: "话题",
- text: `#拼豆 #拼豆diy #手工diy #创意礼物 #二维码 #微信小程序 #送女朋友礼物 #手作 #AI编程 ${t} #豆维`,
- },
- ],
- },
- bilibili: {
- name: "哔哩哔哩",
- fields: [
- {
- label: "标题",
- text: `【豆维】和 ${e} 一起写了个小程序,让拼豆变成能扫的二维码`,
- },
- {
- label: "简介",
- text: `有没有一种可能:就像 AI + 二维码 = 艺术二维码,拼豆 + 二维码,也能变成一幅可以扫码的作品?为了实现这个想法,我和 ${e} 一起写代码,做出了「豆维」小程序。
-
-拼豆不只是用来看的——用「豆维」生成图纸,拼出来的作品用微信一扫,就能读出藏在里面的一句话。
-
-原理:二维码 + 照片融合,配色引擎在 OKLab 色彩空间里,从 MARD 221 种标准色中为每一格挑出「最像、又最好扫」的颜色;生成后自动扫码自检,扫不出可一键优化;最后导出带色号的 A4 图纸和用豆清单。
-
-章节:
-${i}
-
-微信搜索「豆维」小程序即可体验。视频全程 ${Math.round(Le)} 秒,画面/音乐/音效均为网页实时渲染导出。`,
- },
- {
- label: "标签",
- text: `拼豆,拼豆DIY,手工,二维码,微信小程序,创意礼物,独立开发,AI编程,${n},配色算法,豆维`,
- },
- ],
- },
- };
-}
-const _i = 2 / 3;
-function l1({
- A: r,
- fmt: e,
- setFmt: t,
- fps: n,
- setFps: i,
- brand: s,
- setBrand: a,
-}) {
- const o = ye.useRef(null),
- [c, u] = ye.useState(!1),
- [l, d] = ye.useState(0),
- [f, h] = ye.useState(!1),
- [p, m] = ye.useState(!0),
- [b, g] = ye.useState(!1),
- [y, C] = ye.useState(null),
- [_, v] = ye.useState(""),
- I = ye.useRef(null),
- w = ye.useRef({
- playing: !1,
- t: 0,
- ctxStart: 0,
- offset: 0,
- lastDraw: -1,
- dirty: !0,
- }),
- x = ye.useRef(null),
- k = ye.useRef({ safe: f, subs: p, fmt: e, fps: n });
- ((k.current = { safe: f, subs: p, fmt: e, fps: n }),
- ye.useEffect(() => {
- let K = !0;
- return (
- g(!1),
- x.current && (x.current.buf = null),
- (w.current.dirty = !0),
- fa()
- .then(() => {
- K && g(!0);
- })
- .catch((ie) => v("混音失败:" + ie)),
- () => {
- K = !1;
- }
- );
- }, [s]),
- ye.useEffect(() => {
- w.current.dirty = !0;
- }, [f, p, e, n]));
- const S = () => {
- const K = w.current;
- return !K.playing || !x.current
- ? K.t
- : K.offset + (x.current.ctx.currentTime - K.ctxStart);
- },
- E = () => {
- const K = x.current;
- if (K != null && K.src) {
- try {
- K.src.stop();
- } catch {}
- (K.src.disconnect(), (K.src = null));
- }
- },
- B = async (K) => {
- x.current ||
- (x.current = {
- ctx: new AudioContext({ latencyHint: "playback" }),
- buf: null,
- src: null,
- });
- const ie = x.current;
- (ie.ctx.state === "suspended" && (await ie.ctx.resume()),
- ie.buf || (ie.buf = await fa()),
- E());
- const Ie = ie.ctx.createBufferSource();
- ((Ie.buffer = ie.buf), Ie.connect(ie.ctx.destination));
- const Ge = ie.ctx.currentTime + 0.05;
- (Ie.start(Ge, K),
- (ie.src = Ie),
- (w.current.ctxStart = Ge),
- (w.current.offset = K));
- },
- R = async () => {
- let K = w.current.t;
- (K >= Le - 0.05 && (K = 0),
- (w.current.t = K),
- await B(K),
- (w.current.playing = !0),
- u(!0));
- },
- M = () => {
- ((w.current.t = Math.max(0, S())), (w.current.playing = !1), E(), u(!1));
- for (const K of Object.values(r.videos)) K.pause();
- },
- z = async (K) => {
- ((K = Math.max(0, Math.min(Le, K))),
- (w.current.t = K),
- (w.current.dirty = !0),
- d(K),
- w.current.playing && (await B(K)));
- },
- q = () => (w.current.playing ? M() : R()),
- j = ye.useCallback(
- (K, ie) => {
- const Ie = Bi(K),
- Ge = Bi(Math.min(Le, K + 0.1)),
- Fe = Bi(Math.min(Le, K + 0.6)),
- je = new Set(Ie.map((He) => He.id));
- for (const He of Ie) {
- const we = r.videos[He.id];
- if (!we || !we.duration) continue;
- const Oe = Math.min(He.time, we.duration - 0.05),
- st = Ge.find((Ot) => Ot.id === He.id),
- _t = st ? (st.time - He.time) / 0.1 : 1;
- if (!ie || _t < 0.08) {
- (we.paused || we.pause(),
- Math.abs(we.currentTime - Oe) > 0.04 &&
- !we.seeking &&
- (we.currentTime = Oe));
- continue;
- }
- const At = Math.max(0.25, Math.min(4, _t));
- (Math.abs(we.playbackRate - At) > 0.02 && (we.playbackRate = At),
- Math.abs(we.currentTime - Oe) > 0.25 &&
- !we.seeking &&
- (we.currentTime = Oe),
- we.paused && Oe < we.duration - 0.1 && we.play().catch(() => {}));
- }
- for (const [He, we] of Object.entries(r.videos)) {
- if (je.has(He)) continue;
- we.paused || we.pause();
- const Oe = Fe.find((st) => st.id === He);
- Oe &&
- we.duration &&
- Math.abs(we.currentTime - Oe.time) > 0.3 &&
- !we.seeking &&
- (we.currentTime = Math.min(Oe.time, we.duration - 0.05));
- }
- },
- [r],
- );
- (ye.useEffect(() => {
- let K = 0,
- ie = 0;
- const Ie = (Fe) => {
- const je = r.videos[Fe];
- return !je || je.readyState < 2
- ? null
- : { img: je, w: je.videoWidth, h: je.videoHeight };
- },
- Ge = () => {
- K = requestAnimationFrame(Ge);
- const Fe = w.current,
- je = k.current;
- let He = S();
- (Fe.playing && He >= Le && (M(), (He = Le), (Fe.t = Le)),
- j(He, Fe.playing));
- const we = Math.floor(He * je.fps) / je.fps;
- if (
- (we === Fe.lastDraw && !Fe.dirty && !Fe.playing) ||
- (we === Fe.lastDraw && Fe.playing)
- )
- return;
- ((Fe.lastDraw = we), (Fe.dirty = !Fe.playing));
- const Oe = o.current;
- if (!Oe) return;
- const st = is(je.fmt),
- _t = Math.round(st.W * _i),
- At = Math.round(st.H * _i);
- (Oe.width !== _t || Oe.height !== At) &&
- ((Oe.width = _t), (Oe.height = At));
- const Ot = Oe.getContext("2d", { alpha: !1 });
- (Ot.setTransform(_i, 0, 0, _i, 0, 0),
- id(Ot, st, r, Ie, Math.min(we, Le - 0.001), {
- safe: je.safe,
- subs: je.subs,
- }));
- const wr = performance.now();
- wr - ie > 100 && ((ie = wr), d(He));
- };
- return ((K = requestAnimationFrame(Ge)), () => cancelAnimationFrame(K));
- }, [r, j]),
- ye.useEffect(() => {
- const K = (ie) => {
- var Ie, Ge;
- ((Ie = ie.target) == null ? void 0 : Ie.tagName) === "TEXTAREA" ||
- ((Ge = ie.target) == null ? void 0 : Ge.tagName) === "INPUT" ||
- (ie.code === "Space" && (ie.preventDefault(), q()),
- ie.code === "ArrowLeft" && z(S() - 3),
- ie.code === "ArrowRight" && z(S() + 3));
- };
- return (
- window.addEventListener("keydown", K),
- () => window.removeEventListener("keydown", K)
- );
- }),
- ye.useEffect(
- () => () => {
- var K;
- (E(), (K = x.current) == null || K.ctx.close());
- },
- [],
- ));
- const se = async () => {
- (w.current.playing && M(), v(""));
- const K = new AbortController();
- ((I.current = K), C({ p: 0, info: "准备中…" }));
- try {
- const ie = await i1(r, {
- fmt: e,
- fps: n,
- signal: K.signal,
- onProgress: (Ge, Fe) => C({ p: Ge, info: Fe }),
- }),
- Ie = `豆维宣传片_${e === "landscape" ? "横屏B站_1920x1080" : "竖屏抖音_1080x1920"}_${cr[s].label.replace(/\s/g, "")}版_${n}fps.mp4`;
- (s1(ie, Ie),
- C({
- p: 1,
- info: `已导出 ${(ie.size / 1024 / 1024).toFixed(1)} MB · ${Ie}`,
- }),
- setTimeout(() => C(null), 6e3));
- } catch (ie) {
- const Ie = (ie == null ? void 0 : ie.name) === "AbortError";
- (C(null),
- Ie ||
- v(
- "导出失败:" + ((ie == null ? void 0 : ie.message) ?? String(ie)),
- ));
- } finally {
- ((I.current = null), (w.current.dirty = !0));
- }
- },
- le = e === "portrait",
- ue = !!y && y.p < 1 && !!I.current,
- $e = [...qe].reverse().find((K) => l >= K.start) ?? qe[0];
- return U.jsxDEV(
- "div",
- {
- className: "flex flex-col gap-4",
- children: [
- U.jsxDEV(
- "div",
- {
- className: "flex flex-wrap items-center gap-3",
- children: [
- U.jsxDEV(
- aa,
- {
- value: e,
- onChange: (K) => t(K),
- disabled: ue,
- items: [
- { v: "landscape", l: "横屏 16:9 · B站" },
- { v: "portrait", l: "竖屏 9:16 · 抖音" },
- ],
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 201,
- columnNumber: 9,
- },
- this,
- ),
- U.jsxDEV(
- aa,
- {
- value: String(n),
- onChange: (K) => i(Number(K)),
- disabled: ue,
- items: [
- { v: "24", l: "24 fps" },
- { v: "30", l: "30 fps" },
- { v: "60", l: "60 fps" },
- ],
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 202,
- columnNumber: 9,
- },
- this,
- ),
- U.jsxDEV(
- aa,
- {
- value: s,
- onChange: (K) => {
- (w.current.playing && M(), a(K));
- },
- disabled: ue,
- items: Object.keys(cr).map((K) => ({
- v: K,
- l: `和 ${cr[K].label} 一起写`,
- })),
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 203,
- columnNumber: 9,
- },
- this,
- ),
- U.jsxDEV(
- "button",
- {
- onClick: () => h(!f),
- className: `flex items-center gap-1.5 rounded-lg border px-3 py-1.5 text-sm transition ${f ? "border-rose-400/60 bg-rose-500/15 text-rose-200" : "border-white/10 text-white/70 hover:bg-white/5"}`,
- children: [
- U.jsxDEV(
- wd,
- { className: "h-4 w-4" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 205,
- columnNumber: 11,
- },
- this,
- ),
- "平台遮挡区",
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 204,
- columnNumber: 9,
- },
- this,
- ),
- U.jsxDEV(
- "button",
- {
- onClick: () => m(!p),
- className: `flex items-center gap-1.5 rounded-lg border px-3 py-1.5 text-sm transition ${p ? "border-teal-400/60 bg-teal-500/15 text-teal-100" : "border-white/10 text-white/70 hover:bg-white/5"}`,
- children: [
- U.jsxDEV(
- fd,
- { className: "h-4 w-4" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 208,
- columnNumber: 11,
- },
- this,
- ),
- "字幕",
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 207,
- columnNumber: 9,
- },
- this,
- ),
- U.jsxDEV(
- "label",
- {
- title: "第二步 · 选一张照片:换成你自己的照片(导出视频同样生效)",
- className: `flex cursor-pointer items-center gap-1.5 rounded-lg border px-3 py-1.5 text-sm transition border-white/10 text-white/70 hover:bg-white/5 ${ue ? "pointer-events-none opacity-40" : ""}`,
- children: [
- "替换照片",
- U.jsxDEV(
- "input",
- {
- type: "file",
- accept: "image/*",
- className: "hidden",
- onChange: (K) => {
- var ie;
- const Ie = (ie = K.target.files) == null ? void 0 : ie[0];
- if (!Ie) return;
- const Ge = new Image(),
- Fe = URL.createObjectURL(Ie);
- ((Ge.onload = () => {
- (bwSetPhoto(r, Ge), (w.current.dirty = !0), URL.revokeObjectURL(Fe));
- const je = qe.find((He) => He.id === "step2");
- je && !w.current.playing && z(je.start + 3.2);
- }),
- (Ge.src = Fe),
- (K.target.value = ""));
- },
- },
- void 0,
- !1,
- void 0,
- this,
- ),
- ],
- },
- void 0,
- !0,
- void 0,
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 200,
- columnNumber: 7,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- className: `relative mx-auto w-full overflow-hidden rounded-2xl bg-black shadow-2xl ring-1 ring-white/10 ${le ? "max-w-[min(100%,calc((100vh-260px)*9/16))]" : ""}`,
- style: { aspectRatio: le ? "9 / 16" : "16 / 9" },
- children: [
- U.jsxDEV(
- "canvas",
- {
- ref: o,
- onClick: q,
- className: "absolute inset-0 h-full w-full cursor-pointer",
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 213,
- columnNumber: 9,
- },
- this,
- ),
- !c &&
- !ue &&
- U.jsxDEV(
- "button",
- {
- onClick: R,
- disabled: !b,
- className:
- "absolute left-1/2 top-1/2 flex h-20 w-20 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full bg-white/90 text-black shadow-xl transition hover:scale-105 disabled:opacity-60",
- children: b
- ? U.jsxDEV(
- yo,
- { className: "ml-1 h-9 w-9 fill-black" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 216,
- columnNumber: 27,
- },
- this,
- )
- : U.jsxDEV(
- ca,
- { className: "h-8 w-8 animate-spin" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 216,
- columnNumber: 74,
- },
- this,
- ),
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 215,
- columnNumber: 11,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 212,
- columnNumber: 7,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- className: "flex items-center gap-3",
- children: [
- U.jsxDEV(
- "button",
- {
- onClick: q,
- disabled: !b || ue,
- className:
- "flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-white text-black disabled:opacity-50",
- children: c
- ? U.jsxDEV(
- gd,
- { className: "h-5 w-5 fill-black" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 223,
- columnNumber: 22,
- },
- this,
- )
- : U.jsxDEV(
- yo,
- { className: "ml-0.5 h-5 w-5 fill-black" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 223,
- columnNumber: 65,
- },
- this,
- ),
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 222,
- columnNumber: 9,
- },
- this,
- ),
- U.jsxDEV(
- "button",
- {
- onClick: () => z(0),
- className:
- "flex h-9 w-9 shrink-0 items-center justify-center rounded-full border border-white/10 text-white/70 hover:bg-white/5",
- children: U.jsxDEV(
- bd,
- { className: "h-4 w-4" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 225,
- columnNumber: 170,
- },
- this,
- ),
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 225,
- columnNumber: 9,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- className: "relative flex-1",
- children: [
- U.jsxDEV(
- "input",
- {
- type: "range",
- min: 0,
- max: Le,
- step: 0.01,
- value: l,
- disabled: ue,
- onChange: (K) => z(Number(K.target.value)),
- className: "w-full accent-teal-400",
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 227,
- columnNumber: 11,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- className:
- "pointer-events-none absolute inset-x-0 -bottom-1 h-1",
- children: qe.map((K) =>
- U.jsxDEV(
- "span",
- {
- className: "absolute h-1.5 w-px bg-white/30",
- style: { left: `${(K.start / Le) * 100}%` },
- },
- K.id,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 230,
- columnNumber: 32,
- },
- this,
- ),
- ),
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 229,
- columnNumber: 11,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 226,
- columnNumber: 9,
- },
- this,
- ),
- U.jsxDEV(
- "span",
- {
- className:
- "w-28 shrink-0 text-right font-mono text-sm tabular-nums text-white/70",
- children: [rs(l), " / ", rs(Le)],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 233,
- columnNumber: 9,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 221,
- columnNumber: 7,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- className: "-mt-2 text-sm text-white/50",
- children: [
- "当前镜头:",
- U.jsxDEV(
- "span",
- { className: "text-teal-300", children: wo($e.id) },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 235,
- columnNumber: 57,
- },
- this,
- ),
- " · 空格播放/暂停,←/→ 快退快进",
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 235,
- columnNumber: 7,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- className: "rounded-xl border border-white/10 bg-white/[0.03] p-4",
- children: [
- U.jsxDEV(
- "div",
- {
- className: "flex flex-wrap items-center gap-3",
- children: [
- U.jsxDEV(
- "button",
- {
- onClick: se,
- disabled: ue || !b,
- className:
- "flex items-center gap-2 rounded-lg bg-teal-500 px-4 py-2 font-semibold text-black transition hover:bg-teal-400 disabled:opacity-50",
- children: [
- ue
- ? U.jsxDEV(
- ca,
- { className: "h-4 w-4 animate-spin" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 240,
- columnNumber: 26,
- },
- this,
- )
- : U.jsxDEV(
- nl,
- { className: "h-4 w-4" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 240,
- columnNumber: 73,
- },
- this,
- ),
- "导出 MP4(",
- le ? "1080×1920" : "1920×1080",
- " · ",
- n,
- "fps)",
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 239,
- columnNumber: 11,
- },
- this,
- ),
- ue &&
- U.jsxDEV(
- "button",
- {
- onClick: () => {
- var K;
- return (K = I.current) == null ? void 0 : K.abort();
- },
- className:
- "flex items-center gap-1 rounded-lg border border-white/15 px-3 py-2 text-sm text-white/80 hover:bg-white/5",
- children: [
- U.jsxDEV(
- yd,
- { className: "h-4 w-4" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 243,
- columnNumber: 194,
- },
- this,
- ),
- "取消",
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 243,
- columnNumber: 25,
- },
- this,
- ),
- U.jsxDEV(
- "span",
- {
- className: "text-xs text-white/45",
- children:
- "在你的浏览器里逐帧渲染并编码(H.264 + AAC),不上传任何数据。建议使用电脑版 Chrome / Edge。",
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 244,
- columnNumber: 11,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 238,
- columnNumber: 9,
- },
- this,
- ),
- y &&
- U.jsxDEV(
- "div",
- {
- className: "mt-3",
- children: [
- U.jsxDEV(
- "div",
- {
- className:
- "h-2 overflow-hidden rounded-full bg-white/10",
- children: U.jsxDEV(
- "div",
- {
- className:
- "h-full rounded-full bg-gradient-to-r from-teal-400 to-emerald-300 transition-[width]",
- style: { width: `${y.p * 100}%` },
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 248,
- columnNumber: 75,
- },
- this,
- ),
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 248,
- columnNumber: 13,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- className:
- "mt-1.5 flex justify-between text-xs text-white/60",
- children: [
- U.jsxDEV(
- "span",
- { children: y.info },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 249,
- columnNumber: 80,
- },
- this,
- ),
- U.jsxDEV(
- "span",
- { children: [Math.round(y.p * 100), "%"] },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 249,
- columnNumber: 103,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 249,
- columnNumber: 13,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 247,
- columnNumber: 11,
- },
- this,
- ),
- _ &&
- U.jsxDEV(
- "div",
- {
- className:
- "mt-3 rounded-lg bg-rose-500/15 px-3 py-2 text-sm text-rose-200",
- children: _,
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 252,
- columnNumber: 17,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 237,
- columnNumber: 7,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 199,
- columnNumber: 5,
- },
- this,
- );
-}
-function aa({ value: r, onChange: e, items: t, disabled: n }) {
- return U.jsxDEV(
- "div",
- {
- className: "flex rounded-lg border border-white/10 bg-white/[0.03] p-0.5",
- children: t.map((i) =>
- U.jsxDEV(
- "button",
- {
- disabled: n,
- onClick: () => e(i.v),
- className: `rounded-md px-3 py-1.5 text-sm transition disabled:cursor-not-allowed ${r === i.v ? "bg-white text-black font-semibold" : "text-white/70 hover:text-white"}`,
- children: i.l,
- },
- i.v,
- !1,
- {
- fileName: "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 262,
- columnNumber: 9,
- },
- this,
- ),
- ),
- },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/components/studio/Player.tsx",
- lineNumber: 260,
- columnNumber: 5,
- },
- this,
- );
-}
-function Zc(r, e, t, n, i, s = X.ink) {
- const a = i * 1.05;
- return (
- r.save(),
- r.beginPath(),
- r.roundRect(t, n - a * 0.82, a, a, a * 0.24),
- r.clip(),
- r.drawImage(e.images.icon, t, n - a * 0.82, a, a),
- r.restore(),
- be(r, "豆维", t + a + i * 0.28, n, { size: i, color: s }),
- a + i * 0.28 + Fr(r, "豆维", i)
- );
-}
-function Jc(r, e, t, n, i, s = 10) {
- const a = Math.min(n, i) * 0.13;
- (r.save(),
- (r.strokeStyle = X.green),
- (r.lineWidth = s),
- (r.lineCap = "round"));
- for (const [o, c, u, l] of [
- [e, t, 1, 1],
- [e + n, t, -1, 1],
- [e, t + i, 1, -1],
- [e + n, t + i, -1, -1],
- ])
- (r.beginPath(),
- r.moveTo(o, c + l * a),
- r.lineTo(o, c),
- r.lineTo(o + u * a, c),
- r.stroke());
- r.restore();
-}
-function oa(r, e, t, n, i, s, a) {
- for (let o = 0; o < n; o++) {
- const c = Ye(o * 3 + a) * e,
- u = Ye(o * 7 + a + 1) * t;
- i(c, u) || mr(r, c, u, s * (0.7 + Ye(o + a) * 0.6), ct[o % ct.length]);
- }
-}
-function el(r, e, t, n) {
- (r.save(),
- (r.fillStyle = X.green),
- (r.shadowColor = "rgba(0,0,0,0.3)"),
- (r.shadowBlur = 24),
- (r.shadowOffsetY = 8),
- r.beginPath(),
- r.arc(e, t, n, 0, Math.PI * 2),
- r.fill(),
- (r.shadowColor = "transparent"),
- (r.strokeStyle = "#fff"),
- (r.lineWidth = n * 0.2),
- (r.lineCap = "round"),
- (r.lineJoin = "round"),
- r.beginPath(),
- r.moveTo(e - n * 0.42, t + n * 0.02),
- r.lineTo(e - n * 0.1, t + n * 0.34),
- r.lineTo(e + n * 0.46, t - n * 0.3),
- r.stroke(),
- r.restore());
-}
-function u1(r, e, t) {
- const n = is(t),
- i = e.images.p_hold;
- if (t === "landscape") {
- (Gt(r, n),
- oa(
- r,
- n.W,
- n.H,
- 46,
- (l, d) =>
- (l > 1040 && l < 1840 && d > 60 && d < 1030) ||
- (l < 1e3 && d > 150 && d < 950),
- 38,
- 11,
- ));
- const s = 660,
- a = 880,
- o = 1130,
- c = 100;
- (r.save(),
- r.translate(o + s / 2, c + a / 2),
- r.rotate(0.035),
- r.translate(-1460, -540),
- za(r, { img: i, w: i.naturalWidth, h: i.naturalHeight }, o, c, s, a, {
- r: 36,
- shadow: !0,
- border: "#fff",
- }),
- r.restore(),
- Jc(r, o + 70, c + 170, s - 140, s - 140, 12),
- el(r, o + s - 10, c + 40, 64),
- Ue(r, "扫出来了!", o + s / 2, c + a + 4, {
- size: 40,
- bg: X.green,
- align: "center",
- weight: 900,
- }));
- const u = 110;
- (Ue(r, "微信小程序 · 可扫码的拼豆", u, 220, {
- size: 34,
- bg: X.ink,
- dot: X.green,
- }),
- be(r, "这幅拼豆", u, 440, { size: 150, color: X.ink }),
- (r.fillStyle = "rgba(255,187,39,0.55)"),
- r.beginPath(),
- r.roundRect(u - 6, 590, Fr(r, "会说话", 186) + 12, 38, 19),
- r.fill(),
- be(r, "会说话", u, 615, { size: 186, color: X.teal }),
- be(r, "一句话 + 一张照片 → 扫得出的拼豆图纸", u, 735, {
- size: 44,
- weight: 700,
- color: X.sub,
- }),
- ss(r, e.fused, u, 800, 190, { board: !0 }),
- Zc(r, e, u + 230, 930, 74),
- be(r, "MARD 221 色 · 生成即自检 · 一键导出图纸", u + 232, 990, {
- size: 26,
- weight: 600,
- color: X.sub,
- }));
- } else {
- ((r.fillStyle = "#0d1211"),
- r.fillRect(0, 0, n.W, n.H),
- Qr(
- r,
- i,
- i.naturalWidth,
- i.naturalHeight,
- 0,
- 0,
- n.W,
- 1300,
- 1.02,
- 0.5,
- 0.45,
- ));
- const s = r.createLinearGradient(0, 700, 0, 1320);
- (s.addColorStop(0, "rgba(244,241,234,0)"),
- s.addColorStop(1, X.paper),
- (r.fillStyle = s),
- r.fillRect(0, 700, n.W, 620),
- (r.fillStyle = X.paper),
- r.fillRect(0, 1300, n.W, n.H - 1300));
- const a = r.createLinearGradient(0, 0, 0, 420);
- (a.addColorStop(0, "rgba(0,0,0,0.55)"),
- a.addColorStop(1, "rgba(0,0,0,0)"),
- (r.fillStyle = a),
- r.fillRect(0, 0, n.W, 420),
- oa(r, n.W, n.H - 1340, 22, (u) => u > 120 && u < 960, 40, 5),
- r.save(),
- r.translate(0, 1340),
- oa(r, n.W, 580, 26, (u, l) => (u > 90 && u < 990) || l < 40, 40, 23),
- r.restore(),
- Jc(r, 250, 380, 580, 580, 12),
- el(r, 860, 360, 66),
- Ue(r, "微信扫一扫 · 扫出来了", n.W / 2, 300, {
- size: 38,
- bg: X.green,
- align: "center",
- weight: 800,
- }),
- be(r, "这幅拼豆", n.W / 2, 1190, {
- size: 150,
- color: X.ink,
- align: "center",
- stroke: X.paper,
- strokeW: 18,
- }));
- const o = Fr(r, "会说话", 200);
- ((r.fillStyle = "rgba(255,187,39,0.6)"),
- r.beginPath(),
- r.roundRect(n.W / 2 - o / 2 - 8, 1340, o + 16, 42, 21),
- r.fill(),
- be(r, "会说话", n.W / 2, 1370, {
- size: 200,
- color: X.teal,
- align: "center",
- }),
- be(r, "一句话 + 一张照片 → 可扫码拼豆", n.W / 2, 1470, {
- size: 46,
- weight: 700,
- color: X.sub,
- align: "center",
- }));
- const c = 74 * 1.05 + 74 * 0.28 + Fr(r, "豆维", 74);
- Zc(r, e, n.W / 2 - c / 2, 1600, 74);
- }
-}
-function d1(r, e) {
- const t = is(e),
- n = document.createElement("canvas");
- return ((n.width = t.W), (n.height = t.H), u1(n.getContext("2d"), r, e), n);
-}
-function tl({ A: r, fmt: e }) {
- const t = ye.useRef(null),
- n = ye.useRef(null);
- ye.useEffect(() => {
- var o;
- const a = d1(r, e);
- ((a.className = "h-full w-full"),
- (n.current = a),
- (o = t.current) == null || o.replaceChildren(a));
- }, [r, e]);
- const i = () => {
- var a;
- (a = n.current) == null ||
- a.toBlob((o) => {
- if (!o) return;
- const c = URL.createObjectURL(o),
- u = document.createElement("a");
- ((u.href = c),
- (u.download =
- e === "landscape"
- ? "豆维封面_横屏B站_1920x1080.png"
- : "豆维封面_竖屏抖音_1080x1920.png"),
- u.click(),
- setTimeout(() => URL.revokeObjectURL(c), 3e4));
- }, "image/png");
- },
- s = e === "portrait";
- return U.jsxDEV(
- "div",
- {
- className: `flex flex-col gap-2 ${s ? "w-[200px] sm:w-[220px]" : "min-w-0 flex-1"}`,
- children: [
- U.jsxDEV(
- "div",
- {
- ref: t,
- className: "overflow-hidden rounded-xl ring-1 ring-white/10",
- style: { aspectRatio: s ? "9/16" : "16/9" },
- },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 30,
- columnNumber: 7,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- className: "flex items-center justify-between gap-2",
- children: [
- U.jsxDEV(
- "span",
- {
- className: "text-xs text-white/55",
- children: s
- ? "竖屏 1080×1920 · 抖音"
- : "横屏 1920×1080 · B站",
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 32,
- columnNumber: 9,
- },
- this,
- ),
- U.jsxDEV(
- "button",
- {
- onClick: i,
- className:
- "flex items-center gap-1 rounded-md border border-white/15 px-2 py-1 text-xs text-white/80 hover:bg-white/5",
- children: [
- U.jsxDEV(
- nl,
- { className: "h-3.5 w-3.5" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 33,
- columnNumber: 151,
- },
- this,
- ),
- "PNG",
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 33,
- columnNumber: 9,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 31,
- columnNumber: 7,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 29,
- columnNumber: 5,
- },
- this,
- );
-}
-function f1({ A: r }) {
- return U.jsxDEV(
- "section",
- {
- className: "rounded-2xl border border-white/10 bg-white/[0.02] p-5",
- children: [
- U.jsxDEV(
- "h2",
- { className: "mb-1 text-lg font-bold", children: "视频封面" },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 42,
- columnNumber: 7,
- },
- this,
- ),
- U.jsxDEV(
- "p",
- {
- className: "mb-4 text-sm text-white/50",
- children: "竖屏封面的文字放在中部,抖音主页 3:4 裁切后依然完整。",
- },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 43,
- columnNumber: 7,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- className: "flex flex-wrap items-start gap-5",
- children: [
- U.jsxDEV(
- tl,
- { A: r, fmt: "landscape" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 44,
- columnNumber: 57,
- },
- this,
- ),
- U.jsxDEV(
- tl,
- { A: r, fmt: "portrait" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 44,
- columnNumber: 92,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 44,
- columnNumber: 7,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 41,
- columnNumber: 5,
- },
- this,
- );
-}
-function h1({ label: r, text: e }) {
- const [t, n] = ye.useState(!1),
- i = async () => {
- try {
- await navigator.clipboard.writeText(e);
- } catch {
- const s = document.createElement("textarea");
- ((s.value = e),
- document.body.appendChild(s),
- s.select(),
- document.execCommand("copy"),
- s.remove());
- }
- (n(!0), setTimeout(() => n(!1), 1500));
- };
- return U.jsxDEV(
- "div",
- {
- className: "rounded-lg border border-white/10 bg-black/20 p-3",
- children: [
- U.jsxDEV(
- "div",
- {
- className: "mb-1.5 flex items-center justify-between",
- children: [
- U.jsxDEV(
- "span",
- {
- className: "text-xs font-semibold text-white/60",
- children: [
- r,
- " ",
- U.jsxDEV(
- "span",
- {
- className: "font-normal text-white/35",
- children: ["· ", [...e].length, " 字"],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 60,
- columnNumber: 71,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 60,
- columnNumber: 9,
- },
- this,
- ),
- U.jsxDEV(
- "button",
- {
- onClick: i,
- className: `flex items-center gap-1 rounded-md px-2 py-1 text-xs transition ${t ? "bg-emerald-500/20 text-emerald-200" : "border border-white/15 text-white/80 hover:bg-white/5"}`,
- children: [
- t
- ? U.jsxDEV(
- hd,
- { className: "h-3.5 w-3.5" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 62,
- columnNumber: 17,
- },
- this,
- )
- : U.jsxDEV(
- md,
- { className: "h-3.5 w-3.5" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 62,
- columnNumber: 53,
- },
- this,
- ),
- t ? "已复制" : "复制",
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 61,
- columnNumber: 9,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 59,
- columnNumber: 7,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- className:
- "whitespace-pre-wrap text-sm leading-relaxed text-white/85",
- children: e,
- },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 65,
- columnNumber: 7,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 58,
- columnNumber: 5,
- },
- this,
- );
-}
-function m1({ brand: r }) {
- const [e, t] = ye.useState("douyin"),
- n = c1(r),
- i = n[e];
- return U.jsxDEV(
- "section",
- {
- className: "rounded-2xl border border-white/10 bg-white/[0.02] p-5",
- children: [
- U.jsxDEV(
- "div",
- {
- className: "mb-4 flex items-center justify-between gap-3",
- children: [
- U.jsxDEV(
- "h2",
- { className: "text-lg font-bold", children: "发布文案" },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 77,
- columnNumber: 9,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- className: "flex rounded-lg border border-white/10 p-0.5",
- children: ["douyin", "bilibili"].map((s) =>
- U.jsxDEV(
- "button",
- {
- onClick: () => t(s),
- className: `rounded-md px-3 py-1 text-sm ${e === s ? (s === "douyin" ? "bg-white text-black font-semibold" : "bg-sky-400 text-black font-semibold") : "text-white/70"}`,
- children: n[s].name,
- },
- s,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 80,
- columnNumber: 13,
- },
- this,
- ),
- ),
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 78,
- columnNumber: 9,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 76,
- columnNumber: 7,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- className: "flex flex-col gap-3",
- children: i.fields.map((s) =>
- U.jsxDEV(
- h1,
- { label: s.label, text: s.text },
- e + s.label,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 84,
- columnNumber: 65,
- },
- this,
- ),
- ),
- },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 84,
- columnNumber: 7,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 75,
- columnNumber: 5,
- },
- this,
- );
-}
-function p1({ current: r, brand: e }) {
- return U.jsxDEV(
- "ol",
- {
- className: "flex flex-col gap-1 text-sm",
- children: qe.map((t, n) =>
- U.jsxDEV(
- "li",
- {
- className: `flex gap-2 rounded px-2 py-1 ${r === n ? "bg-teal-500/15 text-teal-100" : "text-white/60"}`,
- children: [
- U.jsxDEV(
- "span",
- { className: "font-mono text-white/40", children: rs(t.start) },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 94,
- columnNumber: 11,
- },
- this,
- ),
- wo(t.id, e),
- ],
- },
- t.id,
- !0,
- {
- fileName: "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 93,
- columnNumber: 9,
- },
- this,
- ),
- ),
- },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/components/studio/Extras.tsx",
- lineNumber: 91,
- columnNumber: 5,
- },
- this,
- );
-}
-function g1() {
- const [r, e] = ye.useState(null),
- [t, n] = ye.useState(0),
- [i, s] = ye.useState(""),
- [a, o] = ye.useState(() =>
- typeof window < "u" && window.innerWidth < 700 ? "portrait" : "landscape",
- ),
- [c, u] = ye.useState(30),
- [l, d] = ye.useState("ai"),
- f = (h) => {
- (uf(h), d(h));
- };
- return (
- ye.useEffect(() => {
- (async () => {
- var p;
- try {
- await ((p = document.fonts) == null
- ? void 0
- : p.load('900 40px "Noto Sans SC"'));
- } catch {}
- e(await gf(n));
- })().catch((p) => s(String(p)));
- }, []),
- U.jsxDEV(
- "div",
- {
- className: "min-h-screen bg-[#0b0f0e] text-white",
- children: [
- U.jsxDEV(
- "header",
- {
- className: "border-b border-white/5",
- children: U.jsxDEV(
- "div",
- {
- className:
- "mx-auto flex max-w-[1400px] items-center gap-3 px-5 py-4",
- children: [
- U.jsxDEV(
- "img",
- {
- src: "./media/icon.png",
- alt: "",
- className: "h-9 w-9 rounded-lg",
- },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 30,
- columnNumber: 11,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- children: [
- U.jsxDEV(
- "h1",
- {
- className: "text-lg font-black leading-tight",
- children: "豆维 · 宣传片工作室",
- },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 32,
- columnNumber: 13,
- },
- this,
- ),
- U.jsxDEV(
- "p",
- {
- className: "text-xs text-white/50",
- children: [
- "网页实时渲染 · ",
- Math.round(Le),
- " 秒 · 配乐 / 音效 / 旁白 / 字幕 · 一键导出 MP4",
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 33,
- columnNumber: 13,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 31,
- columnNumber: 11,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 29,
- columnNumber: 9,
- },
- this,
- ),
- },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 28,
- columnNumber: 7,
- },
- this,
- ),
- r
- ? U.jsxDEV(
- "main",
- {
- className:
- "mx-auto flex max-w-[1400px] flex-col gap-6 px-5 py-6",
- children: [
- U.jsxDEV(
- "div",
- {
- className: "grid gap-6 lg:grid-cols-[1fr_300px]",
- children: [
- U.jsxDEV(
- l1,
- {
- A: r,
- fmt: a,
- setFmt: o,
- fps: c,
- setFps: u,
- brand: l,
- setBrand: f,
- },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 49,
- columnNumber: 13,
- },
- this,
- ),
- U.jsxDEV(
- "aside",
- {
- className: "flex flex-col gap-4",
- children: [
- U.jsxDEV(
- "div",
- {
- className:
- "rounded-2xl border border-white/10 bg-white/[0.02] p-4",
- children: [
- U.jsxDEV(
- "h2",
- {
- className:
- "mb-2 flex items-center gap-2 font-bold",
- children: [
- U.jsxDEV(
- pd,
- {
- className:
- "h-4 w-4 text-teal-300",
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/App.tsx",
- lineNumber: 52,
- columnNumber: 72,
- },
- this,
- ),
- "分镜",
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/App.tsx",
- lineNumber: 52,
- columnNumber: 17,
- },
- this,
- ),
- U.jsxDEV(
- p1,
- { brand: l },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/App.tsx",
- lineNumber: 53,
- columnNumber: 17,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/App.tsx",
- lineNumber: 51,
- columnNumber: 15,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- className:
- "rounded-2xl border border-white/10 bg-white/[0.02] p-4 text-sm leading-relaxed text-white/60",
- children: [
- U.jsxDEV(
- "h2",
- {
- className:
- "mb-2 font-bold text-white",
- children: "版式说明",
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/App.tsx",
- lineNumber: 56,
- columnNumber: 17,
- },
- this,
- ),
- U.jsxDEV(
- "p",
- {
- className: "mb-2",
- children: [
- U.jsxDEV(
- "b",
- {
- className: "text-white/85",
- children: "平台版本",
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/App.tsx",
- lineNumber: 57,
- columnNumber: 37,
- },
- this,
- ),
- ":「和 AI / 豆包 AI / WorkBuddy 一起写」三选一,片中旁白、字幕、画面和发布文案同步切换,导出的 MP4 即对应版本。",
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/App.tsx",
- lineNumber: 57,
- columnNumber: 17,
- },
- this,
- ),
- U.jsxDEV(
- "p",
- {
- children: [
- U.jsxDEV(
- "b",
- {
- className: "text-white/85",
- children: "横屏",
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/App.tsx",
- lineNumber: 58,
- columnNumber: 20,
- },
- this,
- ),
- ":1920×1080,适合哔哩哔哩,竖拍素材以模糊背景 + 卡片 / 手机样机呈现。",
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/App.tsx",
- lineNumber: 58,
- columnNumber: 17,
- },
- this,
- ),
- U.jsxDEV(
- "p",
- {
- className: "mt-2",
- children: [
- U.jsxDEV(
- "b",
- {
- className: "text-white/85",
- children: "竖屏",
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/App.tsx",
- lineNumber: 59,
- columnNumber: 37,
- },
- this,
- ),
- ":1080×1920,适合抖音。顶部 210px 避开刘海与状态栏,底部 440px 避开标题、文案和进度条,右侧 150px 避开点赞评论按钮;字幕和关键信息全部在安全区内。打开「平台遮挡区」可查看。",
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/App.tsx",
- lineNumber: 59,
- columnNumber: 17,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName:
- "/workspaces/frontend/src/App.tsx",
- lineNumber: 55,
- columnNumber: 15,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 50,
- columnNumber: 13,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 48,
- columnNumber: 11,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- className: "grid gap-6 lg:grid-cols-2",
- children: [
- U.jsxDEV(
- f1,
- { A: r },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 64,
- columnNumber: 13,
- },
- this,
- ),
- U.jsxDEV(
- m1,
- { brand: l },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 65,
- columnNumber: 13,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 63,
- columnNumber: 11,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 47,
- columnNumber: 9,
- },
- this,
- )
- : U.jsxDEV(
- "div",
- {
- className:
- "flex h-[70vh] flex-col items-center justify-center gap-4",
- children: i
- ? U.jsxDEV(
- "p",
- {
- className: "text-rose-300",
- children: ["素材加载失败:", i],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 40,
- columnNumber: 18,
- },
- this,
- )
- : U.jsxDEV(
- U.Fragment,
- {
- children: [
- U.jsxDEV(
- ca,
- {
- className: "h-8 w-8 animate-spin text-teal-300",
- },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 41,
- columnNumber: 13,
- },
- this,
- ),
- U.jsxDEV(
- "p",
- {
- className: "text-sm text-white/60",
- children: [
- "正在加载视频与照片素材… ",
- Math.round(t * 100),
- "%",
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 42,
- columnNumber: 13,
- },
- this,
- ),
- U.jsxDEV(
- "div",
- {
- className:
- "h-1.5 w-64 overflow-hidden rounded-full bg-white/10",
- children: U.jsxDEV(
- "div",
- {
- className:
- "h-full bg-teal-400 transition-[width]",
- style: { width: `${t * 100}%` },
- },
- void 0,
- !1,
- {
- fileName:
- "/workspaces/frontend/src/App.tsx",
- lineNumber: 43,
- columnNumber: 82,
- },
- this,
- ),
- },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 43,
- columnNumber: 13,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 40,
- columnNumber: 66,
- },
- this,
- ),
- },
- void 0,
- !1,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 39,
- columnNumber: 9,
- },
- this,
- ),
- ],
- },
- void 0,
- !0,
- {
- fileName: "/workspaces/frontend/src/App.tsx",
- lineNumber: 27,
- columnNumber: 5,
- },
- this,
- )
- );
-}
-const C1 = Object.freeze(
- Object.defineProperty({ __proto__: null, default: g1 }, Symbol.toStringTag, {
- value: "Module",
- }),
-);
-export { C1 as A, Dp as C, Ee as E, te as L, S1 as n, P1 as r };
diff --git a/assets/ErrorBoundary-DwultlP_.js b/assets/ErrorBoundary-DwultlP_.js
deleted file mode 100644
index 78b27d02220c6bc02fe177da900bc77c156c3ede..0000000000000000000000000000000000000000
--- a/assets/ErrorBoundary-DwultlP_.js
+++ /dev/null
@@ -1 +0,0 @@
-var m=Object.defineProperty;var p=(e,r,t)=>r in e?m(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t;var i=(e,r,t)=>p(e,typeof r!="symbol"?r+"":r,t);import{j as o}from"./jsx-dev-runtime-Czb3f8pQ.js";import{r as f}from"./index-Br42UDbl.js";import"./index-BlGQAcOD.js";const u="__dep_reload",a=6,c=6e4,g=["reading 'useState'","reading 'useEffect'","reading 'useRef'","reading 'useCallback'","reading 'useMemo'","reading 'useContext'","reading 'useReducer'"];function d(e){return g.some(r=>e.includes(r))}function l(){try{const e=sessionStorage.getItem(u);if(e)return JSON.parse(e)}catch{}return{c:0,t:0}}class N extends f.Component{constructor(){super(...arguments);i(this,"state",{error:null})}static getDerivedStateFromError(t){return{error:t}}componentDidCatch(t){if(!d(t.message))return;const s=l(),n=Date.now()-s.t>c?0:s.c;nlocation.reload(),3e3))}render(){if(this.state.error){if(this.props.fallback)return this.props.fallback;if(d(this.state.error.message)){const{c:t,t:s}=l();if(!(Date.now()-s<=c)||tve[ce]})}}}return Object.freeze(Object.defineProperty(Z,Symbol.toStringTag,{value:"Module"}))}var tp={exports:{}},Zi={},lp={exports:{}},np={},IS;function FE(){return IS||(IS=1,(function(Z){/**
- * @license React
- * scheduler.development.js
- *
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */(function(){function Ot(){if(ro=!1,$l){var O=Z.unstable_now();Me=O;var Y=!0;try{e:{En=!1,An&&(An=!1,yl(x),x=-1),eu=!0;var G=ze;try{t:{for(ml(O),Be=ve(H);Be!==null&&!(Be.expirationTime>O&&Re());){var fe=Be.callback;if(typeof fe=="function"){Be.callback=null,ze=Be.priorityLevel;var _e=fe(Be.expirationTime<=O);if(O=Z.unstable_now(),typeof _e=="function"){Be.callback=_e,ml(O),Y=!0;break t}Be===ve(H)&&ce(H),ml(O)}else ce(H);Be=ve(H)}if(Be!==null)Y=!0;else{var lu=ve(Oe);lu!==null&&fa(z,lu.startTime-O),Y=!1}}break e}finally{Be=null,ze=G,eu=!1}Y=void 0}}finally{Y?ee():$l=!1}}}function Vt(O,Y){var G=O.length;O.push(Y);e:for(;0>>1,_e=O[fe];if(0>>1;feQe(da,G))He<_e&&0>Qe(Dn,da)?(O[fe]=Dn,O[He]=G,fe=He):(O[fe]=da,O[nu]=G,fe=nu);else if(He<_e&&0>Qe(Dn,G))O[fe]=Dn,O[He]=G,fe=He;else break e}}return Y}function Qe(O,Y){var G=O.sortIndex-Y.sortIndex;return G!==0?G:O.id-Y.id}function ml(O){for(var Y=ve(Oe);Y!==null;){if(Y.callback===null)ce(Oe);else if(Y.startTime<=O)ce(Oe),Y.sortIndex=Y.expirationTime,Vt(H,Y);else break;Y=ve(Oe)}}function z(O){if(An=!1,ml(O),!En)if(ve(H)!==null)En=!0,$l||($l=!0,ee());else{var Y=ve(Oe);Y!==null&&fa(z,Y.startTime-O)}}function Re(){return ro?!0:!(Z.unstable_now()-MeO||125fe?(O.sortIndex=G,Vt(Oe,O),ve(H)===null&&O===ve(Oe)&&(An?(yl(x),x=-1):An=!0,fa(z,G-fe))):(O.sortIndex=_e,Vt(H,O),En||eu||(En=!0,$l||($l=!0,ee()))),O},Z.unstable_shouldYield=Re,Z.unstable_wrapCallback=function(O){var Y=ze;return function(){var G=ze;ze=Y;try{return O.apply(this,arguments)}finally{ze=G}}},typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())})()})(np)),np}var PS;function WE(){return PS||(PS=1,lp.exports=FE()),lp.exports}var ap={exports:{}},ct={},eb;function IE(){if(eb)return ct;eb=1;/**
- * @license React
- * react-dom.development.js
- *
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */return(function(){function Z(){}function Ot(E){return""+E}function Vt(E,S,H){var Oe=3` tag.%s',H),typeof E=="string"&&typeof S=="object"&&S!==null&&typeof S.as=="string"){H=S.as;var Oe=ve(H,S.crossOrigin);Re.d.L(E,H,{crossOrigin:Oe,integrity:typeof S.integrity=="string"?S.integrity:void 0,nonce:typeof S.nonce=="string"?S.nonce:void 0,type:typeof S.type=="string"?S.type:void 0,fetchPriority:typeof S.fetchPriority=="string"?S.fetchPriority:void 0,referrerPolicy:typeof S.referrerPolicy=="string"?S.referrerPolicy:void 0,imageSrcSet:typeof S.imageSrcSet=="string"?S.imageSrcSet:void 0,imageSizes:typeof S.imageSizes=="string"?S.imageSizes:void 0,media:typeof S.media=="string"?S.media:void 0})}},ct.preloadModule=function(E,S){var H="";typeof E=="string"&&E||(H+=" The `href` argument encountered was "+ce(E)+"."),S!==void 0&&typeof S!="object"?H+=" The `options` argument encountered was "+ce(S)+".":S&&"as"in S&&typeof S.as!="string"&&(H+=" The `as` option encountered was "+ce(S.as)+"."),H&&console.error('ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `` tag.%s',H),typeof E=="string"&&(S?(H=ve(S.as,S.crossOrigin),Re.d.m(E,{as:typeof S.as=="string"&&S.as!=="script"?S.as:void 0,crossOrigin:H,integrity:typeof S.integrity=="string"?S.integrity:void 0})):Re.d.m(E))},ct.requestFormReset=function(E){Re.d.r(E)},ct.unstable_batchedUpdates=function(E,S){return E(S)},ct.useFormState=function(E,S,H){return ml().useFormState(E,S,H)},ct.useFormStatus=function(){return ml().useHostTransitionStatus()},ct.version="19.2.4",typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())})(),ct}var tb;function PE(){return tb||(tb=1,ap.exports=IE()),ap.exports}var lb;function eA(){if(lb)return Zi;lb=1;/**
- * @license React
- * react-dom-client.development.js
- *
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */return(function(){function Z(e,t){for(e=e.memoizedState;e!==null&&0=t.length)return n;var a=t[l],u=Ze(e)?e.slice():$({},e);return u[a]=Ot(e[a],t,l+1,n),u}function Vt(e,t,l){if(t.length!==l.length)console.warn("copyWithRename() expects paths of the same length");else{for(var n=0;nnn?console.error("Unexpected pop."):(t!==xd[nn]&&console.error("Unexpected Fiber popped."),e.current=Hd[nn],Hd[nn]=null,xd[nn]=null,nn--)}function ee(e,t,l){nn++,Hd[nn]=e.current,xd[nn]=l,e.current=t}function gl(e){return e===null&&console.error("Expected host context to exist. This error is likely caused by a bug in React. Please file an issue."),e}function tu(e,t){ee(Nn,t,e),ee(Wo,e,e),ee(Yn,null,e);var l=t.nodeType;switch(l){case 9:case 11:l=l===9?"#document":"#fragment",t=(t=t.documentElement)&&(t=t.namespaceURI)?Bg(t):Sn;break;default:if(l=t.tagName,t=t.namespaceURI)t=Bg(t),t=qg(t,l);else switch(l){case"svg":t=io;break;case"math":t=ns;break;default:t=Sn}}l=l.toLowerCase(),l=Cp(null,l),l={context:t,ancestorInfo:l},Me(Yn,e),ee(Yn,l,e)}function O(e){Me(Yn,e),Me(Wo,e),Me(Nn,e)}function Y(){return gl(Yn.current)}function G(e){e.memoizedState!==null&&ee(or,e,e);var t=gl(Yn.current),l=e.type,n=qg(t.context,l);l=Cp(t.ancestorInfo,l),n={context:n,ancestorInfo:l},t!==n&&(ee(Wo,e,e),ee(Yn,n,e))}function fe(e){Wo.current===e&&(Me(Yn,e),Me(Wo,e)),or.current===e&&(Me(or,e),Li._currentValue=Pa)}function _e(){}function lu(){if(Io===0){d0=console.log,h0=console.info,p0=console.warn,m0=console.error,y0=console.group,g0=console.groupCollapsed,v0=console.groupEnd;var e={configurable:!0,enumerable:!0,value:_e,writable:!0};Object.defineProperties(console,{info:e,log:e,warn:e,error:e,group:e,groupCollapsed:e,groupEnd:e})}Io++}function nu(){if(Io--,Io===0){var e={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:$({},e,{value:d0}),info:$({},e,{value:h0}),warn:$({},e,{value:p0}),error:$({},e,{value:m0}),group:$({},e,{value:y0}),groupCollapsed:$({},e,{value:g0}),groupEnd:$({},e,{value:v0})})}0>Io&&console.error("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}function da(e){var t=Error.prepareStackTrace;if(Error.prepareStackTrace=void 0,e=e.stack,Error.prepareStackTrace=t,e.startsWith(`Error: react-stack-top-frame
-`)&&(e=e.slice(29)),t=e.indexOf(`
-`),t!==-1&&(e=e.slice(t+1)),t=e.indexOf("react_stack_bottom_frame"),t!==-1&&(t=e.lastIndexOf(`
-`,t)),t!==-1)e=e.slice(0,t);else return"";return e}function He(e){if(wd===void 0)try{throw Error()}catch(l){var t=l.stack.trim().match(/\n( *(at )?)/);wd=t&&t[1]||"",S0=-1)":-1o||r[u]!==p[o]){var m=`
-`+r[u].replace(" at new "," at ");return e.displayName&&m.includes("")&&(m=m.replace("",e.displayName)),typeof e=="function"&&qd.set(e,m),m}while(1<=u&&0<=o);break}}}finally{Bd=!1,v.H=n,nu(),Error.prepareStackTrace=l}return r=(r=e?e.displayName||e.name:"")?He(r):"",typeof e=="function"&&qd.set(e,r),r}function ob(e,t){switch(e.tag){case 26:case 27:case 5:return He(e.type);case 16:return He("Lazy");case 13:return e.child!==t&&t!==null?He("Suspense Fallback"):He("Suspense");case 19:return He("SuspenseList");case 0:case 15:return Dn(e.type,!1);case 11:return Dn(e.type.render,!1);case 1:return Dn(e.type,!0);case 31:return He("Activity");default:return""}}function up(e){try{var t="",l=null;do{t+=ob(e,l);var n=e._debugInfo;if(n)for(var a=n.length-1;0<=a;a--){var u=n[a];if(typeof u.name=="string"){var o=t;e:{var i=u.name,c=u.env,r=u.debugLocation;if(r!=null){var p=da(r),m=p.lastIndexOf(`
-`),f=m===-1?p:p.slice(m+1);if(f.indexOf(i)!==-1){var y=`
-`+f;break e}}y=He(i+(c?" ["+c+"]":""))}t=o+y}}l=e,e=e.return}while(e);return t}catch(A){return`
-Error generating stack: `+A.message+`
-`+A.stack}}function op(e){return(e=e?e.displayName||e.name:"")?He(e):""}function Ji(){if(Bt===null)return null;var e=Bt._debugOwner;return e!=null?$l(e):null}function ib(){if(Bt===null)return"";var e=Bt;try{var t="";switch(e.tag===6&&(e=e.return),e.tag){case 26:case 27:case 5:t+=He(e.type);break;case 13:t+=He("Suspense");break;case 19:t+=He("SuspenseList");break;case 31:t+=He("Activity");break;case 30:case 0:case 15:case 1:e._debugOwner||t!==""||(t+=op(e.type));break;case 11:e._debugOwner||t!==""||(t+=op(e.type.render))}for(;e;)if(typeof e.tag=="number"){var l=e;e=l._debugOwner;var n=l._debugStack;if(e&&n){var a=da(n);a!==""&&(t+=`
-`+a)}}else if(e.debugStack!=null){var u=e.debugStack;(e=e.owner)&&u&&(t+=`
-`+da(u))}else break;var o=t}catch(i){o=`
-Error generating stack: `+i.message+`
-`+i.stack}return o}function M(e,t,l,n,a,u,o){var i=Bt;ss(e);try{return e!==null&&e._debugTask?e._debugTask.run(t.bind(null,l,n,a,u,o)):t(l,n,a,u,o)}finally{ss(i)}throw Error("runWithFiberInDEV should never be called in production. This is a bug in React.")}function ss(e){v.getCurrentStack=e===null?null:ib,ql=!1,Bt=e}function $i(e){return typeof Symbol=="function"&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object"}function Ki(e){try{return fo(e),!1}catch{return!0}}function fo(e){return""+e}function de(e,t){if(Ki(e))return console.error("The provided `%s` attribute is an unsupported type %s. This value must be coerced to a string before using it here.",t,$i(e)),fo(e)}function fs(e,t){if(Ki(e))return console.error("The provided `%s` CSS property is an unsupported type %s. This value must be coerced to a string before using it here.",t,$i(e)),fo(e)}function ds(e){if(Ki(e))return console.error("Form field values (value, checked, defaultValue, or defaultChecked props) must be strings, not %s. This value must be coerced to a string before using it here.",$i(e)),fo(e)}function cb(e){if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u")return!1;var t=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(t.isDisabled)return!0;if(!t.supportsFiber)return console.error("The installed version of React DevTools is too old and will not work with the current version of React. Please update React DevTools. https://react.dev/link/react-devtools"),!0;try{Cu=t.inject(e),ot=t}catch(l){console.error("React instrumentation encountered an error: %o.",l)}return!!t.checkDCE}function be(e){if(typeof sT=="function"&&fT(e),ot&&typeof ot.setStrictMode=="function")try{ot.setStrictMode(Cu,e)}catch(t){jl||(jl=!0,console.error("React instrumentation encountered an error: %o",t))}}function rb(e){return e>>>=0,e===0?32:31-(dT(e)/hT|0)|0}function ha(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return console.error("Should have found matching lanes. This is a bug in React."),e}}function ki(e,t,l){var n=e.pendingLanes;if(n===0)return 0;var a=0,u=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var i=n&134217727;return i!==0?(n=i&~u,n!==0?a=ha(n):(o&=i,o!==0?a=ha(o):l||(l=i&~e,l!==0&&(a=ha(l))))):(i=n&~u,i!==0?a=ha(i):o!==0?a=ha(o):l||(l=n&~e,l!==0&&(a=ha(l)))),a===0?0:t!==0&&t!==a&&(t&u)===0&&(u=a&-a,l=t&-t,u>=l||u===32&&(l&4194048)!==0)?t:a}function ho(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function sb(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return console.error("Should have found matching lanes. This is a bug in React."),-1}}function hs(){var e=rr;return rr<<=1,(rr&62914560)===0&&(rr=4194304),e}function ps(e){for(var t=[],l=0;31>l;l++)t.push(e);return t}function po(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function fb(e,t,l,n,a,u){var o=e.pendingLanes;e.pendingLanes=l,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=l,e.entangledLanes&=l,e.errorRecoveryDisabledLanes&=l,e.shellSuspendCounter=0;var i=e.entanglements,c=e.expirationTimes,r=e.hiddenUpdates;for(l=o&~l;0"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function Xt(e){return e.replace(vT,function(t){return"\\"+t.charCodeAt(0).toString(16)+" "})}function gp(e,t){t.checked===void 0||t.defaultChecked===void 0||R0||(console.error("%s contains an input of type %s with both checked and defaultChecked props. Input elements must be either controlled or uncontrolled (specify either the checked prop, or the defaultChecked prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://react.dev/link/controlled-components",Ji()||"A component",t.type),R0=!0),t.value===void 0||t.defaultValue===void 0||D0||(console.error("%s contains an input of type %s with both value and defaultValue props. Input elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://react.dev/link/controlled-components",Ji()||"A component",t.type),D0=!0)}function bs(e,t,l,n,a,u,o,i){e.name="",o!=null&&typeof o!="function"&&typeof o!="symbol"&&typeof o!="boolean"?(de(o,"type"),e.type=o):e.removeAttribute("type"),t!=null?o==="number"?(t===0&&e.value===""||e.value!=t)&&(e.value=""+Lt(t)):e.value!==""+Lt(t)&&(e.value=""+Lt(t)):o!=="submit"&&o!=="reset"||e.removeAttribute("value"),t!=null?Ts(e,o,Lt(t)):l!=null?Ts(e,o,Lt(l)):n!=null&&e.removeAttribute("value"),a==null&&u!=null&&(e.defaultChecked=!!u),a!=null&&(e.checked=a&&typeof a!="function"&&typeof a!="symbol"),i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"?(de(i,"name"),e.name=""+Lt(i)):e.removeAttribute("name")}function vp(e,t,l,n,a,u,o,i){if(u!=null&&typeof u!="function"&&typeof u!="symbol"&&typeof u!="boolean"&&(de(u,"type"),e.type=u),t!=null||l!=null){if(!(u!=="submit"&&u!=="reset"||t!=null)){Ss(e);return}l=l!=null?""+Lt(l):"",t=t!=null?""+Lt(t):l,i||t===e.value||(e.value=t),e.defaultValue=t}n=n??a,n=typeof n!="function"&&typeof n!="symbol"&&!!n,e.checked=i?e.checked:!!n,e.defaultChecked=!!n,o!=null&&typeof o!="function"&&typeof o!="symbol"&&typeof o!="boolean"&&(de(o,"name"),e.name=o),Ss(e)}function Ts(e,t,l){t==="number"&&Ii(e.ownerDocument)===e||e.defaultValue===""+l||(e.defaultValue=""+l)}function Sp(e,t){t.value==null&&(typeof t.children=="object"&&t.children!==null?Od.Children.forEach(t.children,function(l){l==null||typeof l=="string"||typeof l=="number"||typeof l=="bigint"||z0||(z0=!0,console.error("Cannot infer the option value of complex children. Pass a `value` prop or use a plain string as children to